Compare commits

..

771 Commits

Author SHA1 Message Date
Jamie Curnow
fd30cfe98b Fix linting
Some checks reported errors
bastion/nginx-proxy-manager/pipeline/head Something is wrong with the build of this commit
2022-11-15 07:54:48 +10:00
Jamie Curnow
6f281fef42 Workaround for cloudflare plugin install (#2381) 2022-11-15 07:48:57 +10:00
jc21
41bbfcf165
Merge branch 'master' into develop 2022-11-08 13:32:32 +10:00
Jamie Curnow
80a93e17fa Bump version 2022-11-08 13:31:27 +10:00
Jamie Curnow
4a1eebc54b Linked to contributors instead of managing for every release 2022-11-08 13:30:41 +10:00
jc21
264ba71462
Merge pull request #2230 from wnhrt/add-autofocus-to-login
Added autofocus to email input on login screen
2022-11-08 13:12:45 +10:00
jc21
e229fa89f8
Merge pull request #2222 from mantoufan/add-webp-to-assets.conf-for-cache-assets
Add webp format to assets.conf for Cache Assets
2022-11-08 13:12:13 +10:00
Jamie Curnow
d3b72ae07d Fix tabs after web-resolved change 2022-11-08 11:53:13 +10:00
jc21
b62b6b5112
Merge pull request #2373 from lakkeri/develop
Possible multiple X-Forwarded-For headers
2022-11-08 11:48:05 +10:00
jc21
c44f8c6155
Merge pull request #2312 from knoxell/knoxell#add-namecheap
Added Namecheap certbot dns plugin
2022-11-08 11:45:41 +10:00
jc21
0dfa3d9ca3
Merge pull request #2379 from NginxProxyManager/dependabot/npm_and_yarn/docs/loader-utils-2.0.3
Bump loader-utils from 2.0.0 to 2.0.3 in /docs
2022-11-08 11:44:55 +10:00
jc21
8c7c84906b
Merge pull request #2327 from DFS-90/develop
added DomainOffensive (do.de) certbot dns plugin (update certbot-dns-plugins.js)
2022-11-08 11:44:30 +10:00
jc21
662143cf21
Merge branch 'develop' into develop 2022-11-08 11:44:22 +10:00
jc21
c60fc7926e
Merge pull request #2298 from ATCUSA/develop
Update for docker-compose-plugin command
2022-11-08 11:41:57 +10:00
jc21
cfbdc6c340
Merge pull request #2294 from oleban/add-domeneshop-plugin
Added Domeneshop certbot dns plugin
2022-11-08 11:41:34 +10:00
jc21
2f6d8257ec
Merge pull request #2259 from cuishuang/develop
all: fix some typos
2022-11-08 11:40:42 +10:00
jc21
b9a6b5d4f5
Merge pull request #2355 from rovast/patch-1
Update README.md
2022-11-08 11:01:10 +10:00
dependabot[bot]
32f77dbcee
Bump loader-utils from 2.0.0 to 2.0.3 in /docs
Bumps [loader-utils](https://github.com/webpack/loader-utils) from 2.0.0 to 2.0.3.
- [Release notes](https://github.com/webpack/loader-utils/releases)
- [Changelog](https://github.com/webpack/loader-utils/blob/v2.0.3/CHANGELOG.md)
- [Commits](https://github.com/webpack/loader-utils/compare/v2.0.0...v2.0.3)

---
updated-dependencies:
- dependency-name: loader-utils
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-08 00:53:09 +00:00
lakkeri
052cb8f12d
Possible multiple X-Forwarded-For headers
NMP behind another reverse proxy can multiply X-Forwarded-For headers. $proxy_add_x_forwarded_for equals to $remote_addr if this header not present in client request 
https://nginx.org/en/docs/http/ngx_http_proxy_module.html#var_proxy_add_x_forwarded_for
2022-11-05 16:24:12 +03:00
ROVAST
03b544023b
Update README.md
Fix docker compose up warning message 

```
WARN[0000] network default: network.external.name is deprecated in favor of network.name
```
2022-11-02 10:26:01 +08:00
jc21
5070499cfd
Merge pull request #2335 from Czocher/fix-disable-ipv6
Fix DISABLE_IPV6 flag handling
2022-10-21 08:57:08 +10:00
Paweł Jan Czochański
e77b13d36e
Fix DISABLE_IPV6 flag handling
The DISABLE_IPV6 flag did not turn off ipv6 DNS requests performed by
nginx. This commit changes it and makes nginx-proxy-manager more
compatible with podman.
2022-10-20 07:55:08 +02:00
DFS-90
4bb237d7c2
Update certbot-dns-plugins.js
added DomainOffensive (do.de) certbot dns plugin
2022-10-16 00:24:18 +02:00
knoxell
aa5a7faa94 Added Namecheap 2022-10-08 21:53:34 +02:00
Austin
837f4dcbd4 Update for docker-compose-plugin command 2022-10-02 05:05:46 +00:00
Ole Bøe Andreassen
d73a246b66
Added Domeneshop certbot dns plugin 2022-09-28 11:48:31 +02:00
cui fliter
f85e82973d all: fix some typos
Signed-off-by: cui fliter <imcusg@gmail.com>
2022-09-10 21:08:16 +08:00
Niklas Weinhart
84afec567c Added autofocus to email input on login screen 2022-08-28 19:54:50 +02:00
馒头饭
e1525e5d56 Add webp format to assets.conf for Cache Assets 2022-08-26 03:47:06 +08:00
Jamie Curnow
d2688cf08c CI - don't remove all other images, causing errors in new docker-compose 2022-08-24 07:15:28 +10:00
jc21
7372319568
Merge pull request #2051 from Nobody84/develop
update certbot-dns-duckdns to 0.9
2022-08-23 20:59:16 +10:00
jc21
60ffec5c64
Merge pull request #2072 from NginxProxyManager/dependabot/npm_and_yarn/docs/eventsource-2.0.2
Bump eventsource from 1.0.7 to 2.0.2 in /docs
2022-08-23 20:57:21 +10:00
jc21
23c88f6955
Merge pull request #2090 from swazynski/patch-1
Add trailing slash to example
2022-08-23 20:57:04 +10:00
jc21
dd14207b63
Merge pull request #2110 from cfoellmann/footer-blank
open footer link "Fork me" in new tab/windows (_blank)
2022-08-23 20:44:56 +10:00
jc21
103adfbb57
Merge pull request #2125 from NginxProxyManager/dependabot/npm_and_yarn/test/async-3.2.4
Bump async from 3.2.0 to 3.2.4 in /test
2022-08-23 20:44:32 +10:00
jc21
b673ebe2ca
Merge pull request #2126 from NginxProxyManager/dependabot/npm_and_yarn/backend/async-3.2.4
Bump async from 3.2.1 to 3.2.4 in /backend
2022-08-23 20:44:21 +10:00
jc21
0e0c3df0cd
Merge pull request #2142 from NginxProxyManager/dependabot/npm_and_yarn/frontend/moment-2.29.4
Bump moment from 2.27.0 to 2.29.4 in /frontend
2022-08-23 20:44:08 +10:00
jc21
8dbd482e08
Merge pull request #2143 from NginxProxyManager/dependabot/npm_and_yarn/test/moment-2.29.4
Bump moment from 2.27.0 to 2.29.4 in /test
2022-08-23 20:43:44 +10:00
jc21
ab5f7c0f26
Merge pull request #2144 from NginxProxyManager/dependabot/npm_and_yarn/backend/moment-2.29.4
Bump moment from 2.27.0 to 2.29.4 in /backend
2022-08-23 20:43:35 +10:00
jc21
191f493eb9
Merge pull request #2162 from NginxProxyManager/dependabot/npm_and_yarn/docs/terser-5.14.2
Bump terser from 5.0.0 to 5.14.2 in /docs
2022-08-23 20:43:24 +10:00
jc21
d1f4640a9c
Merge pull request #2164 from NginxProxyManager/dependabot/npm_and_yarn/frontend/terser-4.8.1
Bump terser from 4.8.0 to 4.8.1 in /frontend
2022-08-23 20:43:15 +10:00
jc21
3d97f4578d
Merge pull request #2206 from phulstaert/patch-1
fix typo
2022-08-23 20:42:59 +10:00
Peter Hulstaert
fb0ef08fd8
fix typo 2022-08-18 09:25:45 +02:00
dependabot[bot]
0de78205b5
Bump terser from 4.8.0 to 4.8.1 in /frontend
Bumps [terser](https://github.com/terser/terser) from 4.8.0 to 4.8.1.
- [Release notes](https://github.com/terser/terser/releases)
- [Changelog](https://github.com/terser/terser/blob/master/CHANGELOG.md)
- [Commits](https://github.com/terser/terser/commits)

---
updated-dependencies:
- dependency-name: terser
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-20 21:35:47 +00:00
dependabot[bot]
e0821bd927
Bump terser from 5.0.0 to 5.14.2 in /docs
Bumps [terser](https://github.com/terser/terser) from 5.0.0 to 5.14.2.
- [Release notes](https://github.com/terser/terser/releases)
- [Changelog](https://github.com/terser/terser/blob/master/CHANGELOG.md)
- [Commits](https://github.com/terser/terser/commits)

---
updated-dependencies:
- dependency-name: terser
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-20 01:39:09 +00:00
dependabot[bot]
e5966b54a8
Bump moment from 2.27.0 to 2.29.4 in /backend
Bumps [moment](https://github.com/moment/moment) from 2.27.0 to 2.29.4.
- [Release notes](https://github.com/moment/moment/releases)
- [Changelog](https://github.com/moment/moment/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/moment/moment/compare/2.27.0...2.29.4)

---
updated-dependencies:
- dependency-name: moment
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-07 16:43:24 +00:00
dependabot[bot]
d2f6b09901
Bump moment from 2.27.0 to 2.29.4 in /test
Bumps [moment](https://github.com/moment/moment) from 2.27.0 to 2.29.4.
- [Release notes](https://github.com/moment/moment/releases)
- [Changelog](https://github.com/moment/moment/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/moment/moment/compare/2.27.0...2.29.4)

---
updated-dependencies:
- dependency-name: moment
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-07 16:43:16 +00:00
dependabot[bot]
5c8aa8517b
Bump moment from 2.27.0 to 2.29.4 in /frontend
Bumps [moment](https://github.com/moment/moment) from 2.27.0 to 2.29.4.
- [Release notes](https://github.com/moment/moment/releases)
- [Changelog](https://github.com/moment/moment/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/moment/moment/compare/2.27.0...2.29.4)

---
updated-dependencies:
- dependency-name: moment
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-07 16:43:13 +00:00
dependabot[bot]
1e5916db28
Bump async from 3.2.1 to 3.2.4 in /backend
Bumps [async](https://github.com/caolan/async) from 3.2.1 to 3.2.4.
- [Release notes](https://github.com/caolan/async/releases)
- [Changelog](https://github.com/caolan/async/blob/master/CHANGELOG.md)
- [Commits](https://github.com/caolan/async/compare/v3.2.1...v3.2.4)

---
updated-dependencies:
- dependency-name: async
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-22 17:38:17 +00:00
dependabot[bot]
a3ae6956e2
Bump async from 3.2.0 to 3.2.4 in /test
Bumps [async](https://github.com/caolan/async) from 3.2.0 to 3.2.4.
- [Release notes](https://github.com/caolan/async/releases)
- [Changelog](https://github.com/caolan/async/blob/master/CHANGELOG.md)
- [Commits](https://github.com/caolan/async/compare/v3.2.0...v3.2.4)

---
updated-dependencies:
- dependency-name: async
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-22 16:50:18 +00:00
Christian Foellmann
518b84b38b open footer link "Fork me" in new tab/windows (_blank) 2022-06-15 12:20:54 +02:00
swazynski
932dc4bf02
Add trailing slash to example 2022-06-03 15:20:26 +02:00
dependabot[bot]
bdc3a555b6
Bump eventsource from 1.0.7 to 2.0.2 in /docs
Bumps [eventsource](https://github.com/EventSource/eventsource) from 1.0.7 to 2.0.2.
- [Release notes](https://github.com/EventSource/eventsource/releases)
- [Changelog](https://github.com/EventSource/eventsource/blob/master/HISTORY.md)
- [Commits](https://github.com/EventSource/eventsource/compare/v1.0.7...v2.0.2)

---
updated-dependencies:
- dependency-name: eventsource
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-26 06:36:19 +00:00
Nobody84
d4dcb61ee6
update certbot-dns-duckdns to 0.9 2022-05-14 00:30:18 +02:00
jc21
cce73beb2d
Merge pull request #1967 from NginxProxyManager/develop
v2.9.18
2022-03-31 15:40:49 +10:00
Jamie Curnow
4db34f5894 Bump version, to trigger rebuild with updated base images 2022-03-31 14:43:41 +10:00
jc21
063ac4619f
Merge pull request #1966 from NginxProxyManager/develop
v2.9.17
2022-03-31 11:32:05 +10:00
jc21
d1a338107b
Merge branch 'master' into develop 2022-03-31 10:21:19 +10:00
Jamie Curnow
0d0b7e117f Bump version 2022-03-31 10:20:27 +10:00
jc21
3538f9719f
Merge pull request #1951 from NginxProxyManager/test-html-encode
Fix #1950 attempt to encode hdomain values before render
2022-03-25 09:03:30 +10:00
Jamie Curnow
feaafdc559 Fix #1950 attempt to encode hdomain values before render 2022-03-25 08:31:28 +10:00
jc21
eb148eb8f0
Merge pull request #1904 from NginxProxyManager/dependabot/npm_and_yarn/docs/url-parse-1.5.9
Bump url-parse from 1.5.2 to 1.5.9 in /docs
2022-03-15 07:38:11 +10:00
jc21
e879d41ee4
Merge pull request #1892 from NginxProxyManager/dependabot/npm_and_yarn/docs/prismjs-1.27.0
Bump prismjs from 1.25.0 to 1.27.0 in /docs
2022-03-15 07:18:23 +10:00
jc21
bb26f5b2c7
Merge pull request #1863 from omercnet/patch-1
Update resolvers.conf to break dns cache
2022-03-15 07:17:24 +10:00
dependabot[bot]
8e61d3eadf
Bump url-parse from 1.5.2 to 1.5.9 in /docs
Bumps [url-parse](https://github.com/unshiftio/url-parse) from 1.5.2 to 1.5.9.
- [Release notes](https://github.com/unshiftio/url-parse/releases)
- [Commits](https://github.com/unshiftio/url-parse/compare/1.5.2...1.5.9)

---
updated-dependencies:
- dependency-name: url-parse
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-02 18:35:56 +00:00
dependabot[bot]
749ab36b1a
Bump prismjs from 1.25.0 to 1.27.0 in /docs
Bumps [prismjs](https://github.com/PrismJS/prism) from 1.25.0 to 1.27.0.
- [Release notes](https://github.com/PrismJS/prism/releases)
- [Changelog](https://github.com/PrismJS/prism/blob/master/CHANGELOG.md)
- [Commits](https://github.com/PrismJS/prism/compare/v1.25.0...v1.27.0)

---
updated-dependencies:
- dependency-name: prismjs
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-26 01:52:17 +00:00
jc21
c68874743d
Merge pull request #1864 from NginxProxyManager/develop
v2.9.16
2022-02-19 21:47:15 +10:00
jc21
1a76f4ebfc
Merge branch 'master' into develop 2022-02-17 13:20:44 +10:00
Jamie Curnow
59238d1dc1 Bump version 2022-02-17 13:18:06 +10:00
Jamie Curnow
661f3d6899 Update repo path in docs 2022-02-17 13:15:15 +10:00
jc21
14b889a85f
Merge pull request #1822 from ivankristianto/add-search-feature-redirection
Add Search Feature To Backend Administration
2022-02-17 13:14:35 +10:00
Omer Cohen
ac25171420
Update resolvers.conf to break dns cache
By default, nginx caches answers using the TTL value of a response.
In a dynamic environment containers can get recreated with new IPs,
reducing the validity of the cache allows refreshing these IPs

https://nginx.org/en/docs/http/ngx_http_core_module.html#resolver
2022-02-16 09:31:56 +02:00
jc21
7281ed5968
Merge pull request #1830 from lug-gh/lug-gh-patch-1
Update current year for footer
2022-02-13 20:20:32 +10:00
jc21
dc541b2c72
Merge pull request #1850 from NginxProxyManager/dependabot/npm_and_yarn/docs/follow-redirects-1.14.8
Bump follow-redirects from 1.14.7 to 1.14.8 in /docs
2022-02-13 20:18:47 +10:00
dependabot[bot]
9a854fd8fe
Bump follow-redirects from 1.14.7 to 1.14.8 in /docs
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.14.7 to 1.14.8.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.14.7...v1.14.8)

---
updated-dependencies:
- dependency-name: follow-redirects
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-13 08:02:46 +00:00
Ivan Kristianto
8eb44c404d Add translation for search text 2022-02-12 13:28:16 +07:00
Ivan Kristianto
61b25e1213 Add search feature to Audit Logs 2022-02-12 13:10:23 +07:00
Ivan Kristianto
d3a5a3d0d6 Add search feature to Users 2022-02-12 12:52:22 +07:00
Ivan Kristianto
366fcf0bed Fix nginx/certificates search query 2022-02-12 12:46:06 +07:00
Ivan Kristianto
29c0fcbad6 Add search feature to SSL Certificates 2022-02-12 12:45:29 +07:00
Ivan Kristianto
de84d5d463 Add search feature to Access Lists 2022-02-12 12:17:45 +07:00
Ivan Kristianto
078114ee67 Fix search query for proxy 2022-02-12 11:52:47 +07:00
Ivan Kristianto
49f350fb00 Add search feature to 404 hosts 2022-02-12 11:48:47 +07:00
Ivan Kristianto
e141b5ff20 Add search feature to stream 2022-02-12 11:36:59 +07:00
Ivan Kristianto
181f163cb5 Move render showEmpty into function 2022-02-12 10:40:37 +07:00
Ivan Kristianto
30a9d3ae8d Add search feature to proxy host 2022-02-12 10:38:15 +07:00
lug-gh
83e09ad5a7
Update current year for footer
Update current year for footer
2022-02-05 20:59:21 +01:00
jc21
8e5255a275
Merge pull request #1767 from NginxProxyManager/dependabot/npm_and_yarn/docs/json-schema-0.4.0
Bump json-schema from 0.2.5 to 0.4.0 in /docs
2022-01-31 09:03:11 +10:00
jc21
e4f06368bb
Merge pull request #1768 from NginxProxyManager/dependabot/npm_and_yarn/docs/is-svg-4.3.0
Bump is-svg from 4.2.2 to 4.3.0 in /docs
2022-01-31 09:02:59 +10:00
jc21
0edd87324c
Merge pull request #1773 from NginxProxyManager/certbot-dns-transip-update
Update certbot-dns-transip plugin
2022-01-31 09:02:48 +10:00
Ivan Kristianto
96e034aa75 Add search function for redirection 2022-01-30 22:47:42 +07:00
Jamie Curnow
821432263a Update certbot-dns-transip plugin 2022-01-19 07:36:49 +10:00
Jamie Curnow
5edb16f36e Fix failing pip installs, downgrade setuptools 2022-01-17 21:46:26 +10:00
jc21
a233bc0045
Merge pull request #1766 from NginxProxyManager/develop
v2.9.15
2022-01-17 12:08:45 +10:00
dependabot[bot]
eed40d095e
Bump is-svg from 4.2.2 to 4.3.0 in /docs
Bumps [is-svg](https://github.com/sindresorhus/is-svg) from 4.2.2 to 4.3.0.
- [Release notes](https://github.com/sindresorhus/is-svg/releases)
- [Commits](https://github.com/sindresorhus/is-svg/compare/v4.2.2...v4.3.0)

---
updated-dependencies:
- dependency-name: is-svg
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-17 01:22:20 +00:00
dependabot[bot]
0d0e5295f4
Bump json-schema from 0.2.5 to 0.4.0 in /docs
Bumps [json-schema](https://github.com/kriszyp/json-schema) from 0.2.5 to 0.4.0.
- [Release notes](https://github.com/kriszyp/json-schema/releases)
- [Commits](https://github.com/kriszyp/json-schema/compare/v0.2.5...v0.4.0)

---
updated-dependencies:
- dependency-name: json-schema
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-17 01:21:03 +00:00
jc21
51ac4bc688
Merge branch 'master' into develop 2022-01-17 10:53:03 +10:00
Jamie Curnow
4f97592965 Bump version 2022-01-17 10:48:57 +10:00
jc21
be5a763d39
Merge pull request #1758 from NginxProxyManager/dependabot/npm_and_yarn/docs/markdown-it-12.3.2
Bump markdown-it from 11.0.0 to 12.3.2 in /docs
2022-01-17 10:46:00 +10:00
jc21
c435ce0224
Merge pull request #1760 from NginxProxyManager/dependabot/npm_and_yarn/docs/follow-redirects-1.14.7
Bump follow-redirects from 1.12.1 to 1.14.7 in /docs
2022-01-17 10:45:49 +10:00
jc21
67d8ede247
Merge pull request #1763 from NginxProxyManager/dependabot/npm_and_yarn/docs/node-forge-1.0.0
Bump node-forge from 0.10.0 to 1.0.0 in /docs
2022-01-17 10:45:28 +10:00
jc21
5e98ce32b7
Merge pull request #1764 from troykelly/troykelly#add-constellix
Added Constellix as DNS auth method
2022-01-17 10:45:02 +10:00
Troy Kelly
a2c01655f0 Added Constellix 2022-01-15 09:48:04 +00:00
dependabot[bot]
3a71281937
Bump node-forge from 0.10.0 to 1.0.0 in /docs
Bumps [node-forge](https://github.com/digitalbazaar/forge) from 0.10.0 to 1.0.0.
- [Release notes](https://github.com/digitalbazaar/forge/releases)
- [Changelog](https://github.com/digitalbazaar/forge/blob/main/CHANGELOG.md)
- [Commits](https://github.com/digitalbazaar/forge/compare/0.10.0...v1.0.0)

---
updated-dependencies:
- dependency-name: node-forge
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-14 21:13:50 +00:00
dependabot[bot]
f235ec8b5a
Bump follow-redirects from 1.12.1 to 1.14.7 in /docs
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.12.1 to 1.14.7.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.12.1...v1.14.7)

---
updated-dependencies:
- dependency-name: follow-redirects
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-14 05:54:23 +00:00
dependabot[bot]
fa7df05b92
Bump markdown-it from 11.0.0 to 12.3.2 in /docs
Bumps [markdown-it](https://github.com/markdown-it/markdown-it) from 11.0.0 to 12.3.2.
- [Release notes](https://github.com/markdown-it/markdown-it/releases)
- [Changelog](https://github.com/markdown-it/markdown-it/blob/master/CHANGELOG.md)
- [Commits](https://github.com/markdown-it/markdown-it/compare/11.0.0...12.3.2)

---
updated-dependencies:
- dependency-name: markdown-it
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-12 23:02:03 +00:00
Jamie Curnow
1f3ac7a9ec And update the docker org too 2022-01-11 11:52:25 +10:00
Jamie Curnow
5bd002a568 Forgot to update this docker base image 2022-01-11 11:28:01 +10:00
Jamie Curnow
5fb0cc5fab No need to symlink python, done in base image now 2022-01-11 11:17:19 +10:00
Jamie Curnow
818b9595aa Use renamed nginx-full docker images 2022-01-11 08:57:24 +10:00
Jamie Curnow
c78f641e85 Revert #1614
as it breaks some existing services
2022-01-11 08:54:40 +10:00
jc21
081380c8d5
Merge pull request #1716 from jc21/develop
v2.9.14
2022-01-02 22:31:12 +10:00
jc21
7e451bce0b
Merge pull request #1688 from jlesage/resolvers-fix
Fixed generation of resolvers.conf.
2022-01-02 22:05:32 +10:00
jc21
a082ec0604
Merge pull request #1600 from jc21/updates-dnspod-dns-challenge
Fixes dnspod credentials template
2022-01-02 22:05:15 +10:00
Jamie Curnow
973a10a9d1 Bump version 2022-01-02 21:33:16 +10:00
Jamie Curnow
1ec95096d5 Ensure backend build is pulling node:latest first 2022-01-02 21:24:16 +10:00
chaptergy
e81cc45405 Updates dnspod challenge credentials 2022-01-02 11:49:18 +01:00
jc21
b9ef11e8bf
Merge pull request #1614 from the1ts/feature/proxy-header-additions
Feature: Add two new headers to proxy.conf
2022-01-02 16:11:50 +10:00
jc21
0d8dd03c3d
Merge pull request #1687 from jlesage/fallback-access-fix
Fixed the access log path to match the HTTP one.
2022-01-02 16:10:25 +10:00
jc21
74d610d9ad
Merge pull request #1697 from jc21/official-dns-version-requirement
Sets certbot official dns plugin version requirement to match certbot version
2022-01-02 16:09:27 +10:00
jc21
9146ca6c63
Merge pull request #1698 from jc21/adds-faq-acl-with-login
Adds FAQ entry for acl plus login
2022-01-02 15:39:04 +10:00
jc21
d7e0ae0fa0
Merge pull request #1701 from jc21/escape-credential-backslashes
Correctly escape backslashes in dns plugin credentials
2022-01-02 15:29:31 +10:00
jc21
29ee48530c
Merge pull request #1703 from luoweihua7/develop
fetch cloudflare ipv4/ipv6 fail #1405
2022-01-02 15:28:58 +10:00
jc21
abe53a4bdd
Merge pull request #1704 from jc21/letsencrypt-cert-request-delay
Adds delay after reloading nginx before requesting ssl certificate using http challenge
2022-01-02 15:27:39 +10:00
jc21
2d23bedf12
Merge pull request #1713 from jc21/adds-tencentcloud-dns-challenge
Adds tencent cloud as dns challenge provider
2022-01-02 15:26:25 +10:00
chaptergy
4e17fb476b Adds tencent cloud as dns challenge provider 2022-01-01 17:57:17 +01:00
chaptergy
c803ec7e26 Adds delay after reloading nginx before requesting ssl certificate using http challenge 2021-12-30 13:21:21 +01:00
Larify
7e67f33766 fetch cloudflare ipv4/ipv6 fail #1405 2021-12-30 11:50:21 +08:00
chaptergy
9dd5644183 Correctly escape backslashes in dns plugin credentials 2021-12-29 16:30:49 +01:00
chaptergy
5a8028a72d Adds FAQ entry for acl plus login 2021-12-29 11:35:59 +01:00
chaptergy
747de511d4 Sets certbot official dns plugin version requirement to match certbot version 2021-12-29 09:54:59 +01:00
Tobias Kneidl
7800938fd2 Update default.conf 2021-12-28 18:58:22 +00:00
chaptergy
ab80fe13e9 Fixes custom certificate upload modal 2021-12-28 18:58:22 +00:00
Jamie Curnow
5d106c4064 Bump version 2021-12-28 18:58:22 +00:00
Jamie Curnow
2ac1026e4b Hack for python binary in newer node images 2021-12-28 18:58:22 +00:00
chaptergy
b78c7e1c53 Fixes dnspod credentials template 2021-12-27 21:13:27 +01:00
Jocelyn Le Sage
849bdcda7b Fixed generation of resolvers.conf.
This fixes scenarios where `resolv.conf` generated by dhcpcd has a nameserver with `%interface` appended to its IPv6 address.
For example, a line like this must be properly handled:
nameserver fe80::7747:4aff:fe9a:8cb1%br0
2021-12-26 21:49:55 -05:00
Jocelyn Le Sage
5aae8cd0e3 Fixed the access log path to match the HTTP one. This also fixes its handling by logrotate. 2021-12-26 20:56:42 -05:00
jc21
adc5a2020a
Merge pull request #1666 from TobiasKneidl/patch-1
Update default.conf to follow the default site setting also for ipv6
2021-12-27 11:03:14 +10:00
jc21
40b1521f72
Merge pull request #1677 from jc21/fixes-custom-certificate-modal
Fixes custom certificate upload modal
2021-12-27 11:02:16 +10:00
chaptergy
ac23c66659 Fixes custom certificate upload modal 2021-12-23 12:23:30 +01:00
jc21
84bc33db8a
Merge pull request #1667 from jc21/develop
v2.9.13
2021-12-22 11:53:02 +10:00
jc21
6392df36c3
Merge branch 'master' into develop 2021-12-22 11:52:27 +10:00
Jamie Curnow
c82843279c Bump version 2021-12-22 11:51:32 +10:00
Jamie Curnow
b394eb8e55 Hack for python binary in newer node images 2021-12-22 11:05:57 +10:00
Tobias Kneidl
bb422d4454
Update default.conf 2021-12-22 00:24:05 +01:00
Paul Mansfield
3dfe23836c
Add two new headers to proxy.conf
Fixes #1609. Adding both  X-Forwarded-Host  and X-Forwarded-Port, this is vital for some services behind a proxy (used to allow creation of absolute links in html). I've had to include at least the Host version in the past for jenkins and nexus.
Been running locally for 24 hours, does not appear to break any of my 15+ services currently running behind NPM would allow people to host those services without the need for advanced configuration
2021-11-29 13:48:39 +00:00
jc21
d45f39aae3
Merge pull request #1538 from jc21/adds-http-challenge-test
Adds buttons to test availability of server from public internet
2021-11-10 09:15:26 +10:00
jc21
cb091040a8
Merge pull request #1578 from jc21/undo-switch-to-variables
Reverts back to proxy_pass without variables
2021-11-10 09:13:02 +10:00
chaptergy
ddd538944a Skip migration if setting does not exist 2021-11-09 14:03:39 +01:00
chaptergy
1f879f67a9 Reverts back to proxy_pass without variables 2021-11-09 13:57:39 +01:00
Chaptergy
ee89dedd0f Adds migration to regenerate default host 2021-11-08 23:11:56 +01:00
jc21
9ab5333652
Merge pull request #1574 from jc21/develop
v2.9.12
2021-11-08 14:34:31 +10:00
Jamie Curnow
3bd97ae1b0 Version bump 2021-11-08 13:37:44 +10:00
jc21
432062e0f4
Merge pull request #1559 from jc21/variable-fix-custom-locations
Fixes custom location with capture groups
2021-11-08 12:29:43 +10:00
jc21
0c8bbb4bc2
Merge pull request #1561 from jc21/header-warning-for-advanced-config
Adds advanced config header warning
2021-11-08 12:28:34 +10:00
jc21
48e96c46d5
Merge pull request #1565 from jc21/removes-hsts-from-admin-ui
Removes HSTS from admin ui
2021-11-08 12:27:36 +10:00
jc21
25e9acf618
Merge pull request #1566 from jc21/cleans-dependencies
Removes unused dependencies
2021-11-08 12:27:04 +10:00
jc21
a517e80236
Merge pull request #1567 from jc21/removes-renew-delay
Removes random delay when renewing certificates with the renew now button
2021-11-08 12:26:34 +10:00
jc21
3d4d3bc73b
Merge pull request #1572 from jc21/letsencrypt-config-file
Uses letsencrypt config file everywhere
2021-11-08 12:25:48 +10:00
Julian Reinhardt
cf4d1f73fa Uses letsencrypt config file everywhere 2021-11-06 22:31:13 +01:00
Julian Reinhardt
c203d1a0d8 Requires ~() in location to remove $request_uri and removes $request_uri if it is just a slash 2021-11-06 13:38:02 +01:00
Julian Reinhardt
5f29f6b039 Removes random delay when renewing certificates with the renew now button 2021-11-05 14:20:12 +01:00
Julian Reinhardt
f75b5b867b Fixes formatting 2021-11-05 14:01:50 +01:00
Julian Reinhardt
67463ca136 Removes unused dependencies 2021-11-05 13:59:19 +01:00
Julian Reinhardt
8db541f37f Removes HSTS from admin ui 2021-11-05 00:09:05 +01:00
Julian Reinhardt
a5229d0e92 Adds advanced config header warning and replaces variable info with translation 2021-11-04 12:01:01 +01:00
Julian Reinhardt
38ec0f9f95 Adds logs to backend when testing http challenge 2021-11-04 11:16:23 +01:00
Julian Reinhardt
3d80759a21 Renames the $upstream variables and does not append $request_ui if capture group exists in location 2021-11-04 10:08:15 +01:00
jc21
d95cd36b3e
Merge pull request #1544 from piuswalter/patch-1
Fixed typo in i18n translation file
2021-11-03 09:42:49 +10:00
jc21
4c6b96ad5d
Merge pull request #1546 from jc21/removes-swagger-containter
Removes swagger container
2021-11-03 09:41:41 +10:00
jc21
c3bef2867e
Merge pull request #1547 from jc21/makes-sqlite-default
Changes documentation to make SQLite the default db
2021-11-03 09:41:02 +10:00
Julian Reinhardt
efc5bff2e1 Makes SQLite the default database in documentation 2021-11-02 12:24:23 +01:00
Julian Reinhardt
ffe3db8c08 Falls back to SQLite if no environment variables are provided 2021-11-02 12:22:39 +01:00
Julian Reinhardt
4ada0feae3 Removes swagger container and adds exposed port for DB in dev env 2021-11-02 11:33:22 +01:00
Pius Walter
e17de6058e Fixed typo 2021-11-01 17:43:46 +01:00
Julian Reinhardt
9efe6cfb39 Minor fixes 2021-10-31 13:41:29 +01:00
Julian Reinhardt
c86a1a50bd Fixes formatting 2021-10-31 00:28:43 +02:00
Julian Reinhardt
c55476b196 Adds buttons to test availability of server from public internet 2021-10-31 00:19:18 +02:00
jc21
3b47decbb0
Merge pull request #1528 from jc21/develop
v2.9.11
2021-10-27 22:11:55 +10:00
Jamie Curnow
d0bfa082e0 Bump version 2021-10-27 21:43:07 +10:00
jc21
6b7a8b009e
Merge pull request #1519 from jc21/fixes-incorrect-proxy-path
Updates proxy paths
2021-10-27 21:42:18 +10:00
Julian Reinhardt
ca59e585d8 Uses variable in proxy_pass for normal proxy hosts 2021-10-25 14:58:02 +02:00
Julian Reinhardt
bbde7a108a Use variable with full uri in proxy pass 2021-10-25 14:48:22 +02:00
Julian Reinhardt
87731a8b5c Revert "Utilise variable for custom locations proxy_pass"
This reverts commit 6c1ae77a2a40283c5444c2f7e0a7c8227aeecbd2.
2021-10-25 14:27:37 +02:00
jc21
29d4bd4ccf
Merge pull request #1517 from jc21/develop
v2.9.10
2021-10-25 15:48:43 +10:00
jc21
925ad90f91
Merge branch 'master' into develop 2021-10-25 14:26:47 +10:00
Jamie Curnow
650ae61c43 Version bump 2021-10-25 11:35:44 +10:00
jc21
02f3f9704f
Merge pull request #1480 from jc21/prefer-isrg-cert-chain
Sets the cert chain to prefer ISRG Root X1
2021-10-25 08:42:31 +10:00
jc21
da7c3057b4
Merge pull request #1481 from jc21/certificate-no-domain-sorting
Removes sorting of domain names when creating a certificate
2021-10-25 08:40:19 +10:00
jc21
040b45cafa
Merge pull request #1496 from jc21/fixes-cache-busting
Adds cache busting to js bundles as well
2021-10-25 08:30:15 +10:00
jc21
8ece310b9f
Merge pull request #1514 from jc21/adds-dns-websupportsk-challenge
Adds Webbsupport.sk dns plugin
2021-10-25 08:26:20 +10:00
jc21
96959db3c2
Merge pull request #1504 from jc21/removes-certbot-plugin-prefixes
Removes certbot plugin prefixes
2021-10-25 08:26:03 +10:00
Julian Reinhardt
6360100611 Adds Webbsupport.sk dns plugin 2021-10-24 22:14:59 +02:00
Julian Reinhardt
b833044cea Fixes formatting 2021-10-20 18:38:21 +02:00
Julian Reinhardt
97909830f5 Removes dns plugin prefixes 2021-10-20 18:16:54 +02:00
Julian Reinhardt
8ae2de2f49 Updates certbot-dns-ionos to newest version 2021-10-20 18:08:11 +02:00
chaptergy
bf7b659e89 Adds cache busting to js bundles as well 2021-10-17 19:15:35 +02:00
chaptergy
4e3c7749af Removes sorting of domain names when creating a certificate 2021-10-12 16:18:11 +02:00
chaptergy
f63441921f Sets the cert chain to prefer ISRG Root X1 2021-10-12 16:11:47 +02:00
jc21
725ba83606
Merge pull request #1443 from jc21/dependabot/npm_and_yarn/docs/ansi-regex-5.0.1
Bump ansi-regex from 5.0.0 to 5.0.1 in /docs
2021-10-12 10:36:48 +10:00
jc21
281906c0b5
Merge pull request #1476 from jc21/dependabot/npm_and_yarn/backend/objection-2.2.16
Bump objection from 2.2.2 to 2.2.16 in /backend
2021-10-12 10:36:34 +10:00
dependabot[bot]
8ed121f43d
Bump ansi-regex from 5.0.0 to 5.0.1 in /docs
Bumps [ansi-regex](https://github.com/chalk/ansi-regex) from 5.0.0 to 5.0.1.
- [Release notes](https://github.com/chalk/ansi-regex/releases)
- [Commits](https://github.com/chalk/ansi-regex/compare/v5.0.0...v5.0.1)

---
updated-dependencies:
- dependency-name: ansi-regex
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-10-11 01:57:51 +00:00
jc21
81a9cab2b3
Merge pull request #1464 from jc21/fixes-navigation-on-mobile
Adds toggle to header to display menu on mobile
2021-10-11 11:55:37 +10:00
jc21
8d98a417c5
Merge pull request #1469 from jc21/certbot-plugin-updates
Certbot plugin updates
2021-10-11 11:54:51 +10:00
dependabot[bot]
6fa81b179b
Bump objection from 2.2.2 to 2.2.16 in /backend
Bumps [objection](https://github.com/vincit/objection.js) from 2.2.2 to 2.2.16.
- [Release notes](https://github.com/vincit/objection.js/releases)
- [Commits](https://github.com/vincit/objection.js/commits/2.2.16)

---
updated-dependencies:
- dependency-name: objection
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-10-11 01:53:33 +00:00
jc21
9e169fbb42
Merge pull request #1474 from Djelibeybi/add-oci-dns
Add DNS provider for Oracle Cloud Infrastructure (OCI) DNS
2021-10-11 11:53:26 +10:00
Jamie Curnow
27f84f880a Updated node-sass and sass-loader 2021-10-11 11:11:46 +10:00
Avi Miller
0d9c941b4e
Add support for Oracle Cloud Infrastructure (OCI) DNS
Signed-off-by: Avi Miller <avi.miller@oracle.com>
2021-10-10 08:49:12 +11:00
chaptergy
8865aa9c8c Fixes formatting 2021-10-07 17:39:18 +02:00
chaptergy
6d8c4218f1 Replaces fixed certbot plugin version with optional version requirements 2021-10-07 17:13:48 +02:00
chaptergy
c134a43337 Updates DirectAdmin plugin to prevent certbot downgrade 2021-10-06 17:58:07 +02:00
chaptergy
780759dc27 Adds toggle to header to display menu on mobile 2021-10-05 21:00:10 +02:00
jc21
85128f08f3
Merge pull request #1409 from jc21/dependabot/npm_and_yarn/docs/set-value-4.0.1
Bump set-value from 3.0.2 to 4.0.1 in /docs
2021-09-30 13:16:28 +10:00
jc21
d2f8c1e5f1
Merge pull request #1412 from jc21/dependabot/npm_and_yarn/docs/prismjs-1.25.0
Bump prismjs from 1.24.0 to 1.25.0 in /docs
2021-09-30 13:16:20 +10:00
jc21
9c88b9c1e9
Merge pull request #1415 from jc21/dependabot/npm_and_yarn/docs/nth-check-2.0.1
Bump nth-check from 1.0.2 to 2.0.1 in /docs
2021-09-30 13:16:10 +10:00
dependabot[bot]
13fd2ce4e2
Bump nth-check from 1.0.2 to 2.0.1 in /docs
Bumps [nth-check](https://github.com/fb55/nth-check) from 1.0.2 to 2.0.1.
- [Release notes](https://github.com/fb55/nth-check/releases)
- [Commits](https://github.com/fb55/nth-check/compare/v1.0.2...v2.0.1)

---
updated-dependencies:
- dependency-name: nth-check
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-09-22 04:54:41 +00:00
dependabot[bot]
9979f516d6
Bump prismjs from 1.24.0 to 1.25.0 in /docs
Bumps [prismjs](https://github.com/PrismJS/prism) from 1.24.0 to 1.25.0.
- [Release notes](https://github.com/PrismJS/prism/releases)
- [Changelog](https://github.com/PrismJS/prism/blob/master/CHANGELOG.md)
- [Commits](https://github.com/PrismJS/prism/compare/v1.24.0...v1.25.0)

---
updated-dependencies:
- dependency-name: prismjs
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-09-20 21:48:33 +00:00
dependabot[bot]
39a5cd2d6e
Bump set-value from 3.0.2 to 4.0.1 in /docs
Bumps [set-value](https://github.com/jonschlinkert/set-value) from 3.0.2 to 4.0.1.
- [Release notes](https://github.com/jonschlinkert/set-value/releases)
- [Commits](https://github.com/jonschlinkert/set-value/compare/3.0.2...4.0.1)

---
updated-dependencies:
- dependency-name: set-value
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-09-16 04:26:17 +00:00
jc21
784516283f
Merge pull request #1399 from nikhen/i845
data.email should NOT be shorter than 8 characters #845
2021-09-13 11:03:22 +10:00
nikhen
ce503232c3 data.email should NOT be shorter than 8 characters #845 2021-09-12 15:01:55 +02:00
jc21
f2edf9130f
Merge pull request #1396 from nikhen/develop
1.1.1.1 used as a placeholder, despite being real external website/address #686
2021-09-12 20:42:51 +10:00
nikhen
413ab50fc4 Change example IP: 0.0.0.0 -> 203.0.113.25 2021-09-12 12:28:25 +02:00
nikhen
c1880bd3ff 1.1.1.1 used as a placeholder, despite being real external website/address #686 2021-09-11 17:21:32 +02:00
Jamie Curnow
0f0a672275 Added another contributor 2021-09-10 14:49:11 +10:00
jc21
06c5f991e7
Merge pull request #1390 from jc21/develop
v2.9.9
2021-09-10 13:50:47 +10:00
Jamie Curnow
babc5b7a38 Bumped version 2021-09-10 07:54:10 +10:00
Jamie Curnow
b96c996a45 Log more info for internal errors in debug mode 2021-09-09 08:46:09 +10:00
jc21
fb8f2c2f9a
Merge pull request #1384 from bergi9/patch-1
Add SSL and HTTP2 into IPv6 on listen.conf
2021-09-08 11:30:00 +10:00
jc21
6794937391
Merge pull request #1376 from realJoshByrnes/develop
Fixed some typos in Advanced Config readme
2021-09-08 10:52:25 +10:00
bergi9
f022e84979
Add SSL and HTTP2 into IPv6 on listen.conf
I can only server contents with IPv6 because I'm sitting behind CGN on IPv4. When enabling HTTP2 it still not serve contents with HTTP2 as there are missing arguments in the `listen`. But it still does the SSL encryption.
Previous to this commit it generates:
```
listen 80;
listen [::]:80;

listen 443 ssl http2;
listen [::]:443;
```
Now it generates:
```
listen 80;
listen [::]:80;

listen 443 ssl http2;
listen [::]:443 ssl http2;
```
2021-09-07 22:50:49 +02:00
Josh Byrnes
fd5ac952cc Fixed some typos in Advanced Config readme 2021-09-05 05:47:14 +10:00
jc21
07f60e5c77
Merge pull request #1367 from jc21/dependabot/npm_and_yarn/docs/tar-6.1.11
Bump tar from 6.1.6 to 6.1.11 in /docs
2021-09-02 11:52:52 +10:00
jc21
628b8a7e1f
Merge pull request #1368 from jc21/dependabot/npm_and_yarn/backend/tar-4.4.19
Bump tar from 4.4.15 to 4.4.19 in /backend
2021-09-02 11:52:39 +10:00
dependabot[bot]
30a442807d
Bump tar from 4.4.15 to 4.4.19 in /backend
Bumps [tar](https://github.com/npm/node-tar) from 4.4.15 to 4.4.19.
- [Release notes](https://github.com/npm/node-tar/releases)
- [Changelog](https://github.com/npm/node-tar/blob/main/CHANGELOG.md)
- [Commits](https://github.com/npm/node-tar/compare/v4.4.15...v4.4.19)

---
updated-dependencies:
- dependency-name: tar
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-09-02 00:11:00 +00:00
jc21
1626c8edd1
Merge pull request #1343 from ssrahul96/develop
Added support to download Let's Encrypt Certificate
2021-09-02 10:09:45 +10:00
Rahul Somasundaram
ca6561bf6c
updated debug statement 2021-09-01 11:50:51 +05:30
Rahul Somasundaram
273a81471d
Revert "updated debug statement"
This reverts commit 8b07a67133bf9d2ee80beeb40262d83d236b9e20.
2021-09-01 11:47:47 +05:30
Rahul Somasundaram
8b07a67133
updated debug statement 2021-09-01 11:46:10 +05:30
Rahul Somasundaram
32089ea272
deferenced symlinks and downloaded the certs from live directory 2021-09-01 11:41:27 +05:30
Rahul Somasundaram
658acd147c
updated certificate path 2021-09-01 07:38:11 +05:30
jc21
ca3370a6ac
Merge pull request #1366 from BjoernAkAManf/patch-1
Forwarding host should be anyOf not oneOf
2021-09-01 07:25:35 +10:00
dependabot[bot]
c4e2557de2
Bump tar from 6.1.6 to 6.1.11 in /docs
Bumps [tar](https://github.com/npm/node-tar) from 6.1.6 to 6.1.11.
- [Release notes](https://github.com/npm/node-tar/releases)
- [Changelog](https://github.com/npm/node-tar/blob/main/CHANGELOG.md)
- [Commits](https://github.com/npm/node-tar/compare/v6.1.6...v6.1.11)

---
updated-dependencies:
- dependency-name: tar
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-31 19:03:35 +00:00
Björn Heinrichs
6f2b4fdf86
Forwarding host should be anyOf not oneOf
Should fix #1354
2021-08-31 19:27:43 +02:00
Rahul Somasundaram
f302ff71c9
corrected message 2021-08-30 16:36:13 +05:30
jc21
fee87a44d6
Merge pull request #1348 from jc21/develop
v2.9.8
2021-08-25 10:11:10 +10:00
Rahul Somasundaram
8944609b63
fixed linting 2021-08-24 07:28:17 +05:30
Rahul Somasundaram
be87c45f27
thrown exception for non LE certificates 2021-08-24 06:01:08 +05:30
Rahul Somasundaram
1b1807c79a removed debug lines 2021-08-23 18:03:47 +05:30
Rahul Somasundaram
a8f4699816 [frontend] certificate download changes 2021-08-23 15:47:03 +05:30
Rahul Somasundaram
ac3df6dd77
fixed comments 2021-08-23 09:29:33 +05:30
Jamie Curnow
5c67908460 Bump version, added contributors 2021-08-23 13:55:48 +10:00
Rahul Somasundaram
7b67ef3015
fixed linting 2021-08-23 09:17:42 +05:30
Rahul Somasundaram
e5a3b5ee2f
added endpoint to download certificates 2021-08-23 09:03:24 +05:30
Jamie Curnow
5e9ff4d2bf Add healthcheck back for ci containers 2021-08-23 09:29:11 +10:00
jc21
daa71764b6
Merge pull request #1338 from bmbvenom/patch-1
remove dummy cert references to Nginx Proxy Manager
2021-08-23 08:52:01 +10:00
Jamie Curnow
6a6c2ef192 Remove healthchecks and mention how to optin to them in docs 2021-08-23 08:50:07 +10:00
bmbvenom
320315956d
remove dummy cert references to Nginx Proxy Manager
Based on this issue: https://github.com/jc21/nginx-proxy-manager/issues/1024
2021-08-21 22:37:14 -07:00
Jamie Curnow
4f10d129c2 Reload nginx after access list change. Fixes #1328 2021-08-19 08:55:53 +10:00
Jamie Curnow
62eb3fcd85 Updated docker base image location 2021-08-17 11:28:30 +10:00
jc21
ab40e4e2cf
Merge pull request #1036 from BjoernAkAManf/master
Allows hostname instead of ip for streams
2021-08-16 13:40:40 +10:00
jc21
0bb9450642
Merge pull request #1323 from jc21/dependabot/npm_and_yarn/docs/url-parse-1.5.2
Bump url-parse from 1.5.0 to 1.5.2 in /docs
2021-08-16 13:38:16 +10:00
dependabot[bot]
a6e15532b9
Bump url-parse from 1.5.0 to 1.5.2 in /docs
Bumps [url-parse](https://github.com/unshiftio/url-parse) from 1.5.0 to 1.5.2.
- [Release notes](https://github.com/unshiftio/url-parse/releases)
- [Commits](https://github.com/unshiftio/url-parse/compare/1.5.0...1.5.2)

---
updated-dependencies:
- dependency-name: url-parse
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-16 03:37:58 +00:00
jc21
9a89a8a77e
Merge pull request #1209 from jc21/dependabot/npm_and_yarn/docs/prismjs-1.24.0
Bump prismjs from 1.23.0 to 1.24.0 in /docs
2021-08-16 13:37:56 +10:00
jc21
fe3675dc7a
Merge pull request #1210 from jc21/dependabot/npm_and_yarn/backend/normalize-url-4.5.1
Bump normalize-url from 4.5.0 to 4.5.1 in /backend
2021-08-16 13:37:47 +10:00
jc21
5c9acc2bff
Merge pull request #1309 from jc21/dependabot/npm_and_yarn/backend/path-parse-1.0.7
Bump path-parse from 1.0.6 to 1.0.7 in /backend
2021-08-16 13:37:36 +10:00
jc21
c94e937a50
Merge pull request #1308 from jc21/dependabot/npm_and_yarn/frontend/path-parse-1.0.7
Bump path-parse from 1.0.6 to 1.0.7 in /frontend
2021-08-16 13:37:26 +10:00
jc21
3e4e10e644
Merge pull request #1310 from jc21/dependabot/npm_and_yarn/docs/path-parse-1.0.7
Bump path-parse from 1.0.6 to 1.0.7 in /docs
2021-08-16 13:37:15 +10:00
Björn Heinrichs
ba7bb57ca2
Incorporate feedback
- Empty function removed
- Placeholder and Maxlength restored
- Validation improved
- Typo fixed
2021-08-13 11:32:01 +02:00
dependabot[bot]
14c125150a
Bump path-parse from 1.0.6 to 1.0.7 in /docs
Bumps [path-parse](https://github.com/jbgutierrez/path-parse) from 1.0.6 to 1.0.7.
- [Release notes](https://github.com/jbgutierrez/path-parse/releases)
- [Commits](https://github.com/jbgutierrez/path-parse/commits/v1.0.7)

---
updated-dependencies:
- dependency-name: path-parse
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-12 03:03:43 +00:00
dependabot[bot]
053701a702
Bump path-parse from 1.0.6 to 1.0.7 in /backend
Bumps [path-parse](https://github.com/jbgutierrez/path-parse) from 1.0.6 to 1.0.7.
- [Release notes](https://github.com/jbgutierrez/path-parse/releases)
- [Commits](https://github.com/jbgutierrez/path-parse/commits/v1.0.7)

---
updated-dependencies:
- dependency-name: path-parse
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-12 00:57:11 +00:00
dependabot[bot]
3fc3e43042
Bump path-parse from 1.0.6 to 1.0.7 in /frontend
Bumps [path-parse](https://github.com/jbgutierrez/path-parse) from 1.0.6 to 1.0.7.
- [Release notes](https://github.com/jbgutierrez/path-parse/releases)
- [Commits](https://github.com/jbgutierrez/path-parse/commits/v1.0.7)

---
updated-dependencies:
- dependency-name: path-parse
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-12 00:56:50 +00:00
jc21
b0dc68d7d4
Merge pull request #1300 from FMeinicke/develop
Add deSEC DNS provider
2021-08-09 15:30:53 +10:00
Florian Meinicke
e895baaeb4 Add deSEC DNS provider 2021-08-08 19:22:17 +02:00
jc21
c47f6fdb21
Merge pull request #1294 from jc21/develop
v2.9.7
2021-08-07 21:15:47 +10:00
jc21
9e188e441a
Merge branch 'master' into develop 2021-08-07 20:06:40 +10:00
Jamie Curnow
f6efcdf9f9 Bumped version 2021-08-07 20:05:53 +10:00
David Dosoudil
b1ceda3af4 Update letsencrypt.ini to support ECDSA keys
Since we have newer certbot available, it's time to support more modern and safer ECDSA keys instead of RSA.
2021-08-07 20:05:53 +10:00
jc21
cd3a0684d0
Merge pull request #1293 from jc21/dependabot/npm_and_yarn/docs/tar-6.1.6
Bump tar from 6.0.2 to 6.1.6 in /docs
2021-08-07 19:07:08 +10:00
jc21
f25e54c6cb
Merge pull request #1211 from gabbe/dns-loopia
Added Loopia dns provider
2021-08-07 13:04:11 +10:00
jc21
66f86cf497
Merge pull request #1258 from nightah/fix-location-proxy_pass
Utilise variable for custom locations proxy_pass
2021-08-07 13:03:33 +10:00
dependabot[bot]
d260edc547
Bump tar from 6.0.2 to 6.1.6 in /docs
Bumps [tar](https://github.com/npm/node-tar) from 6.0.2 to 6.1.6.
- [Release notes](https://github.com/npm/node-tar/releases)
- [Changelog](https://github.com/npm/node-tar/blob/main/CHANGELOG.md)
- [Commits](https://github.com/npm/node-tar/compare/v6.0.2...v6.1.6)

---
updated-dependencies:
- dependency-name: tar
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-07 03:02:18 +00:00
jc21
ba1e6fa984
Merge pull request #1265 from phantomski77/master
Update letsencrypt.ini to support ECDSA keys
2021-08-07 13:01:14 +10:00
jc21
6b59f36213
Merge pull request #1287 from jc21/dependabot/npm_and_yarn/backend/tar-4.4.15
Bump tar from 4.4.13 to 4.4.15 in /backend
2021-08-07 13:00:55 +10:00
jc21
1894960762
Merge pull request #1286 from jc21/fixes-certificate-renewal
Fixes certificate renewal
2021-08-07 12:59:58 +10:00
chaptergy
83c5c55f32
Fixes creation of certificates using the http challenge 2021-08-06 10:56:06 +02:00
dependabot[bot]
fb8c0b9a48
Bump tar from 4.4.13 to 4.4.15 in /backend
Bumps [tar](https://github.com/npm/node-tar) from 4.4.13 to 4.4.15.
- [Release notes](https://github.com/npm/node-tar/releases)
- [Changelog](https://github.com/npm/node-tar/blob/main/CHANGELOG.md)
- [Commits](https://github.com/npm/node-tar/compare/v4.4.13...v4.4.15)

---
updated-dependencies:
- dependency-name: tar
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-04 20:15:26 +00:00
chaptergy
d34691152c
Fixes renewal unused http certificates 2021-08-04 14:07:53 +02:00
chaptergy
cea80b482e
Fixes certificate renewal for dns challenges 2021-08-04 13:47:44 +02:00
David Dosoudil
c460a8fa5c
Update letsencrypt.ini to support ECDSA keys
Since we have newer certbot available, it's time to support more modern and safer ECDSA keys instead of RSA.
2021-07-28 11:25:24 +01:00
jc21
5f852437fe
Merge pull request #1261 from jc21/develop
v2.9.6
2021-07-25 23:19:35 +10:00
Jamie Curnow
8aded1a685 Bump version 2021-07-25 21:10:26 +10:00
Jamie Curnow
f2acb9e150 Tweaks to s6 scripts 2021-07-25 21:09:02 +10:00
jc21
6f3a00c9b8
Merge pull request #1255 from jc21/fixes-crash-when-logrotation-fails 2021-07-24 08:50:12 +10:00
chaptergy
fbae107c04
Changes owner of logs to root on every container start 2021-07-23 09:11:43 +02:00
Amir Zarrinkafsh
6c1ae77a2a
Utilise variable for custom locations proxy_pass
If a custom location is currently set to proxy to a DNS hostname this hostname is cached by nginx. When the underlying IP for the hostname changes this will be cached in nginx until it is restarted. This behaviour is somewhat undesirable if utilising containers.

This change sets the proxy_pass for custom locations into a variable and utilises said variable for routing to the upstream backend. This will ensure that nginx will utilise the resolver and resolve the hostname to the current IP instead of relying on the nginx cache.
2021-07-23 16:24:46 +10:00
chaptergy
67e8ca6714
Fixes crash when logrotate fails 2021-07-22 14:05:21 +02:00
jc21
a56d976947
Merge pull request #1248 from jc21/develop
v2.9.5
2021-07-19 22:10:23 +10:00
jc21
ac0bb6bee2
Merge branch 'master' into develop 2021-07-19 15:59:06 +10:00
Jamie Curnow
dee67dac75 Bumped version, added contributors 2021-07-19 15:58:15 +10:00
jc21
9458cfbd1a
Merge pull request #1229 from demize/auth_request-fix
Disable auth_request in letsencrypt-acme-challenge.conf
2021-07-18 21:54:59 +10:00
jc21
4b8bdd22b3
Merge pull request #1181 from Theyooo/fix-wildcard-domains-regex
Fix wildcard domain regex
2021-07-18 19:05:23 +10:00
jc21
a4c143e2d1
Merge pull request #1178 from mrdink/patch-1
Update messages.json
2021-07-12 07:54:36 +10:00
jc21
e91019feb9
Merge pull request #1140 from jc21/adds-logrotation
Adds logrotation
2021-07-12 07:54:02 +10:00
jc21
8a37ec72b7
Merge pull request #1212 from jc21/dependabot/npm_and_yarn/docs/color-string-1.5.5
Bump color-string from 1.5.3 to 1.5.5 in /docs
2021-07-12 07:52:49 +10:00
jc21
c263a33095
Merge pull request #1222 from PUP-Loki/patch-1
Added Joker dns provider
2021-07-12 07:52:34 +10:00
demize
4b2c0115db Add to letsencrypt-acme-challenge.conf to allow for ACME challenges on proxy hosts using auth_requests 2021-07-10 15:02:09 -04:00
chaptergy
673f40bd85
Removes force parameter from logrotate 2021-07-09 12:34:50 +02:00
PUP-Loki
b9f8108cd3
Added Joker dns provider 2021-07-07 08:49:30 +01:00
dependabot[bot]
a16ecf656b
Bump color-string from 1.5.3 to 1.5.5 in /docs
Bumps [color-string](https://github.com/Qix-/color-string) from 1.5.3 to 1.5.5.
- [Release notes](https://github.com/Qix-/color-string/releases)
- [Changelog](https://github.com/Qix-/color-string/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Qix-/color-string/commits/1.5.5)

---
updated-dependencies:
- dependency-name: color-string
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-06-30 23:58:23 +00:00
Jamie Curnow
842cff130b Re-add missing certbot force renewal flag
and cleaned up this horrible file a bit
2021-07-01 09:57:26 +10:00
gabbe
346b9b4b79 Added Loopia dns provider 2021-06-30 14:11:58 +02:00
chaptergy
56c317d223
All logs in single folder
nginx cannot create the folder structure for logs
2021-06-29 23:07:54 +02:00
chaptergy
b7b150a979
Run logrotation binary from program 2021-06-29 21:18:29 +02:00
chaptergy
fae848bd1b
Store host logs in subfolders 2021-06-29 20:40:36 +02:00
dependabot[bot]
a5b8087dc5
Bump normalize-url from 4.5.0 to 4.5.1 in /backend
Bumps [normalize-url](https://github.com/sindresorhus/normalize-url) from 4.5.0 to 4.5.1.
- [Release notes](https://github.com/sindresorhus/normalize-url/releases)
- [Commits](https://github.com/sindresorhus/normalize-url/commits)

---
updated-dependencies:
- dependency-name: normalize-url
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-06-29 11:59:33 +00:00
dependabot[bot]
7aa078e025
Bump prismjs from 1.23.0 to 1.24.0 in /docs
Bumps [prismjs](https://github.com/PrismJS/prism) from 1.23.0 to 1.24.0.
- [Release notes](https://github.com/PrismJS/prism/releases)
- [Changelog](https://github.com/PrismJS/prism/blob/master/CHANGELOG.md)
- [Commits](https://github.com/PrismJS/prism/compare/v1.23.0...v1.24.0)

---
updated-dependencies:
- dependency-name: prismjs
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-06-28 19:45:20 +00:00
jc21
4b6b276b64
Merge pull request #1195 from jc21/develop
v2.9.4
2021-06-22 09:41:47 +10:00
Jamie Curnow
0373daae5c Bump version 2021-06-22 08:55:37 +10:00
jc21
7f30dd0475
Merge pull request #1194 from jc21/dependabot/npm_and_yarn/docs/set-getter-0.1.1
Bump set-getter from 0.1.0 to 0.1.1 in /docs
2021-06-22 08:19:36 +10:00
dependabot[bot]
d2a77c2371
Bump set-getter from 0.1.0 to 0.1.1 in /docs
Bumps [set-getter](https://github.com/doowb/set-getter) from 0.1.0 to 0.1.1.
- [Release notes](https://github.com/doowb/set-getter/releases)
- [Commits](https://github.com/doowb/set-getter/commits/0.1.1)

---
updated-dependencies:
- dependency-name: set-getter
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-06-21 21:26:26 +00:00
jc21
104f65b541
Merge pull request #1169 from jc21/dependabot/npm_and_yarn/test/glob-parent-5.1.2
Bump glob-parent from 5.1.0 to 5.1.2 in /test
2021-06-19 10:31:47 +10:00
jc21
d0fb4b6914
Merge pull request #1177 from jc21/dependabot/npm_and_yarn/frontend/postcss-7.0.36
Bump postcss from 7.0.32 to 7.0.36 in /frontend
2021-06-19 10:31:36 +10:00
jc21
42c3272def
Merge pull request #1182 from DSorlov/develop
Update ssl-ciphers.conf
2021-06-19 10:30:43 +10:00
jc21
2812889d61
Merge pull request #1186 from jc21/use-certbot-from-path
Use the certbot command from the PATH variable
2021-06-19 10:24:21 +10:00
chaptergy
bd3a13b2a5
Also rotate other logs 2021-06-18 10:43:56 +02:00
chaptergy
289d179142
Adds logrotate 2021-06-18 09:38:48 +02:00
chaptergy
deca493912
Splits access and error logs for each host 2021-06-18 09:38:48 +02:00
chaptergy
d16bf7d6c0
Adds explicit names to dev containers 2021-06-18 09:38:48 +02:00
chaptergy
3f1415dad1
Use the certbot command from the PATH variable 2021-06-18 09:22:42 +02:00
Daniel Sörlöv
3e744b6b2d Update ssl-ciphers.conf
Removing support (by default) for all the unsecure protocols. This should be the default and if needed additional support can be configured. As this is a security feature it should be aligned with a moderate policy. This is updated using the latest recomendation as found on https://ssl-config.mozilla.org/#server=nginx&version=1.17.7&config=intermediate&openssl=1.1.1d&guideline=5.6
2021-06-17 15:17:13 +02:00
Théo Sallou
56c4f8a106 fix wildcard domains regex 2021-06-17 11:51:51 +02:00
Justin Peacock
99ef8bae4c
Update messages.json
small change but updated the year in the footer. maybe there's a better way to grab the date with a function?
2021-06-16 09:29:55 -04:00
dependabot[bot]
b7f0343730
Bump postcss from 7.0.32 to 7.0.36 in /frontend
Bumps [postcss](https://github.com/postcss/postcss) from 7.0.32 to 7.0.36.
- [Release notes](https://github.com/postcss/postcss/releases)
- [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/postcss/postcss/compare/7.0.32...7.0.36)

---
updated-dependencies:
- dependency-name: postcss
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-06-16 10:16:48 +00:00
jc21
c807b59fb4
Merge pull request #1149 from Fuechslein/develop 2021-06-16 20:16:08 +10:00
jc21
60fc57431a
Merge pull request #1136 from jc21/dependabot/npm_and_yarn/docs/ws-7.4.6
Bump ws from 7.3.1 to 7.4.6 in /docs
2021-06-11 12:11:30 +10:00
dependabot[bot]
d988a3a307
Bump glob-parent from 5.1.0 to 5.1.2 in /test
Bumps [glob-parent](https://github.com/gulpjs/glob-parent) from 5.1.0 to 5.1.2.
- [Release notes](https://github.com/gulpjs/glob-parent/releases)
- [Changelog](https://github.com/gulpjs/glob-parent/blob/main/CHANGELOG.md)
- [Commits](https://github.com/gulpjs/glob-parent/compare/v5.1.0...v5.1.2)

---
updated-dependencies:
- dependency-name: glob-parent
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-06-11 01:26:02 +00:00
jc21
de763d3fa9
Merge pull request #1170 from jc21/dependabot/npm_and_yarn/docs/glob-parent-5.1.2
Bump glob-parent from 5.1.1 to 5.1.2 in /docs
2021-06-11 11:25:28 +10:00
jc21
21bfb61cc8
Merge pull request #1068 from jc21/dependabot/npm_and_yarn/frontend/underscore-1.12.1
Bump underscore from 1.10.2 to 1.12.1 in /frontend
2021-06-11 10:01:30 +10:00
dependabot[bot]
a79adeb280
Bump ws from 7.3.1 to 7.4.6 in /docs
Bumps [ws](https://github.com/websockets/ws) from 7.3.1 to 7.4.6.
- [Release notes](https://github.com/websockets/ws/releases)
- [Commits](https://github.com/websockets/ws/compare/7.3.1...7.4.6)

Signed-off-by: dependabot[bot] <support@github.com>
2021-06-10 23:08:37 +00:00
jc21
9b7a019222
Merge pull request #1159 from jc21/changes-real_ip-ranges-to-local-network
Sets real_ip ranges to local network only
2021-06-11 09:07:57 +10:00
jc21
e65143d276
Merge pull request #1164 from jc21/dependabot/npm_and_yarn/docs/normalize-url-5.3.1
Bump normalize-url from 5.1.0 to 5.3.1 in /docs
2021-06-11 09:07:06 +10:00
dependabot[bot]
61bb183eda
Bump glob-parent from 5.1.1 to 5.1.2 in /docs
Bumps [glob-parent](https://github.com/gulpjs/glob-parent) from 5.1.1 to 5.1.2.
- [Release notes](https://github.com/gulpjs/glob-parent/releases)
- [Changelog](https://github.com/gulpjs/glob-parent/blob/main/CHANGELOG.md)
- [Commits](https://github.com/gulpjs/glob-parent/compare/v5.1.1...v5.1.2)

---
updated-dependencies:
- dependency-name: glob-parent
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-06-10 23:06:36 +00:00
jc21
f3d3a6db91
Merge pull request #1165 from jc21/dependabot/npm_and_yarn/docs/css-what-5.0.1
Bump css-what from 3.3.0 to 5.0.1 in /docs
2021-06-11 09:05:46 +10:00
dependabot[bot]
9ebb443cb7
Bump css-what from 3.3.0 to 5.0.1 in /docs
Bumps [css-what](https://github.com/fb55/css-what) from 3.3.0 to 5.0.1.
- [Release notes](https://github.com/fb55/css-what/releases)
- [Commits](https://github.com/fb55/css-what/compare/v3.3.0...v5.0.1)

---
updated-dependencies:
- dependency-name: css-what
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-06-09 19:18:07 +00:00
dependabot[bot]
fa4c4d0a8d
Bump normalize-url from 5.1.0 to 5.3.1 in /docs
Bumps [normalize-url](https://github.com/sindresorhus/normalize-url) from 5.1.0 to 5.3.1.
- [Release notes](https://github.com/sindresorhus/normalize-url/releases)
- [Commits](https://github.com/sindresorhus/normalize-url/commits)

---
updated-dependencies:
- dependency-name: normalize-url
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-06-09 00:57:18 +00:00
Jamie Curnow
3e1518fef6 Updated docs for docker restart policy 2021-06-08 08:48:26 +10:00
jc21
e59db84721
Merge pull request #1155 from ChrisTracy/patch-1
Adding "restart: always" to ReadMe
2021-06-08 08:45:28 +10:00
Chris Tracy
c281b31fc8
Update README.md 2021-06-07 09:38:45 -05:00
jc21
1c93ca9896
Merge pull request #1158 from jc21/fixes-duckdns-certbot 2021-06-07 18:33:25 +10:00
chaptergy
df5836e573
Sets real_ip ranges to local network only 2021-06-07 08:30:39 +02:00
chaptergy
41ef35f0d0
Fixes duckdns certbot 2021-06-07 08:27:01 +02:00
chaptergy
5e6ce8643f
Adds reddit badge to readme 2021-06-07 06:19:29 +00:00
jc21
f575400bc8
Merge pull request #1081 from vipergts450/vipergts450-custom_location-patch
Vipergts450 custom location patch
2021-06-07 12:46:23 +10:00
jc21
6d9a335b0e
Merge pull request #1129 from jc21/dependabot/npm_and_yarn/docs/dns-packet-5.2.2
Bump dns-packet from 5.2.1 to 5.2.2 in /docs
2021-06-07 12:44:26 +10:00
jc21
f94eb5f318
Merge pull request #1123 from jc21/dependabot/npm_and_yarn/docs/browserslist-4.16.5
Bump browserslist from 4.13.0 to 4.16.5 in /docs
2021-06-07 09:30:49 +10:00
Chris Tracy
245fa421a2
Adding "restart: always" to ReadMe
Adding "restart: always" to ReadMe. I had a hard time figuring out why once of my NPM containers would not start on reboot while the rest of them would.
2021-06-06 12:14:58 -05:00
Fuechslein
655094a816
Update certbot-dns-plugins.js 2021-06-06 16:44:44 +02:00
Yannik Roth
d544650b05
fix spacings. again. 2021-06-03 19:42:14 +02:00
Yannik Roth
d9d682585c
fix spaces/tabs 2021-06-03 19:35:30 +02:00
Fuechslein
44a202552e Restore default build script 2021-06-03 18:36:25 +02:00
Fuechslein
fd6673420b Added IONOS and Infomaniak certbot plugins 2021-06-03 18:33:33 +02:00
jc21
0e9cd5db9c
Merge pull request #1122 from jc21/fixes-some-database-issues
Fixes some database issues on raspberry pi
2021-05-31 08:43:28 +10:00
dependabot[bot]
6da6e6f145
Bump dns-packet from 5.2.1 to 5.2.2 in /docs
Bumps [dns-packet](https://github.com/mafintosh/dns-packet) from 5.2.1 to 5.2.2.
- [Release notes](https://github.com/mafintosh/dns-packet/releases)
- [Changelog](https://github.com/mafintosh/dns-packet/blob/master/CHANGELOG.md)
- [Commits](https://github.com/mafintosh/dns-packet/compare/v5.2.1...v5.2.2)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-26 18:51:46 +00:00
dependabot[bot]
bdaa7460e4
Bump browserslist from 4.13.0 to 4.16.5 in /docs
Bumps [browserslist](https://github.com/browserslist/browserslist) from 4.13.0 to 4.16.5.
- [Release notes](https://github.com/browserslist/browserslist/releases)
- [Changelog](https://github.com/browserslist/browserslist/blob/main/CHANGELOG.md)
- [Commits](https://github.com/browserslist/browserslist/compare/4.13.0...4.16.5)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-26 04:04:42 +00:00
chaptergy
d6d1c1ac35
Updates raspberry pi docker compose in documentation 2021-05-25 14:18:51 +02:00
chaptergy
67958155fc
Updates generated sqlite config in documentation 2021-05-25 14:18:01 +02:00
chaptergy
198bd74ec6
Adds useNullAsDefault to default sqlite config 2021-05-25 14:16:46 +02:00
jc21
92eec95dad
Merge pull request #1111 from jc21/develop
v2.9.3
2021-05-21 08:59:01 +10:00
jc21
b73a034fca
Merge branch 'master' into develop 2021-05-20 13:34:43 +10:00
Jamie Curnow
11b508f021 Bump version, added contributors 2021-05-20 13:31:14 +10:00
jc21
c2b5be37f9
Merge pull request #966 from razvanstoica89/master
Add new details about how to run this image on a Raspberry Pi device.
2021-05-20 08:15:31 +10:00
jc21
1a04863a08
Merge pull request #972 from psharma04/master
Add info about SSL
2021-05-20 08:14:28 +10:00
jc21
077d3eb993
Merge pull request #1071 from jc21/dependabot/npm_and_yarn/frontend/ua-parser-js-0.7.28
Bump ua-parser-js from 0.7.21 to 0.7.28 in /frontend
2021-05-20 08:12:41 +10:00
jc21
ac38221bdf
Merge pull request #1094 from jc21/dependabot/npm_and_yarn/docs/postcss-8.2.10
Bump postcss from 7.0.32 to 8.2.10 in /docs
2021-05-20 08:12:25 +10:00
jc21
9f146b8fc3
Merge pull request #1099 from jc21/updates-dns-providers
Updates Porkbun, DuckDNS & Azure challenge providers
2021-05-20 08:12:12 +10:00
jc21
9a2d9659a7
Merge pull request #1100 from jc21/show-entity-ids-in-frontend
Displays entity id for each entry in frontend
2021-05-20 08:11:12 +10:00
jc21
6faae5350a
Merge pull request #1107 from jc21/improved-issue-templates
Updates issue templates
2021-05-20 08:10:01 +10:00
chaptergy
2616709e7f
Reactivates Azure dns challenge with new version 2021-05-19 21:07:56 +02:00
chaptergy
bed9ff084c
Adds dns challenge issue template 2021-05-18 20:44:06 +02:00
chaptergy
fb3082b0bb
Updates issue templates to prevent segment information to show up in issue 2021-05-18 20:10:50 +02:00
chaptergy
c8439b8429
Displays entity id for each entry in frontend
Displays this id inside the three-dot-menu on the right
2021-05-16 16:57:05 +02:00
chaptergy
4c3632d3e7
Automatically sort DNS challenge providers by display name on render 2021-05-15 19:16:28 +02:00
chaptergy
24d8cd57da
Updates DuckDNS to a working version 2021-05-15 18:35:49 +02:00
chaptergy
b7c0a8b0c2
Sorts providers alphabetically 2021-05-15 18:32:49 +02:00
chaptergy
d6d7b22b1e
Adds porkbun as dns provider 2021-05-15 18:31:33 +02:00
jc21
5269c957ce
Merge pull request #1085 from jc21/improved-new-password-error-messages
Improved new password error messages
2021-05-13 08:24:12 +10:00
RBXII3
bf8d2672c8
Typo (used \m instead of \n) 2021-05-13 08:24:08 +10:00
jc21
8461acab9b
Merge pull request #1088 from bikram990/develop
Added support for Dynu DNS Provider
2021-05-13 08:23:10 +10:00
jc21
731ae43fe8
Merge pull request #1095 from jc21/godaddy-dns
Adds GoDaddy DNS and temporarily disables Azure DNS
2021-05-13 08:22:37 +10:00
jc21
5354c85352
Merge pull request #1096 from jc21/serve-fonts-locally
Serves font locally
2021-05-13 08:22:00 +10:00
chaptergy
22a37bb923
Disables azure dns provider temporarily 2021-05-12 18:49:28 +02:00
chaptergy
07bbece704
Serves font locally 2021-05-12 18:03:10 +02:00
chaptergy
9af2f50d81
Adds GoDaddy DNS provider 2021-05-12 16:28:09 +02:00
dependabot[bot]
7b148f7970
Bump postcss from 7.0.32 to 8.2.10 in /docs
Bumps [postcss](https://github.com/postcss/postcss) from 7.0.32 to 8.2.10.
- [Release notes](https://github.com/postcss/postcss/releases)
- [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/postcss/postcss/compare/7.0.32...8.2.10)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-12 06:59:49 +00:00
Bikramjeet Singh
a1e52d919f Added support for Dynu DNS Provider 2021-05-11 20:24:52 +05:30
chaptergy
899b487daa
Puts backend errors into own error field 2021-05-10 19:58:28 +02:00
jc21
86eeb5fc44
Merge pull request #1084 from jc21/develop
v2.9.2
2021-05-10 09:10:13 +10:00
Jamie Curnow
62a708b416 Version bump 2021-05-10 08:18:19 +10:00
jc21
a7ce8704b3
Merge pull request #1069 from jc21/dependabot/npm_and_yarn/backend/lodash-4.17.21
Bump lodash from 4.17.19 to 4.17.21 in /backend
2021-05-10 08:15:22 +10:00
jc21
7319a13077
Merge pull request #1074 from jc21/dependabot/npm_and_yarn/frontend/lodash-4.17.21
Bump lodash from 4.17.19 to 4.17.21 in /frontend
2021-05-10 08:15:13 +10:00
jc21
95bd4d93c5
Merge pull request #1080 from jc21/dependabot/npm_and_yarn/frontend/hosted-git-info-2.8.9
Bump hosted-git-info from 2.8.8 to 2.8.9 in /frontend
2021-05-10 08:15:01 +10:00
jc21
69c33f0395
Merge pull request #1083 from chaptergy/adds-more-dns-challenges
Adds more dns challenges
2021-05-10 08:14:07 +10:00
chaptergy
cd4caea2dc
Adds coudns dns provider 2021-05-09 21:47:30 +02:00
chaptergy
c9daf19940
Reorders some providers alphabetically 2021-05-09 21:36:52 +02:00
chaptergy
7c2540b193
Adds Azure dns provider
Issue #864
2021-05-09 19:46:20 +02:00
chaptergy
3e600552dc
Adds regru dns provider
Issue #938
2021-05-09 19:45:42 +02:00
vipergts450
69ee6b1699
Update nginx.js 2021-05-07 23:38:32 -04:00
vipergts450
ca1ea042b2
Update nginx.js 2021-05-07 23:31:51 -04:00
vipergts450
f26df7d9bb
Update nginx.js 2021-05-07 22:43:22 -04:00
Jamie Curnow
ba45705571 Partial revert of 421934e
Keeping the server block of websocket definitions but also bringing back the
location block after discussions on #1067
2021-05-08 12:17:10 +10:00
dependabot[bot]
bf8ea71c77
Bump hosted-git-info from 2.8.8 to 2.8.9 in /frontend
Bumps [hosted-git-info](https://github.com/npm/hosted-git-info) from 2.8.8 to 2.8.9.
- [Release notes](https://github.com/npm/hosted-git-info/releases)
- [Changelog](https://github.com/npm/hosted-git-info/blob/v2.8.9/CHANGELOG.md)
- [Commits](https://github.com/npm/hosted-git-info/compare/v2.8.8...v2.8.9)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-08 02:12:03 +00:00
dependabot[bot]
7deb64a5de
Bump lodash from 4.17.19 to 4.17.21 in /backend
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.19 to 4.17.21.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.19...4.17.21)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-08 02:11:35 +00:00
dependabot[bot]
e283865d3d
Bump lodash from 4.17.19 to 4.17.21 in /frontend
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.19 to 4.17.21.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.19...4.17.21)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-08 02:11:13 +00:00
jc21
a32be3e96b
Merge pull request #1070 from jc21/dependabot/npm_and_yarn/docs/lodash-4.17.21
Bump lodash from 4.17.19 to 4.17.21 in /docs
2021-05-08 12:10:48 +10:00
jc21
0cfd6eab3f
Merge pull request #1072 from jc21/dependabot/npm_and_yarn/docs/url-parse-1.5.0
Bump url-parse from 1.4.7 to 1.5.0 in /docs
2021-05-08 12:10:40 +10:00
jc21
c2361f13e6
Merge pull request #1073 from jc21/dependabot/npm_and_yarn/test/lodash-4.17.21
Bump lodash from 4.17.19 to 4.17.21 in /test
2021-05-08 12:10:30 +10:00
jc21
bc81de54b9
Merge pull request #1078 from jc21/master 2021-05-08 00:21:17 +10:00
jc21
07884bc9b1
Merge pull request #1076 from jc21/develop
v2.9.1
2021-05-07 18:57:53 +10:00
dependabot[bot]
58c3204187
Bump lodash from 4.17.19 to 4.17.21 in /test
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.19 to 4.17.21.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.19...4.17.21)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-07 03:52:24 +00:00
dependabot[bot]
19d3deddd4
Bump url-parse from 1.4.7 to 1.5.0 in /docs
Bumps [url-parse](https://github.com/unshiftio/url-parse) from 1.4.7 to 1.5.0.
- [Release notes](https://github.com/unshiftio/url-parse/releases)
- [Commits](https://github.com/unshiftio/url-parse/compare/1.4.7...1.5.0)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-07 03:51:57 +00:00
dependabot[bot]
f0233b947e
Bump ua-parser-js from 0.7.21 to 0.7.28 in /frontend
Bumps [ua-parser-js](https://github.com/faisalman/ua-parser-js) from 0.7.21 to 0.7.28.
- [Release notes](https://github.com/faisalman/ua-parser-js/releases)
- [Commits](https://github.com/faisalman/ua-parser-js/compare/0.7.21...0.7.28)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-07 03:51:51 +00:00
dependabot[bot]
c6a90a2fd0
Bump lodash from 4.17.19 to 4.17.21 in /docs
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.19 to 4.17.21.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.19...4.17.21)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-07 03:51:51 +00:00
Jamie Curnow
3607c30d98 Bump version 2021-05-07 13:51:35 +10:00
Jamie Curnow
717105f243 Revert installing certbot. This is handled by base image jc21/nginx-full now
Update path of certbot, and use the pip instead
2021-05-07 13:49:31 +10:00
dependabot[bot]
2373e4a06d
Bump underscore from 1.10.2 to 1.12.1 in /frontend
Bumps [underscore](https://github.com/jashkenas/underscore) from 1.10.2 to 1.12.1.
- [Release notes](https://github.com/jashkenas/underscore/releases)
- [Commits](https://github.com/jashkenas/underscore/compare/1.10.2...1.12.1)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-07 03:05:13 +00:00
vipergts450
4c76803f13
Rearrange _location.conf template
Allow more of the main host parameters into the custom location configuration and reorder to make more sense.
2021-05-06 22:30:45 -04:00
vipergts450
6a46e88f8f
Fix renderLocations to accept more parameters from host
Amend renderLocations to pass more host parameters into the custom locations to match the requirements set for the default location. This will apply all parameters set in the UI to all custom locations.
2021-05-06 22:29:21 -04:00
vipergts450
e4e94d5be0
Update nginx.js
Adds ability for custom location templates to handle includes
2021-05-06 14:50:09 -04:00
vipergts450
a3b896fa70
Update _location.conf 2021-05-06 14:48:38 -04:00
vipergts450
60347a90e9
Update _location.conf 2021-05-06 11:40:40 -04:00
Jamie Curnow
a02d4ec46f Use certbot from pip instead of apt 2021-05-06 19:10:40 +10:00
jc21
485bae8f22
Merge pull request #1064 from jc21/develop
v2.9.0
2021-05-06 12:45:21 +10:00
Jamie Curnow
655477316b Version bump, contributors added, apt tweak 2021-05-06 11:32:54 +10:00
jc21
e22f87dee7
Merge pull request #975 from thegamingninja/feature/more-access-ips
Improved Access List Form
2021-05-06 11:06:08 +10:00
THEGamingninja
d3337322dd Add target _blank to href 2021-05-05 21:02:04 -04:00
jc21
6202f4f943
Merge pull request #1034 from jonasled/patch-2
don't fix the select height, to fix multiline select
2021-05-06 10:54:12 +10:00
jc21
b42cc9ed3e
Merge pull request #1050 from jc21/dependabot/npm_and_yarn/frontend/y18n-4.0.3
Bump y18n from 4.0.0 to 4.0.3 in /frontend
2021-04-30 07:16:06 +10:00
jc21
fbf72c0f61
Merge pull request #958 from italobb/patch-1
docker-compose Instructions for streams support
2021-04-29 21:49:13 +10:00
jc21
cbd0b0c070
Merge pull request #964 from jc21/dependabot/npm_and_yarn/docs/is-svg-4.2.2
Bump is-svg from 4.2.1 to 4.2.2 in /docs
2021-04-29 21:45:00 +10:00
jc21
874f049323
Merge pull request #965 from jc21/dependabot/npm_and_yarn/docs/ssri-8.0.1
Bump ssri from 8.0.0 to 8.0.1 in /docs
2021-04-29 21:44:39 +10:00
dependabot[bot]
42ab4020e2
Bump y18n from 4.0.0 to 4.0.3 in /frontend
Bumps [y18n](https://github.com/yargs/y18n) from 4.0.0 to 4.0.3.
- [Release notes](https://github.com/yargs/y18n/releases)
- [Changelog](https://github.com/yargs/y18n/blob/y18n-v4.0.3/CHANGELOG.md)
- [Commits](https://github.com/yargs/y18n/compare/v4.0.0...y18n-v4.0.3)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-29 11:44:15 +00:00
jc21
7ab9683b87
Merge pull request #987 from jc21/dependabot/npm_and_yarn/backend/y18n-4.0.1
Bump y18n from 4.0.0 to 4.0.1 in /backend
2021-04-29 21:43:59 +10:00
jc21
865facfd05
Merge pull request #988 from jc21/dependabot/npm_and_yarn/test/y18n-4.0.1
Bump y18n from 4.0.0 to 4.0.1 in /test
2021-04-29 21:43:37 +10:00
jc21
0951f4a202
Merge pull request #989 from jc21/dependabot/npm_and_yarn/docs/y18n-4.0.1
Bump y18n from 4.0.0 to 4.0.1 in /docs
2021-04-29 21:43:22 +10:00
jc21
882ec27969
Merge pull request #1017 from Stealthii/bugfix/config-application
Apply 'Force SSL' and 'Enable Websockets' to full host definition
2021-04-29 21:42:58 +10:00
jc21
a84158c1ff
Merge pull request #1020 from stegmannb/patch-1
Updated credentials for netcup dns challenge
2021-04-29 21:40:49 +10:00
dependabot[bot]
161d3ec817
Bump ssri from 8.0.0 to 8.0.1 in /docs
Bumps [ssri](https://github.com/npm/ssri) from 8.0.0 to 8.0.1.
- [Release notes](https://github.com/npm/ssri/releases)
- [Changelog](https://github.com/npm/ssri/blob/latest/CHANGELOG.md)
- [Commits](https://github.com/npm/ssri/compare/v8.0.0...v8.0.1)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-29 11:38:19 +00:00
jc21
5b15249689
Merge pull request #1042 from hepelayo/duckdnsCertbotPlugin
Add DuckDNS certbot plugin
2021-04-29 21:37:58 +10:00
jc21
602fce1c7e
Merge pull request #1046 from jc21/dependabot/npm_and_yarn/frontend/ssri-6.0.2
Bump ssri from 6.0.1 to 6.0.2 in /frontend
2021-04-29 21:36:55 +10:00
Jamie Curnow
f2f653e345 Remove platform specific determination 2021-04-29 11:19:59 +10:00
dependabot[bot]
b55738bd6e
Bump ssri from 6.0.1 to 6.0.2 in /frontend
Bumps [ssri](https://github.com/npm/ssri) from 6.0.1 to 6.0.2.
- [Release notes](https://github.com/npm/ssri/releases)
- [Changelog](https://github.com/npm/ssri/blob/v6.0.2/CHANGELOG.md)
- [Commits](https://github.com/npm/ssri/compare/v6.0.1...v6.0.2)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-28 23:39:48 +00:00
jc21
b39a59ce72
Merge pull request #1045 from jc21/nginx-full
Switch to nginx-full base
2021-04-29 09:29:46 +10:00
Jamie Curnow
9872daf29f Switch to nginx-full base 2021-04-29 08:28:40 +10:00
Héctor Pelayo
91044e730b Correct indentation 2021-04-26 22:35:52 +02:00
Héctor Pelayo
656a7dceef Correct spacing 2021-04-26 22:31:16 +02:00
Héctor Pelayo
d636502eaa Add DuckDNS certbot plugin
Uses https://github.com/infinityofspace/certbot_dns_duckdns certbot plugin to implement DuckDNS DNS challenge in order to obtain Wildcard certificates.

Requires that the user inserts his duckDNS token in "Credentials File Content" input box.
2021-04-26 20:25:24 +02:00
Björn Heinrichs
389fd158ad allows hostname instead of ip for streams 2021-04-24 01:09:01 +02:00
Jonas Leder
30fa63b379
don't fix the select height, to fix multiline select 2021-04-23 21:25:57 +02:00
Bastian Stegmann
691063545c
Updated credentials for netcup dns challange
The netcup DNS challenge currently fails because the credentials are not found.
2021-04-15 09:48:08 +02:00
Daniel Porter
421934efed Move 'Allow Websockets' definitions to host root configuration
This fixes issues with these settings not applying to custom locations
defined under hosts.
2021-04-13 20:04:35 +01:00
Daniel Porter
f056b9dc7f Move 'Force SSL' definitions to host root configuration
This fixes issues with these settings not applying to custom locations
defined under hosts.
2021-04-13 19:59:49 +01:00
dependabot[bot]
48d421ba28
Bump y18n from 4.0.0 to 4.0.1 in /docs
Bumps [y18n](https://github.com/yargs/y18n) from 4.0.0 to 4.0.1.
- [Release notes](https://github.com/yargs/y18n/releases)
- [Changelog](https://github.com/yargs/y18n/blob/master/CHANGELOG.md)
- [Commits](https://github.com/yargs/y18n/commits)

Signed-off-by: dependabot[bot] <support@github.com>
2021-03-31 17:28:00 +00:00
dependabot[bot]
096b714117
Bump y18n from 4.0.0 to 4.0.1 in /test
Bumps [y18n](https://github.com/yargs/y18n) from 4.0.0 to 4.0.1.
- [Release notes](https://github.com/yargs/y18n/releases)
- [Changelog](https://github.com/yargs/y18n/blob/master/CHANGELOG.md)
- [Commits](https://github.com/yargs/y18n/commits)

Signed-off-by: dependabot[bot] <support@github.com>
2021-03-31 14:28:11 +00:00
dependabot[bot]
0d25dc1aaa
Bump y18n from 4.0.0 to 4.0.1 in /backend
Bumps [y18n](https://github.com/yargs/y18n) from 4.0.0 to 4.0.1.
- [Release notes](https://github.com/yargs/y18n/releases)
- [Changelog](https://github.com/yargs/y18n/blob/master/CHANGELOG.md)
- [Commits](https://github.com/yargs/y18n/commits)

Signed-off-by: dependabot[bot] <support@github.com>
2021-03-31 14:25:26 +00:00
THEGamingninja
63d3c2d06f Add More Access List Entries & Access List Help 2021-03-25 14:59:07 -04:00
RBXII3
5fc704ccad
Add info about SSL 2021-03-23 13:49:14 +11:00
Razvan Stoica
61d99561c1
Set ports to default value 2021-03-22 09:50:25 +02:00
Razvan Stoica
c26ce2083f Add new details about how to run this image on a Raspberry Pi device. 2021-03-21 18:02:53 +02:00
dependabot[bot]
847d71f72a
Bump is-svg from 4.2.1 to 4.2.2 in /docs
Bumps [is-svg](https://github.com/sindresorhus/is-svg) from 4.2.1 to 4.2.2.
- [Release notes](https://github.com/sindresorhus/is-svg/releases)
- [Commits](https://github.com/sindresorhus/is-svg/compare/v4.2.1...v4.2.2)

Signed-off-by: dependabot[bot] <support@github.com>
2021-03-21 00:12:10 +00:00
Italo Borssatto
3c35039445
docker-compose Instructions for streams support
A simple example to make the docker-compose configuration support stream configurations.
2021-03-18 01:20:47 -03:00
jc21
1a64d44857
Merge pull request #955 from jc21/develop
v2.8.1
2021-03-18 09:36:26 +10:00
Jamie Curnow
ba5f0c212c Bumped version 2021-03-17 14:56:22 +10:00
jc21
4eddb5d7f3
Merge pull request #769 from jc21/dependabot/npm_and_yarn/frontend/ini-1.3.8
Bump ini from 1.3.5 to 1.3.8 in /frontend
2021-03-17 14:54:45 +10:00
Jamie Curnow
3b104710d5 Restrict redirect http code 2021-03-17 14:53:57 +10:00
jc21
74db0004bd
Merge pull request #883 from baruffaldi/master
Forward scheme and http code added for redirection hosts
2021-03-17 11:30:26 +10:00
jc21
6e67352a0f
Merge pull request #880 from jlesage/jwt-key-pair-no-restart
Removed the need to restart Nginx Proxy Manager after generating JWT key pair
2021-03-17 11:09:37 +10:00
Jamie Curnow
b127f02468 Added upgrade steps 2021-03-17 08:58:45 +10:00
jc21
c9c53d9670
Merge pull request #903 from ogarai/edit-disabled-host
Prevent activating nginx config after editing disabled proxy host
2021-03-17 08:32:14 +10:00
jc21
d36dbb868b
Merge pull request #942 from nielscil/develop-certbot-dns-transip
Added TransIP dns provider
2021-03-17 08:30:05 +10:00
jc21
b7fb2cfe92
Merge pull request #947 from phantomski77/patch-2
Update _hsts.conf template to increase HSTS max-age value
2021-03-17 08:29:46 +10:00
Niels Bouma
d0a0c77556
acmedns indentation fix 2021-03-16 13:36:17 +01:00
Niels Bouma
9469b9c78a
fixed closing brace 2021-03-16 12:57:26 +01:00
jc21
e4988f34c7
Merge pull request #943 from phantomski77/patch-1
Update README.md
2021-03-16 19:51:03 +10:00
jc21
1fe9e24f0a
Merge pull request #920 from jc21/dependabot/npm_and_yarn/docs/prismjs-1.23.0
Bump prismjs from 1.21.0 to 1.23.0 in /docs
2021-03-16 19:50:28 +10:00
jc21
9c39de3454
Merge pull request #935 from jc21/dependabot/npm_and_yarn/frontend/elliptic-6.5.4
Bump elliptic from 6.5.3 to 6.5.4 in /frontend
2021-03-16 19:50:14 +10:00
jc21
9bb68ad4eb
Merge pull request #937 from jc21/dependabot/npm_and_yarn/docs/elliptic-6.5.4
Bump elliptic from 6.5.3 to 6.5.4 in /docs
2021-03-16 19:49:59 +10:00
jc21
5bf774bee1
Merge branch 'develop' into develop-certbot-dns-transip 2021-03-16 19:49:27 +10:00
jc21
99514464fb
Merge pull request #946 from ijaron/dns-acme
Add ACME-DNS certbot plugin
2021-03-16 19:48:13 +10:00
jc21
3bf1c1e531
Merge pull request #948 from GurjinderSingh/patch-1
Update README.md
2021-03-16 13:59:04 +10:00
Jamie Curnow
e2e31094aa Fix CI, no var needed for this 2021-03-16 11:32:38 +10:00
Gurjinder Singh
f29ff15167
Update README.md
found it in config file was going to add option
	# Custom
	include /data/nginx/custom/http_top[.]conf;
 
b7b808d98d/docker/rootfs/etc/nginx/nginx.conf (L72)
2021-03-14 05:13:26 -04:00
David Dosoudil
1c64252015
Update _hsts.conf template
I propose the change to max-age value of HSTS from 1 year to 2 years.
2021-03-13 12:40:47 +00:00
ijaron
ead19915f3 Add ACME-DNS certbot plugin
uses https://github.com/pan-net-security/certbot-dns-acmedns in to implement ACME-DNS support.
Requires file in /data with following layout
# cat /data/acme-registration.json
{
  "something.acme.com": {
    "username": "6e14735c-2c6a-447e-b63d-a23ac4438bd7",
    "password": "dd6gnYS-IxrQfDLbdPRX3hrFhS_SLrwbS0kSl_i8",
    "fulldomain": "3b750a0e-c627-423f-9966-4799c6a9533b.auth.example.org",
    "subdomain": "3b750a0e-c627-423f-9966-4799c6a9533b",
    "allowfrom": []
  }
}
2021-03-12 14:24:56 -06:00
David Dosoudil
967e0dd98a
Update README.md
Secrets need both global and local per-service declaration, otherwise fails as "not found". Local configuration added for both app and db.
2021-03-11 21:59:26 +00:00
Niels Bouma
bd0324dba0
credentials property naming for transip
credentials property naming for transip
2021-03-11 15:44:20 +01:00
Niels Bouma
607fb83a1e
Added transIP certbot dns plugin 2021-03-11 13:33:42 +01:00
Jamie Curnow
bb5fc58f3a Revert "Fix CI, use docker for a yarn command"
This reverts commit afbec0aca96fd860bbaaed0bebf9e5294e6ea325.
2021-03-11 09:29:08 +10:00
Jamie Curnow
afbec0aca9 Fix CI, use docker for a yarn command 2021-03-11 08:41:10 +10:00
dependabot[bot]
1e5d9dfbff
Bump elliptic from 6.5.3 to 6.5.4 in /docs
Bumps [elliptic](https://github.com/indutny/elliptic) from 6.5.3 to 6.5.4.
- [Release notes](https://github.com/indutny/elliptic/releases)
- [Commits](https://github.com/indutny/elliptic/compare/v6.5.3...v6.5.4)

Signed-off-by: dependabot[bot] <support@github.com>
2021-03-10 10:39:22 +00:00
dependabot[bot]
cfcb657cde
Bump elliptic from 6.5.3 to 6.5.4 in /frontend
Bumps [elliptic](https://github.com/indutny/elliptic) from 6.5.3 to 6.5.4.
- [Release notes](https://github.com/indutny/elliptic/releases)
- [Commits](https://github.com/indutny/elliptic/compare/v6.5.3...v6.5.4)

Signed-off-by: dependabot[bot] <support@github.com>
2021-03-10 08:19:41 +00:00
dependabot[bot]
7f243e6f06
Bump prismjs from 1.21.0 to 1.23.0 in /docs
Bumps [prismjs](https://github.com/PrismJS/prism) from 1.21.0 to 1.23.0.
- [Release notes](https://github.com/PrismJS/prism/releases)
- [Changelog](https://github.com/PrismJS/prism/blob/master/CHANGELOG.md)
- [Commits](https://github.com/PrismJS/prism/compare/v1.21.0...v1.23.0)

Signed-off-by: dependabot[bot] <support@github.com>
2021-03-01 21:06:50 +00:00
Orko Garai
7e7032c051 Prevent activating nginx config after editing disabled proxy host 2021-02-18 23:05:30 +00:00
jc21
b7b808d98d
Merge pull request #899 from jc21/develop
Docs for a docker network
2021-02-17 20:56:10 +10:00
Jamie Curnow
a21289bf11 Docs for a docker network 2021-02-17 20:55:12 +10:00
jc21
4a8d01224a
Merge pull request #897 from jc21/develop
Update github templates and docs
2021-02-17 20:19:49 +10:00
Jamie Curnow
f0eebc43e3 Update github templates and docs 2021-02-17 20:18:12 +10:00
baruffaldi
49fbf031d1 $scheme is displayed as "auto" on hosts listing 2021-02-10 19:43:29 +01:00
baruffaldi
4060718e5c Hotfix: This group of assignments is not aligned 2021-02-10 18:26:19 +01:00
baruffaldi
49b0f11ae7 migrations 2021-02-10 18:13:12 +01:00
baruffaldi
9b83d35ef4 Migrations 2021-02-10 18:12:02 +01:00
baruffaldi
eb20add0c7 Migrations hotfix 2021-02-10 17:16:33 +01:00
baruffaldi
1f122e9145 Database migrations created 2021-02-10 15:57:28 +01:00
baruffaldi
329d0ecaed Added forward scheme to table columns 2021-02-10 15:27:11 +01:00
baruffaldi
77a2ee948a Updated list table
Added state code columns
Better form columns sizing
2021-02-10 15:25:19 +01:00
baruffaldi
ebeda6345e Globalization done
Ready to merge
2021-02-10 14:11:01 +01:00
baruffaldi
e35138ebed Added scheme to definitions 2021-02-10 10:42:34 +01:00
baruffaldi
8ba6c4f7e7 Added http_code definition 2021-02-10 09:55:41 +01:00
baruffaldi
6df7b72e08 Forward scheme and http code added for redirection hosts
You can now configure the forward_scheme and forward_http_code on user interface (section redirection hosts)
2021-02-09 11:23:15 +01:00
Jocelyn Le Sage
fe13b12f43 Removed the need to restart Nginx Proxy Manager after generating JWT key pair. 2021-02-08 17:36:58 -05:00
jc21
ea28da90b2
Merge pull request #876 from jc21/develop
v2.8.0
2021-02-08 15:01:31 +10:00
Jamie Curnow
b243324c65 Added contributors and bumped version 2021-02-08 12:23:52 +10:00
jc21
a2dde00f40
Merge pull request #868 from lorisbergeron/eurodns-as-provider
Add EuroDNS as a DNS provider
2021-02-08 12:22:33 +10:00
jc21
5ff07faa7e
Merge pull request #872 from ahgraber/master
Add Docker secrets
2021-02-08 11:59:23 +10:00
Jamie Curnow
272c652847 Updated docs to use latest mariadb-aria image 2021-02-08 11:56:21 +10:00
ahgraber
3964bbf3fe update advanced-config/readme with secrets 2021-02-07 19:12:20 -05:00
ahgraber
11175aaa5f revert docker/dev before PR 2021-02-07 09:52:37 -05:00
ahgraber
7fcc4a7ef0 cleanup 2021-02-06 20:05:40 -05:00
ahgraber
5abb9458c7 fix linebreaks in secrets 2021-02-05 23:47:30 -05:00
Loris Bergeron
0ca5587a6f EuroDNS fix key-spacing error 2021-02-05 23:40:31 +01:00
Loris Bergeron
d29650882b EuroDNS fix key-spacing error 2021-02-05 23:29:01 +01:00
Loris Bergeron
9c3a7b02ec Add EuroDNS as a DNS provider 2021-02-05 23:17:51 +01:00
Alex Graber
ef3a073af5 local builds & secrets 2021-02-05 16:52:24 -05:00
ahgraber
15c4857a4b fix /docker/dev/docker-compose.yaml 2021-02-04 14:03:17 -05:00
Alex Graber
63a71afbc8 beta s6 secrets 2021-02-04 11:25:26 -05:00
Alex Graber
64761ee9c6 beta secrets 2021-02-04 11:15:31 -05:00
ahgraber
d6c344b5ec add local docker-compose to build 2021-02-02 08:58:45 -05:00
jc21
d27826d10e
Merge pull request #850 from MooBaloo/master
Add new custom http.conf above includes for NPM-generated files
2021-02-01 12:10:31 +10:00
MooBaloo
4ac52a0e25
Add custom .conf above includes for NPM-generated files.
Added a new clause for custom http_top.conf above the include clauses for NPM-generated files. Allows for more flexibility with adding custom nginx .conf files to NPM

Use case: adding a configuration change needs to be present before other custom configuration files are called and reference configuration from the custom http_top.conf file.
Example: add a new log_format in http_top.conf, then referencing it in a access_log clause in server_proxy.conf.
2021-01-28 05:52:41 -05:00
jc21
efa841d75a
Merge pull request #842 from Shuro/patch-1
Use configured default page also for IPv6
2021-01-28 08:45:12 +10:00
Shuro
d1fac583ea
Use configured default page also for IPv6
Just a small check for the ipv6 variable, similar to _listen.conf,
so that the configured default page is also delivered on ipv6 requests.
2021-01-25 01:28:50 +01:00
jc21
8cb44c7b97
Merge pull request #830 from jc21/develop
Updated version fixes #823
2021-01-18 12:15:20 +10:00
jc21
f2293a9dda
Merge branch 'master' into develop 2021-01-18 12:15:04 +10:00
Jamie Curnow
da0d1d4a2f Updated version fixes #823 2021-01-18 12:14:13 +10:00
jc21
6a8d5e2166
Merge pull request #820 from jc21/develop
v2.7.3
2021-01-12 11:13:35 +10:00
jc21
d732665a23
Merge branch 'master' into develop 2021-01-12 09:06:34 +10:00
Jamie Curnow
e0748c9bc7 Bumped version 2021-01-12 09:05:27 +10:00
dependabot[bot]
23573543a3
Bump ini from 1.3.5 to 1.3.8 in /frontend
Bumps [ini](https://github.com/isaacs/ini) from 1.3.5 to 1.3.8.
- [Release notes](https://github.com/isaacs/ini/releases)
- [Commits](https://github.com/isaacs/ini/compare/v1.3.5...v1.3.8)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-06 23:36:33 +00:00
jc21
bfb328238e
Merge pull request #806 from jc21/develop
v2.7.2
2021-01-07 09:35:35 +10:00
Jamie Curnow
64cc4f57d6 Version bump and acknowledgements 2021-01-06 21:48:10 +10:00
jc21
7a3c91c6a4
Merge pull request #804 from lebrou34/master
Add Gandi Live DNS to certbot-dns-plugins.js
2021-01-06 13:14:54 +10:00
lebrou34
508bc62852
Update certbot-dns-plugins.js 2021-01-05 18:47:22 +01:00
lebrou34
59e8446d47
Update certbot-dns-plugins.js 2021-01-05 18:41:26 +01:00
lebrou34
d13596d2f7
Update certbot-dns-plugins.js 2021-01-05 18:35:18 +01:00
lebrou34
9adccfa341
Update certbot-dns-plugins.js 2021-01-05 18:19:27 +01:00
lebrou34
5cc3b53378
Update certbot-dns-plugins.js 2021-01-05 18:11:10 +01:00
lebrou34
b62b0a2fb7
Update certbot-dns-plugins.js 2021-01-05 17:36:47 +01:00
jc21
1faac4edf2
Merge pull request #750 from klutchell/klutchell-patch-1
allow custom stream conf
2021-01-03 20:14:55 +10:00
jc21
4c60dce169
Merge pull request #796 from lightglitch/patch-1
Fix dead hosts verification count
2021-01-03 20:14:36 +10:00
jc21
771f31f44d
Merge pull request #770 from jc21/dependabot/npm_and_yarn/backend/ini-1.3.8
Bump ini from 1.3.5 to 1.3.8 in /backend
2021-01-03 20:14:21 +10:00
jc21
8bedb95e1d
Merge pull request #771 from jc21/dependabot/npm_and_yarn/test/ini-1.3.8
Bump ini from 1.3.5 to 1.3.8 in /test
2021-01-03 20:14:03 +10:00
jc21
ac4be08df2
Merge pull request #772 from jc21/dependabot/npm_and_yarn/docs/ini-1.3.8
Bump ini from 1.3.5 to 1.3.8 in /docs
2021-01-03 20:13:49 +10:00
jc21
0d6e058e23
Merge pull request #774 from chaptergy/better-custom-certificate-handling
Better custom certificate handling
2021-01-03 12:09:55 +10:00
Mário Franco
bee2ceb667
Fix dead hosts verification count 2021-01-02 04:58:14 +00:00
chaptergy
6af13d4f40 Removes explicit privkeytype check and adds passphrase error 2020-12-14 12:08:39 +01:00
dependabot[bot]
9dd0ebd899
Bump ini from 1.3.5 to 1.3.8 in /docs
Bumps [ini](https://github.com/isaacs/ini) from 1.3.5 to 1.3.8.
- [Release notes](https://github.com/isaacs/ini/releases)
- [Commits](https://github.com/isaacs/ini/compare/v1.3.5...v1.3.8)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-12 10:17:11 +00:00
dependabot[bot]
6e97bfa717
Bump ini from 1.3.5 to 1.3.8 in /test
Bumps [ini](https://github.com/isaacs/ini) from 1.3.5 to 1.3.8.
- [Release notes](https://github.com/isaacs/ini/releases)
- [Commits](https://github.com/isaacs/ini/compare/v1.3.5...v1.3.8)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-12 08:23:59 +00:00
dependabot[bot]
07b69f41eb
Bump ini from 1.3.5 to 1.3.8 in /backend
Bumps [ini](https://github.com/isaacs/ini) from 1.3.5 to 1.3.8.
- [Release notes](https://github.com/isaacs/ini/releases)
- [Commits](https://github.com/isaacs/ini/compare/v1.3.5...v1.3.8)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-12 08:23:45 +00:00
Kyle Harding
6bd2ac7d6d
Update README.md 2020-12-01 14:24:14 -05:00
Kyle Harding
528e5ef3bc
allow custom stream conf
Allow a top-level custom `stream` configuration file to be loaded.
2020-12-01 14:22:31 -05:00
Jamie Curnow
bc1c50ac92 Added contributor 2020-11-22 21:50:57 +10:00
jc21
8c2ab42b75
Merge pull request #738 from WaterCalm/master
add aliyun DNS plugin
2020-11-22 21:48:24 +10:00
WaterCalm
62053d15d4
add aliyun DNS plugin
add aliyun DNS plugin
2020-11-22 16:08:56 +08:00
Jamie Curnow
6fed642aba Cypress docker build should be faster and added mkcert for later 2020-11-22 16:57:12 +10:00
jc21
72ac549a58
Merge pull request #729 from jc21/develop
v2.7.1
2020-11-18 22:55:47 +10:00
jc21
9f38617135
Merge branch 'master' into develop 2020-11-18 22:55:37 +10:00
Jamie Curnow
94eec805df Version bump 2020-11-18 21:46:21 +10:00
Jamie Curnow
05a940e732 Fix instances where config file exists and env vars don't 2020-11-18 21:42:03 +10:00
jc21
1c43cc2181
Merge pull request #725 from jc21/develop
v2.7.0
2020-11-18 14:30:44 +10:00
jc21
657ee73ff1
Merge branch 'master' into develop 2020-11-18 12:22:34 +10:00
Jamie Curnow
4ee5d993cf Bumped version 2020-11-18 12:21:35 +10:00
jc21
70a445e2d7
Merge pull request #704 from chaptergy/allow-setup-without-config-file
Removes the need of a config file and allows db config via environment
2020-11-18 12:18:45 +10:00
jc21
2115da210d
Merge pull request #694 from chaptergy/visual-indicator-for-certificate-deletion
Adds visual indicator for certificate deletion
2020-11-09 10:10:55 +10:00
jc21
540554c4f6
Merge pull request #695 from chaptergy/failed-certificate-autoremove
Adds autoremove of failed certificate creations in DB
2020-11-09 10:10:00 +10:00
chaptergy
1337c50d28 Use latest tag in full setup instructions 2020-11-07 19:37:35 +01:00
chaptergy
c5ceb3b2b1 Removes obsolete file mount 2020-11-07 13:54:18 +01:00
chaptergy
57fc1d8f08 Removes the need of a config file and allows db config via environment 2020-11-07 13:24:01 +01:00
chaptergy
1518ecd1e9 Adds autoremove of failed certificate creations in DB 2020-11-06 12:29:38 +01:00
chaptergy
6be0343918 Adds visual indicator for certificate deletion 2020-11-06 11:51:42 +01:00
jc21
cf8812c932
Merge pull request #692 from jc21/develop
v2.6.2
2020-11-06 19:31:10 +10:00
Jamie Curnow
5bc3e474a9 Merge branch 'real_ip' of github.com:jc21/nginx-proxy-manager into develop 2020-11-06 13:21:37 +10:00
Jamie Curnow
13eaa346bc Use remote addr as real ip 2020-11-06 13:21:22 +10:00
Jamie Curnow
d7437cc4a7 Test for real-ip header 2020-11-06 13:17:30 +10:00
Jamie Curnow
ddb3c6590c Version bump 2020-11-06 13:06:15 +10:00
Jamie Curnow
89d6773bda Merge branch 'develop' of github.com:jc21/nginx-proxy-manager into real_ip 2020-11-06 09:18:25 +10:00
Jamie Curnow
3651b9484f Fix for pip install error when there are no plugins to install 2020-11-06 09:17:52 +10:00
Jamie Curnow
2200c950b7 Merge branch 'develop' of github.com:jc21/nginx-proxy-manager into real_ip 2020-11-06 09:12:35 +10:00
jc21
14f84f01b5
Merge pull request #687 from chaptergy/allow-additional-dns-challenge-dependencies
Allow additional dns challenge dependencies
2020-11-06 09:02:35 +10:00
chaptergy
cb014027bb Makes sure credentials folder exist every time before saving credentials 2020-11-04 19:31:40 +01:00
chaptergy
32e5155783 Fixes Linting errors 2020-11-03 22:38:09 +01:00
chaptergy
a3159ad59e Converts tabs to spaces 2020-11-03 22:24:03 +01:00
chaptergy
60a40197f1 Always install additional dependencies for dns plugins 2020-11-03 21:59:18 +01:00
chaptergy
7d693a4271 Expands and refactors dns plugin list 2020-11-03 21:28:50 +01:00
Jamie Curnow
f192748bf9 Use x-real-ip header for the real-ip module 2020-10-19 11:40:50 +10:00
jc21
96f401cba6
Merge pull request #664 from chaptergy/fixes-expiring-hosts-renewal
Adds certbot plugin installation check on startup
2020-10-19 08:50:44 +10:00
jc21
ffd2430160
Merge pull request #666 from MarceloLagos/master
Check key for RSA header otherwise use EC, and output fix.
2020-10-19 08:45:28 +10:00
MarceloLagos
190cd2d6bb
Update certificate.js 2020-10-17 23:46:18 -06:00
MarceloLagos
7ba58bdbd3
Update certificate.js 2020-10-17 23:27:12 -06:00
chaptergy
08ab62108f Fixes eslint errors 2020-10-17 12:54:38 +02:00
chaptergy
1028de8158 Adds certbot plugin installation check on startup 2020-10-17 12:13:08 +02:00
jc21
301499dc52
Merge pull request #659 from jc21/develop
v2.6.1
2020-10-16 15:53:56 +10:00
jc21
5c2f13ed8e
Merge branch 'master' into develop 2020-10-16 13:44:10 +10:00
Jamie Curnow
e30ad81f69 Updated version 2020-10-16 13:43:13 +10:00
Jamie Curnow
21f36f535f Don't spit out a ; if the preceeding value is empty 2020-10-16 13:41:08 +10:00
jc21
c14236823a
Merge pull request #656 from chaptergy/fixes-custom-certificate-upload
Fixes custom certificate upload
2020-10-16 08:33:51 +10:00
chaptergy
551a9fe1c6 Fixes custom certificate upload 2020-10-15 14:58:05 +02:00
jc21
e3399e1035
Merge pull request #654 from jc21/develop
2.6.0 Release
2020-10-15 15:14:57 +10:00
Jamie Curnow
c413b4af3f Added contributors 2020-10-15 14:06:21 +10:00
Jamie Curnow
dbf5dec23b Bump version 2020-10-15 10:40:01 +10:00
Jamie Curnow
10f0eb17d7 Fix linting errors 2020-10-15 10:33:51 +10:00
jc21
e3b680c351
Merge pull request #653 from jmwebslave/dont-pass-auth-header
Pass/Don't Pass Auth Header
2020-10-15 10:10:33 +10:00
James Morgan
0df0545777 Allows auth information from AccessList not to be passed to proxied hosts. Resolves issue #153.
Signed-off-by: James Morgan <jmorgan.au+github@gmail.com>
2020-10-15 10:23:09 +11:00
jc21
165bfc9f5f
Merge pull request #607 from jc21/dependabot/npm_and_yarn/docs/node-forge-0.10.0
Bump node-forge from 0.9.1 to 0.10.0 in /docs
2020-10-15 08:34:14 +10:00
jc21
5830bd73b9
Merge pull request #608 from Philip-Mooney/master
Fix for access list getAll when not granted all permissions
2020-10-15 08:33:58 +10:00
jc21
3c4ce839b9
Merge pull request #635 from chaptergy/allow-more-dns-challenges
Allow DNS challenges not just for cloudflare
2020-10-14 19:12:15 +10:00
chaptergy
ac9f052309 Fixes linting errors 2020-10-14 09:55:45 +02:00
chaptergy
049e424957 Adds special case for Route53 2020-10-14 09:20:52 +02:00
chaptergy
07e78aec48 Adds error stack information in prod environment for certificates 2020-10-08 15:30:13 +02:00
chaptergy
3fec135fe5 Fixes ESlint formatting errors 2020-10-08 14:38:19 +02:00
chaptergy
867fe1322b Unifies directory structure in dev and prod containers 2020-10-08 13:38:20 +02:00
chaptergy
95208a50a7 Increases timeouts in front- and backend 2020-10-08 13:21:17 +02:00
chaptergy
514b13fcc2 Fixes build issues due to globally used file 2020-10-06 16:12:12 +02:00
chaptergy
4cbc1f5bbe Minor refactoring 2020-10-06 15:37:51 +02:00
chaptergy
64de36cdf2 Adds more DNS plugins 2020-10-06 15:16:45 +02:00
chaptergy
093b48ad7b Implements backend changes to allow more dns challenges 2020-10-06 14:52:06 +02:00
chaptergy
05f6a55a0b Adds frontend improvements and fixes 2020-10-06 14:49:02 +02:00
chaptergy
2523424f68 Updates dockerfiles 2020-10-05 01:04:18 +02:00
chaptergy
b81325d7bf Implements dns challenge provider selection in frontend 2020-10-05 01:04:06 +02:00
Philip Mooney
3e10b7b2b1 Fix for access list getAll when not granted all permissions 2020-09-19 22:16:16 +01:00
dependabot[bot]
e5cb750015
Bump node-forge from 0.9.1 to 0.10.0 in /docs
Bumps [node-forge](https://github.com/digitalbazaar/forge) from 0.9.1 to 0.10.0.
- [Release notes](https://github.com/digitalbazaar/forge/releases)
- [Changelog](https://github.com/digitalbazaar/forge/blob/master/CHANGELOG.md)
- [Commits](https://github.com/digitalbazaar/forge/compare/0.9.1...0.10.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-09-17 23:42:28 +00:00
jc21
28f72086ec
Merge pull request #592 from jc21/develop
v2.5.0
2020-09-04 09:07:47 +10:00
Jamie Curnow
a6b9bd7b01 Version bump and contributors 2020-09-03 14:11:44 +10:00
Jamie Curnow
2c5eac9dad Merge branch 'master' of github.com:jc21/nginx-proxy-manager into develop 2020-09-03 14:03:43 +10:00
jc21
87f61b8527
Merge pull request #572 from jipjan/features/dns-cloudflare
Add DNS CloudFlare with wildcard support
2020-09-03 14:01:05 +10:00
jc21
74bfe490c6
Merge pull request #587 from duhruh/bug/custom-ssl-inputs
Allow inputs to update
2020-09-03 13:53:17 +10:00
David Rivera
015167f34d
Allow inputs to update 2020-08-29 20:24:51 -07:00
jc21
4bafc7ff1a
Merge pull request #546 from jc21/dependabot/npm_and_yarn/docs/prismjs-1.21.0
Bump prismjs from 1.20.0 to 1.21.0 in /docs
2020-08-25 10:51:11 +10:00
jc21
bf8beb50b4
Merge pull request #559 from jlesage/remove-webroot-certbot-arg
Removed the hardcoded `--webroot` certbot argument to better support DNS challenge
2020-08-25 08:44:00 +10:00
jc21
e5034a34f5
Merge pull request #570 from jc21/dependabot/npm_and_yarn/backend/bcrypt-5.0.0
Bump bcrypt from 4.0.1 to 5.0.0 in /backend
2020-08-25 08:31:48 +10:00
Jaap-Jan de Wit
a561605653 show in ssl certificates list that CloudFlare is used 2020-08-24 09:09:52 +00:00
Jaap-Jan de Wit
e8596c1554 cloudflare DNS also possible while adding proxy, redirection and 404 2020-08-24 09:00:00 +00:00
Jaap-Jan de Wit
ab67481e99 fix eslint errors 2020-08-23 18:56:25 +00:00
Jaap-Jan de Wit
1b611e67c8 Merge commit 'c5aa2b9f771cbd4c78c239ed0791aeb8d9e4d2e4' into features/dns-cloudflare 2020-08-23 18:30:07 +00:00
Jaap-Jan de Wit
c5aa2b9f77 add cloudflare renew and make revoke working for both by deleting unnecessary config command 2020-08-23 18:29:16 +00:00
Jaap-Jan de Wit
cff6c4d1f5 - prevent wildcard generation when not using Cloudflare dns
- fix cloudflare token required logic
2020-08-23 16:48:14 +00:00
Jaap-Jan de Wit
077cf75ef2 wildcard support 2020-08-23 13:24:20 +00:00
Jaap-Jan de Wit
ff1770204c request via cloudflare dns working 2020-08-23 12:50:41 +00:00
Jaap-Jan de Wit
b9a95840e0 add cloudflare dns option to letsencrypt via manual certificate 2020-08-23 11:40:41 +00:00
Jaap-Jan de Wit
2d7576c57e add cloudflare dns also to dev docker file 2020-08-23 10:54:36 +00:00
Jaap-Jan
251aac716a Add CloudFlare DNS plugin to certbot 2020-08-21 09:49:43 +02:00
jc21
6694a42270
Merge pull request #560 from jlesage/remove-from-unixtime
Removed usage of `FROM_UNIXTIME` mysql-specific function.
2020-08-21 14:21:40 +10:00
dependabot[bot]
f78a4c6ad1
Bump bcrypt from 4.0.1 to 5.0.0 in /backend
Bumps [bcrypt](https://github.com/kelektiv/node.bcrypt.js) from 4.0.1 to 5.0.0.
- [Release notes](https://github.com/kelektiv/node.bcrypt.js/releases)
- [Changelog](https://github.com/kelektiv/node.bcrypt.js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/kelektiv/node.bcrypt.js/compare/v4.0.1...v5.0.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-08-20 17:01:00 +00:00
Jocelyn Le Sage
83fad8bcda Removed usage of FROM_UNIXTIME mysql-specific function.
This provide better interoperability with different databases (e.g. sqlite).
Fixes #557
2020-08-14 19:31:05 -04:00
Jocelyn Le Sage
f539e813aa Removed the hardcoded --webroot certbot argument to better support DNS challenge. Also, this option is already set in the default letsencrypt.ini. 2020-08-14 14:28:03 -04:00
Jamie Curnow
5d65166777 Ignore local subnets for real IP determination 2020-08-12 09:32:40 +10:00
dependabot[bot]
70346138a7
Bump prismjs from 1.20.0 to 1.21.0 in /docs
Bumps [prismjs](https://github.com/PrismJS/prism) from 1.20.0 to 1.21.0.
- [Release notes](https://github.com/PrismJS/prism/releases)
- [Changelog](https://github.com/PrismJS/prism/blob/master/CHANGELOG.md)
- [Commits](https://github.com/PrismJS/prism/compare/v1.20.0...v1.21.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-08-08 00:02:04 +00:00
jc21
d68656559c
Merge pull request #544 from jlesage/sqlite-now-helper-fix
Fixed now_helper for sqlite (time is missing)
2020-08-07 08:37:00 +10:00
Jocelyn Le Sage
01660b5b80 Fixed now_helper for sqlite: it should also returns the time. 2020-08-06 17:16:22 -04:00
jc21
74010acd85
Merge pull request #543 from jc21/develop
v2.4.0
2020-08-06 16:00:10 +10:00
Jamie Curnow
7c7d255172 Added another contributor 2020-08-06 14:46:19 +10:00
jc21
058f1e9835
Merge pull request #464 from vrenjith/patch-1
Update location-item.ejs - forward_host size increase to 200
2020-08-06 14:45:09 +10:00
Jamie Curnow
b4fc629ec0 Bumped version 2020-08-06 14:43:34 +10:00
Jamie Curnow
ae06b2da75 Updated deps and added contributor 2020-08-06 14:40:54 +10:00
Jamie Curnow
54d423a11f Updated doc for sqlite 2020-08-06 14:27:29 +10:00
Jamie Curnow
5da6c97a00 Pull cypress tests from correct location 2020-08-06 13:57:33 +10:00
Jamie Curnow
bf2f13443f Cypress fixes 2020-08-06 12:47:24 +10:00
Jamie Curnow
9ce4c3fe2f CI fix 2020-08-06 12:02:47 +10:00
Jamie Curnow
4a07bf666d Added users cypress tests 2020-08-06 11:57:31 +10:00
Jamie Curnow
5be46b4b20 Cypress fixes 2020-08-06 11:26:37 +10:00
Jamie Curnow
7fd825b76b Use development config file in CI 2020-08-06 10:59:25 +10:00
Jamie Curnow
b23d59dec7 Updated cypress to 4.12.1 2020-08-06 09:00:52 +10:00
Jamie Curnow
492d450d26 Sqlite Tweaks
- Added cypress testing in CI for sqlite
- Cleaned up promises in setup
- Ensure check for settings is strict
2020-08-06 08:58:20 +10:00
jc21
04412f3624
Merge pull request #510 from tg44/multidb-re
Multidb - sqlite support
2020-08-06 08:33:00 +10:00
Jamie Curnow
c41057b28a Revert builx push experiment 2020-07-31 09:28:45 +10:00
Jamie Curnow
8312bc0100 Use same tags for experiment 2020-07-30 14:00:59 +10:00
Jamie Curnow
85ac43bc5e Merge branch 'master' of github.com:jc21/nginx-proxy-manager into develop 2020-07-30 08:31:18 +10:00
Jamie Curnow
d1a0780c7a Attempt to circumvent docker login token timeouts 2020-07-30 08:30:26 +10:00
jc21
f9b8d76527
Merge pull request #513 from jc21/dependabot/npm_and_yarn/frontend/lodash-4.17.19
Bump lodash from 4.17.15 to 4.17.19 in /frontend
2020-07-20 12:39:10 +10:00
jc21
26f00eeae4
Merge branch 'master' into dependabot/npm_and_yarn/frontend/lodash-4.17.19 2020-07-20 10:59:15 +10:00
jc21
1bc2df2178
Merge pull request #514 from jc21/dependabot/npm_and_yarn/docs/lodash-4.17.19
Bump lodash from 4.17.15 to 4.17.19 in /docs
2020-07-20 10:58:36 +10:00
dependabot[bot]
8dfbcef198
Bump lodash from 4.17.15 to 4.17.19 in /docs
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.15 to 4.17.19.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.15...4.17.19)

Signed-off-by: dependabot[bot] <support@github.com>
2020-07-19 20:33:49 +00:00
Gergo Torcsvari
6690b7735d sqlite3 and psql support 2020-07-19 20:04:29 +02:00
Gergo Torcsvari
a9e7222e5e introduced now_helper for multidb capabilities 2020-07-19 20:03:53 +02:00
Gergo Torcsvari
f8edeb2775 fixed migration and setup
more info: https://github.com/knex/knex/issues/2820
2020-07-19 20:02:20 +02:00
dependabot[bot]
d1786fe159
Bump lodash from 4.17.15 to 4.17.19 in /frontend
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.15 to 4.17.19.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.15...4.17.19)

Signed-off-by: dependabot[bot] <support@github.com>
2020-07-19 15:20:28 +00:00
vrenjith
157a12fb7c
Update location-item.ejs 2020-06-19 01:56:16 +05:30
jc21
3f723b1638
Merge pull request #454 from jc21/develop
v2.3.1
2020-06-09 09:47:31 +10:00
Jamie Curnow
e2e9835d01 Version bump 2020-06-09 09:17:25 +10:00
jc21
7599617b67
Merge pull request #452 from jc21/dependabot/npm_and_yarn/docs/websocket-extensions-0.1.4
Bump websocket-extensions from 0.1.3 to 0.1.4 in /docs
2020-06-08 11:14:20 +10:00
dependabot[bot]
18a5b11033
Bump websocket-extensions from 0.1.3 to 0.1.4 in /docs
Bumps [websocket-extensions](https://github.com/faye/websocket-extensions-node) from 0.1.3 to 0.1.4.
- [Release notes](https://github.com/faye/websocket-extensions-node/releases)
- [Changelog](https://github.com/faye/websocket-extensions-node/blob/master/CHANGELOG.md)
- [Commits](https://github.com/faye/websocket-extensions-node/compare/0.1.3...0.1.4)

Signed-off-by: dependabot[bot] <support@github.com>
2020-06-07 23:36:47 +00:00
Jamie Curnow
fff31b0f34 Ensure we're using the latest node image 2020-06-03 10:30:29 +10:00
Jamie Curnow
c02e30663a Revert last 2020-06-02 20:21:27 +10:00
Jamie Curnow
4c6527cafc Ensure python2 is installed for frontend build 2020-06-02 20:09:27 +10:00
jc21
55bddb12e5
Merge pull request #435 from Subv/access_lists_ips
Don't use duplicate relations when eager-loading access list items and clients.
2020-06-02 19:42:27 +10:00
Subv
d95861e1fb Don't use duplicate relations when eager-loading access list items and clients.
This fixes an Objection warning: 'Duplicate relation "proxy_hosts" in a relation expression. You should use "a.[b, c]" instead of "[a.b, a.c]". This will cause an error in objection 2.0'.

It also fixes the access list clients not being properly eager-loaded when building the proxy host nginx configuration files. Closes #434
2020-05-29 20:29:34 -05:00
Jamie Curnow
94754a5cb3 Revert CI debug 2020-05-28 20:26:16 +10:00
jc21
546f862236
Merge pull request #429 from jc21/develop
v2.3.0
2020-05-28 17:06:19 +10:00
jc21
f105e29e56
Merge branch 'master' into develop 2020-05-28 15:38:38 +10:00
Jamie Curnow
5c15993d06 Contributors 7 wide 2020-05-28 13:31:41 +10:00
Jamie Curnow
a369ea1080 Bump version 2020-05-28 13:29:55 +10:00
Jamie Curnow
98068c0f57 Debug CI by leaving images alive 2020-05-28 13:26:36 +10:00
jc21
e0ef8683a2
Merge pull request #428 from jc21/openresty
Openresty base
2020-05-28 12:22:31 +10:00
Jamie Curnow
66412a75f9 Revert to node base now that base has openresty 2020-05-28 09:25:29 +10:00
jc21
84d8fb0899
Merge pull request #403 from Indemnity83/empty-auth
Don't ask for username/password if none are defined
2020-05-28 09:18:50 +10:00
Jamie Curnow
c631537dbe Don't wipe out nginx dir, keeps luajit 2020-05-27 10:38:00 +10:00
Jamie Curnow
8d2f49541c Use OpenResty base image 2020-05-26 14:38:41 +10:00
Jamie Curnow
55a28e3437 Merge branch 'develop' of github.com:jc21/nginx-proxy-manager into develop 2020-05-25 14:53:46 +10:00
Jamie Curnow
67ea2d01c8 Added gitter, contributors 2020-05-25 14:53:35 +10:00
jc21
dab229e37c
Merge pull request #406 from theraw/patch-1
set proper timeout.
2020-05-25 14:37:06 +10:00
jc21
7084473330
Merge pull request #416 from jc21/develop
v2.2.4
2020-05-21 16:52:16 +10:00
Jamie Curnow
dd2e335fae Cypress 4.6.0 and tweaks to scripts 2020-05-21 16:11:19 +10:00
Jamie Curnow
1ff87bbc12 Version bump 2020-05-21 15:09:51 +10:00
Jamie Curnow
2ebfdcf0c9 Fix LE certs for IPv6 only domains Fixes 394 2020-05-20 22:21:26 +10:00
Jamie Curnow
8ab161a3ee Merge branch 'develop' of github.com:jc21/nginx-proxy-manager into develop 2020-05-20 21:53:44 +10:00
Jamie Curnow
e74b9617be Added product support github template 2020-05-20 21:40:54 +10:00
jc21
c3d88c83e3
Merge pull request #402 from Indemnity83/patch-2
Fix address validation rule to allow 'all' keyword
2020-05-20 21:16:11 +10:00
Jamie Curnow
3e912a7474 Added FAQ to docs 2020-05-20 21:14:00 +10:00
jc21
0d726a1d83
Merge pull request #405 from Indemnity83/fix-satisfy
fix spelling of 'satisfy'
2020-05-20 20:44:38 +10:00
ƬHE ЯAW ☣
affabf065e
set proper timeout. 2020-05-11 00:24:02 +02:00
Kyle Klaus
e6ea77d263 fix spelling of 'satisfy'
Fixes #385
2020-05-09 18:01:43 -07:00
Kyle Klaus
df73c2a458 skip auth check if no users defined 2020-05-09 15:51:11 -07:00
Kyle Klaus
96c5c79aef
Fix address validation rule to allow 'all' keyword
The rule was looking for the keyword 'any' but should have been looking for 'all' 

http://nginx.org/en/docs/http/ngx_http_access_module.html
2020-05-09 09:31:58 -07:00
jc21
64922f07ff
Merge pull request #388 from jc21/dependabot/npm_and_yarn/frontend/jquery-3.5.0
Bump jquery from 3.4.1 to 3.5.0 in /frontend
2020-05-07 14:53:24 +10:00
jc21
bae21f3210
Merge pull request #397 from Indemnity83/patch-1
apply migration to correct table
2020-05-05 10:14:47 +10:00
Jamie Curnow
0702a4e58e Fix incorrect var 2020-05-05 10:00:41 +10:00
Kyle Klaus
31f1d304d6
apply migration to correct table 2020-05-04 16:56:26 -07:00
dependabot[bot]
291a74c295
Bump jquery from 3.4.1 to 3.5.0 in /frontend
Bumps [jquery](https://github.com/jquery/jquery) from 3.4.1 to 3.5.0.
- [Release notes](https://github.com/jquery/jquery/releases)
- [Commits](https://github.com/jquery/jquery/compare/3.4.1...3.5.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-04-30 14:43:28 +00:00
Jamie Curnow
c0e9d1eb2f Fix satisy typo 2020-04-22 11:11:20 +10:00
jc21
a7cabdde3a
Merge pull request #376 from spalger/expand-forward-host-size
expand the maximum size of the forward_host
2020-04-17 08:59:55 +10:00
spalger
3af560c2d0 switch to 255 limit to match db 2020-04-16 15:14:49 -07:00
spalger
1d23d5c761 remove maxlength from html too 2020-04-16 15:13:28 -07:00
spalger
995db12f22 remove arbitrary length limit of forward_host 2020-04-16 14:00:22 -07:00
jc21
4c60bfb66b
Merge pull request #370 from jc21/develop
v2.2.3
2020-04-15 15:06:56 +10:00
jc21
1716747047
Merge branch 'master' into develop 2020-04-15 14:19:07 +10:00
Jamie Curnow
090b4d0388 Version bump 2020-04-15 14:18:27 +10:00
jc21
a9f068daa8
Merge pull request #360 from Indemnity83/ip-access-control
Client Access Lists
2020-04-15 08:29:40 +10:00
Kyle Klaus
f5ee91aeb3 write access list to proxy host config 2020-04-13 23:32:00 -07:00
Kyle Klaus
e2ee2cbf2d enforce a 'deny all' default rule
this ensures that an access list is 'secure by default' and requires the user to create exceptions or holes in the proection instead of building the wall entirely. This also means that we no longer require the user to input any username/passwords or client addressses and can avoid internal errors which generate unhelpful user errors.
2020-04-13 23:31:54 -07:00
jc21
dcf8364899
Merge pull request #368 from jc21/develop
Support ipv6 address as a origin header, hopefully fixes #149
2020-04-14 14:40:00 +10:00
Jamie Curnow
b783602786 Support ipv6 address as a origin header, hopefully fixes #149 2020-04-14 13:01:13 +10:00
Kyle Klaus
005e64eb9f valite auth/access rules in backend 2020-04-13 19:23:55 -07:00
Kyle Klaus
e9e5d293cc expand address format
now accepts CIDR notation, IPv6 or the string 'any'
2020-04-13 19:16:18 -07:00
jc21
a57255350f
Merge pull request #365 from jc21/develop
Develop
2020-04-14 09:10:45 +10:00
jc21
781442bf1e
Merge pull request #361 from Xantios/fix-bad-gateway
Fixes #310 Clarification on the docs
2020-04-14 09:09:39 +10:00
jc21
604bd2c576
Merge pull request #358 from dpanesso/dev-formatting
Documentation formatting
2020-04-14 08:37:23 +10:00
Xantios Krugor
d9e1e1bbb7 Fixes #310 Clarification on the docs 2020-04-11 13:03:15 +02:00
Kyle Klaus
907e9e182d remove testing cruft 2020-04-11 00:42:58 -07:00
Kyle Klaus
0f238a5021 add satisfy configuration to the ui 2020-04-11 00:26:54 -07:00
Kyle Klaus
8d432bd60a refine the UI labeling 2020-04-10 20:22:01 -07:00
Kyle Klaus
fd932c7678 fix bugs preventing client rules from being updated 2020-04-10 17:42:44 -07:00
Kyle Klaus
46a9f5cb96 add basic functionality to front end 2020-04-10 17:33:14 -07:00
Kyle Klaus
f990d3f674 add access list clients to back-end 2020-04-10 16:38:54 -07:00
David Panesso
4a6de8deee Documentation formatting on advanced configuration page 2020-04-10 00:57:45 -05:00
jc21
9a7a216b23
Merge pull request #352 from jc21/develop
Develop
2020-04-07 12:09:17 +10:00
jc21
fccaaaae4d
Merge branch 'master' into develop 2020-04-07 12:09:09 +10:00
Jamie Curnow
a882b0be82 Merge branch 'develop' of github.com:jc21/nginx-proxy-manager into develop 2020-04-07 12:06:55 +10:00
Jamie Curnow
db7bbab768 Updated npm deps 2020-04-07 12:06:36 +10:00
jc21
030e553549
Merge pull request #351 from jc21/develop
v2.2.2 Release
2020-04-07 12:01:48 +10:00
jc21
8b0ca8e367
Merge branch 'master' into develop 2020-04-07 11:23:03 +10:00
Jamie Curnow
83b2b07200 Version bump 2020-04-07 10:45:45 +10:00
Jamie Curnow
bdb591af9e - Add ability to disable ipv6, fixes #312
- Added ipv6 listening to hosts when configured, fixes #236 and #149
- Added documentation about disabling ipv6
- Updated npm packages
2020-04-07 10:43:19 +10:00
197 changed files with 13449 additions and 6922 deletions

View File

@ -6,15 +6,30 @@ labels: bug
assignees: '' assignees: ''
--- ---
<!--
Are you in the right place?
- If you are looking for support on how to get your upstream server forwarding, please consider asking the community on Reddit.
- If you are writing code changes to contribute and need to ask about the internals of the software, Gitter is the best place to ask.
- If you think you found a bug with NPM (not Nginx, or your upstream server or MySql) then you are in the *right place.*
-->
**Checklist** **Checklist**
- Have you pulled and found the error with `jc21/nginx-proxy-manager:latest` docker image? - Have you pulled and found the error with `jc21/nginx-proxy-manager:latest` docker image?
- Yes / No
- Are you sure you're not using someone else's docker image? - Are you sure you're not using someone else's docker image?
- If having problems with Lets Encrypt, have you made absolutely sure your site is accessible from outside of your network? - Yes / No
- Have you searched for similar issues (both open and closed)?
- Yes / No
**Describe the bug** **Describe the bug**
- A clear and concise description of what the bug is. <!-- A clear and concise description of what the bug is. -->
- What version of Nginx Proxy Manager is reported on the login page?
**Nginx Proxy Manager Version**
<!-- What version of Nginx Proxy Manager is reported on the login page? -->
**To Reproduce** **To Reproduce**
Steps to reproduce the behavior: Steps to reproduce the behavior:
@ -23,14 +38,18 @@ Steps to reproduce the behavior:
3. Scroll down to '....' 3. Scroll down to '....'
4. See error 4. See error
**Expected behavior** **Expected behavior**
A clear and concise description of what you expected to happen. <!-- A clear and concise description of what you expected to happen. -->
**Screenshots** **Screenshots**
If applicable, add screenshots to help explain your problem. <!-- If applicable, add screenshots to help explain your problem. -->
**Operating System** **Operating System**
- Please specify if using a Rpi, Mac, orchestration tool or any other setups that might affect the reproduction of this error. <!-- Please specify if using a Rpi, Mac, orchestration tool or any other setups that might affect the reproduction of this error. -->
**Additional context** **Additional context**
Add any other context about the problem here, docker version, browser version if applicable to the problem. Too much info is better than too little. <!-- Add any other context about the problem here, docker version, browser version, logs if applicable to the problem. Too much info is better than too little. -->

View File

@ -0,0 +1,18 @@
---
name: DNS challenge provider request
about: Suggest a new provider to be available for a certificate DNS challenge
title: ''
labels: dns provider request
assignees: ''
---
**What provider would you like to see added to NPM?**
<!-- What is this provider called? -->
**Have you checked if a certbot plugin exists?**
<!--
Currently NPM only supports DNS challenge providers for which a certbot plugin exists.
You can visit pypi.org, and search for a package with the name `certbot-dns-<privider>`.
-->

View File

@ -7,14 +7,26 @@ assignees: ''
--- ---
<!--
Are you in the right place?
- If you are looking for support on how to get your upstream server forwarding, please consider asking the community on Reddit.
- If you are writing code changes to contribute and need to ask about the internals of the software, Gitter is the best place to ask.
- If you think you found a bug with NPM (not Nginx, or your upstream server or MySql) then you are in the *right place.*
-->
**Is your feature request related to a problem? Please describe.** **Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] <!-- A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] -->
**Describe the solution you'd like** **Describe the solution you'd like**
A clear and concise description of what you want to happen. <!-- A clear and concise description of what you want to happen. -->
**Describe alternatives you've considered** **Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered. <!-- A clear and concise description of any alternative solutions or features you've considered. -->
**Additional context** **Additional context**
Add any other context or screenshots about the feature request here. <!-- Add any other context or screenshots about the feature request here. -->

2
.gitignore vendored
View File

@ -2,4 +2,4 @@
.idea .idea
._* ._*
.vscode .vscode
certbot-help.txt

View File

@ -1,10 +0,0 @@
{
"database": {
"engine": "mysql",
"host": "db",
"name": "npm",
"user": "npm",
"password": "npm",
"port": 3306
}
}

View File

@ -1 +1 @@
2.2.1 2.9.19

64
Jenkinsfile vendored
View File

@ -5,6 +5,7 @@ pipeline {
options { options {
buildDiscarder(logRotator(numToKeepStr: '5')) buildDiscarder(logRotator(numToKeepStr: '5'))
disableConcurrentBuilds() disableConcurrentBuilds()
ansiColor('xterm')
} }
environment { environment {
IMAGE = "nginx-proxy-manager" IMAGE = "nginx-proxy-manager"
@ -55,20 +56,19 @@ pipeline {
} }
stage('Frontend') { stage('Frontend') {
steps { steps {
ansiColor('xterm') {
sh './scripts/frontend-build' sh './scripts/frontend-build'
} }
} }
}
stage('Backend') { stage('Backend') {
steps { steps {
ansiColor('xterm') {
echo 'Checking Syntax ...' echo 'Checking Syntax ...'
sh 'docker pull nginxproxymanager/nginx-full:certbot-node'
// See: https://github.com/yarnpkg/yarn/issues/3254 // See: https://github.com/yarnpkg/yarn/issues/3254
sh '''docker run --rm \\ sh '''docker run --rm \\
-v "$(pwd)/backend:/app" \\ -v "$(pwd)/backend:/app" \\
-v "$(pwd)/global:/app/global" \\
-w /app \\ -w /app \\
node:latest \\ nginxproxymanager/nginx-full:certbot-node \\
sh -c "yarn install && yarn eslint . && rm -rf node_modules" sh -c "yarn install && yarn eslint . && rm -rf node_modules"
''' '''
@ -85,26 +85,49 @@ pipeline {
''' '''
} }
} }
} stage('Integration Tests Sqlite') {
stage('Test') {
steps { steps {
ansiColor('xterm') {
// Bring up a stack // Bring up a stack
sh 'docker-compose up -d fullstack' sh 'docker-compose up -d fullstack-sqlite'
sh './scripts/wait-healthy $(docker-compose ps -q fullstack) 120' sh './scripts/wait-healthy $(docker-compose ps -q fullstack-sqlite) 120'
// Run tests // Run tests
sh 'rm -rf test/results' sh 'rm -rf test/results'
sh 'docker-compose up cypress' sh 'docker-compose up cypress-sqlite'
// Get results // Get results
sh 'docker cp -L "$(docker-compose ps -q cypress):/results" test/' sh 'docker cp -L "$(docker-compose ps -q cypress-sqlite):/test/results" test/'
}
} }
post { post {
always { always {
// Dumps to analyze later // Dumps to analyze later
sh 'mkdir -p debug' sh 'mkdir -p debug'
sh 'docker-compose logs fullstack | gzip > debug/docker_fullstack.log.gz' sh 'docker-compose logs fullstack-sqlite | gzip > debug/docker_fullstack_sqlite.log.gz'
sh 'docker-compose logs db | gzip > debug/docker_db.log.gz'
// Cypress videos and screenshot artifacts
dir(path: 'test/results') {
archiveArtifacts allowEmptyArchive: true, artifacts: '**/*', excludes: '**/*.xml'
}
junit 'test/results/junit/*'
}
}
}
stage('Integration Tests Mysql') {
steps {
// Bring up a stack
sh 'docker-compose up -d fullstack-mysql'
sh './scripts/wait-healthy $(docker-compose ps -q fullstack-mysql) 120'
// Run tests
sh 'rm -rf test/results'
sh 'docker-compose up cypress-mysql'
// Get results
sh 'docker cp -L "$(docker-compose ps -q cypress-mysql):/test/results" test/'
}
post {
always {
// Dumps to analyze later
sh 'mkdir -p debug'
sh 'docker-compose logs fullstack-mysql | gzip > debug/docker_fullstack_mysql.log.gz'
sh 'docker-compose logs db | gzip > debug/docker_db.log.gz' sh 'docker-compose logs db | gzip > debug/docker_db.log.gz'
// Cypress videos and screenshot artifacts // Cypress videos and screenshot artifacts
dir(path: 'test/results') { dir(path: 'test/results') {
@ -121,7 +144,6 @@ pipeline {
} }
} }
steps { steps {
ansiColor('xterm') {
dir(path: 'docs') { dir(path: 'docs') {
sh 'yarn install' sh 'yarn install'
sh 'yarn build' sh 'yarn build'
@ -134,7 +156,6 @@ pipeline {
archiveArtifacts(artifacts: 'docs/docs.tgz', allowEmptyArchive: false) archiveArtifacts(artifacts: 'docs/docs.tgz', allowEmptyArchive: false)
} }
} }
}
stage('MultiArch Build') { stage('MultiArch Build') {
when { when {
not { not {
@ -142,15 +163,14 @@ pipeline {
} }
} }
steps { steps {
ansiColor('xterm') {
withCredentials([usernamePassword(credentialsId: 'jc21-dockerhub', passwordVariable: 'dpass', usernameVariable: 'duser')]) { withCredentials([usernamePassword(credentialsId: 'jc21-dockerhub', passwordVariable: 'dpass', usernameVariable: 'duser')]) {
// Docker Login
sh "docker login -u '${duser}' -p '${dpass}'" sh "docker login -u '${duser}' -p '${dpass}'"
// Buildx with push // Buildx with push from cache
sh "./scripts/buildx --push ${BUILDX_PUSH_TAGS}" sh "./scripts/buildx --push ${BUILDX_PUSH_TAGS}"
} }
} }
} }
}
stage('Docs Deploy') { stage('Docs Deploy') {
when { when {
allOf { allOf {
@ -193,19 +213,17 @@ pipeline {
} }
} }
steps { steps {
ansiColor('xterm') {
script { script {
def comment = pullRequest.comment("Docker Image for build ${BUILD_NUMBER} is available on [DockerHub](https://cloud.docker.com/repository/docker/jc21/${IMAGE}) as `jc21/${IMAGE}:github-${BRANCH_LOWER}`") def comment = pullRequest.comment("This is an automated message from CI:\n\nDocker Image for build ${BUILD_NUMBER} is available on [DockerHub](https://cloud.docker.com/repository/docker/jc21/${IMAGE}) as `jc21/${IMAGE}:github-${BRANCH_LOWER}`\n\n**Note:** ensure you backup your NPM instance before testing this PR image! Especially if this PR contains database changes.")
}
} }
} }
} }
} }
post { post {
always { always {
sh 'docker-compose down --rmi all --remove-orphans --volumes -t 30' sh 'docker-compose down --remove-orphans --volumes -t 30'
sh 'echo Reverting ownership' sh 'echo Reverting ownership'
sh 'docker run --rm -v $(pwd):/data ${DOCKER_CI_TOOLS} chown -R $(id -u):$(id -g) /data' sh 'docker run --rm -v $(pwd):/data jc21/ci-tools chown -R $(id -u):$(id -g) /data'
} }
success { success {
juxtapose event: 'success' juxtapose event: 'success'

View File

@ -1,22 +1,19 @@
<p align="center"> <p align="center">
<img src="https://nginxproxymanager.com/github.png"> <img src="https://nginxproxymanager.com/github.png">
<br><br> <br><br>
<img src="https://img.shields.io/badge/version-2.2.1-green.svg?style=for-the-badge"> <img src="https://img.shields.io/badge/version-2.9.19-green.svg?style=for-the-badge">
<a href="https://hub.docker.com/repository/docker/jc21/nginx-proxy-manager"> <a href="https://hub.docker.com/repository/docker/jc21/nginx-proxy-manager">
<img src="https://img.shields.io/docker/stars/jc21/nginx-proxy-manager.svg?style=for-the-badge"> <img src="https://img.shields.io/docker/stars/jc21/nginx-proxy-manager.svg?style=for-the-badge">
</a> </a>
<a href="https://hub.docker.com/repository/docker/jc21/nginx-proxy-manager"> <a href="https://hub.docker.com/repository/docker/jc21/nginx-proxy-manager">
<img src="https://img.shields.io/docker/pulls/jc21/nginx-proxy-manager.svg?style=for-the-badge"> <img src="https://img.shields.io/docker/pulls/jc21/nginx-proxy-manager.svg?style=for-the-badge">
</a> </a>
<a href="https://ci.nginxproxymanager.com/blue/organizations/jenkins/nginx-proxy-manager/branches/">
<img src="https://img.shields.io/jenkins/build?jobUrl=https%3A%2F%2Fci.nginxproxymanager.com%2Fjob%2Fnginx-proxy-manager%2Fjob%2Fmaster&style=for-the-badge">
</a>
</p> </p>
This project comes as a pre-built docker image that enables you to easily forward to your websites This project comes as a pre-built docker image that enables you to easily forward to your websites
running at home or otherwise, including free SSL, without having to know too much about Nginx or Letsencrypt. running at home or otherwise, including free SSL, without having to know too much about Nginx or Letsencrypt.
- [Quick Setup](https://nginxproxymanager.com#quick-setup) - [Quick Setup](#quick-setup)
- [Full Setup](https://nginxproxymanager.com/setup/) - [Full Setup](https://nginxproxymanager.com/setup/)
- [Screenshots](https://nginxproxymanager.com/screenshots/) - [Screenshots](https://nginxproxymanager.com/screenshots/)
@ -48,3 +45,65 @@ I won't go in to too much detail here but here are the basics for someone new to
2. Add port forwarding for port 80 and 443 to the server hosting this project 2. Add port forwarding for port 80 and 443 to the server hosting this project
3. Configure your domain name details to point to your home, either with a static ip or a service like DuckDNS or [Amazon Route53](https://github.com/jc21/route53-ddns) 3. Configure your domain name details to point to your home, either with a static ip or a service like DuckDNS or [Amazon Route53](https://github.com/jc21/route53-ddns)
4. Use the Nginx Proxy Manager as your gateway to forward to your other web based services 4. Use the Nginx Proxy Manager as your gateway to forward to your other web based services
## Quick Setup
1. Install Docker and Docker-Compose
- [Docker Install documentation](https://docs.docker.com/install/)
- [Docker-Compose Install documentation](https://docs.docker.com/compose/install/)
2. Create a docker-compose.yml file similar to this:
```yml
version: '3'
services:
app:
image: 'jc21/nginx-proxy-manager:latest'
restart: unless-stopped
ports:
- '80:80'
- '81:81'
- '443:443'
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
```
3. Bring up your stack by running
```bash
docker-compose up -d
# If using docker-compose-plugin
docker compose up -d
```
4. Log in to the Admin UI
When your docker container is running, connect to it on port `81` for the admin interface.
Sometimes this can take a little bit because of the entropy of keys.
[http://127.0.0.1:81](http://127.0.0.1:81)
Default Admin User:
```
Email: admin@example.com
Password: changeme
```
Immediately after logging in with this default user you will be asked to modify your details and change your password.
## Contributors
Special thanks to [all of our contributors](https://github.com/NginxProxyManager/nginx-proxy-manager/graphs/contributors).
## Getting Support
1. [Found a bug?](https://github.com/NginxProxyManager/nginx-proxy-manager/issues)
2. [Discussions](https://github.com/NginxProxyManager/nginx-proxy-manager/discussions)
3. [Development Gitter](https://gitter.im/nginx-proxy-manager/community)
4. [Reddit](https://reddit.com/r/nginxproxymanager)

2
backend/.gitignore vendored
View File

@ -4,3 +4,5 @@ yarn-error.log
tmp tmp
certbot.log certbot.log
node_modules node_modules
core.*

View File

@ -40,7 +40,6 @@ app.use(function (req, res, next) {
} }
res.set({ res.set({
'Strict-Transport-Security': 'includeSubDomains; max-age=631138519; preload',
'X-XSS-Protection': '1; mode=block', 'X-XSS-Protection': '1; mode=block',
'X-Content-Type-Options': 'nosniff', 'X-Content-Type-Options': 'nosniff',
'X-Frame-Options': x_frame_options, 'X-Frame-Options': x_frame_options,
@ -66,7 +65,7 @@ app.use(function (err, req, res, next) {
} }
}; };
if (process.env.NODE_ENV === 'development') { if (process.env.NODE_ENV === 'development' || (req.baseUrl + req.path).includes('nginx/certificates')) {
payload.debug = { payload.debug = {
stack: typeof err.stack !== 'undefined' && err.stack ? err.stack.split('\n') : null, stack: typeof err.stack !== 'undefined' && err.stack ? err.stack.split('\n') : null,
previous: err.previous previous: err.previous
@ -75,7 +74,7 @@ app.use(function (err, req, res, next) {
// Not every error is worth logging - but this is good for now until it gets annoying. // Not every error is worth logging - but this is good for now until it gets annoying.
if (typeof err.stack !== 'undefined' && err.stack) { if (typeof err.stack !== 'undefined' && err.stack) {
if (process.env.NODE_ENV === 'development') { if (process.env.NODE_ENV === 'development' || process.env.DEBUG) {
log.debug(err.stack); log.debug(err.stack);
} else if (typeof err.public == 'undefined' || !err.public) { } else if (typeof err.public == 'undefined' || !err.public) {
log.warn(err.message); log.warn(err.message);

View File

@ -0,0 +1,26 @@
{
"database": {
"engine": "knex-native",
"knex": {
"client": "sqlite3",
"connection": {
"filename": "/app/config/mydb.sqlite"
},
"pool": {
"min": 0,
"max": 1,
"createTimeoutMillis": 3000,
"acquireTimeoutMillis": 30000,
"idleTimeoutMillis": 30000,
"reapIntervalMillis": 1000,
"createRetryIntervalMillis": 100,
"propagateCreateError": false
},
"migrations": {
"tableName": "migrations",
"stub": "src/backend/lib/migrate_template.js",
"directory": "src/backend/migrations"
}
}
}
}

View File

@ -4,7 +4,11 @@ if (!config.has('database')) {
throw new Error('Database config does not exist! Please read the instructions: https://github.com/jc21/nginx-proxy-manager/blob/master/doc/INSTALL.md'); throw new Error('Database config does not exist! Please read the instructions: https://github.com/jc21/nginx-proxy-manager/blob/master/doc/INSTALL.md');
} }
let data = { function generateDbConfig() {
if (config.database.engine === 'knex-native') {
return config.database.knex;
} else
return {
client: config.database.engine, client: config.database.engine,
connection: { connection: {
host: config.database.host, host: config.database.host,
@ -16,7 +20,11 @@ let data = {
migrations: { migrations: {
tableName: 'migrations' tableName: 'migrations'
} }
}; };
}
let data = generateDbConfig();
if (typeof config.database.version !== 'undefined') { if (typeof config.database.version !== 'undefined') {
data.version = config.database.version; data.version = config.database.version;

View File

@ -2,7 +2,10 @@
const logger = require('./logger').global; const logger = require('./logger').global;
function appStart () { async function appStart () {
// Create config file db settings if environment variables have been set
await createDbConfigFromEnvironment();
const migrate = require('./migrate'); const migrate = require('./migrate');
const setup = require('./setup'); const setup = require('./setup');
const app = require('./app'); const app = require('./app');
@ -39,9 +42,94 @@ function appStart () {
}); });
} }
async function createDbConfigFromEnvironment() {
return new Promise((resolve, reject) => {
const envMysqlHost = process.env.DB_MYSQL_HOST || null;
const envMysqlPort = process.env.DB_MYSQL_PORT || null;
const envMysqlUser = process.env.DB_MYSQL_USER || null;
const envMysqlName = process.env.DB_MYSQL_NAME || null;
let envSqliteFile = process.env.DB_SQLITE_FILE || null;
const fs = require('fs');
const filename = (process.env.NODE_CONFIG_DIR || './config') + '/' + (process.env.NODE_ENV || 'default') + '.json';
let configData = {};
try {
configData = require(filename);
} catch (err) {
// do nothing
}
if (configData.database && configData.database.engine && !configData.database.fromEnv) {
logger.info('Manual db configuration already exists, skipping config creation from environment variables');
resolve();
return;
}
if ((!envMysqlHost || !envMysqlPort || !envMysqlUser || !envMysqlName) && !envSqliteFile){
envSqliteFile = '/data/database.sqlite';
logger.info(`No valid environment variables for database provided, using default SQLite file '${envSqliteFile}'`);
}
if (envMysqlHost && envMysqlPort && envMysqlUser && envMysqlName) {
const newConfig = {
fromEnv: true,
engine: 'mysql',
host: envMysqlHost,
port: envMysqlPort,
user: envMysqlUser,
password: process.env.DB_MYSQL_PASSWORD,
name: envMysqlName,
};
if (JSON.stringify(configData.database) === JSON.stringify(newConfig)) {
// Config is unchanged, skip overwrite
resolve();
return;
}
logger.info('Generating MySQL knex configuration from environment variables');
configData.database = newConfig;
} else {
const newConfig = {
fromEnv: true,
engine: 'knex-native',
knex: {
client: 'sqlite3',
connection: {
filename: envSqliteFile
},
useNullAsDefault: true
}
};
if (JSON.stringify(configData.database) === JSON.stringify(newConfig)) {
// Config is unchanged, skip overwrite
resolve();
return;
}
logger.info('Generating SQLite knex configuration');
configData.database = newConfig;
}
// Write config
fs.writeFile(filename, JSON.stringify(configData, null, 2), (err) => {
if (err) {
logger.error('Could not write db config to config file: ' + filename);
reject(err);
} else {
logger.debug('Wrote db configuration to config file: ' + filename);
resolve();
}
});
});
}
try { try {
appStart(); appStart();
} catch (err) { } catch (err) {
logger.error(err.message, err); logger.error(err.message, err);
process.exit(1); process.exit(1);
} }

View File

@ -5,6 +5,7 @@ const logger = require('../logger').access;
const error = require('../lib/error'); const error = require('../lib/error');
const accessListModel = require('../models/access_list'); const accessListModel = require('../models/access_list');
const accessListAuthModel = require('../models/access_list_auth'); const accessListAuthModel = require('../models/access_list_auth');
const accessListClientModel = require('../models/access_list_client');
const proxyHostModel = require('../models/proxy_host'); const proxyHostModel = require('../models/proxy_host');
const internalAuditLog = require('./audit-log'); const internalAuditLog = require('./audit-log');
const internalNginx = require('./nginx'); const internalNginx = require('./nginx');
@ -29,14 +30,17 @@ const internalAccessList = {
.omit(omissions()) .omit(omissions())
.insertAndFetch({ .insertAndFetch({
name: data.name, name: data.name,
satisfy_any: data.satisfy_any,
pass_auth: data.pass_auth,
owner_user_id: access.token.getUserId(1) owner_user_id: access.token.getUserId(1)
}); });
}) })
.then((row) => { .then((row) => {
data.id = row.id; data.id = row.id;
// Now add the items
let promises = []; let promises = [];
// Now add the items
data.items.map((item) => { data.items.map((item) => {
promises.push(accessListAuthModel promises.push(accessListAuthModel
.query() .query()
@ -48,13 +52,27 @@ const internalAccessList = {
); );
}); });
// Now add the clients
if (typeof data.clients !== 'undefined' && data.clients) {
data.clients.map((client) => {
promises.push(accessListClientModel
.query()
.insert({
access_list_id: row.id,
address: client.address,
directive: client.directive
})
);
});
}
return Promise.all(promises); return Promise.all(promises);
}) })
.then(() => { .then(() => {
// re-fetch with expansions // re-fetch with expansions
return internalAccessList.get(access, { return internalAccessList.get(access, {
id: data.id, id: data.id,
expand: ['owner', 'items'] expand: ['owner', 'items', 'clients', 'proxy_hosts.access_list.[clients,items]']
}, true /* <- skip masking */); }, true /* <- skip masking */);
}) })
.then((row) => { .then((row) => {
@ -64,7 +82,7 @@ const internalAccessList = {
return internalAccessList.build(row) return internalAccessList.build(row)
.then(() => { .then(() => {
if (row.proxy_host_count) { if (row.proxy_host_count) {
return internalNginx.reload(); return internalNginx.bulkGenerateConfigs('proxy_host', row.proxy_hosts);
} }
}) })
.then(() => { .then(() => {
@ -100,7 +118,6 @@ const internalAccessList = {
// Sanity check that something crazy hasn't happened // Sanity check that something crazy hasn't happened
throw new error.InternalValidationError('Access List could not be updated, IDs do not match: ' + row.id + ' !== ' + data.id); throw new error.InternalValidationError('Access List could not be updated, IDs do not match: ' + row.id + ' !== ' + data.id);
} }
}) })
.then(() => { .then(() => {
// patch name if specified // patch name if specified
@ -109,7 +126,9 @@ const internalAccessList = {
.query() .query()
.where({id: data.id}) .where({id: data.id})
.patch({ .patch({
name: data.name name: data.name,
satisfy_any: data.satisfy_any,
pass_auth: data.pass_auth,
}); });
} }
}) })
@ -153,6 +172,39 @@ const internalAccessList = {
}); });
} }
}) })
.then(() => {
// Check for clients and add/update/remove them
if (typeof data.clients !== 'undefined' && data.clients) {
let promises = [];
data.clients.map(function (client) {
if (client.address) {
promises.push(accessListClientModel
.query()
.insert({
access_list_id: data.id,
address: client.address,
directive: client.directive
})
);
}
});
let query = accessListClientModel
.query()
.delete()
.where('access_list_id', data.id);
return query
.then(() => {
// Add new items
if (promises.length) {
return Promise.all(promises);
}
});
}
})
.then(internalNginx.reload)
.then(() => { .then(() => {
// Add to audit log // Add to audit log
return internalAuditLog.add(access, { return internalAuditLog.add(access, {
@ -166,14 +218,14 @@ const internalAccessList = {
// re-fetch with expansions // re-fetch with expansions
return internalAccessList.get(access, { return internalAccessList.get(access, {
id: data.id, id: data.id,
expand: ['owner', 'items'] expand: ['owner', 'items', 'clients', 'proxy_hosts.access_list.[clients,items]']
}, true /* <- skip masking */); }, true /* <- skip masking */);
}) })
.then((row) => { .then((row) => {
return internalAccessList.build(row) return internalAccessList.build(row)
.then(() => { .then(() => {
if (row.proxy_host_count) { if (row.proxy_host_count) {
return internalNginx.reload(); return internalNginx.bulkGenerateConfigs('proxy_host', row.proxy_hosts);
} }
}) })
.then(() => { .then(() => {
@ -204,7 +256,7 @@ const internalAccessList = {
.joinRaw('LEFT JOIN `proxy_host` ON `proxy_host`.`access_list_id` = `access_list`.`id` AND `proxy_host`.`is_deleted` = 0') .joinRaw('LEFT JOIN `proxy_host` ON `proxy_host`.`access_list_id` = `access_list`.`id` AND `proxy_host`.`is_deleted` = 0')
.where('access_list.is_deleted', 0) .where('access_list.is_deleted', 0)
.andWhere('access_list.id', data.id) .andWhere('access_list.id', data.id)
.allowEager('[owner,items,proxy_hosts]') .allowEager('[owner,items,clients,proxy_hosts.[*, access_list.[clients,items]]]')
.omit(['access_list.is_deleted']) .omit(['access_list.is_deleted'])
.first(); .first();
@ -246,7 +298,7 @@ const internalAccessList = {
delete: (access, data) => { delete: (access, data) => {
return access.can('access_lists:delete', data.id) return access.can('access_lists:delete', data.id)
.then(() => { .then(() => {
return internalAccessList.get(access, {id: data.id, expand: ['proxy_hosts', 'items']}); return internalAccessList.get(access, {id: data.id, expand: ['proxy_hosts', 'items', 'clients']});
}) })
.then((row) => { .then((row) => {
if (!row) { if (!row) {
@ -330,11 +382,11 @@ const internalAccessList = {
.where('access_list.is_deleted', 0) .where('access_list.is_deleted', 0)
.groupBy('access_list.id') .groupBy('access_list.id')
.omit(['access_list.is_deleted']) .omit(['access_list.is_deleted'])
.allowEager('[owner,items]') .allowEager('[owner,items,clients]')
.orderBy('access_list.name', 'ASC'); .orderBy('access_list.name', 'ASC');
if (access_data.permission_visibility !== 'all') { if (access_data.permission_visibility !== 'all') {
query.andWhere('owner_user_id', access.token.getUserId(1)); query.andWhere('access_list.owner_user_id', access.token.getUserId(1));
} }
// Query is used for searching // Query is used for searching

View File

@ -1,18 +1,22 @@
const fs = require('fs');
const _ = require('lodash'); const _ = require('lodash');
const fs = require('fs');
const https = require('https');
const tempWrite = require('temp-write');
const moment = require('moment');
const logger = require('../logger').ssl; const logger = require('../logger').ssl;
const error = require('../lib/error'); const error = require('../lib/error');
const certificateModel = require('../models/certificate');
const internalAuditLog = require('./audit-log');
const tempWrite = require('temp-write');
const utils = require('../lib/utils'); const utils = require('../lib/utils');
const moment = require('moment'); const certificateModel = require('../models/certificate');
const debug_mode = process.env.NODE_ENV !== 'production' || !!process.env.DEBUG; const dnsPlugins = require('../global/certbot-dns-plugins');
const le_staging = process.env.NODE_ENV !== 'production'; const internalAuditLog = require('./audit-log');
const internalNginx = require('./nginx'); const internalNginx = require('./nginx');
const internalHost = require('./host'); const internalHost = require('./host');
const certbot_command = '/usr/bin/certbot'; const letsencryptStaging = process.env.NODE_ENV !== 'production';
const le_config = '/etc/letsencrypt.ini'; const letsencryptConfig = '/etc/letsencrypt.ini';
const certbotCommand = 'certbot';
const archiver = require('archiver');
const path = require('path');
const { isArray } = require('lodash');
function omissions() { function omissions() {
return ['is_deleted']; return ['is_deleted'];
@ -20,14 +24,14 @@ function omissions() {
const internalCertificate = { const internalCertificate = {
allowed_ssl_files: ['certificate', 'certificate_key', 'intermediate_certificate'], allowedSslFiles: ['certificate', 'certificate_key', 'intermediate_certificate'],
interval_timeout: 1000 * 60 * 60, // 1 hour intervalTimeout: 1000 * 60 * 60, // 1 hour
interval: null, interval: null,
interval_processing: false, intervalProcessing: false,
initTimer: () => { initTimer: () => {
logger.info('Let\'s Encrypt Renewal Timer initialized'); logger.info('Let\'s Encrypt Renewal Timer initialized');
internalCertificate.interval = setInterval(internalCertificate.processExpiringHosts, internalCertificate.interval_timeout); internalCertificate.interval = setInterval(internalCertificate.processExpiringHosts, internalCertificate.intervalTimeout);
// And do this now as well // And do this now as well
internalCertificate.processExpiringHosts(); internalCertificate.processExpiringHosts();
}, },
@ -36,15 +40,15 @@ const internalCertificate = {
* Triggered by a timer, this will check for expiring hosts and renew their ssl certs if required * Triggered by a timer, this will check for expiring hosts and renew their ssl certs if required
*/ */
processExpiringHosts: () => { processExpiringHosts: () => {
if (!internalCertificate.interval_processing) { if (!internalCertificate.intervalProcessing) {
internalCertificate.interval_processing = true; internalCertificate.intervalProcessing = true;
logger.info('Renewing SSL certs close to expiry...'); logger.info('Renewing SSL certs close to expiry...');
let cmd = certbot_command + ' renew --non-interactive --quiet ' + const cmd = certbotCommand + ' renew --non-interactive --quiet ' +
'--config "' + le_config + '" ' + '--config "' + letsencryptConfig + '" ' +
'--preferred-challenges "dns,http" ' + '--preferred-challenges "dns,http" ' +
'--disable-hook-validation ' + '--disable-hook-validation ' +
(le_staging ? '--staging' : ''); (letsencryptStaging ? '--staging' : '');
return utils.exec(cmd) return utils.exec(cmd)
.then((result) => { .then((result) => {
@ -77,7 +81,7 @@ const internalCertificate = {
.where('id', certificate.id) .where('id', certificate.id)
.andWhere('provider', 'letsencrypt') .andWhere('provider', 'letsencrypt')
.patch({ .patch({
expires_on: certificateModel.raw('FROM_UNIXTIME(' + cert_info.dates.to + ')') expires_on: moment(cert_info.dates.to, 'X').format('YYYY-MM-DD HH:mm:ss')
}); });
}) })
.catch((err) => { .catch((err) => {
@ -92,11 +96,11 @@ const internalCertificate = {
}); });
}) })
.then(() => { .then(() => {
internalCertificate.interval_processing = false; internalCertificate.intervalProcessing = false;
}) })
.catch((err) => { .catch((err) => {
logger.error(err); logger.error(err);
internalCertificate.interval_processing = false; internalCertificate.intervalProcessing = false;
}); });
} }
}, },
@ -112,7 +116,7 @@ const internalCertificate = {
data.owner_user_id = access.token.getUserId(1); data.owner_user_id = access.token.getUserId(1);
if (data.provider === 'letsencrypt') { if (data.provider === 'letsencrypt') {
data.nice_name = data.domain_names.sort().join(', '); data.nice_name = data.domain_names.join(', ');
} }
return certificateModel return certificateModel
@ -141,9 +145,33 @@ const internalCertificate = {
}); });
}) })
.then((in_use_result) => { .then((in_use_result) => {
// With DNS challenge no config is needed, so skip 3 and 5.
if (certificate.meta.dns_challenge) {
return internalNginx.reload().then(() => {
// 4. Request cert
return internalCertificate.requestLetsEncryptSslWithDnsChallenge(certificate);
})
.then(internalNginx.reload)
.then(() => {
// 6. Re-instate previously disabled hosts
return internalCertificate.enableInUseHosts(in_use_result);
})
.then(() => {
return certificate;
})
.catch((err) => {
// In the event of failure, revert things and throw err back
return internalCertificate.enableInUseHosts(in_use_result)
.then(internalNginx.reload)
.then(() => {
throw err;
});
});
} else {
// 3. Generate the LE config // 3. Generate the LE config
return internalNginx.generateLetsEncryptRequestConfig(certificate) return internalNginx.generateLetsEncryptRequestConfig(certificate)
.then(internalNginx.reload) .then(internalNginx.reload)
.then(async() => await new Promise((r) => setTimeout(r, 5000)))
.then(() => { .then(() => {
// 4. Request cert // 4. Request cert
return internalCertificate.requestLetsEncryptSsl(certificate); return internalCertificate.requestLetsEncryptSsl(certificate);
@ -171,6 +199,7 @@ const internalCertificate = {
throw err; throw err;
}); });
}); });
}
}) })
.then(() => { .then(() => {
// At this point, the letsencrypt cert should exist on disk. // At this point, the letsencrypt cert should exist on disk.
@ -180,7 +209,7 @@ const internalCertificate = {
return certificateModel return certificateModel
.query() .query()
.patchAndFetchById(certificate.id, { .patchAndFetchById(certificate.id, {
expires_on: certificateModel.raw('FROM_UNIXTIME(' + cert_info.dates.to + ')') expires_on: moment(cert_info.dates.to, 'X').format('YYYY-MM-DD HH:mm:ss')
}) })
.then((saved_row) => { .then((saved_row) => {
// Add cert data for audit log // Add cert data for audit log
@ -191,6 +220,13 @@ const internalCertificate = {
return saved_row; return saved_row;
}); });
}); });
}).catch(async (error) => {
// Delete the certificate from the database if it was not created successfully
await certificateModel
.query()
.deleteById(certificate.id);
throw error;
}); });
} else { } else {
return certificate; return certificate;
@ -304,6 +340,71 @@ const internalCertificate = {
}); });
}, },
/**
* @param {Access} access
* @param {Object} data
* @param {Number} data.id
* @returns {Promise}
*/
download: (access, data) => {
return new Promise((resolve, reject) => {
access.can('certificates:get', data)
.then(() => {
return internalCertificate.get(access, data);
})
.then((certificate) => {
if (certificate.provider === 'letsencrypt') {
const zipDirectory = '/etc/letsencrypt/live/npm-' + data.id;
if (!fs.existsSync(zipDirectory)) {
throw new error.ItemNotFoundError('Certificate ' + certificate.nice_name + ' does not exists');
}
let certFiles = fs.readdirSync(zipDirectory)
.filter((fn) => fn.endsWith('.pem'))
.map((fn) => fs.realpathSync(path.join(zipDirectory, fn)));
const downloadName = 'npm-' + data.id + '-' + `${Date.now()}.zip`;
const opName = '/tmp/' + downloadName;
internalCertificate.zipFiles(certFiles, opName)
.then(() => {
logger.debug('zip completed : ', opName);
const resp = {
fileName: opName
};
resolve(resp);
}).catch((err) => reject(err));
} else {
throw new error.ValidationError('Only Let\'sEncrypt certificates can be downloaded');
}
}).catch((err) => reject(err));
});
},
/**
* @param {String} source
* @param {String} out
* @returns {Promise}
*/
zipFiles(source, out) {
const archive = archiver('zip', { zlib: { level: 9 } });
const stream = fs.createWriteStream(out);
return new Promise((resolve, reject) => {
source
.map((fl) => {
let fileName = path.basename(fl);
logger.debug(fl, 'added to certificate zip');
archive.file(fl, { name: fileName });
});
archive
.on('error', (err) => reject(err))
.pipe(stream);
stream.on('close', () => resolve());
archive.finalize();
});
},
/** /**
* @param {Access} access * @param {Access} access
* @param {Object} data * @param {Object} data
@ -376,7 +477,7 @@ const internalCertificate = {
// Query is used for searching // Query is used for searching
if (typeof search_query === 'string') { if (typeof search_query === 'string') {
query.where(function () { query.where(function () {
this.where('name', 'like', '%' + search_query + '%'); this.where('nice_name', 'like', '%' + search_query + '%');
}); });
} }
@ -416,11 +517,9 @@ const internalCertificate = {
* @returns {Promise} * @returns {Promise}
*/ */
writeCustomCert: (certificate) => { writeCustomCert: (certificate) => {
if (debug_mode) {
logger.info('Writing Custom Certificate:', certificate); logger.info('Writing Custom Certificate:', certificate);
}
let dir = '/data/custom_ssl/npm-' + certificate.id; const dir = '/data/custom_ssl/npm-' + certificate.id;
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (certificate.provider === 'letsencrypt') { if (certificate.provider === 'letsencrypt') {
@ -428,9 +527,9 @@ const internalCertificate = {
return; return;
} }
let cert_data = certificate.meta.certificate; let certData = certificate.meta.certificate;
if (typeof certificate.meta.intermediate_certificate !== 'undefined') { if (typeof certificate.meta.intermediate_certificate !== 'undefined') {
cert_data = cert_data + '\n' + certificate.meta.intermediate_certificate; certData = certData + '\n' + certificate.meta.intermediate_certificate;
} }
try { try {
@ -442,7 +541,7 @@ const internalCertificate = {
return; return;
} }
fs.writeFile(dir + '/fullchain.pem', cert_data, function (err) { fs.writeFile(dir + '/fullchain.pem', certData, function (err) {
if (err) { if (err) {
reject(err); reject(err);
} else { } else {
@ -492,7 +591,7 @@ const internalCertificate = {
// Put file contents into an object // Put file contents into an object
let files = {}; let files = {};
_.map(data.files, (file, name) => { _.map(data.files, (file, name) => {
if (internalCertificate.allowed_ssl_files.indexOf(name) !== -1) { if (internalCertificate.allowedSslFiles.indexOf(name) !== -1) {
files[name] = file.data.toString(); files[name] = file.data.toString();
} }
}); });
@ -550,7 +649,7 @@ const internalCertificate = {
} }
_.map(data.files, (file, name) => { _.map(data.files, (file, name) => {
if (internalCertificate.allowed_ssl_files.indexOf(name) !== -1) { if (internalCertificate.allowedSslFiles.indexOf(name) !== -1) {
row.meta[name] = file.data.toString(); row.meta[name] = file.data.toString();
} }
}); });
@ -558,7 +657,7 @@ const internalCertificate = {
// TODO: This uses a mysql only raw function that won't translate to postgres // TODO: This uses a mysql only raw function that won't translate to postgres
return internalCertificate.update(access, { return internalCertificate.update(access, {
id: data.id, id: data.id,
expires_on: certificateModel.raw('FROM_UNIXTIME(' + validations.certificate.dates.to + ')'), expires_on: moment(validations.certificate.dates.to, 'X').format('YYYY-MM-DD HH:mm:ss'),
domain_names: [validations.certificate.cn], domain_names: [validations.certificate.cn],
meta: _.clone(row.meta) // Prevent the update method from changing this value that we'll use later meta: _.clone(row.meta) // Prevent the update method from changing this value that we'll use later
}) })
@ -569,7 +668,7 @@ const internalCertificate = {
}); });
}) })
.then(() => { .then(() => {
return _.pick(row.meta, internalCertificate.allowed_ssl_files); return _.pick(row.meta, internalCertificate.allowedSslFiles);
}); });
}); });
}, },
@ -583,17 +682,25 @@ const internalCertificate = {
checkPrivateKey: (private_key) => { checkPrivateKey: (private_key) => {
return tempWrite(private_key, '/tmp') return tempWrite(private_key, '/tmp')
.then((filepath) => { .then((filepath) => {
return utils.exec('openssl rsa -in ' + filepath + ' -check -noout') return new Promise((resolve, reject) => {
const failTimeout = setTimeout(() => {
reject(new error.ValidationError('Result Validation Error: Validation timed out. This could be due to the key being passphrase-protected.'));
}, 10000);
utils
.exec('openssl pkey -in ' + filepath + ' -check -noout 2>&1 ')
.then((result) => { .then((result) => {
if (!result.toLowerCase().includes('key ok')) { clearTimeout(failTimeout);
throw new error.ValidationError(result); if (!result.toLowerCase().includes('key is valid')) {
reject(new error.ValidationError('Result Validation Error: ' + result));
} }
fs.unlinkSync(filepath); fs.unlinkSync(filepath);
return true; resolve(true);
}).catch((err) => { })
.catch((err) => {
clearTimeout(failTimeout);
fs.unlinkSync(filepath); fs.unlinkSync(filepath);
throw new error.ValidationError('Certificate Key is not valid (' + err.message + ')', err); reject(new error.ValidationError('Certificate Key is not valid (' + err.message + ')', err));
});
}); });
}); });
}, },
@ -609,9 +716,9 @@ const internalCertificate = {
return tempWrite(certificate, '/tmp') return tempWrite(certificate, '/tmp')
.then((filepath) => { .then((filepath) => {
return internalCertificate.getCertificateInfoFromFile(filepath, throw_expired) return internalCertificate.getCertificateInfoFromFile(filepath, throw_expired)
.then((cert_data) => { .then((certData) => {
fs.unlinkSync(filepath); fs.unlinkSync(filepath);
return cert_data; return certData;
}).catch((err) => { }).catch((err) => {
fs.unlinkSync(filepath); fs.unlinkSync(filepath);
throw err; throw err;
@ -627,33 +734,33 @@ const internalCertificate = {
* @param {Boolean} [throw_expired] Throw when the certificate is out of date * @param {Boolean} [throw_expired] Throw when the certificate is out of date
*/ */
getCertificateInfoFromFile: (certificate_file, throw_expired) => { getCertificateInfoFromFile: (certificate_file, throw_expired) => {
let cert_data = {}; let certData = {};
return utils.exec('openssl x509 -in ' + certificate_file + ' -subject -noout') return utils.exec('openssl x509 -in ' + certificate_file + ' -subject -noout')
.then((result) => { .then((result) => {
// subject=CN = something.example.com // subject=CN = something.example.com
let regex = /(?:subject=)?[^=]+=\s+(\S+)/gim; const regex = /(?:subject=)?[^=]+=\s+(\S+)/gim;
let match = regex.exec(result); const match = regex.exec(result);
if (typeof match[1] === 'undefined') { if (typeof match[1] === 'undefined') {
throw new error.ValidationError('Could not determine subject from certificate: ' + result); throw new error.ValidationError('Could not determine subject from certificate: ' + result);
} }
cert_data['cn'] = match[1]; certData['cn'] = match[1];
}) })
.then(() => { .then(() => {
return utils.exec('openssl x509 -in ' + certificate_file + ' -issuer -noout'); return utils.exec('openssl x509 -in ' + certificate_file + ' -issuer -noout');
}) })
.then((result) => { .then((result) => {
// issuer=C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3 // issuer=C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
let regex = /^(?:issuer=)?(.*)$/gim; const regex = /^(?:issuer=)?(.*)$/gim;
let match = regex.exec(result); const match = regex.exec(result);
if (typeof match[1] === 'undefined') { if (typeof match[1] === 'undefined') {
throw new error.ValidationError('Could not determine issuer from certificate: ' + result); throw new error.ValidationError('Could not determine issuer from certificate: ' + result);
} }
cert_data['issuer'] = match[1]; certData['issuer'] = match[1];
}) })
.then(() => { .then(() => {
return utils.exec('openssl x509 -in ' + certificate_file + ' -dates -noout'); return utils.exec('openssl x509 -in ' + certificate_file + ' -dates -noout');
@ -661,39 +768,39 @@ const internalCertificate = {
.then((result) => { .then((result) => {
// notBefore=Jul 14 04:04:29 2018 GMT // notBefore=Jul 14 04:04:29 2018 GMT
// notAfter=Oct 12 04:04:29 2018 GMT // notAfter=Oct 12 04:04:29 2018 GMT
let valid_from = null; let validFrom = null;
let valid_to = null; let validTo = null;
let lines = result.split('\n'); const lines = result.split('\n');
lines.map(function (str) { lines.map(function (str) {
let regex = /^(\S+)=(.*)$/gim; const regex = /^(\S+)=(.*)$/gim;
let match = regex.exec(str.trim()); const match = regex.exec(str.trim());
if (match && typeof match[2] !== 'undefined') { if (match && typeof match[2] !== 'undefined') {
let date = parseInt(moment(match[2], 'MMM DD HH:mm:ss YYYY z').format('X'), 10); const date = parseInt(moment(match[2], 'MMM DD HH:mm:ss YYYY z').format('X'), 10);
if (match[1].toLowerCase() === 'notbefore') { if (match[1].toLowerCase() === 'notbefore') {
valid_from = date; validFrom = date;
} else if (match[1].toLowerCase() === 'notafter') { } else if (match[1].toLowerCase() === 'notafter') {
valid_to = date; validTo = date;
} }
} }
}); });
if (!valid_from || !valid_to) { if (!validFrom || !validTo) {
throw new error.ValidationError('Could not determine dates from certificate: ' + result); throw new error.ValidationError('Could not determine dates from certificate: ' + result);
} }
if (throw_expired && valid_to < parseInt(moment().format('X'), 10)) { if (throw_expired && validTo < parseInt(moment().format('X'), 10)) {
throw new error.ValidationError('Certificate has expired'); throw new error.ValidationError('Certificate has expired');
} }
cert_data['dates'] = { certData['dates'] = {
from: valid_from, from: validFrom,
to: valid_to to: validTo
}; };
return cert_data; return certData;
}).catch((err) => { }).catch((err) => {
throw new error.ValidationError('Certificate is not valid (' + err.message + ')', err); throw new error.ValidationError('Certificate is not valid (' + err.message + ')', err);
}); });
@ -707,7 +814,7 @@ const internalCertificate = {
* @returns {Object} * @returns {Object}
*/ */
cleanMeta: function (meta, remove) { cleanMeta: function (meta, remove) {
internalCertificate.allowed_ssl_files.map((key) => { internalCertificate.allowedSslFiles.map((key) => {
if (typeof meta[key] !== 'undefined' && meta[key]) { if (typeof meta[key] !== 'undefined' && meta[key]) {
if (remove) { if (remove) {
delete meta[key]; delete meta[key];
@ -721,25 +828,24 @@ const internalCertificate = {
}, },
/** /**
* Request a certificate using the http challenge
* @param {Object} certificate the certificate row * @param {Object} certificate the certificate row
* @returns {Promise} * @returns {Promise}
*/ */
requestLetsEncryptSsl: (certificate) => { requestLetsEncryptSsl: (certificate) => {
logger.info('Requesting Let\'sEncrypt certificates for Cert #' + certificate.id + ': ' + certificate.domain_names.join(', ')); logger.info('Requesting Let\'sEncrypt certificates for Cert #' + certificate.id + ': ' + certificate.domain_names.join(', '));
let cmd = certbot_command + ' certonly --non-interactive ' + const cmd = certbotCommand + ' certonly ' +
'--config "' + le_config + '" ' + '--config "' + letsencryptConfig + '" ' +
'--cert-name "npm-' + certificate.id + '" ' + '--cert-name "npm-' + certificate.id + '" ' +
'--agree-tos ' + '--agree-tos ' +
'--authenticator webroot ' +
'--email "' + certificate.meta.letsencrypt_email + '" ' + '--email "' + certificate.meta.letsencrypt_email + '" ' +
'--preferred-challenges "dns,http" ' + '--preferred-challenges "dns,http" ' +
'--webroot ' +
'--domains "' + certificate.domain_names.join(',') + '" ' + '--domains "' + certificate.domain_names.join(',') + '" ' +
(le_staging ? '--staging' : ''); (letsencryptStaging ? '--staging' : '');
if (debug_mode) {
logger.info('Command:', cmd); logger.info('Command:', cmd);
}
return utils.exec(cmd) return utils.exec(cmd)
.then((result) => { .then((result) => {
@ -748,6 +854,81 @@ const internalCertificate = {
}); });
}, },
/**
* @param {Object} certificate the certificate row
* @param {String} dns_provider the dns provider name (key used in `certbot-dns-plugins.js`)
* @param {String | null} credentials the content of this providers credentials file
* @param {String} propagation_seconds the cloudflare api token
* @returns {Promise}
*/
requestLetsEncryptSslWithDnsChallenge: (certificate) => {
const dns_plugin = dnsPlugins[certificate.meta.dns_provider];
if (!dns_plugin) {
throw Error(`Unknown DNS provider '${certificate.meta.dns_provider}'`);
}
logger.info(`Requesting Let'sEncrypt certificates via ${dns_plugin.display_name} for Cert #${certificate.id}: ${certificate.domain_names.join(', ')}`);
const credentialsLocation = '/etc/letsencrypt/credentials/credentials-' + certificate.id;
// Escape single quotes and backslashes
const escapedCredentials = certificate.meta.dns_provider_credentials.replaceAll('\'', '\\\'').replaceAll('\\', '\\\\');
const credentialsCmd = 'mkdir -p /etc/letsencrypt/credentials 2> /dev/null; echo \'' + escapedCredentials + '\' > \'' + credentialsLocation + '\' && chmod 600 \'' + credentialsLocation + '\'';
let prepareCmd = 'pip install ' + dns_plugin.package_name + (dns_plugin.version_requirement || '') + ' ' + dns_plugin.dependencies;
// Special case for cloudflare
if (dns_plugin.package_name === 'certbot-dns-cloudflare') {
prepareCmd = 'pip install certbot-dns-cloudflare --index-url https://www.piwheels.org/simple --prefer-binary';
}
// Whether the plugin has a --<name>-credentials argument
const hasConfigArg = certificate.meta.dns_provider !== 'route53';
let mainCmd = certbotCommand + ' certonly ' +
'--config "' + letsencryptConfig + '" ' +
'--cert-name "npm-' + certificate.id + '" ' +
'--agree-tos ' +
'--email "' + certificate.meta.letsencrypt_email + '" ' +
'--domains "' + certificate.domain_names.join(',') + '" ' +
'--authenticator ' + dns_plugin.full_plugin_name + ' ' +
(
hasConfigArg
? '--' + dns_plugin.full_plugin_name + '-credentials "' + credentialsLocation + '"'
: ''
) +
(
certificate.meta.propagation_seconds !== undefined
? ' --' + dns_plugin.full_plugin_name + '-propagation-seconds ' + certificate.meta.propagation_seconds
: ''
) +
(letsencryptStaging ? ' --staging' : '');
// Prepend the path to the credentials file as an environment variable
if (certificate.meta.dns_provider === 'route53') {
mainCmd = 'AWS_CONFIG_FILE=\'' + credentialsLocation + '\' ' + mainCmd;
}
logger.info('Command:', `${credentialsCmd} && ${prepareCmd} && ${mainCmd}`);
return utils.exec(credentialsCmd)
.then(() => {
return utils.exec(prepareCmd)
.then(() => {
return utils.exec(mainCmd)
.then(async (result) => {
logger.info(result);
return result;
});
});
}).catch(async (err) => {
// Don't fail if file does not exist
const delete_credentialsCmd = `rm -f '${credentialsLocation}' || true`;
await utils.exec(delete_credentialsCmd);
throw err;
});
},
/** /**
* @param {Access} access * @param {Access} access
* @param {Object} data * @param {Object} data
@ -761,7 +942,9 @@ const internalCertificate = {
}) })
.then((certificate) => { .then((certificate) => {
if (certificate.provider === 'letsencrypt') { if (certificate.provider === 'letsencrypt') {
return internalCertificate.renewLetsEncryptSsl(certificate) const renewMethod = certificate.meta.dns_challenge ? internalCertificate.renewLetsEncryptSslWithDnsChallenge : internalCertificate.renewLetsEncryptSsl;
return renewMethod(certificate)
.then(() => { .then(() => {
return internalCertificate.getCertificateInfoFromFile('/etc/letsencrypt/live/npm-' + certificate.id + '/fullchain.pem'); return internalCertificate.getCertificateInfoFromFile('/etc/letsencrypt/live/npm-' + certificate.id + '/fullchain.pem');
}) })
@ -769,7 +952,7 @@ const internalCertificate = {
return certificateModel return certificateModel
.query() .query()
.patchAndFetchById(certificate.id, { .patchAndFetchById(certificate.id, {
expires_on: certificateModel.raw('FROM_UNIXTIME(' + cert_info.dates.to + ')') expires_on: moment(cert_info.dates.to, 'X').format('YYYY-MM-DD HH:mm:ss')
}); });
}) })
.then((updated_certificate) => { .then((updated_certificate) => {
@ -797,16 +980,15 @@ const internalCertificate = {
renewLetsEncryptSsl: (certificate) => { renewLetsEncryptSsl: (certificate) => {
logger.info('Renewing Let\'sEncrypt certificates for Cert #' + certificate.id + ': ' + certificate.domain_names.join(', ')); logger.info('Renewing Let\'sEncrypt certificates for Cert #' + certificate.id + ': ' + certificate.domain_names.join(', '));
let cmd = certbot_command + ' renew --non-interactive ' + const cmd = certbotCommand + ' renew --force-renewal ' +
'--config "' + le_config + '" ' + '--config "' + letsencryptConfig + '" ' +
'--cert-name "npm-' + certificate.id + '" ' + '--cert-name "npm-' + certificate.id + '" ' +
'--preferred-challenges "dns,http" ' + '--preferred-challenges "dns,http" ' +
'--no-random-sleep-on-renew ' +
'--disable-hook-validation ' + '--disable-hook-validation ' +
(le_staging ? '--staging' : ''); (letsencryptStaging ? '--staging' : '');
if (debug_mode) {
logger.info('Command:', cmd); logger.info('Command:', cmd);
}
return utils.exec(cmd) return utils.exec(cmd)
.then((result) => { .then((result) => {
@ -815,6 +997,41 @@ const internalCertificate = {
}); });
}, },
/**
* @param {Object} certificate the certificate row
* @returns {Promise}
*/
renewLetsEncryptSslWithDnsChallenge: (certificate) => {
const dns_plugin = dnsPlugins[certificate.meta.dns_provider];
if (!dns_plugin) {
throw Error(`Unknown DNS provider '${certificate.meta.dns_provider}'`);
}
logger.info(`Renewing Let'sEncrypt certificates via ${dns_plugin.display_name} for Cert #${certificate.id}: ${certificate.domain_names.join(', ')}`);
let mainCmd = certbotCommand + ' renew ' +
'--config "' + letsencryptConfig + '" ' +
'--cert-name "npm-' + certificate.id + '" ' +
'--disable-hook-validation ' +
'--no-random-sleep-on-renew ' +
(letsencryptStaging ? ' --staging' : '');
// Prepend the path to the credentials file as an environment variable
if (certificate.meta.dns_provider === 'route53') {
const credentialsLocation = '/etc/letsencrypt/credentials/credentials-' + certificate.id;
mainCmd = 'AWS_CONFIG_FILE=\'' + credentialsLocation + '\' ' + mainCmd;
}
logger.info('Command:', mainCmd);
return utils.exec(mainCmd)
.then(async (result) => {
logger.info(result);
return result;
});
},
/** /**
* @param {Object} certificate the certificate row * @param {Object} certificate the certificate row
* @param {Boolean} [throw_errors] * @param {Boolean} [throw_errors]
@ -823,28 +1040,25 @@ const internalCertificate = {
revokeLetsEncryptSsl: (certificate, throw_errors) => { revokeLetsEncryptSsl: (certificate, throw_errors) => {
logger.info('Revoking Let\'sEncrypt certificates for Cert #' + certificate.id + ': ' + certificate.domain_names.join(', ')); logger.info('Revoking Let\'sEncrypt certificates for Cert #' + certificate.id + ': ' + certificate.domain_names.join(', '));
let cmd = certbot_command + ' revoke --non-interactive ' + const mainCmd = certbotCommand + ' revoke ' +
'--config "' + le_config + '" ' + '--config "' + letsencryptConfig + '" ' +
'--cert-path "/etc/letsencrypt/live/npm-' + certificate.id + '/fullchain.pem" ' + '--cert-path "/etc/letsencrypt/live/npm-' + certificate.id + '/fullchain.pem" ' +
'--delete-after-revoke ' + '--delete-after-revoke ' +
(le_staging ? '--staging' : ''); (letsencryptStaging ? '--staging' : '');
if (debug_mode) { // Don't fail command if file does not exist
logger.info('Command:', cmd); const delete_credentialsCmd = `rm -f '/etc/letsencrypt/credentials/credentials-${certificate.id}' || true`;
}
return utils.exec(cmd) logger.info('Command:', mainCmd + '; ' + delete_credentialsCmd);
.then((result) => {
if (debug_mode) { return utils.exec(mainCmd)
logger.info('Command:', cmd); .then(async (result) => {
} await utils.exec(delete_credentialsCmd);
logger.info(result); logger.info(result);
return result; return result;
}) })
.catch((err) => { .catch((err) => {
if (debug_mode) {
logger.error(err.message); logger.error(err.message);
}
if (throw_errors) { if (throw_errors) {
throw err; throw err;
@ -857,9 +1071,9 @@ const internalCertificate = {
* @returns {Boolean} * @returns {Boolean}
*/ */
hasLetsEncryptSslCerts: (certificate) => { hasLetsEncryptSslCerts: (certificate) => {
let le_path = '/etc/letsencrypt/live/npm-' + certificate.id; const letsencryptPath = '/etc/letsencrypt/live/npm-' + certificate.id;
return fs.existsSync(le_path + '/fullchain.pem') && fs.existsSync(le_path + '/privkey.pem'); return fs.existsSync(letsencryptPath + '/fullchain.pem') && fs.existsSync(letsencryptPath + '/privkey.pem');
}, },
/** /**
@ -920,6 +1134,94 @@ const internalCertificate = {
} else { } else {
return Promise.resolve(); return Promise.resolve();
} }
},
testHttpsChallenge: async (access, domains) => {
await access.can('certificates:list');
if (!isArray(domains)) {
throw new error.InternalValidationError('Domains must be an array of strings');
}
if (domains.length === 0) {
throw new error.InternalValidationError('No domains provided');
}
// Create a test challenge file
const testChallengeDir = '/data/letsencrypt-acme-challenge/.well-known/acme-challenge';
const testChallengeFile = testChallengeDir + '/test-challenge';
fs.mkdirSync(testChallengeDir, {recursive: true});
fs.writeFileSync(testChallengeFile, 'Success', {encoding: 'utf8'});
async function performTestForDomain (domain) {
logger.info('Testing http challenge for ' + domain);
const url = `http://${domain}/.well-known/acme-challenge/test-challenge`;
const formBody = `method=G&url=${encodeURI(url)}&bodytype=T&requestbody=&headername=User-Agent&headervalue=None&locationid=1&ch=false&cc=false`;
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': Buffer.byteLength(formBody)
}
};
const result = await new Promise((resolve) => {
const req = https.request('https://www.site24x7.com/tools/restapi-tester', options, function (res) {
let responseBody = '';
res.on('data', (chunk) => responseBody = responseBody + chunk);
res.on('end', function () {
const parsedBody = JSON.parse(responseBody + '');
if (res.statusCode !== 200) {
logger.warn(`Failed to test HTTP challenge for domain ${domain}`, res);
resolve(undefined);
}
resolve(parsedBody);
});
});
// Make sure to write the request body.
req.write(formBody);
req.end();
req.on('error', function (e) { logger.warn(`Failed to test HTTP challenge for domain ${domain}`, e);
resolve(undefined); });
});
if (!result) {
// Some error occurred while trying to get the data
return 'failed';
} else if (`${result.responsecode}` === '200' && result.htmlresponse === 'Success') {
// Server exists and has responded with the correct data
return 'ok';
} else if (`${result.responsecode}` === '200') {
// Server exists but has responded with wrong data
logger.info(`HTTP challenge test failed for domain ${domain} because of invalid returned data:`, result.htmlresponse);
return 'wrong-data';
} else if (`${result.responsecode}` === '404') {
// Server exists but responded with a 404
logger.info(`HTTP challenge test failed for domain ${domain} because code 404 was returned`);
return '404';
} else if (`${result.responsecode}` === '0' || (typeof result.reason === 'string' && result.reason.toLowerCase() === 'host unavailable')) {
// Server does not exist at domain
logger.info(`HTTP challenge test failed for domain ${domain} the host was not found`);
return 'no-host';
} else {
// Other errors
logger.info(`HTTP challenge test failed for domain ${domain} because code ${result.responsecode} was returned`);
return `other:${result.responsecode}`;
}
}
const results = {};
for (const domain of domains){
results[domain] = await performTestForDomain(domain);
}
// Remove the test challenge file
fs.unlinkSync(testChallengeFile);
return results;
} }
}; };

View File

@ -106,7 +106,7 @@ const internalHost = {
response_object.total_count += response_object.redirection_hosts.length; response_object.total_count += response_object.redirection_hosts.length;
} }
if (promises_results[1]) { if (promises_results[2]) {
// Dead Hosts // Dead Hosts
response_object.dead_hosts = internalHost._getHostsWithDomains(promises_results[2], domain_names); response_object.dead_hosts = internalHost._getHostsWithDomains(promises_results[2], domain_names);
response_object.total_count += response_object.dead_hosts.length; response_object.total_count += response_object.dead_hosts.length;
@ -158,7 +158,7 @@ const internalHost = {
} }
} }
if (promises_results[1]) { if (promises_results[2]) {
// Dead Hosts // Dead Hosts
if (internalHost._checkHostnameRecordsTaken(hostname, promises_results[2], ignore_type === 'dead' && ignore_id ? ignore_id : 0)) { if (internalHost._checkHostnameRecordsTaken(hostname, promises_results[2], ignore_type === 'dead' && ignore_id ? ignore_id : 0)) {
is_taken = true; is_taken = true;

View File

@ -9,6 +9,9 @@ const CLOUDFRONT_URL = 'https://ip-ranges.amazonaws.com/ip-ranges.json';
const CLOUDFARE_V4_URL = 'https://www.cloudflare.com/ips-v4'; const CLOUDFARE_V4_URL = 'https://www.cloudflare.com/ips-v4';
const CLOUDFARE_V6_URL = 'https://www.cloudflare.com/ips-v6'; const CLOUDFARE_V6_URL = 'https://www.cloudflare.com/ips-v6';
const regIpV4 = /^(\d+\.?){4}\/\d+/;
const regIpV6 = /^(([\da-fA-F]+)?:)+\/\d+/;
const internalIpRanges = { const internalIpRanges = {
interval_timeout: 1000 * 60 * 60 * 6, // 6 hours interval_timeout: 1000 * 60 * 60 * 6, // 6 hours
@ -74,14 +77,14 @@ const internalIpRanges = {
return internalIpRanges.fetchUrl(CLOUDFARE_V4_URL); return internalIpRanges.fetchUrl(CLOUDFARE_V4_URL);
}) })
.then((cloudfare_data) => { .then((cloudfare_data) => {
let items = cloudfare_data.split('\n'); let items = cloudfare_data.split('\n').filter((line) => regIpV4.test(line));
ip_ranges = [... ip_ranges, ... items]; ip_ranges = [... ip_ranges, ... items];
}) })
.then(() => { .then(() => {
return internalIpRanges.fetchUrl(CLOUDFARE_V6_URL); return internalIpRanges.fetchUrl(CLOUDFARE_V6_URL);
}) })
.then((cloudfare_data) => { .then((cloudfare_data) => {
let items = cloudfare_data.split('\n'); let items = cloudfare_data.split('\n').filter((line) => regIpV6.test(line));
ip_ranges = [... ip_ranges, ... items]; ip_ranges = [... ip_ranges, ... items];
}) })
.then(() => { .then(() => {

View File

@ -136,6 +136,8 @@ const internalNginx = {
* @returns {Promise} * @returns {Promise}
*/ */
renderLocations: (host) => { renderLocations: (host) => {
//logger.info('host = ' + JSON.stringify(host, null, 2));
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let template; let template;
@ -146,12 +148,18 @@ const internalNginx = {
return; return;
} }
let renderer = new Liquid(); let renderer = new Liquid({
root: __dirname + '/../templates/'
});
let renderedLocations = ''; let renderedLocations = '';
const locationRendering = async () => { const locationRendering = async () => {
for (let i = 0; i < host.locations.length; i++) { for (let i = 0; i < host.locations.length; i++) {
let locationCopy = Object.assign({}, host.locations[i]); let locationCopy = Object.assign({}, {access_list_id: host.access_list_id}, {certificate_id: host.certificate_id},
{ssl_forced: host.ssl_forced}, {caching_enabled: host.caching_enabled}, {block_exploits: host.block_exploits},
{allow_websocket_upgrade: host.allow_websocket_upgrade}, {http2_support: host.http2_support},
{hsts_enabled: host.hsts_enabled}, {hsts_subdomains: host.hsts_subdomains}, {access_list: host.access_list},
{certificate: host.certificate}, host.locations[i]);
if (locationCopy.forward_host.indexOf('/') > -1) { if (locationCopy.forward_host.indexOf('/') > -1) {
const splitted = locationCopy.forward_host.split('/'); const splitted = locationCopy.forward_host.split('/');
@ -160,12 +168,16 @@ const internalNginx = {
locationCopy.forward_path = `/${splitted.join('/')}`; locationCopy.forward_path = `/${splitted.join('/')}`;
} }
//logger.info('locationCopy = ' + JSON.stringify(locationCopy, null, 2));
// eslint-disable-next-line // eslint-disable-next-line
renderedLocations += await renderer.parseAndRender(template, locationCopy); renderedLocations += await renderer.parseAndRender(template, locationCopy);
} }
}; };
locationRendering().then(() => resolve(renderedLocations)); locationRendering().then(() => resolve(renderedLocations));
}); });
}, },
@ -181,6 +193,8 @@ const internalNginx = {
logger.info('Generating ' + host_type + ' Config:', host); logger.info('Generating ' + host_type + ' Config:', host);
} }
// logger.info('host = ' + JSON.stringify(host, null, 2));
let renderEngine = new Liquid({ let renderEngine = new Liquid({
root: __dirname + '/../templates/' root: __dirname + '/../templates/'
}); });
@ -208,6 +222,7 @@ const internalNginx = {
} }
if (host.locations) { if (host.locations) {
//logger.info ('host.locations = ' + JSON.stringify(host.locations, null, 2));
origLocations = [].concat(host.locations); origLocations = [].concat(host.locations);
locationsPromise = internalNginx.renderLocations(host).then((renderedLocations) => { locationsPromise = internalNginx.renderLocations(host).then((renderedLocations) => {
host.locations = renderedLocations; host.locations = renderedLocations;
@ -224,6 +239,9 @@ const internalNginx = {
locationsPromise = Promise.resolve(); locationsPromise = Promise.resolve();
} }
// Set the IPv6 setting for the host
host.ipv6 = internalNginx.ipv6Enabled();
locationsPromise.then(() => { locationsPromise.then(() => {
renderEngine renderEngine
.parseAndRender(template, host) .parseAndRender(template, host)
@ -270,6 +288,7 @@ const internalNginx = {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let template = null; let template = null;
let filename = '/data/nginx/temp/letsencrypt_' + certificate.id + '.conf'; let filename = '/data/nginx/temp/letsencrypt_' + certificate.id + '.conf';
try { try {
template = fs.readFileSync(__dirname + '/../templates/letsencrypt-request.conf', {encoding: 'utf8'}); template = fs.readFileSync(__dirname + '/../templates/letsencrypt-request.conf', {encoding: 'utf8'});
} catch (err) { } catch (err) {
@ -277,6 +296,8 @@ const internalNginx = {
return; return;
} }
certificate.ipv6 = internalNginx.ipv6Enabled();
renderEngine renderEngine
.parseAndRender(template, certificate) .parseAndRender(template, certificate)
.then((config_text) => { .then((config_text) => {
@ -396,6 +417,18 @@ const internalNginx = {
*/ */
advancedConfigHasDefaultLocation: function (config) { advancedConfigHasDefaultLocation: function (config) {
return !!config.match(/^(?:.*;)?\s*?location\s*?\/\s*?{/im); return !!config.match(/^(?:.*;)?\s*?location\s*?\/\s*?{/im);
},
/**
* @returns {boolean}
*/
ipv6Enabled: function () {
if (typeof process.env.DISABLE_IPV6 !== 'undefined') {
const disabled = process.env.DISABLE_IPV6.toLowerCase();
return !(disabled === 'on' || disabled === 'true' || disabled === '1' || disabled === 'yes');
}
return true;
} }
}; };

View File

@ -73,7 +73,7 @@ const internalProxyHost = {
// re-fetch with cert // re-fetch with cert
return internalProxyHost.get(access, { return internalProxyHost.get(access, {
id: row.id, id: row.id,
expand: ['certificate', 'owner', 'access_list'] expand: ['certificate', 'owner', 'access_list.[clients,items]']
}); });
}) })
.then((row) => { .then((row) => {
@ -186,9 +186,13 @@ const internalProxyHost = {
.then(() => { .then(() => {
return internalProxyHost.get(access, { return internalProxyHost.get(access, {
id: data.id, id: data.id,
expand: ['owner', 'certificate', 'access_list'] expand: ['owner', 'certificate', 'access_list.[clients,items]']
}) })
.then((row) => { .then((row) => {
if (!row.enabled) {
// No need to add nginx config if host is disabled
return row;
}
// Configure nginx // Configure nginx
return internalNginx.configure(proxyHostModel, 'proxy_host', row) return internalNginx.configure(proxyHostModel, 'proxy_host', row)
.then((new_meta) => { .then((new_meta) => {
@ -219,7 +223,7 @@ const internalProxyHost = {
.query() .query()
.where('is_deleted', 0) .where('is_deleted', 0)
.andWhere('id', data.id) .andWhere('id', data.id)
.allowEager('[owner,access_list,certificate]') .allowEager('[owner,access_list,access_list.[clients,items],certificate]')
.first(); .first();
if (access_data.permission_visibility !== 'all') { if (access_data.permission_visibility !== 'all') {

View File

@ -4,11 +4,21 @@ module.exports = function (req, res, next) {
if (req.headers.origin) { if (req.headers.origin) {
// very relaxed validation.... const originSchema = {
validator({ oneOf: [
{
type: 'string', type: 'string',
pattern: '^[a-z\\-]+:\\/\\/(?:[\\w\\-\\.]+(:[0-9]+)?/?)?$' pattern: '^[a-z\\-]+:\\/\\/(?:[\\w\\-\\.]+(:[0-9]+)?/?)?$'
}, req.headers.origin) },
{
type: 'string',
pattern: '^[a-z\\-]+:\\/\\/(?:\\[([a-z0-9]{0,4}\\:?)+\\])?/?(:[0-9]+)?$'
}
]
};
// very relaxed validation....
validator(originSchema, req.headers.origin)
.then(function () { .then(function () {
res.set({ res.set({
'Access-Control-Allow-Origin': req.headers.origin, 'Access-Control-Allow-Origin': req.headers.origin,

View File

@ -22,22 +22,6 @@ exports.up = function (knex/*, Promise*/) {
}) })
.then(() => { .then(() => {
logger.info('[' + migrate_name + '] setting Table created'); logger.info('[' + migrate_name + '] setting Table created');
// TODO: add settings
let settingModel = require('../models/setting');
return settingModel
.query()
.insert({
id: 'default-site',
name: 'Default Site',
description: 'What to show when Nginx is hit with an unknown Host',
value: 'congratulations',
meta: {}
});
})
.then(() => {
logger.info('[' + migrate_name + '] Default settings added');
}); });
}; };

View File

@ -0,0 +1,53 @@
const migrate_name = 'access_list_client';
const logger = require('../logger').migrate;
/**
* Migrate
*
* @see http://knexjs.org/#Schema
*
* @param {Object} knex
* @param {Promise} Promise
* @returns {Promise}
*/
exports.up = function (knex/*, Promise*/) {
logger.info('[' + migrate_name + '] Migrating Up...');
return knex.schema.createTable('access_list_client', (table) => {
table.increments().primary();
table.dateTime('created_on').notNull();
table.dateTime('modified_on').notNull();
table.integer('access_list_id').notNull().unsigned();
table.string('address').notNull();
table.string('directive').notNull();
table.json('meta').notNull();
})
.then(function () {
logger.info('[' + migrate_name + '] access_list_client Table created');
return knex.schema.table('access_list', function (access_list) {
access_list.integer('satify_any').notNull().defaultTo(0);
});
})
.then(() => {
logger.info('[' + migrate_name + '] access_list Table altered');
});
};
/**
* Undo Migrate
*
* @param {Object} knex
* @param {Promise} Promise
* @returns {Promise}
*/
exports.down = function (knex/*, Promise*/) {
logger.info('[' + migrate_name + '] Migrating Down...');
return knex.schema.dropTable('access_list_client')
.then(() => {
logger.info('[' + migrate_name + '] access_list_client Table dropped');
});
};

View File

@ -0,0 +1,34 @@
const migrate_name = 'access_list_client_fix';
const logger = require('../logger').migrate;
/**
* Migrate
*
* @see http://knexjs.org/#Schema
*
* @param {Object} knex
* @param {Promise} Promise
* @returns {Promise}
*/
exports.up = function (knex/*, Promise*/) {
logger.info('[' + migrate_name + '] Migrating Up...');
return knex.schema.table('access_list', function (access_list) {
access_list.renameColumn('satify_any', 'satisfy_any');
})
.then(() => {
logger.info('[' + migrate_name + '] access_list Table altered');
});
};
/**
* Undo Migrate
*
* @param {Object} knex
* @param {Promise} Promise
* @returns {Promise}
*/
exports.down = function (knex, Promise) {
logger.warn('[' + migrate_name + '] You can\'t migrate down this one.');
return Promise.resolve(true);
};

View File

@ -0,0 +1,41 @@
const migrate_name = 'pass_auth';
const logger = require('../logger').migrate;
/**
* Migrate
*
* @see http://knexjs.org/#Schema
*
* @param {Object} knex
* @param {Promise} Promise
* @returns {Promise}
*/
exports.up = function (knex/*, Promise*/) {
logger.info('[' + migrate_name + '] Migrating Up...');
return knex.schema.table('access_list', function (access_list) {
access_list.integer('pass_auth').notNull().defaultTo(1);
})
.then(() => {
logger.info('[' + migrate_name + '] access_list Table altered');
});
};
/**
* Undo Migrate
*
* @param {Object} knex
* @param {Promise} Promise
* @returns {Promise}
*/
exports.down = function (knex/*, Promise*/) {
logger.info('[' + migrate_name + '] Migrating Down...');
return knex.schema.table('access_list', function (access_list) {
access_list.dropColumn('pass_auth');
})
.then(() => {
logger.info('[' + migrate_name + '] access_list pass_auth Column dropped');
});
};

View File

@ -0,0 +1,41 @@
const migrate_name = 'redirection_scheme';
const logger = require('../logger').migrate;
/**
* Migrate
*
* @see http://knexjs.org/#Schema
*
* @param {Object} knex
* @param {Promise} Promise
* @returns {Promise}
*/
exports.up = function (knex/*, Promise*/) {
logger.info('[' + migrate_name + '] Migrating Up...');
return knex.schema.table('redirection_host', (table) => {
table.string('forward_scheme').notNull().defaultTo('$scheme');
})
.then(function () {
logger.info('[' + migrate_name + '] redirection_host Table altered');
});
};
/**
* Undo Migrate
*
* @param {Object} knex
* @param {Promise} Promise
* @returns {Promise}
*/
exports.down = function (knex/*, Promise*/) {
logger.info('[' + migrate_name + '] Migrating Down...');
return knex.schema.table('redirection_host', (table) => {
table.dropColumn('forward_scheme');
})
.then(function () {
logger.info('[' + migrate_name + '] redirection_host Table altered');
});
};

View File

@ -0,0 +1,41 @@
const migrate_name = 'redirection_status_code';
const logger = require('../logger').migrate;
/**
* Migrate
*
* @see http://knexjs.org/#Schema
*
* @param {Object} knex
* @param {Promise} Promise
* @returns {Promise}
*/
exports.up = function (knex/*, Promise*/) {
logger.info('[' + migrate_name + '] Migrating Up...');
return knex.schema.table('redirection_host', (table) => {
table.integer('forward_http_code').notNull().unsigned().defaultTo(302);
})
.then(function () {
logger.info('[' + migrate_name + '] redirection_host Table altered');
});
};
/**
* Undo Migrate
*
* @param {Object} knex
* @param {Promise} Promise
* @returns {Promise}
*/
exports.down = function (knex/*, Promise*/) {
logger.info('[' + migrate_name + '] Migrating Down...');
return knex.schema.table('redirection_host', (table) => {
table.dropColumn('forward_http_code');
})
.then(function () {
logger.info('[' + migrate_name + '] redirection_host Table altered');
});
};

View File

@ -0,0 +1,40 @@
const migrate_name = 'stream_domain';
const logger = require('../logger').migrate;
/**
* Migrate
*
* @see http://knexjs.org/#Schema
*
* @param {Object} knex
* @param {Promise} Promise
* @returns {Promise}
*/
exports.up = function (knex/*, Promise*/) {
logger.info('[' + migrate_name + '] Migrating Up...');
return knex.schema.table('stream', (table) => {
table.renameColumn('forward_ip', 'forwarding_host');
})
.then(function () {
logger.info('[' + migrate_name + '] stream Table altered');
});
};
/**
* Undo Migrate
*
* @param {Object} knex
* @param {Promise} Promise
* @returns {Promise}
*/
exports.down = function (knex/*, Promise*/) {
logger.info('[' + migrate_name + '] Migrating Down...');
return knex.schema.table('stream', (table) => {
table.renameColumn('forwarding_host', 'forward_ip');
})
.then(function () {
logger.info('[' + migrate_name + '] stream Table altered');
});
};

View File

@ -0,0 +1,50 @@
const migrate_name = 'stream_domain';
const logger = require('../logger').migrate;
const internalNginx = require('../internal/nginx');
async function regenerateDefaultHost(knex) {
const row = await knex('setting').select('*').where('id', 'default-site').first();
if (!row) {
return Promise.resolve();
}
return internalNginx.deleteConfig('default')
.then(() => {
return internalNginx.generateConfig('default', row);
})
.then(() => {
return internalNginx.test();
})
.then(() => {
return internalNginx.reload();
});
}
/**
* Migrate
*
* @see http://knexjs.org/#Schema
*
* @param {Object} knex
* @param {Promise} Promise
* @returns {Promise}
*/
exports.up = function (knex) {
logger.info('[' + migrate_name + '] Migrating Up...');
return regenerateDefaultHost(knex);
};
/**
* Undo Migrate
*
* @param {Object} knex
* @param {Promise} Promise
* @returns {Promise}
*/
exports.down = function (knex) {
logger.info('[' + migrate_name + '] Migrating Down...');
return regenerateDefaultHost(knex);
};

View File

@ -5,13 +5,15 @@ const db = require('../db');
const Model = require('objection').Model; const Model = require('objection').Model;
const User = require('./user'); const User = require('./user');
const AccessListAuth = require('./access_list_auth'); const AccessListAuth = require('./access_list_auth');
const AccessListClient = require('./access_list_client');
const now = require('./now_helper');
Model.knex(db); Model.knex(db);
class AccessList extends Model { class AccessList extends Model {
$beforeInsert () { $beforeInsert () {
this.created_on = Model.raw('NOW()'); this.created_on = now();
this.modified_on = Model.raw('NOW()'); this.modified_on = now();
// Default for meta // Default for meta
if (typeof this.meta === 'undefined') { if (typeof this.meta === 'undefined') {
@ -20,7 +22,7 @@ class AccessList extends Model {
} }
$beforeUpdate () { $beforeUpdate () {
this.modified_on = Model.raw('NOW()'); this.modified_on = now();
} }
static get name () { static get name () {
@ -62,6 +64,17 @@ class AccessList extends Model {
qb.omit(['id', 'created_on', 'modified_on', 'access_list_id', 'meta']); qb.omit(['id', 'created_on', 'modified_on', 'access_list_id', 'meta']);
} }
}, },
clients: {
relation: Model.HasManyRelation,
modelClass: AccessListClient,
join: {
from: 'access_list.id',
to: 'access_list_client.access_list_id'
},
modify: function (qb) {
qb.omit(['id', 'created_on', 'modified_on', 'access_list_id', 'meta']);
}
},
proxy_hosts: { proxy_hosts: {
relation: Model.HasManyRelation, relation: Model.HasManyRelation,
modelClass: ProxyHost, modelClass: ProxyHost,
@ -76,6 +89,14 @@ class AccessList extends Model {
} }
}; };
} }
get satisfy() {
return this.satisfy_any ? 'satisfy any' : 'satisfy all';
}
get passauth() {
return this.pass_auth ? '' : 'proxy_set_header Authorization "";';
}
} }
module.exports = AccessList; module.exports = AccessList;

View File

@ -3,13 +3,14 @@
const db = require('../db'); const db = require('../db');
const Model = require('objection').Model; const Model = require('objection').Model;
const now = require('./now_helper');
Model.knex(db); Model.knex(db);
class AccessListAuth extends Model { class AccessListAuth extends Model {
$beforeInsert () { $beforeInsert () {
this.created_on = Model.raw('NOW()'); this.created_on = now();
this.modified_on = Model.raw('NOW()'); this.modified_on = now();
// Default for meta // Default for meta
if (typeof this.meta === 'undefined') { if (typeof this.meta === 'undefined') {
@ -18,7 +19,7 @@ class AccessListAuth extends Model {
} }
$beforeUpdate () { $beforeUpdate () {
this.modified_on = Model.raw('NOW()'); this.modified_on = now();
} }
static get name () { static get name () {

View File

@ -0,0 +1,59 @@
// Objection Docs:
// http://vincit.github.io/objection.js/
const db = require('../db');
const Model = require('objection').Model;
const now = require('./now_helper');
Model.knex(db);
class AccessListClient extends Model {
$beforeInsert () {
this.created_on = now();
this.modified_on = now();
// Default for meta
if (typeof this.meta === 'undefined') {
this.meta = {};
}
}
$beforeUpdate () {
this.modified_on = now();
}
static get name () {
return 'AccessListClient';
}
static get tableName () {
return 'access_list_client';
}
static get jsonAttributes () {
return ['meta'];
}
static get relationMappings () {
return {
access_list: {
relation: Model.HasOneRelation,
modelClass: require('./access_list'),
join: {
from: 'access_list_client.access_list_id',
to: 'access_list.id'
},
modify: function (qb) {
qb.where('access_list.is_deleted', 0);
qb.omit(['created_on', 'modified_on', 'is_deleted', 'access_list_id']);
}
}
};
}
get rule() {
return `${this.directive} ${this.address}`;
}
}
module.exports = AccessListClient;

View File

@ -4,13 +4,14 @@
const db = require('../db'); const db = require('../db');
const Model = require('objection').Model; const Model = require('objection').Model;
const User = require('./user'); const User = require('./user');
const now = require('./now_helper');
Model.knex(db); Model.knex(db);
class AuditLog extends Model { class AuditLog extends Model {
$beforeInsert () { $beforeInsert () {
this.created_on = Model.raw('NOW()'); this.created_on = now();
this.modified_on = Model.raw('NOW()'); this.modified_on = now();
// Default for meta // Default for meta
if (typeof this.meta === 'undefined') { if (typeof this.meta === 'undefined') {
@ -19,7 +20,7 @@ class AuditLog extends Model {
} }
$beforeUpdate () { $beforeUpdate () {
this.modified_on = Model.raw('NOW()'); this.modified_on = now();
} }
static get name () { static get name () {

View File

@ -5,6 +5,7 @@ const bcrypt = require('bcrypt');
const db = require('../db'); const db = require('../db');
const Model = require('objection').Model; const Model = require('objection').Model;
const User = require('./user'); const User = require('./user');
const now = require('./now_helper');
Model.knex(db); Model.knex(db);
@ -24,8 +25,8 @@ function encryptPassword () {
class Auth extends Model { class Auth extends Model {
$beforeInsert (queryContext) { $beforeInsert (queryContext) {
this.created_on = Model.raw('NOW()'); this.created_on = now();
this.modified_on = Model.raw('NOW()'); this.modified_on = now();
// Default for meta // Default for meta
if (typeof this.meta === 'undefined') { if (typeof this.meta === 'undefined') {
@ -36,7 +37,7 @@ class Auth extends Model {
} }
$beforeUpdate (queryContext) { $beforeUpdate (queryContext) {
this.modified_on = Model.raw('NOW()'); this.modified_on = now();
return encryptPassword.apply(this, queryContext); return encryptPassword.apply(this, queryContext);
} }

View File

@ -4,17 +4,18 @@
const db = require('../db'); const db = require('../db');
const Model = require('objection').Model; const Model = require('objection').Model;
const User = require('./user'); const User = require('./user');
const now = require('./now_helper');
Model.knex(db); Model.knex(db);
class Certificate extends Model { class Certificate extends Model {
$beforeInsert () { $beforeInsert () {
this.created_on = Model.raw('NOW()'); this.created_on = now();
this.modified_on = Model.raw('NOW()'); this.modified_on = now();
// Default for expires_on // Default for expires_on
if (typeof this.expires_on === 'undefined') { if (typeof this.expires_on === 'undefined') {
this.expires_on = Model.raw('NOW()'); this.expires_on = now();
} }
// Default for domain_names // Default for domain_names
@ -31,7 +32,7 @@ class Certificate extends Model {
} }
$beforeUpdate () { $beforeUpdate () {
this.modified_on = Model.raw('NOW()'); this.modified_on = now();
// Sort domain_names // Sort domain_names
if (typeof this.domain_names !== 'undefined') { if (typeof this.domain_names !== 'undefined') {

View File

@ -5,13 +5,14 @@ const db = require('../db');
const Model = require('objection').Model; const Model = require('objection').Model;
const User = require('./user'); const User = require('./user');
const Certificate = require('./certificate'); const Certificate = require('./certificate');
const now = require('./now_helper');
Model.knex(db); Model.knex(db);
class DeadHost extends Model { class DeadHost extends Model {
$beforeInsert () { $beforeInsert () {
this.created_on = Model.raw('NOW()'); this.created_on = now();
this.modified_on = Model.raw('NOW()'); this.modified_on = now();
// Default for domain_names // Default for domain_names
if (typeof this.domain_names === 'undefined') { if (typeof this.domain_names === 'undefined') {
@ -27,7 +28,7 @@ class DeadHost extends Model {
} }
$beforeUpdate () { $beforeUpdate () {
this.modified_on = Model.raw('NOW()'); this.modified_on = now();
// Sort domain_names // Sort domain_names
if (typeof this.domain_names !== 'undefined') { if (typeof this.domain_names !== 'undefined') {

View File

@ -0,0 +1,13 @@
const db = require('../db');
const config = require('config');
const Model = require('objection').Model;
Model.knex(db);
module.exports = function () {
if (config.database.knex && config.database.knex.client === 'sqlite3') {
return Model.raw('datetime(\'now\',\'localtime\')');
} else {
return Model.raw('NOW()');
}
};

View File

@ -6,13 +6,14 @@ const Model = require('objection').Model;
const User = require('./user'); const User = require('./user');
const AccessList = require('./access_list'); const AccessList = require('./access_list');
const Certificate = require('./certificate'); const Certificate = require('./certificate');
const now = require('./now_helper');
Model.knex(db); Model.knex(db);
class ProxyHost extends Model { class ProxyHost extends Model {
$beforeInsert () { $beforeInsert () {
this.created_on = Model.raw('NOW()'); this.created_on = now();
this.modified_on = Model.raw('NOW()'); this.modified_on = now();
// Default for domain_names // Default for domain_names
if (typeof this.domain_names === 'undefined') { if (typeof this.domain_names === 'undefined') {
@ -28,7 +29,7 @@ class ProxyHost extends Model {
} }
$beforeUpdate () { $beforeUpdate () {
this.modified_on = Model.raw('NOW()'); this.modified_on = now();
// Sort domain_names // Sort domain_names
if (typeof this.domain_names !== 'undefined') { if (typeof this.domain_names !== 'undefined') {

View File

@ -5,13 +5,14 @@ const db = require('../db');
const Model = require('objection').Model; const Model = require('objection').Model;
const User = require('./user'); const User = require('./user');
const Certificate = require('./certificate'); const Certificate = require('./certificate');
const now = require('./now_helper');
Model.knex(db); Model.knex(db);
class RedirectionHost extends Model { class RedirectionHost extends Model {
$beforeInsert () { $beforeInsert () {
this.created_on = Model.raw('NOW()'); this.created_on = now();
this.modified_on = Model.raw('NOW()'); this.modified_on = now();
// Default for domain_names // Default for domain_names
if (typeof this.domain_names === 'undefined') { if (typeof this.domain_names === 'undefined') {
@ -27,7 +28,7 @@ class RedirectionHost extends Model {
} }
$beforeUpdate () { $beforeUpdate () {
this.modified_on = Model.raw('NOW()'); this.modified_on = now();
// Sort domain_names // Sort domain_names
if (typeof this.domain_names !== 'undefined') { if (typeof this.domain_names !== 'undefined') {

View File

@ -4,13 +4,14 @@
const db = require('../db'); const db = require('../db');
const Model = require('objection').Model; const Model = require('objection').Model;
const User = require('./user'); const User = require('./user');
const now = require('./now_helper');
Model.knex(db); Model.knex(db);
class Stream extends Model { class Stream extends Model {
$beforeInsert () { $beforeInsert () {
this.created_on = Model.raw('NOW()'); this.created_on = now();
this.modified_on = Model.raw('NOW()'); this.modified_on = now();
// Default for meta // Default for meta
if (typeof this.meta === 'undefined') { if (typeof this.meta === 'undefined') {
@ -19,7 +20,7 @@ class Stream extends Model {
} }
$beforeUpdate () { $beforeUpdate () {
this.modified_on = Model.raw('NOW()'); this.modified_on = now();
} }
static get name () { static get name () {

View File

@ -4,15 +4,23 @@
*/ */
const _ = require('lodash'); const _ = require('lodash');
const config = require('config');
const jwt = require('jsonwebtoken'); const jwt = require('jsonwebtoken');
const crypto = require('crypto'); const crypto = require('crypto');
const error = require('../lib/error'); const error = require('../lib/error');
const ALGO = 'RS256'; const ALGO = 'RS256';
let public_key = null;
let private_key = null;
function checkJWTKeyPair() {
if (!public_key || !private_key) {
let config = require('config');
public_key = config.get('jwt.pub');
private_key = config.get('jwt.key');
}
}
module.exports = function () { module.exports = function () {
const public_key = config.get('jwt.pub');
const private_key = config.get('jwt.key');
let token_data = {}; let token_data = {};
@ -32,6 +40,8 @@ module.exports = function () {
.toString('base64') .toString('base64')
.substr(-8); .substr(-8);
checkJWTKeyPair();
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
jwt.sign(payload, private_key, options, (err, token) => { jwt.sign(payload, private_key, options, (err, token) => {
if (err) { if (err) {
@ -53,6 +63,7 @@ module.exports = function () {
*/ */
load: function (token) { load: function (token) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
checkJWTKeyPair();
try { try {
if (!token || token === null || token === 'null') { if (!token || token === null || token === 'null') {
reject(new error.AuthError('Empty token')); reject(new error.AuthError('Empty token'));

View File

@ -4,13 +4,14 @@
const db = require('../db'); const db = require('../db');
const Model = require('objection').Model; const Model = require('objection').Model;
const UserPermission = require('./user_permission'); const UserPermission = require('./user_permission');
const now = require('./now_helper');
Model.knex(db); Model.knex(db);
class User extends Model { class User extends Model {
$beforeInsert () { $beforeInsert () {
this.created_on = Model.raw('NOW()'); this.created_on = now();
this.modified_on = Model.raw('NOW()'); this.modified_on = now();
// Default for roles // Default for roles
if (typeof this.roles === 'undefined') { if (typeof this.roles === 'undefined') {
@ -19,7 +20,7 @@ class User extends Model {
} }
$beforeUpdate () { $beforeUpdate () {
this.modified_on = Model.raw('NOW()'); this.modified_on = now();
} }
static get name () { static get name () {

View File

@ -3,17 +3,18 @@
const db = require('../db'); const db = require('../db');
const Model = require('objection').Model; const Model = require('objection').Model;
const now = require('./now_helper');
Model.knex(db); Model.knex(db);
class UserPermission extends Model { class UserPermission extends Model {
$beforeInsert () { $beforeInsert () {
this.created_on = Model.raw('NOW()'); this.created_on = now();
this.modified_on = Model.raw('NOW()'); this.modified_on = now();
} }
$beforeUpdate () { $beforeUpdate () {
this.modified_on = Model.raw('NOW()'); this.modified_on = now();
} }
static get name () { static get name () {

View File

@ -4,32 +4,30 @@
"description": "A beautiful interface for creating Nginx endpoints", "description": "A beautiful interface for creating Nginx endpoints",
"main": "js/index.js", "main": "js/index.js",
"dependencies": { "dependencies": {
"ajv": "^6.11.0", "ajv": "^6.12.0",
"archiver": "^5.3.0",
"batchflow": "^0.4.0", "batchflow": "^0.4.0",
"bcrypt": "^3.0.8", "bcrypt": "^5.0.0",
"body-parser": "^1.19.0", "body-parser": "^1.19.0",
"compression": "^1.7.4", "compression": "^1.7.4",
"config": "^3.2.5", "config": "^3.3.1",
"diskdb": "^0.1.17",
"express": "^4.17.1", "express": "^4.17.1",
"express-fileupload": "^1.1.6", "express-fileupload": "^1.1.9",
"gravatar": "^1.8.0", "gravatar": "^1.8.0",
"html-entities": "^1.2.1", "json-schema-ref-parser": "^8.0.0",
"json-schema-ref-parser": "^7.1.3",
"jsonwebtoken": "^8.5.1", "jsonwebtoken": "^8.5.1",
"knex": "^0.20.10", "knex": "^0.20.13",
"liquidjs": "^9.7.1", "liquidjs": "^9.11.10",
"lodash": "^4.17.15", "lodash": "^4.17.21",
"moment": "^2.24.0", "moment": "^2.29.4",
"mysql": "^2.18.1", "mysql": "^2.18.1",
"node-rsa": "^1.0.7", "node-rsa": "^1.0.8",
"nodemon": "^2.0.2", "nodemon": "^2.0.2",
"objection": "^2.1.3", "objection": "^2.2.16",
"path": "^0.12.7", "path": "^0.12.7",
"restler": "^3.4.0",
"signale": "^1.4.0", "signale": "^1.4.0",
"temp-write": "^4.0.0", "sqlite3": "^4.1.1",
"unix-timestamp": "^0.2.0" "temp-write": "^4.0.0"
}, },
"signale": { "signale": {
"displayDate": true, "displayDate": true,
@ -40,6 +38,6 @@
"devDependencies": { "devDependencies": {
"eslint": "^6.8.0", "eslint": "^6.8.0",
"eslint-plugin-align-assignments": "^1.1.2", "eslint-plugin-align-assignments": "^1.1.2",
"prettier": "^1.19.1" "prettier": "^2.0.4"
} }
} }

View File

@ -58,6 +58,7 @@ router
.post((req, res, next) => { .post((req, res, next) => {
apiValidator({$ref: 'endpoints/certificates#/links/1/schema'}, req.body) apiValidator({$ref: 'endpoints/certificates#/links/1/schema'}, req.body)
.then((payload) => { .then((payload) => {
req.setTimeout(900000); // 15 minutes timeout
return internalCertificate.create(res.locals.access, payload); return internalCertificate.create(res.locals.access, payload);
}) })
.then((result) => { .then((result) => {
@ -67,6 +68,32 @@ router
.catch(next); .catch(next);
}); });
/**
* Test HTTP challenge for domains
*
* /api/nginx/certificates/test-http
*/
router
.route('/test-http')
.options((req, res) => {
res.sendStatus(204);
})
.all(jwtdecode())
/**
* GET /api/nginx/certificates/test-http
*
* Test HTTP challenge for domains
*/
.get((req, res, next) => {
internalCertificate.testHttpsChallenge(res.locals.access, JSON.parse(req.query.domains))
.then((result) => {
res.status(200)
.send(result);
})
.catch(next);
});
/** /**
* Specific certificate * Specific certificate
* *
@ -197,6 +224,7 @@ router
* Renew certificate * Renew certificate
*/ */
.post((req, res, next) => { .post((req, res, next) => {
req.setTimeout(900000); // 15 minutes timeout
internalCertificate.renew(res.locals.access, { internalCertificate.renew(res.locals.access, {
id: parseInt(req.params.certificate_id, 10) id: parseInt(req.params.certificate_id, 10)
}) })
@ -207,6 +235,34 @@ router
.catch(next); .catch(next);
}); });
/**
* Download LE Certs
*
* /api/nginx/certificates/123/download
*/
router
.route('/:certificate_id/download')
.options((req, res) => {
res.sendStatus(204);
})
.all(jwtdecode())
/**
* GET /api/nginx/certificates/123/download
*
* Renew certificate
*/
.get((req, res, next) => {
internalCertificate.download(res.locals.access, {
id: parseInt(req.params.certificate_id, 10)
})
.then((result) => {
res.status(200)
.download(result.fileName);
})
.catch(next);
});
/** /**
* Validate Certs before saving * Validate Certs before saving
* *

View File

@ -153,7 +153,7 @@
"example": "john@example.com", "example": "john@example.com",
"format": "email", "format": "email",
"type": "string", "type": "string",
"minLength": 8, "minLength": 6,
"maxLength": 100 "maxLength": 100
}, },
"password": { "password": {
@ -179,6 +179,19 @@
"pattern": "^(?:\\*\\.)?(?:[^.*]+\\.?)+[^.]$" "pattern": "^(?:\\*\\.)?(?:[^.*]+\\.?)+[^.]$"
} }
}, },
"http_code": {
"description": "Redirect HTTP Status Code",
"example": 302,
"type": "integer",
"minimum": 300,
"maximum": 308
},
"scheme": {
"description": "RFC Protocol",
"example": "HTTPS or $scheme",
"type": "string",
"minLength": 4
},
"enabled": { "enabled": {
"description": "Is Enabled", "description": "Is Enabled",
"example": true, "example": true,

View File

@ -19,6 +19,32 @@
"type": "string", "type": "string",
"description": "Name of the Access List" "description": "Name of the Access List"
}, },
"directive": {
"type": "string",
"enum": ["allow", "deny"]
},
"address": {
"oneOf": [
{
"type": "string",
"pattern": "^([0-9]{1,3}\\.){3}[0-9]{1,3}(/([0-9]|[1-2][0-9]|3[0-2]))?$"
},
{
"type": "string",
"pattern": "^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*(/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8]))?$"
},
{
"type": "string",
"pattern": "^all$"
}
]
},
"satisfy_any": {
"type": "boolean"
},
"pass_auth": {
"type": "boolean"
},
"meta": { "meta": {
"type": "object" "type": "object"
} }
@ -71,16 +97,20 @@
"schema": { "schema": {
"type": "object", "type": "object",
"additionalProperties": false, "additionalProperties": false,
"required": [ "required": ["name"],
"name"
],
"properties": { "properties": {
"name": { "name": {
"$ref": "#/definitions/name" "$ref": "#/definitions/name"
}, },
"satisfy_any": {
"$ref": "#/definitions/satisfy_any"
},
"pass_auth": {
"$ref": "#/definitions/pass_auth"
},
"items": { "items": {
"type": "array", "type": "array",
"minItems": 1, "minItems": 0,
"items": { "items": {
"type": "object", "type": "object",
"additionalProperties": false, "additionalProperties": false,
@ -96,6 +126,22 @@
} }
} }
}, },
"clients": {
"type": "array",
"minItems": 0,
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"address": {
"$ref": "#/definitions/address"
},
"directive": {
"$ref": "#/definitions/directive"
}
}
}
},
"meta": { "meta": {
"$ref": "#/definitions/meta" "$ref": "#/definitions/meta"
} }
@ -124,9 +170,15 @@
"name": { "name": {
"$ref": "#/definitions/name" "$ref": "#/definitions/name"
}, },
"satisfy_any": {
"$ref": "#/definitions/satisfy_any"
},
"pass_auth": {
"$ref": "#/definitions/pass_auth"
},
"items": { "items": {
"type": "array", "type": "array",
"minItems": 1, "minItems": 0,
"items": { "items": {
"type": "object", "type": "object",
"additionalProperties": false, "additionalProperties": false,
@ -141,6 +193,22 @@
} }
} }
} }
},
"clients": {
"type": "array",
"minItems": 0,
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"address": {
"$ref": "#/definitions/address"
},
"directive": {
"$ref": "#/definitions/directive"
}
}
}
} }
} }
}, },

View File

@ -41,6 +41,24 @@
}, },
"letsencrypt_agree": { "letsencrypt_agree": {
"type": "boolean" "type": "boolean"
},
"dns_challenge": {
"type": "boolean"
},
"dns_provider": {
"type": "string"
},
"dns_provider_credentials": {
"type": "string"
},
"propagation_seconds": {
"anyOf": [
{
"type": "integer",
"minimum": 0
}
]
} }
} }
} }
@ -139,6 +157,17 @@
"targetSchema": { "targetSchema": {
"type": "boolean" "type": "boolean"
} }
},
{
"title": "Test HTTP Challenge",
"description": "Tests whether the HTTP challenge should work",
"href": "/nginx/certificates/{definitions.identity.example}/test-http",
"access": "private",
"method": "GET",
"rel": "info",
"http_header": {
"$ref": "../examples.json#/definitions/auth_header"
}
} }
] ]
} }

View File

@ -25,7 +25,7 @@
"forward_host": { "forward_host": {
"type": "string", "type": "string",
"minLength": 1, "minLength": 1,
"maxLength": 50 "maxLength": 255
}, },
"forward_port": { "forward_port": {
"type": "integer", "type": "integer",

View File

@ -18,6 +18,12 @@
"domain_names": { "domain_names": {
"$ref": "../definitions.json#/definitions/domain_names" "$ref": "../definitions.json#/definitions/domain_names"
}, },
"forward_http_code": {
"$ref": "../definitions.json#/definitions/http_code"
},
"forward_scheme": {
"$ref": "../definitions.json#/definitions/scheme"
},
"forward_domain_name": { "forward_domain_name": {
"$ref": "../definitions.json#/definitions/domain_name" "$ref": "../definitions.json#/definitions/domain_name"
}, },
@ -67,6 +73,12 @@
"domain_names": { "domain_names": {
"$ref": "#/definitions/domain_names" "$ref": "#/definitions/domain_names"
}, },
"forward_http_code": {
"$ref": "#/definitions/forward_http_code"
},
"forward_scheme": {
"$ref": "#/definitions/forward_scheme"
},
"forward_domain_name": { "forward_domain_name": {
"$ref": "#/definitions/forward_domain_name" "$ref": "#/definitions/forward_domain_name"
}, },
@ -134,12 +146,20 @@
"additionalProperties": false, "additionalProperties": false,
"required": [ "required": [
"domain_names", "domain_names",
"forward_scheme",
"forward_http_code",
"forward_domain_name" "forward_domain_name"
], ],
"properties": { "properties": {
"domain_names": { "domain_names": {
"$ref": "#/definitions/domain_names" "$ref": "#/definitions/domain_names"
}, },
"forward_http_code": {
"$ref": "#/definitions/forward_http_code"
},
"forward_scheme": {
"$ref": "#/definitions/forward_scheme"
},
"forward_domain_name": { "forward_domain_name": {
"$ref": "#/definitions/forward_domain_name" "$ref": "#/definitions/forward_domain_name"
}, },
@ -195,6 +215,12 @@
"domain_names": { "domain_names": {
"$ref": "#/definitions/domain_names" "$ref": "#/definitions/domain_names"
}, },
"forward_http_code": {
"$ref": "#/definitions/forward_http_code"
},
"forward_scheme": {
"$ref": "#/definitions/forward_scheme"
},
"forward_domain_name": { "forward_domain_name": {
"$ref": "#/definitions/forward_domain_name" "$ref": "#/definitions/forward_domain_name"
}, },

View File

@ -20,10 +20,21 @@
"minimum": 1, "minimum": 1,
"maximum": 65535 "maximum": 65535
}, },
"forward_ip": { "forwarding_host": {
"anyOf": [
{
"$ref": "../definitions.json#/definitions/domain_name"
},
{
"type": "string", "type": "string",
"format": "ipv4" "format": "ipv4"
}, },
{
"type": "string",
"format": "ipv6"
}
]
},
"forwarding_port": { "forwarding_port": {
"type": "integer", "type": "integer",
"minimum": 1, "minimum": 1,
@ -55,8 +66,8 @@
"incoming_port": { "incoming_port": {
"$ref": "#/definitions/incoming_port" "$ref": "#/definitions/incoming_port"
}, },
"forward_ip": { "forwarding_host": {
"$ref": "#/definitions/forward_ip" "$ref": "#/definitions/forwarding_host"
}, },
"forwarding_port": { "forwarding_port": {
"$ref": "#/definitions/forwarding_port" "$ref": "#/definitions/forwarding_port"
@ -107,15 +118,15 @@
"additionalProperties": false, "additionalProperties": false,
"required": [ "required": [
"incoming_port", "incoming_port",
"forward_ip", "forwarding_host",
"forwarding_port" "forwarding_port"
], ],
"properties": { "properties": {
"incoming_port": { "incoming_port": {
"$ref": "#/definitions/incoming_port" "$ref": "#/definitions/incoming_port"
}, },
"forward_ip": { "forwarding_host": {
"$ref": "#/definitions/forward_ip" "$ref": "#/definitions/forwarding_host"
}, },
"forwarding_port": { "forwarding_port": {
"$ref": "#/definitions/forwarding_port" "$ref": "#/definitions/forwarding_port"
@ -154,8 +165,8 @@
"incoming_port": { "incoming_port": {
"$ref": "#/definitions/incoming_port" "$ref": "#/definitions/incoming_port"
}, },
"forward_ip": { "forwarding_host": {
"$ref": "#/definitions/forward_ip" "$ref": "#/definitions/forwarding_host"
}, },
"forwarding_port": { "forwarding_port": {
"$ref": "#/definitions/forwarding_port" "$ref": "#/definitions/forwarding_port"

View File

@ -2,12 +2,21 @@ const fs = require('fs');
const NodeRSA = require('node-rsa'); const NodeRSA = require('node-rsa');
const config = require('config'); const config = require('config');
const logger = require('./logger').setup; const logger = require('./logger').setup;
const certificateModel = require('./models/certificate');
const userModel = require('./models/user'); const userModel = require('./models/user');
const userPermissionModel = require('./models/user_permission'); const userPermissionModel = require('./models/user_permission');
const utils = require('./lib/utils');
const authModel = require('./models/auth'); const authModel = require('./models/auth');
const settingModel = require('./models/setting');
const dns_plugins = require('./global/certbot-dns-plugins');
const debug_mode = process.env.NODE_ENV !== 'production' || !!process.env.DEBUG; const debug_mode = process.env.NODE_ENV !== 'production' || !!process.env.DEBUG;
module.exports = function () { /**
* Creates a new JWT RSA Keypair if not alread set on the config
*
* @returns {Promise}
*/
const setupJwt = () => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
// Now go and check if the jwt gpg keys have been created and if not, create them // Now go and check if the jwt gpg keys have been created and if not, create them
if (!config.has('jwt') || !config.has('jwt.key') || !config.has('jwt.pub')) { if (!config.has('jwt') || !config.has('jwt.key') || !config.has('jwt.pub')) {
@ -27,12 +36,12 @@ module.exports = function () {
} }
// Now create the keys and save them in the config. // Now create the keys and save them in the config.
let key = new NodeRSA({b: 2048}); let key = new NodeRSA({ b: 2048 });
key.generateKeyPair(); key.generateKeyPair();
config_data.jwt = { config_data.jwt = {
key: key.exportKey('private').toString(), key: key.exportKey('private').toString(),
pub: key.exportKey('public').toString() pub: key.exportKey('public').toString(),
}; };
// Write config // Write config
@ -42,12 +51,10 @@ module.exports = function () {
reject(err); reject(err);
} else { } else {
logger.info('Wrote JWT key pair to config file: ' + filename); logger.info('Wrote JWT key pair to config file: ' + filename);
delete require.cache[require.resolve('config')];
logger.warn('Restarting interface to apply new configuration'); resolve();
process.exit(0);
} }
}); });
} else { } else {
// JWT key pair exists // JWT key pair exists
if (debug_mode) { if (debug_mode) {
@ -56,14 +63,20 @@ module.exports = function () {
resolve(); resolve();
} }
}) });
.then(() => { };
/**
* Creates a default admin users if one doesn't already exist in the database
*
* @returns {Promise}
*/
const setupDefaultUser = () => {
return userModel return userModel
.query() .query()
.select(userModel.raw('COUNT(`id`) as `count`')) .select(userModel.raw('COUNT(`id`) as `count`'))
.where('is_deleted', 0) .where('is_deleted', 0)
.first(); .first()
})
.then((row) => { .then((row) => {
if (!row.count) { if (!row.count) {
// Create a new user and set password // Create a new user and set password
@ -75,7 +88,7 @@ module.exports = function () {
name: 'Administrator', name: 'Administrator',
nickname: 'Admin', nickname: 'Admin',
avatar: '', avatar: '',
roles: ['admin'] roles: ['admin'],
}; };
return userModel return userModel
@ -88,12 +101,10 @@ module.exports = function () {
user_id: user.id, user_id: user.id,
type: 'password', type: 'password',
secret: 'changeme', secret: 'changeme',
meta: {} meta: {},
}) })
.then(() => { .then(() => {
return userPermissionModel return userPermissionModel.query().insert({
.query()
.insert({
user_id: user.id, user_id: user.id,
visibility: 'all', visibility: 'all',
proxy_hosts: 'manage', proxy_hosts: 'manage',
@ -101,15 +112,131 @@ module.exports = function () {
dead_hosts: 'manage', dead_hosts: 'manage',
streams: 'manage', streams: 'manage',
access_lists: 'manage', access_lists: 'manage',
certificates: 'manage' certificates: 'manage',
}); });
}); });
}) })
.then(() => { .then(() => {
logger.info('Initial setup completed'); logger.info('Initial admin setup completed');
}); });
} else if (debug_mode) { } else if (debug_mode) {
logger.debug('Admin user setup not required'); logger.debug('Admin user setup not required');
} }
}); });
}; };
/**
* Creates default settings if they don't already exist in the database
*
* @returns {Promise}
*/
const setupDefaultSettings = () => {
return settingModel
.query()
.select(settingModel.raw('COUNT(`id`) as `count`'))
.where({id: 'default-site'})
.first()
.then((row) => {
if (!row.count) {
settingModel
.query()
.insert({
id: 'default-site',
name: 'Default Site',
description: 'What to show when Nginx is hit with an unknown Host',
value: 'congratulations',
meta: {},
})
.then(() => {
logger.info('Default settings added');
});
}
if (debug_mode) {
logger.debug('Default setting setup not required');
}
});
};
/**
* Installs all Certbot plugins which are required for an installed certificate
*
* @returns {Promise}
*/
const setupCertbotPlugins = () => {
return certificateModel
.query()
.where('is_deleted', 0)
.andWhere('provider', 'letsencrypt')
.then((certificates) => {
if (certificates && certificates.length) {
let plugins = [];
let promises = [];
let install_cloudflare_plugin = false;
certificates.map(function (certificate) {
if (certificate.meta && certificate.meta.dns_challenge === true) {
const dns_plugin = dns_plugins[certificate.meta.dns_provider];
if (dns_plugin.package_name === 'certbot-dns-cloudflare') {
install_cloudflare_plugin = true;
} else {
const packages_to_install = `${dns_plugin.package_name}${dns_plugin.version_requirement || ''} ${dns_plugin.dependencies}`;
if (plugins.indexOf(packages_to_install) === -1) plugins.push(packages_to_install);
}
// Make sure credentials file exists
const credentials_loc = '/etc/letsencrypt/credentials/credentials-' + certificate.id;
// Escape single quotes and backslashes
const escapedCredentials = certificate.meta.dns_provider_credentials.replaceAll('\'', '\\\'').replaceAll('\\', '\\\\');
const credentials_cmd = '[ -f \'' + credentials_loc + '\' ] || { mkdir -p /etc/letsencrypt/credentials 2> /dev/null; echo \'' + escapedCredentials + '\' > \'' + credentials_loc + '\' && chmod 600 \'' + credentials_loc + '\'; }';
promises.push(utils.exec(credentials_cmd));
}
});
if (plugins.length) {
const install_cmd = 'pip install ' + plugins.join(' ');
promises.push(utils.exec(install_cmd));
}
if (install_cloudflare_plugin) {
promises.push(utils.exec('pip install certbot-dns-cloudflare --index-url https://www.piwheels.org/simple --prefer-binary'));
}
if (promises.length) {
return Promise.all(promises)
.then(() => {
logger.info('Added Certbot plugins ' + plugins.join(', '));
});
}
}
});
};
/**
* Starts a timer to call run the logrotation binary every two days
* @returns {Promise}
*/
const setupLogrotation = () => {
const intervalTimeout = 1000 * 60 * 60 * 24 * 2; // 2 days
const runLogrotate = async () => {
try {
await utils.exec('logrotate /etc/logrotate.d/nginx-proxy-manager');
logger.info('Logrotate completed.');
} catch (e) { logger.warn(e); }
};
logger.info('Logrotate Timer initialized');
setInterval(runLogrotate, intervalTimeout);
// And do this now as well
return runLogrotate();
};
module.exports = function () {
return setupJwt()
.then(setupDefaultUser)
.then(setupDefaultSettings)
.then(setupCertbotPlugins)
.then(setupLogrotation);
};

View File

@ -1,8 +1,8 @@
{% if certificate and certificate_id > 0 -%} {% if certificate and certificate_id > 0 -%}
{% if ssl_forced == 1 or ssl_forced == true %} {% if ssl_forced == 1 or ssl_forced == true %}
{% if hsts_enabled == 1 or hsts_enabled == true %} {% if hsts_enabled == 1 or hsts_enabled == true %}
# HSTS (ngx_http_headers_module is required) (31536000 seconds = 1 year) # HSTS (ngx_http_headers_module is required) (63072000 seconds = 2 years)
add_header Strict-Transport-Security "max-age=31536000;{% if hsts_subdomains == 1 or hsts_subdomains == true -%} includeSubDomains;{% endif %} preload" always; add_header Strict-Transport-Security "max-age=63072000;{% if hsts_subdomains == 1 or hsts_subdomains == true -%} includeSubDomains;{% endif %} preload" always;
{% endif %} {% endif %}
{% endif %} {% endif %}
{% endif %} {% endif %}

View File

@ -1,5 +1,15 @@
listen 80; listen 80;
{% if ipv6 -%}
listen [::]:80;
{% else -%}
#listen [::]:80;
{% endif %}
{% if certificate -%} {% if certificate -%}
listen 443 ssl{% if http2_support %} http2{% endif %}; listen 443 ssl{% if http2_support %} http2{% endif %};
{% if ipv6 -%}
listen [::]:443 ssl{% if http2_support %} http2{% endif %};
{% else -%}
#listen [::]:443;
{% endif %}
{% endif %} {% endif %}
server_name {{ domain_names | join: " " }}; server_name {{ domain_names | join: " " }};

View File

@ -3,7 +3,43 @@
proxy_set_header X-Forwarded-Scheme $scheme; proxy_set_header X-Forwarded-Scheme $scheme;
proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass {{ forward_scheme }}://{{ forward_host }}:{{ forward_port }}{{ forward_path }}; proxy_pass {{ forward_scheme }}://{{ forward_host }}:{{ forward_port }}{{ forward_path }};
{% if access_list_id > 0 %}
{% if access_list.items.length > 0 %}
# Authorization
auth_basic "Authorization required";
auth_basic_user_file /data/access/{{ access_list_id }};
{{ access_list.passauth }}
{% endif %}
# Access Rules
{% for client in access_list.clients %}
{{- client.rule -}};
{% endfor %}deny all;
# Access checks must...
{% if access_list.satisfy %}
{{ access_list.satisfy }};
{% endif %}
{% endif %}
{% include "_assets.conf" %}
{% include "_exploits.conf" %}
{% include "_forced_ssl.conf" %}
{% include "_hsts.conf" %}
{% if allow_websocket_upgrade == 1 or allow_websocket_upgrade == true %}
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
proxy_http_version 1.1;
{% endif %}
{{ advanced_config }} {{ advanced_config }}
} }

View File

@ -5,14 +5,15 @@ server {
{% include "_listen.conf" %} {% include "_listen.conf" %}
{% include "_certificates.conf" %} {% include "_certificates.conf" %}
{% include "_hsts.conf" %} {% include "_hsts.conf" %}
{% include "_forced_ssl.conf" %}
access_log /data/logs/dead_host-{{ id }}.log standard; access_log /data/logs/dead-host-{{ id }}_access.log standard;
error_log /data/logs/dead-host-{{ id }}_error.log warn;
{{ advanced_config }} {{ advanced_config }}
{% if use_default_location %} {% if use_default_location %}
location / { location / {
{% include "_forced_ssl.conf" %}
{% include "_hsts.conf" %} {% include "_hsts.conf" %}
return 404; return 404;
} }

View File

@ -6,10 +6,18 @@
{%- else %} {%- else %}
server { server {
listen 80 default; listen 80 default;
{% if ipv6 -%}
listen [::]:80 default;
{% else -%}
#listen [::]:80 default;
{% endif %}
server_name default-host.localhost; server_name default-host.localhost;
access_log /data/logs/default_host.log combined; access_log /data/logs/default-host_access.log combined;
error_log /data/logs/default-host_error.log warn;
{% include "_exploits.conf" %} {% include "_exploits.conf" %}
include conf.d/include/letsencrypt-acme-challenge.conf;
{%- if value == "404" %} {%- if value == "404" %}
location / { location / {
return 404; return 404;

View File

@ -2,9 +2,14 @@
server { server {
listen 80; listen 80;
{% if ipv6 -%}
listen [::]:80;
{% endif %}
server_name {{ domain_names | join: " " }}; server_name {{ domain_names | join: " " }};
access_log /data/logs/letsencrypt-requests.log standard; access_log /data/logs/letsencrypt-requests_access.log standard;
error_log /data/logs/letsencrypt-requests_error.log warn;
include conf.d/include/letsencrypt-acme-challenge.conf; include conf.d/include/letsencrypt-acme-challenge.conf;

View File

@ -11,8 +11,16 @@ server {
{% include "_assets.conf" %} {% include "_assets.conf" %}
{% include "_exploits.conf" %} {% include "_exploits.conf" %}
{% include "_hsts.conf" %} {% include "_hsts.conf" %}
{% include "_forced_ssl.conf" %}
access_log /data/logs/proxy_host-{{ id }}.log proxy; {% if allow_websocket_upgrade == 1 or allow_websocket_upgrade == true %}
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
proxy_http_version 1.1;
{% endif %}
access_log /data/logs/proxy-host-{{ id }}_access.log proxy;
error_log /data/logs/proxy-host-{{ id }}_error.log warn;
{{ advanced_config }} {{ advanced_config }}
@ -21,13 +29,28 @@ server {
{% if use_default_location %} {% if use_default_location %}
location / { location / {
{%- if access_list_id > 0 -%}
# Access List {% if access_list_id > 0 %}
{% if access_list.items.length > 0 %}
# Authorization
auth_basic "Authorization required"; auth_basic "Authorization required";
auth_basic_user_file /data/access/{{ access_list_id }}; auth_basic_user_file /data/access/{{ access_list_id }};
{%- endif %}
{% include "_forced_ssl.conf" %} {{ access_list.passauth }}
{% endif %}
# Access Rules
{% for client in access_list.clients %}
{{- client.rule -}};
{% endfor %}deny all;
# Access checks must...
{% if access_list.satisfy %}
{{ access_list.satisfy }};
{% endif %}
{% endif %}
{% include "_hsts.conf" %} {% include "_hsts.conf" %}
{% if allow_websocket_upgrade == 1 or allow_websocket_upgrade == true %} {% if allow_websocket_upgrade == 1 or allow_websocket_upgrade == true %}

View File

@ -7,20 +7,21 @@ server {
{% include "_assets.conf" %} {% include "_assets.conf" %}
{% include "_exploits.conf" %} {% include "_exploits.conf" %}
{% include "_hsts.conf" %} {% include "_hsts.conf" %}
{% include "_forced_ssl.conf" %}
access_log /data/logs/redirection_host-{{ id }}.log standard; access_log /data/logs/redirection-host-{{ id }}_access.log standard;
error_log /data/logs/redirection-host-{{ id }}_error.log warn;
{{ advanced_config }} {{ advanced_config }}
{% if use_default_location %} {% if use_default_location %}
location / { location / {
{% include "_forced_ssl.conf" %}
{% include "_hsts.conf" %} {% include "_hsts.conf" %}
{% if preserve_path == 1 or preserve_path == true %} {% if preserve_path == 1 or preserve_path == true %}
return 301 $scheme://{{ forward_domain_name }}$request_uri; return {{ forward_http_code }} {{ forward_scheme }}://{{ forward_domain_name }}$request_uri;
{% else %} {% else %}
return 301 $scheme://{{ forward_domain_name }}; return {{ forward_http_code }} {{ forward_scheme }}://{{ forward_domain_name }};
{% endif %} {% endif %}
} }
{% endif %} {% endif %}

View File

@ -6,7 +6,13 @@
{% if tcp_forwarding == 1 or tcp_forwarding == true -%} {% if tcp_forwarding == 1 or tcp_forwarding == true -%}
server { server {
listen {{ incoming_port }}; listen {{ incoming_port }};
proxy_pass {{ forward_ip }}:{{ forwarding_port }}; {% if ipv6 -%}
listen [::]:{{ incoming_port }};
{% else -%}
#listen [::]:{{ incoming_port }};
{% endif %}
proxy_pass {{ forwarding_host }}:{{ forwarding_port }};
# Custom # Custom
include /data/nginx/custom/server_stream[.]conf; include /data/nginx/custom/server_stream[.]conf;
@ -16,7 +22,12 @@ server {
{% if udp_forwarding == 1 or udp_forwarding == true %} {% if udp_forwarding == 1 or udp_forwarding == true %}
server { server {
listen {{ incoming_port }} udp; listen {{ incoming_port }} udp;
proxy_pass {{ forward_ip }}:{{ forwarding_port }}; {% if ipv6 -%}
listen [::]:{{ incoming_port }} udp;
{% else -%}
#listen [::]:{{ incoming_port }} udp;
{% endif %}
proxy_pass {{ forwarding_host }}:{{ forwarding_port }};
# Custom # Custom
include /data/nginx/custom/server_stream[.]conf; include /data/nginx/custom/server_stream[.]conf;

File diff suppressed because it is too large Load Diff

14
docker/.dive-ci Normal file
View File

@ -0,0 +1,14 @@
rules:
# If the efficiency is measured below X%, mark as failed.
# Expressed as a ratio between 0-1.
lowestEfficiency: 0.99
# If the amount of wasted space is at least X or larger than X, mark as failed.
# Expressed in B, KB, MB, and GB.
highestWastedBytes: 15MB
# If the amount of wasted space makes up for X% or more of the image, mark as failed.
# Note: the base image layer is NOT included in the total image size.
# Expressed as a ratio between 0-1; fails if the threshold is met or crossed.
highestUserWastedPercent: 0.02

View File

@ -3,45 +3,61 @@
# This file assumes that the frontend has been built using ./scripts/frontend-build # This file assumes that the frontend has been built using ./scripts/frontend-build
FROM --platform=${TARGETPLATFORM:-linux/amd64} jc21/alpine-nginx-full:node FROM nginxproxymanager/nginx-full:certbot-node
ARG TARGETPLATFORM ARG TARGETPLATFORM
ARG BUILDPLATFORM
ARG BUILD_VERSION ARG BUILD_VERSION
ARG BUILD_COMMIT ARG BUILD_COMMIT
ARG BUILD_DATE ARG BUILD_DATE
ENV SUPPRESS_NO_CONFIG_WARNING=1 ENV SUPPRESS_NO_CONFIG_WARNING=1 \
ENV S6_FIX_ATTRS_HIDDEN=1 S6_FIX_ATTRS_HIDDEN=1 \
ENV NODE_ENV=production S6_BEHAVIOUR_IF_STAGE2_FAILS=1 \
NODE_ENV=production \
NPM_BUILD_VERSION="${BUILD_VERSION}" \
NPM_BUILD_COMMIT="${BUILD_COMMIT}" \
NPM_BUILD_DATE="${BUILD_DATE}"
RUN echo "fs.file-max = 65535" > /etc/sysctl.conf \ RUN echo "fs.file-max = 65535" > /etc/sysctl.conf \
&& rm -rf /etc/nginx \ && apt-get update \
&& apk update \ && apt-get install -y --no-install-recommends jq logrotate \
&& apk add python2 certbot jq \ && apt-get clean \
&& rm -rf /var/cache/apk/* && rm -rf /var/lib/apt/lists/*
ENV NPM_BUILD_VERSION="${BUILD_VERSION}" NPM_BUILD_COMMIT="${BUILD_COMMIT}" NPM_BUILD_DATE="${BUILD_DATE}"
# s6 overlay # s6 overlay
COPY scripts/install-s6 /tmp/install-s6 COPY scripts/install-s6 /tmp/install-s6
RUN /tmp/install-s6 "${TARGETPLATFORM}" && rm -f /tmp/install-s6 RUN /tmp/install-s6 "${TARGETPLATFORM}" && rm -f /tmp/install-s6
EXPOSE 80 EXPOSE 80 81 443
EXPOSE 81
EXPOSE 443
COPY docker/rootfs / COPY backend /app
ADD backend /app COPY frontend/dist /app/frontend
ADD frontend/dist /app/frontend COPY global /app/global
WORKDIR /app WORKDIR /app
RUN yarn install RUN yarn install
# add late to limit cache-busting by modifications
COPY docker/rootfs /
# Remove frontend service not required for prod, dev nginx config as well # Remove frontend service not required for prod, dev nginx config as well
RUN rm -rf /etc/services.d/frontend RUN rm -f /etc/nginx/conf.d/dev.conf RUN rm -rf /etc/services.d/frontend /etc/nginx/conf.d/dev.conf
# Change permission of logrotate config file
RUN chmod 644 /etc/logrotate.d/nginx-proxy-manager
# fix for pip installs
# https://github.com/NginxProxyManager/nginx-proxy-manager/issues/1769
RUN pip uninstall --yes setuptools \
&& pip install "setuptools==58.0.0"
VOLUME [ "/data", "/etc/letsencrypt" ] VOLUME [ "/data", "/etc/letsencrypt" ]
CMD [ "/init" ] ENTRYPOINT [ "/init" ]
HEALTHCHECK --interval=5s --timeout=3s CMD /bin/check-health LABEL org.label-schema.schema-version="1.0" \
org.label-schema.license="MIT" \
org.label-schema.name="nginx-proxy-manager" \
org.label-schema.description="Docker container for managing Nginx proxy hosts with a simple, powerful interface " \
org.label-schema.url="https://github.com/jc21/nginx-proxy-manager" \
org.label-schema.vcs-url="https://github.com/jc21/nginx-proxy-manager.git" \
org.label-schema.cmd="docker run --rm -ti jc21/nginx-proxy-manager:latest"

View File

@ -1,15 +1,15 @@
FROM jc21/alpine-nginx-full:node FROM nginxproxymanager/nginx-full:certbot-node
LABEL maintainer="Jamie Curnow <jc@jc21.com>" LABEL maintainer="Jamie Curnow <jc@jc21.com>"
ENV S6_LOGGING=0 ENV S6_LOGGING=0 \
ENV SUPPRESS_NO_CONFIG_WARNING=1 SUPPRESS_NO_CONFIG_WARNING=1 \
ENV S6_FIX_ATTRS_HIDDEN=1 S6_FIX_ATTRS_HIDDEN=1
RUN echo "fs.file-max = 65535" > /etc/sysctl.conf \ RUN echo "fs.file-max = 65535" > /etc/sysctl.conf \
&& rm -rf /etc/nginx \ && apt-get update \
&& apk update \ && apt-get install -y certbot jq python3-pip logrotate \
&& apk add python2 certbot jq \ && apt-get clean \
&& rm -rf /var/cache/apk/* && rm -rf /var/lib/apt/lists/*
# Task # Task
RUN cd /usr \ RUN cd /usr \
@ -18,15 +18,12 @@ RUN cd /usr \
COPY rootfs / COPY rootfs /
RUN rm -f /etc/nginx/conf.d/production.conf RUN rm -f /etc/nginx/conf.d/production.conf
RUN chmod 644 /etc/logrotate.d/nginx-proxy-manager
# s6 overlay # s6 overlay
RUN curl -L -o /tmp/s6-overlay-amd64.tar.gz "https://github.com/just-containers/s6-overlay/releases/download/v1.22.1.0/s6-overlay-amd64.tar.gz" \ RUN curl -L -o /tmp/s6-overlay-amd64.tar.gz "https://github.com/just-containers/s6-overlay/releases/download/v1.22.1.0/s6-overlay-amd64.tar.gz" \
&& tar -xzf /tmp/s6-overlay-amd64.tar.gz -C / && tar -xzf /tmp/s6-overlay-amd64.tar.gz -C /
EXPOSE 80 EXPOSE 80 81 443
EXPOSE 81 ENTRYPOINT [ "/init" ]
EXPOSE 443
CMD [ "/init" ]
HEALTHCHECK --interval=5s --timeout=3s CMD /bin/check-health

View File

@ -2,20 +2,45 @@
version: "3" version: "3"
services: services:
fullstack: fullstack-mysql:
image: ${IMAGE}:ci-${BUILD_NUMBER} image: ${IMAGE}:ci-${BUILD_NUMBER}
environment: environment:
- NODE_ENV=development NODE_ENV: "development"
- FORCE_COLOR=1 FORCE_COLOR: 1
DB_MYSQL_HOST: "db"
DB_MYSQL_PORT: 3306
DB_MYSQL_USER: "npm"
DB_MYSQL_PASSWORD: "npm"
DB_MYSQL_NAME: "npm"
volumes: volumes:
- npm_data:/data - npm_data:/data
- ../.jenkins/config.json:/app/config/production.json
expose: expose:
- 81 - 81
- 80 - 80
- 443 - 443
depends_on: depends_on:
- db - db
healthcheck:
test: ["CMD", "/bin/check-health"]
interval: 10s
timeout: 3s
fullstack-sqlite:
image: ${IMAGE}:ci-${BUILD_NUMBER}
environment:
NODE_ENV: "development"
FORCE_COLOR: 1
DB_SQLITE_FILE: "/data/database.sqlite"
volumes:
- npm_data:/data
expose:
- 81
- 80
- 443
healthcheck:
test: ["CMD", "/bin/check-health"]
interval: 10s
timeout: 3s
db: db:
image: jc21/mariadb-aria image: jc21/mariadb-aria
@ -27,13 +52,24 @@ services:
volumes: volumes:
- db_data:/var/lib/mysql - db_data:/var/lib/mysql
cypress: cypress-mysql:
image: ${IMAGE}-cypress:ci-${BUILD_NUMBER} image: ${IMAGE}-cypress:ci-${BUILD_NUMBER}
build: build:
context: ../ context: ../test/
dockerfile: test/cypress/Dockerfile dockerfile: cypress/Dockerfile
environment: environment:
CYPRESS_baseUrl: "http://fullstack:81" CYPRESS_baseUrl: "http://fullstack-mysql:81"
volumes:
- cypress-logs:/results
command: cypress run --browser chrome --config-file=${CYPRESS_CONFIG:-cypress/config/ci.json}
cypress-sqlite:
image: ${IMAGE}-cypress:ci-${BUILD_NUMBER}
build:
context: ../test/
dockerfile: cypress/Dockerfile
environment:
CYPRESS_baseUrl: "http://fullstack-sqlite:81"
volumes: volumes:
- cypress-logs:/results - cypress-logs:/results
command: cypress run --browser chrome --config-file=${CYPRESS_CONFIG:-cypress/config/ci.json} command: cypress run --browser chrome --config-file=${CYPRESS_CONFIG:-cypress/config/ci.json}

View File

@ -1,9 +1,9 @@
# WARNING: This is a DEVELOPMENT docker-compose file, it should not be used for production. # WARNING: This is a DEVELOPMENT docker-compose file, it should not be used for production.
version: "3" version: "3.5"
services: services:
npm: npm:
image: nginxproxymanager:dev image: nginxproxymanager:dev
container_name: npm_core
build: build:
context: ./ context: ./
dockerfile: ./dev/Dockerfile dockerfile: ./dev/Dockerfile
@ -11,20 +11,36 @@ services:
- 3080:80 - 3080:80
- 3081:81 - 3081:81
- 3443:443 - 3443:443
networks:
- nginx_proxy_manager
environment: environment:
- NODE_ENV=development NODE_ENV: "development"
- FORCE_COLOR=1 FORCE_COLOR: 1
- DEVELOPMENT=true DEVELOPMENT: "true"
DB_MYSQL_HOST: "db"
DB_MYSQL_PORT: 3306
DB_MYSQL_USER: "npm"
DB_MYSQL_PASSWORD: "npm"
DB_MYSQL_NAME: "npm"
# DB_SQLITE_FILE: "/data/database.sqlite"
# DISABLE_IPV6: "true"
volumes: volumes:
- npm_data:/data - npm_data:/data
- le_data:/etc/letsencrypt - le_data:/etc/letsencrypt
- ..:/app - ../backend:/app
- ../frontend:/app/frontend
- ../global:/app/global
depends_on: depends_on:
- db - db
working_dir: /app working_dir: /app
db: db:
image: jc21/mariadb-aria image: jc21/mariadb-aria
container_name: npm_db
ports:
- 33306:3306
networks:
- nginx_proxy_manager
environment: environment:
MYSQL_ROOT_PASSWORD: "npm" MYSQL_ROOT_PASSWORD: "npm"
MYSQL_DATABASE: "npm" MYSQL_DATABASE: "npm"
@ -33,17 +49,14 @@ services:
volumes: volumes:
- db_data:/var/lib/mysql - db_data:/var/lib/mysql
swagger:
image: 'swaggerapi/swagger-ui:latest'
ports:
- 3001:80
environment:
URL: "http://127.0.0.1:3081/api/schema"
PORT: '80'
depends_on:
- npm
volumes: volumes:
npm_data: npm_data:
name: npm_core_data
le_data: le_data:
name: npm_le_data
db_data: db_data:
name: npm_db_data
networks:
nginx_proxy_manager:
name: npm_network

View File

@ -0,0 +1,46 @@
#!/bin/bash
# This command reads the `DISABLE_IPV6` env var and will either enable
# or disable ipv6 in all nginx configs based on this setting.
# Lowercase
DISABLE_IPV6=$(echo "${DISABLE_IPV6:-}" | tr '[:upper:]' '[:lower:]')
CYAN='\E[1;36m'
BLUE='\E[1;34m'
YELLOW='\E[1;33m'
RED='\E[1;31m'
RESET='\E[0m'
FOLDER=$1
if [ "$FOLDER" == "" ]; then
echo -e "${RED} $0 requires a absolute folder path as the first argument!${RESET}"
echo -e "${YELLOW} ie: $0 /data/nginx${RESET}"
exit 1
fi
FILES=$(find "$FOLDER" -type f -name "*.conf")
if [ "$DISABLE_IPV6" == "true" ] || [ "$DISABLE_IPV6" == "on" ] || [ "$DISABLE_IPV6" == "1" ] || [ "$DISABLE_IPV6" == "yes" ]; then
# IPV6 is disabled
echo "Disabling IPV6 in hosts"
echo -e "${BLUE} ${CYAN}Disabling IPV6 in hosts: ${YELLOW}${FOLDER}${RESET}"
# Iterate over configs and run the regex
for FILE in $FILES
do
echo -e " ${BLUE} ${YELLOW}${FILE}${RESET}"
sed -E -i 's/^([^#]*)listen \[::\]/\1#listen [::]/g' "$FILE"
done
else
# IPV6 is enabled
echo -e "${BLUE} ${CYAN}Enabling IPV6 in hosts: ${YELLOW}${FOLDER}${RESET}"
# Iterate over configs and run the regex
for FILE in $FILES
do
echo -e " ${BLUE} ${YELLOW}${FILE}${RESET}"
sed -E -i 's/^(\s*)#listen \[::\]/\1listen [::]/g' "$FILE"
done
fi

View File

@ -1,2 +1,3 @@
* *
!.gitignore !.gitignore
!*.sh

View File

@ -0,0 +1,7 @@
#!/usr/bin/with-contenv bash
set -e
mkdir -p /data/logs
echo "Changing ownership of /data/logs to $(id -u):$(id -g)"
chown -R "$(id -u):$(id -g)" /data/logs

View File

@ -0,0 +1,29 @@
#!/usr/bin/with-contenv bash
# ref: https://github.com/linuxserver/docker-baseimage-alpine/blob/master/root/etc/cont-init.d/01-envfile
# in s6, environmental variables are written as text files for s6 to monitor
# search through full-path filenames for files ending in "__FILE"
for FILENAME in $(find /var/run/s6/container_environment/ | grep "__FILE$"); do
echo "[secret-init] Evaluating ${FILENAME##*/} ..."
# set SECRETFILE to the contents of the full-path textfile
SECRETFILE=$(cat ${FILENAME})
# SECRETFILE=${FILENAME}
# echo "[secret-init] Set SECRETFILE to ${SECRETFILE}" # DEBUG - rm for prod!
# if SECRETFILE exists / is not null
if [[ -f ${SECRETFILE} ]]; then
# strip the appended "__FILE" from environmental variable name ...
STRIPFILE=$(echo ${FILENAME} | sed "s/__FILE//g")
# echo "[secret-init] Set STRIPFILE to ${STRIPFILE}" # DEBUG - rm for prod!
# ... and set value to contents of secretfile
# since s6 uses text files, this is effectively "export ..."
printf $(cat ${SECRETFILE}) > ${STRIPFILE}
# echo "[secret-init] Set ${STRIPFILE##*/} to $(cat ${STRIPFILE})" # DEBUG - rm for prod!"
echo "[secret-init] Success! ${STRIPFILE##*/} set from ${FILENAME##*/}"
else
echo "[secret-init] cannot find secret in ${FILENAME}"
fi
done

View File

@ -1,4 +1,6 @@
text = True text = True
non-interactive = True non-interactive = True
authenticator = webroot
webroot-path = /data/letsencrypt-acme-challenge webroot-path = /data/letsencrypt-acme-challenge
key-type = ecdsa
elliptic-curve = secp384r1
preferred-chain = ISRG Root X1

View File

@ -0,0 +1,25 @@
/data/logs/*_access.log /data/logs/*/access.log {
create 0644 root root
weekly
rotate 4
missingok
notifempty
compress
sharedscripts
postrotate
/bin/kill -USR1 `cat /run/nginx.pid 2>/dev/null` 2>/dev/null || true
endscript
}
/data/logs/*_error.log /data/logs/*/error.log {
create 0644 root root
weekly
rotate 10
missingok
notifempty
compress
sharedscripts
postrotate
/bin/kill -USR1 `cat /run/nginx.pid 2>/dev/null` 2>/dev/null || true
endscript
}

View File

@ -8,10 +8,11 @@ server {
set $port "80"; set $port "80";
server_name localhost-nginx-proxy-manager; server_name localhost-nginx-proxy-manager;
access_log /data/logs/default.log standard; access_log /data/logs/fallback_access.log standard;
error_log /dev/null crit; error_log /data/logs/fallback_error.log warn;
include conf.d/include/assets.conf; include conf.d/include/assets.conf;
include conf.d/include/block-exploits.conf; include conf.d/include/block-exploits.conf;
include conf.d/include/letsencrypt-acme-challenge.conf;
location / { location / {
index index.html; index index.html;
@ -29,7 +30,7 @@ server {
set $port "443"; set $port "443";
server_name localhost; server_name localhost;
access_log /data/logs/default.log standard; access_log /data/logs/fallback_access.log standard;
error_log /dev/null crit; error_log /dev/null crit;
ssl_certificate /data/nginx/dummycert.pem; ssl_certificate /data/nginx/dummycert.pem;
ssl_certificate_key /data/nginx/dummykey.pem; ssl_certificate_key /data/nginx/dummykey.pem;

View File

@ -17,6 +17,9 @@ server {
proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass http://127.0.0.1:3000/; proxy_pass http://127.0.0.1:3000/;
proxy_read_timeout 15m;
proxy_send_timeout 15m;
} }
location / { location / {

View File

@ -1,4 +1,4 @@
location ~* ^.*\.(css|js|jpe?g|gif|png|woff|eot|ttf|svg|ico|css\.map|js\.map)$ { location ~* ^.*\.(css|js|jpe?g|gif|png|webp|woff|eot|ttf|svg|ico|css\.map|js\.map)$ {
if_modified_since off; if_modified_since off;
# use the public cache # use the public cache

View File

@ -1,196 +1,2 @@
# This should be left blank is it is populated programatically
set_real_ip_from 144.220.0.0/16; # by the application backend.
set_real_ip_from 52.124.128.0/17;
set_real_ip_from 54.230.0.0/16;
set_real_ip_from 54.239.128.0/18;
set_real_ip_from 52.82.128.0/19;
set_real_ip_from 99.84.0.0/16;
set_real_ip_from 204.246.172.0/24;
set_real_ip_from 205.251.192.0/19;
set_real_ip_from 54.239.192.0/19;
set_real_ip_from 70.132.0.0/18;
set_real_ip_from 13.32.0.0/15;
set_real_ip_from 13.224.0.0/14;
set_real_ip_from 13.35.0.0/16;
set_real_ip_from 204.246.164.0/22;
set_real_ip_from 204.246.168.0/22;
set_real_ip_from 71.152.0.0/17;
set_real_ip_from 216.137.32.0/19;
set_real_ip_from 205.251.249.0/24;
set_real_ip_from 99.86.0.0/16;
set_real_ip_from 52.46.0.0/18;
set_real_ip_from 52.84.0.0/15;
set_real_ip_from 204.246.173.0/24;
set_real_ip_from 130.176.0.0/16;
set_real_ip_from 64.252.64.0/18;
set_real_ip_from 204.246.174.0/23;
set_real_ip_from 64.252.128.0/18;
set_real_ip_from 205.251.254.0/24;
set_real_ip_from 143.204.0.0/16;
set_real_ip_from 205.251.252.0/23;
set_real_ip_from 204.246.176.0/20;
set_real_ip_from 13.249.0.0/16;
set_real_ip_from 54.240.128.0/18;
set_real_ip_from 205.251.250.0/23;
set_real_ip_from 52.222.128.0/17;
set_real_ip_from 54.182.0.0/16;
set_real_ip_from 54.192.0.0/16;
set_real_ip_from 13.124.199.0/24;
set_real_ip_from 34.226.14.0/24;
set_real_ip_from 52.15.127.128/26;
set_real_ip_from 35.158.136.0/24;
set_real_ip_from 52.57.254.0/24;
set_real_ip_from 18.216.170.128/25;
set_real_ip_from 13.52.204.0/23;
set_real_ip_from 13.54.63.128/26;
set_real_ip_from 13.59.250.0/26;
set_real_ip_from 13.210.67.128/26;
set_real_ip_from 35.167.191.128/26;
set_real_ip_from 52.47.139.0/24;
set_real_ip_from 52.199.127.192/26;
set_real_ip_from 52.212.248.0/26;
set_real_ip_from 52.66.194.128/26;
set_real_ip_from 13.113.203.0/24;
set_real_ip_from 99.79.168.0/23;
set_real_ip_from 34.195.252.0/24;
set_real_ip_from 35.162.63.192/26;
set_real_ip_from 34.223.12.224/27;
set_real_ip_from 52.56.127.0/25;
set_real_ip_from 34.223.80.192/26;
set_real_ip_from 13.228.69.0/24;
set_real_ip_from 34.216.51.0/25;
set_real_ip_from 3.231.2.0/25;
set_real_ip_from 54.233.255.128/26;
set_real_ip_from 18.200.212.0/23;
set_real_ip_from 52.52.191.128/26;
set_real_ip_from 3.234.232.224/27;
set_real_ip_from 52.78.247.128/26;
set_real_ip_from 52.220.191.0/26;
set_real_ip_from 34.232.163.208/29;
set_real_ip_from 2600:9000:eee::/48;
set_real_ip_from 2600:9000:4000::/36;
set_real_ip_from 2600:9000:3000::/36;
set_real_ip_from 2600:9000:f000::/36;
set_real_ip_from 2600:9000:fff::/48;
set_real_ip_from 2600:9000:2000::/36;
set_real_ip_from 2600:9000:1000::/36;
set_real_ip_from 2600:9000:ddd::/48;
set_real_ip_from 2600:9000:5300::/40;
set_real_ip_from 173.245.48.0/20;
set_real_ip_from 103.21.244.0/22;
set_real_ip_from 103.22.200.0/22;
set_real_ip_from 103.31.4.0/22;
set_real_ip_from 141.101.64.0/18;
set_real_ip_from 108.162.192.0/18;
set_real_ip_from 190.93.240.0/20;
set_real_ip_from 188.114.96.0/20;
set_real_ip_from 197.234.240.0/22;
set_real_ip_from 198.41.128.0/17;
set_real_ip_from 162.158.0.0/15;
set_real_ip_from 104.16.0.0/12;
set_real_ip_from 172.64.0.0/13;
set_real_ip_from 131.0.72.0/22;
set_real_ip_from 2400:cb00::/32;
set_real_ip_from 2606:4700::/32;
set_real_ip_from 2803:f800::/32;
set_real_ip_from 2405:b500::/32;
set_real_ip_from 2405:8100::/32;
set_real_ip_from 2a06:98c0::/29;
set_real_ip_from 2c0f:f248::/32;

View File

@ -5,6 +5,7 @@ location ^~ /.well-known/acme-challenge/ {
# Since this is for letsencrypt authentication of a domain and they do not give IP ranges of their infrastructure # Since this is for letsencrypt authentication of a domain and they do not give IP ranges of their infrastructure
# we need to open up access by turning off auth and IP ACL for this location. # we need to open up access by turning off auth and IP ACL for this location.
auth_basic off; auth_basic off;
auth_request off;
allow all; allow all;
# Set correct content type. According to this: # Set correct content type. According to this:

View File

@ -2,5 +2,7 @@ add_header X-Served-By $host;
proxy_set_header Host $host; proxy_set_header Host $host;
proxy_set_header X-Forwarded-Scheme $scheme; proxy_set_header X-Forwarded-Scheme $scheme;
proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass $forward_scheme://$server:$port; proxy_set_header X-Real-IP $remote_addr;
proxy_pass $forward_scheme://$server:$port$request_uri;

View File

@ -3,7 +3,5 @@ ssl_session_cache shared:SSL:50m;
# intermediate configuration. tweak to your needs. # intermediate configuration. tweak to your needs.
ssl_protocols TLSv1.2 TLSv1.3; ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'EECDH+AESGCM:AES256+EECDH:AES256+EDH:EDH+AESGCM:ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE- ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384';
ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AE ssl_prefer_server_ciphers off;
S128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES';
ssl_prefer_server_ciphers on;

View File

@ -18,6 +18,9 @@ server {
proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass http://127.0.0.1:3000/; proxy_pass http://127.0.0.1:3000/;
proxy_read_timeout 15m;
proxy_send_timeout 15m;
} }
location / { location / {

View File

@ -9,7 +9,7 @@ worker_processes auto;
# Enables the use of JIT for regular expressions to speed-up their processing. # Enables the use of JIT for regular expressions to speed-up their processing.
pcre_jit on; pcre_jit on;
error_log /data/logs/error.log warn; error_log /data/logs/fallback_error.log warn;
# Includes files with directives to load dynamic modules. # Includes files with directives to load dynamic modules.
include /etc/nginx/modules/*.conf; include /etc/nginx/modules/*.conf;
@ -26,12 +26,15 @@ http {
tcp_nopush on; tcp_nopush on;
tcp_nodelay on; tcp_nodelay on;
client_body_temp_path /tmp/nginx/body 1 2; client_body_temp_path /tmp/nginx/body 1 2;
keepalive_timeout 65; keepalive_timeout 90s;
proxy_connect_timeout 90s;
proxy_send_timeout 90s;
proxy_read_timeout 90s;
ssl_prefer_server_ciphers on; ssl_prefer_server_ciphers on;
gzip on; gzip on;
proxy_ignore_client_abort off; proxy_ignore_client_abort off;
client_max_body_size 2000m; client_max_body_size 2000m;
server_names_hash_bucket_size 64; server_names_hash_bucket_size 1024;
proxy_http_version 1.1; proxy_http_version 1.1;
proxy_set_header X-Forwarded-Scheme $scheme; proxy_set_header X-Forwarded-Scheme $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
@ -43,8 +46,7 @@ http {
log_format proxy '[$time_local] $upstream_cache_status $upstream_status $status - $request_method $scheme $host "$request_uri" [Client $remote_addr] [Length $body_bytes_sent] [Gzip $gzip_ratio] [Sent-to $server] "$http_user_agent" "$http_referer"'; log_format proxy '[$time_local] $upstream_cache_status $upstream_status $status - $request_method $scheme $host "$request_uri" [Client $remote_addr] [Length $body_bytes_sent] [Gzip $gzip_ratio] [Sent-to $server] "$http_user_agent" "$http_referer"';
log_format standard '[$time_local] $status - $request_method $scheme $host "$request_uri" [Client $remote_addr] [Length $body_bytes_sent] [Gzip $gzip_ratio] "$http_user_agent" "$http_referer"'; log_format standard '[$time_local] $status - $request_method $scheme $host "$request_uri" [Client $remote_addr] [Length $body_bytes_sent] [Gzip $gzip_ratio] "$http_user_agent" "$http_referer"';
access_log /data/logs/fallback_access.log proxy;
access_log /data/logs/default.log proxy;
# Dynamically generated resolvers file # Dynamically generated resolvers file
include /etc/nginx/conf.d/include/resolvers.conf; include /etc/nginx/conf.d/include/resolvers.conf;
@ -55,14 +57,20 @@ http {
} }
# Real IP Determination # Real IP Determination
# Docker subnet:
set_real_ip_from 172.0.0.0/8; # Local subnets:
set_real_ip_from 10.0.0.0/8;
set_real_ip_from 172.16.0.0/12; # Includes Docker subnet
set_real_ip_from 192.168.0.0/16;
# NPM generated CDN ip ranges: # NPM generated CDN ip ranges:
include conf.d/include/ip_ranges.conf; include conf.d/include/ip_ranges.conf;
# always put the following 2 lines after ip subnets: # always put the following 2 lines after ip subnets:
real_ip_header X-Forwarded-For; real_ip_header X-Real-IP;
real_ip_recursive on; real_ip_recursive on;
# Custom
include /data/nginx/custom/http_top[.]conf;
# Files generated by NPM # Files generated by NPM
include /etc/nginx/conf.d/*.conf; include /etc/nginx/conf.d/*.conf;
include /data/nginx/default_host/*.conf; include /data/nginx/default_host/*.conf;
@ -78,6 +86,9 @@ http {
stream { stream {
# Files generated by NPM # Files generated by NPM
include /data/nginx/stream/*.conf; include /data/nginx/stream/*.conf;
# Custom
include /data/nginx/custom/stream[.]conf;
} }
# Custom # Custom

View File

@ -4,6 +4,7 @@
if [ "$DEVELOPMENT" == "true" ]; then if [ "$DEVELOPMENT" == "true" ]; then
cd /app/frontend || exit 1 cd /app/frontend || exit 1
# If yarn install fails: add --verbose --network-concurrency 1
yarn install yarn install
yarn watch yarn watch
else else

View File

@ -5,7 +5,8 @@ mkdir -p /data/letsencrypt-acme-challenge
cd /app || echo cd /app || echo
if [ "$DEVELOPMENT" == "true" ]; then if [ "$DEVELOPMENT" == "true" ]; then
cd /app/backend || exit 1 cd /app || exit 1
# If yarn install fails: add --verbose --network-concurrency 1
yarn install yarn install
node --max_old_space_size=250 --abort_on_uncaught_exception node_modules/nodemon/bin/nodemon.js node --max_old_space_size=250 --abort_on_uncaught_exception node_modules/nodemon/bin/nodemon.js
else else

View File

@ -24,8 +24,12 @@ chown root /tmp/nginx
# Dynamically generate resolvers file, if resolver is IPv6, enclose in `[]` # Dynamically generate resolvers file, if resolver is IPv6, enclose in `[]`
# thanks @tfmm # thanks @tfmm
echo resolver "$(awk 'BEGIN{ORS=" "} $1=="nameserver" {print ($2 ~ ":")? "["$2"]": $2}' /etc/resolv.conf);" > /etc/nginx/conf.d/include/resolvers.conf if [ "$DISABLE_IPV6" == "true" ] || [ "$DISABLE_IPV6" == "on" ] || [ "$DISABLE_IPV6" == "1" ] || [ "$DISABLE_IPV6" == "yes" ];
then
echo resolver "$(awk 'BEGIN{ORS=" "} $1=="nameserver" { sub(/%.*$/,"",$2); print ($2 ~ ":")? "["$2"]": $2}' /etc/resolv.conf) ipv6=off valid=10s;" > /etc/nginx/conf.d/include/resolvers.conf
else
echo resolver "$(awk 'BEGIN{ORS=" "} $1=="nameserver" { sub(/%.*$/,"",$2); print ($2 ~ ":")? "["$2"]": $2}' /etc/resolv.conf) valid=10s;" > /etc/nginx/conf.d/include/resolvers.conf
fi
# Generate dummy self-signed certificate. # Generate dummy self-signed certificate.
if [ ! -f /data/nginx/dummycert.pem ] || [ ! -f /data/nginx/dummykey.pem ] if [ ! -f /data/nginx/dummycert.pem ] || [ ! -f /data/nginx/dummykey.pem ]
then then
@ -36,10 +40,14 @@ then
-days 3650 \ -days 3650 \
-nodes \ -nodes \
-x509 \ -x509 \
-subj '/O=Nginx Proxy Manager/OU=Dummy Certificate/CN=localhost' \ -subj '/O=localhost/OU=localhost/CN=localhost' \
-keyout /data/nginx/dummykey.pem \ -keyout /data/nginx/dummykey.pem \
-out /data/nginx/dummycert.pem -out /data/nginx/dummycert.pem
echo "Complete" echo "Complete"
fi fi
# Handle IPV6 settings
/bin/handle-ipv6-setting /etc/nginx/conf.d
/bin/handle-ipv6-setting /data/nginx
exec nginx exec nginx

View File

@ -16,5 +16,7 @@ alias h='cd ~;clear;'
echo -e -n '\E[1;34m' echo -e -n '\E[1;34m'
figlet -w 120 "NginxProxyManager" figlet -w 120 "NginxProxyManager"
echo -e "\E[1;36mVersion \E[1;32m${NPM_BUILD_VERSION:-2.0.0-dev}\E[1;36m (${NPM_BUILD_COMMIT:-dev}) ${NPM_BUILD_DATE:-0000-00-00}, Nginx \E[1;32m${NGINX_VERSION:-unknown}\E[1;36m, Alpine \E[1;32m${VERSION_ID:-unknown}\E[1;36m, Kernel \E[1;32m$(uname -r)\E[0m" echo -e "\E[1;36mVersion \E[1;32m${NPM_BUILD_VERSION:-2.0.0-dev} (${NPM_BUILD_COMMIT:-dev}) ${NPM_BUILD_DATE:-0000-00-00}\E[1;36m, OpenResty \E[1;32m${OPENRESTY_VERSION:-unknown}\E[1;36m, ${ID:-debian} \E[1;32m${VERSION:-unknown}\E[1;36m, Certbot \E[1;32m$(certbot --version)\E[0m"
echo echo -e -n '\E[1;34m'
cat /built-for-arch
echo -e '\E[0m'

View File

@ -47,6 +47,8 @@ module.exports = {
["/screenshots/", "Screenshots"], ["/screenshots/", "Screenshots"],
["/setup/", "Setup Instructions"], ["/setup/", "Setup Instructions"],
["/advanced-config/", "Advanced Configuration"], ["/advanced-config/", "Advanced Configuration"],
["/upgrading/", "Upgrading"],
["/faq/", "Frequently Asked Questions"],
["/third-party/", "Third Party"] ["/third-party/", "Third Party"]
] ]
} }

View File

@ -37,57 +37,3 @@ footer: MIT Licensed | Copyright © 2016-present jc21.com
<p>Configure other users to either view or manage their own hosts. Full access permissions are available.</p> <p>Configure other users to either view or manage their own hosts. Full access permissions are available.</p>
</div> </div>
</div> </div>
### Quick Setup
1. Install Docker and Docker-Compose
- [Docker Install documentation](https://docs.docker.com/install/)
- [Docker-Compose Install documentation](https://docs.docker.com/compose/install/)
2. Create a docker-compose.yml file similar to this:
```yml
version: '3'
services:
app:
image: 'jc21/nginx-proxy-manager:latest'
ports:
- '80:80'
- '81:81'
- '443:443'
volumes:
- ./config.json:/app/config/production.json
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
db:
image: 'jc21/mariadb-aria:10.4'
environment:
MYSQL_ROOT_PASSWORD: 'npm'
MYSQL_DATABASE: 'npm'
MYSQL_USER: 'npm'
MYSQL_PASSWORD: 'npm'
volumes:
- ./data/mysql:/var/lib/mysql
```
3. Bring up your stack
```bash
docker-compose up -d
```
4. Log in to the Admin UI
When your docker container is running, connect to it on port `81` for the admin interface.
[http://127.0.0.1:81](http://127.0.0.1:81)
Default Admin User:
```
Email: admin@example.com
Password: changeme
```
Immediately after logging in with this default user you will be asked to modify your details and change your password.

View File

@ -1,6 +1,146 @@
# Advanced Configuration # Advanced Configuration
### Custom Nginx Configurations ## Best Practice: Use a Docker network
For those who have a few of their upstream services running in Docker on the same Docker
host as NPM, here's a trick to secure things a bit better. By creating a custom Docker network,
you don't need to publish ports for your upstream services to all of the Docker host's interfaces.
Create a network, ie "scoobydoo":
```bash
docker network create scoobydoo
```
Then add the following to the `docker-compose.yml` file for both NPM and any other
services running on this Docker host:
```yml
networks:
default:
external: true
name: scoobydoo
```
Let's look at a Portainer example:
```yml
version: '3'
services:
portainer:
image: portainer/portainer
privileged: true
volumes:
- './data:/data'
- '/var/run/docker.sock:/var/run/docker.sock'
restart: unless-stopped
networks:
default:
external: true
name: scoobydoo
```
Now in the NPM UI you can create a proxy host with `portainer` as the hostname,
and port `9000` as the port. Even though this port isn't listed in the docker-compose
file, it's "exposed" by the Portainer Docker image for you and not available on
the Docker host outside of this Docker network. The service name is used as the
hostname, so make sure your service names are unique when using the same network.
## Docker Healthcheck
The `Dockerfile` that builds this project does not include a `HEALTHCHECK` but you can opt in to this
feature by adding the following to the service in your `docker-compose.yml` file:
```yml
healthcheck:
test: ["CMD", "/bin/check-health"]
interval: 10s
timeout: 3s
```
## Docker Secrets
This image supports the use of Docker secrets to import from file and keep sensitive usernames or passwords from being passed or preserved in plaintext.
You can set any environment variable from a file by appending `__FILE` (double-underscore FILE) to the environmental variable name.
```yml
version: "3.7"
secrets:
# Secrets are single-line text files where the sole content is the secret
# Paths in this example assume that secrets are kept in local folder called ".secrets"
DB_ROOT_PWD:
file: .secrets/db_root_pwd.txt
MYSQL_PWD:
file: .secrets/mysql_pwd.txt
services:
app:
image: 'jc21/nginx-proxy-manager:latest'
restart: unless-stopped
ports:
# Public HTTP Port:
- '80:80'
# Public HTTPS Port:
- '443:443'
# Admin Web Port:
- '81:81'
environment:
# These are the settings to access your db
DB_MYSQL_HOST: "db"
DB_MYSQL_PORT: 3306
DB_MYSQL_USER: "npm"
# DB_MYSQL_PASSWORD: "npm" # use secret instead
DB_MYSQL_PASSWORD__FILE: /run/secrets/MYSQL_PWD
DB_MYSQL_NAME: "npm"
# If you would rather use Sqlite uncomment this
# and remove all DB_MYSQL_* lines above
# DB_SQLITE_FILE: "/data/database.sqlite"
# Uncomment this if IPv6 is not enabled on your host
# DISABLE_IPV6: 'true'
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
secrets:
- MYSQL_PWD
depends_on:
- db
db:
image: jc21/mariadb-aria
restart: unless-stopped
environment:
# MYSQL_ROOT_PASSWORD: "npm" # use secret instead
MYSQL_ROOT_PASSWORD__FILE: /run/secrets/DB_ROOT_PWD
MYSQL_DATABASE: "npm"
MYSQL_USER: "npm"
# MYSQL_PASSWORD: "npm" # use secret instead
MYSQL_PASSWORD__FILE: /run/secrets/MYSQL_PWD
volumes:
- ./data/mysql:/var/lib/mysql
secrets:
- DB_ROOT_PWD
- MYSQL_PWD
```
## Disabling IPv6
On some Docker hosts IPv6 may not be enabled. In these cases, the following message may be seen in the log:
> Address family not supported by protocol
The easy fix is to add a Docker environment variable to the Nginx Proxy Manager stack:
```yml
environment:
DISABLE_IPV6: 'true'
```
## Custom Nginx Configurations
If you are a more advanced user, you might be itching for extra Nginx customizability. If you are a more advanced user, you might be itching for extra Nginx customizability.
@ -8,18 +148,20 @@ NPM has the ability to include different custom configuration snippets in differ
You can add your custom configuration snippet files at `/data/nginx/custom` as follow: You can add your custom configuration snippet files at `/data/nginx/custom` as follow:
`/data/nginx/custom/root.conf`: Included at the very end of nginx.conf - `/data/nginx/custom/root.conf`: Included at the very end of nginx.conf
`/data/nginx/custom/http.conf`: Included at the end of the main http block - `/data/nginx/custom/http_top.conf`: Included at the top of the main http block
`/data/nginx/custom/server_proxy.conf`: Included at the end of every proxy server block - `/data/nginx/custom/http.conf`: Included at the end of the main http block
`/data/nginx/custom/server_redirect.conf`: Included at the end of every redirection server block - `/data/nginx/custom/stream.conf`: Included at the end of the main stream block
`/data/nginx/custom/server_stream.conf`: Included at the end of every stream server block - `/data/nginx/custom/server_proxy.conf`: Included at the end of every proxy server block
`/data/nginx/custom/server_stream_tcp.conf`: Included at the end of every TCP stream server block - `/data/nginx/custom/server_redirect.conf`: Included at the end of every redirection server block
`/data/nginx/custom/server_stream_udp.conf`: Included at the end of every UDP stream server block - `/data/nginx/custom/server_stream.conf`: Included at the end of every stream server block
- `/data/nginx/custom/server_stream_tcp.conf`: Included at the end of every TCP stream server block
- `/data/nginx/custom/server_stream_udp.conf`: Included at the end of every UDP stream server block
Every file is optional. Every file is optional.
### X-FRAME-OPTIONS Header ## X-FRAME-OPTIONS Header
You can configure the [`X-FRAME-OPTIONS`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options) header You can configure the [`X-FRAME-OPTIONS`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options) header
value by specifying it as a Docker environment variable. The default if not specified is `deny`. value by specifying it as a Docker environment variable. The default if not specified is `deny`.

26
docs/faq/README.md Normal file
View File

@ -0,0 +1,26 @@
# FAQ
## Do I have to use Docker?
Yes, that's how this project is packaged.
This makes it easier to support the project when I have control over the version of Nginx and NodeJS
being used. In future this could change if the backend was no longer using NodeJS and it's long list
of dependencies.
## Can I run it on a Raspberry Pi?
Yes! The docker image is multi-arch and is built for a variety of architectures. If yours is
[not listed](https://hub.docker.com/r/jc21/nginx-proxy-manager/tags) please open a
[GitHub issue](https://github.com/jc21/nginx-proxy-manager/issues/new?assignees=&labels=enhancement&template=feature_request.md&title=).
## I can't get my service to proxy properly?
Your best bet is to ask the [Reddit community for support](https://www.reddit.com/r/nginxproxymanager/). There's safety in numbers.
Gitter is best left for anyone contributing to the project to ask for help about internals, code reviews etc.
## When adding username and password access control to a proxy host, I can no longer login into the app.
Having an Access Control List (ACL) with username and password requires the browser to always send this username and password in the `Authorization` header on each request. If your proxied app also requires authentication (like Nginx Proxy Manager itself), most likely the app will also use the `Authorization` header to transmit this information, as this is the standardized header meant for this kind of information. However having multiples of the same headers is not allowed in the [internet standard](https://www.rfc-editor.org/rfc/rfc7230#section-3.2.2) and almost all apps do not support multiple values in the `Authorization` header. Hence one of the two logins will be broken. This can only be fixed by either removing one of the logins or by changing the app to use other non-standard headers for authorization.

File diff suppressed because it is too large Load Diff

View File

@ -1,85 +1,35 @@
# Full Setup Instructions # Full Setup Instructions
### Configuration File ## Running the App
**The configuration file needs to be provided by you!** Create a `docker-compose.yml` file:
Don't worry, this is easy to do.
The app requires a configuration file to let it know what database you're using. By default, this file is called config.json.
Here's an example configuration for `mysql` (or mariadb) that is compatible with the docker-compose example below:
```json
{
"database": {
"engine": "mysql",
"host": "db",
"name": "npm",
"user": "npm",
"password": "npm",
"port": 3306
}
}
```
Once you've created your configuration file it's easy to mount it in the docker container.
**Note:** After the first run of the application, the config file will be altered to include generated encryption keys unique to your installation. These keys
affect the login and session management of the application. If these keys change for any reason, all users will be logged out.
### Database
This app doesn't come with a database, you have to provide one yourself. Currently only `mysql/mariadb` is supported for the minimum versions:
- MySQL v5.7.8+
- MariaDB v10.2.7+
It's easy to use another docker container for your database also and link it as part of the docker stack, so that's what the following examples
are going to use.
::: warning
When using a `mariadb` database, the NPM configuration file should still use the `mysql` engine!
:::
### Running the App
Via `docker-compose`:
```yml ```yml
version: "3" version: "3"
services: services:
app: app:
image: jc21/nginx-proxy-manager:2 image: 'jc21/nginx-proxy-manager:latest'
restart: always restart: unless-stopped
ports: ports:
# Public HTTP Port: # These ports are in format <host-port>:<container-port>
- '80:80' - '80:80' # Public HTTP Port
# Public HTTPS Port: - '443:443' # Public HTTPS Port
- '443:443' - '81:81' # Admin Web Port
# Admin Web Port: # Add any other Stream port you want to expose
- '81:81' # - '21:21' # FTP
# Uncomment the next line if you uncomment anything in the section
# environment:
# Uncomment this if you want to change the location of
# the SQLite DB file within the container
# DB_SQLITE_FILE: "/data/database.sqlite"
# Uncomment this if IPv6 is not enabled on your host
# DISABLE_IPV6: 'true'
volumes: volumes:
# Make sure this config.json file exists as per instructions above:
- ./config.json:/app/config/production.json
- ./data:/data - ./data:/data
- ./letsencrypt:/etc/letsencrypt - ./letsencrypt:/etc/letsencrypt
depends_on:
- db
db:
image: jc21/mariadb-aria:10.4
restart: always
environment:
MYSQL_ROOT_PASSWORD: "npm"
MYSQL_DATABASE: "npm"
MYSQL_USER: "npm"
MYSQL_PASSWORD: "npm"
volumes:
- ./data/mysql:/var/lib/mysql
``` ```
Then: Then:
@ -88,9 +38,64 @@ Then:
docker-compose up -d docker-compose up -d
``` ```
The config file (config.json) must be present in this directory. ## Using MySQL / MariaDB Database
### Running on Raspberry PI / ARM devices If you opt for the MySQL configuration you will have to provide the database server yourself. You can also use MariaDB. Here are the minimum supported versions:
- MySQL v5.7.8+
- MariaDB v10.2.7+
It's easy to use another docker container for your database also and link it as part of the docker stack, so that's what the following examples
are going to use.
Here is an example of what your `docker-compose.yml` will look like when using a MariaDB container:
```yml
version: "3"
services:
app:
image: 'jc21/nginx-proxy-manager:latest'
restart: unless-stopped
ports:
# These ports are in format <host-port>:<container-port>
- '80:80' # Public HTTP Port
- '443:443' # Public HTTPS Port
- '81:81' # Admin Web Port
# Add any other Stream port you want to expose
# - '21:21' # FTP
environment:
DB_MYSQL_HOST: "db"
DB_MYSQL_PORT: 3306
DB_MYSQL_USER: "npm"
DB_MYSQL_PASSWORD: "npm"
DB_MYSQL_NAME: "npm"
# Uncomment this if IPv6 is not enabled on your host
# DISABLE_IPV6: 'true'
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
depends_on:
- db
db:
image: 'jc21/mariadb-aria:latest'
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: 'npm'
MYSQL_DATABASE: 'npm'
MYSQL_USER: 'npm'
MYSQL_PASSWORD: 'npm'
volumes:
- ./data/mysql:/var/lib/mysql
```
::: warning
Please note, that `DB_MYSQL_*` environment variables will take precedent over `DB_SQLITE_*` variables. So if you keep the MySQL variables, you will not be able to use SQLite.
:::
## Running on Raspberry PI / ARM devices
The docker images support the following architectures: The docker images support the following architectures:
- amd64 - amd64
@ -100,15 +105,16 @@ The docker images support the following architectures:
The docker images are a manifest of all the architecture docker builds supported, so this means The docker images are a manifest of all the architecture docker builds supported, so this means
you don't have to worry about doing anything special and you can follow the common instructions above. you don't have to worry about doing anything special and you can follow the common instructions above.
Check out the [dockerhub tags](https://cloud.docker.com/repository/registry-1.docker.io/jc21/nginx-proxy-manager/tags) Check out the [dockerhub tags](https://hub.docker.com/r/jc21/nginx-proxy-manager/tags)
for a list of supported architectures and if you want one that doesn't exist, for a list of supported architectures and if you want one that doesn't exist,
[create a feature request](https://github.com/jc21/nginx-proxy-manager/issues/new?assignees=&labels=enhancement&template=feature_request.md&title=). [create a feature request](https://github.com/NginxProxyManager/nginx-proxy-manager/issues/new?assignees=&labels=enhancement&template=feature_request.md&title=).
Also, if you don't know how to already, follow [this guide to install docker and docker-compose](https://manre-universe.net/how-to-run-docker-and-docker-compose-on-raspbian/) Also, if you don't know how to already, follow [this guide to install docker and docker-compose](https://manre-universe.net/how-to-run-docker-and-docker-compose-on-raspbian/)
on Raspbian. on Raspbian.
Please note that the `jc21/mariadb-aria:latest` image might have some problems on some ARM devices, if you want a separate database container, use the `yobasystems/alpine-mariadb:latest` image.
### Initial Run ## Initial Run
After the app is running for the first time, the following will happen: After the app is running for the first time, the following will happen:
@ -119,7 +125,7 @@ After the app is running for the first time, the following will happen:
This process can take a couple of minutes depending on your machine. This process can take a couple of minutes depending on your machine.
### Default Administrator User ## Default Administrator User
``` ```
Email: admin@example.com Email: admin@example.com
@ -127,3 +133,50 @@ Password: changeme
``` ```
Immediately after logging in with this default user you will be asked to modify your details and change your password. Immediately after logging in with this default user you will be asked to modify your details and change your password.
## Configuration File
::: warning
This section is meant for advanced users
:::
If you would like more control over the database settings you can define a custom config JSON file.
Here's an example for `sqlite` configuration as it is generated from the environment variables:
```json
{
"database": {
"engine": "knex-native",
"knex": {
"client": "sqlite3",
"connection": {
"filename": "/data/database.sqlite"
},
"useNullAsDefault": true
}
}
}
```
You can modify the `knex` object with your custom configuration, but note that not all knex clients might be installed in the image.
Once you've created your configuration file you can mount it to `/app/config/production.json` inside you container using:
```
[...]
services:
app:
image: 'jc21/nginx-proxy-manager:latest'
[...]
volumes:
- ./config.json:/app/config/production.json
[...]
[...]
```
**Note:** After the first run of the application, the config file will be altered to include generated encryption keys unique to your installation.
These keys affect the login and session management of the application. If these keys change for any reason, all users will be logged out.

View File

@ -1,12 +1,16 @@
# Third Party # Third Party
As this software gains popularity it's common to see it integrated with other platforms. Please be aware that unless specifically mentioned in the documenation of those As this software gains popularity it's common to see it integrated with other platforms. Please be aware that unless specifically mentioned in the documentation of those
integrations, they are *not supported* by me. integrations, they are *not supported* by me.
Known integrations: Known integrations:
- [HomeAssistant Hass.io plugin](https://github.com/hassio-addons/addon-nginx-proxy-manager) - [HomeAssistant Hass.io plugin](https://github.com/hassio-addons/addon-nginx-proxy-manager)
- [UnRaid / Synology](https://github.com/jlesage/docker-nginx-proxy-manager) - [UnRaid / Synology](https://github.com/jlesage/docker-nginx-proxy-manager)
- [Proxmox Scripts](https://github.com/ej52/proxmox-scripts/tree/main/lxc/nginx-proxy-manager)
- [nginxproxymanagerGraf](https://github.com/ma-karai/nginxproxymanagerGraf)
If you would like your integration of NPM listed, please open a If you would like your integration of NPM listed, please open a
[Github issue](https://github.com/jc21/nginx-proxy-manager/issues/new?assignees=&labels=enhancement&template=feature_request.md&title=) [Github issue](https://github.com/jc21/nginx-proxy-manager/issues/new?assignees=&labels=enhancement&template=feature_request.md&title=)

11
docs/upgrading/README.md Normal file
View File

@ -0,0 +1,11 @@
# Upgrading
```bash
docker-compose pull
docker-compose up -d
```
This project will automatically update any databases or other requirements so you don't have to follow
any crazy instructions. These steps above will pull the latest updates and recreate the docker
containers.

File diff suppressed because it is too large Load Diff

View File

@ -1 +0,0 @@
./node_modules/tabler-ui/dist/assets/fonts

1
frontend/fonts/feather Symbolic link
View File

@ -0,0 +1 @@
../node_modules/tabler-ui/dist/assets/fonts/feather

Some files were not shown because too many files have changed in this diff Show More