Security
- Check advanced_config permissions before creating a certificate on
host update (proxy, redirection and 404 hosts). A refused request
previously requested a Let's Encrypt certificate first, leaving an
orphan certificate and using up rate limit.
- Only trust X-NPM-Peer-Addr when it comes with a secret generated at
container start. The admin nginx sends both headers. Any proxy host or
stream forwarding to 127.0.0.1:3000 was also a loopback peer, so it
could forge the header and get a fresh rate-limit bucket on every
request. Without the secret (dev, or a mounted production.conf), the
header is ignored.
- Add a login limit per IP across all accounts (30 failed attempts a
minute) alongside the per-account one. Before this, one address could
spray passwords over any number of accounts. Behind a shared proxy,
everyone using that proxy shares this limit.
- Stop trusting X-Real-IP from loopback. It was only there for an older
version of the rate limiter, and it let a stream host forwarding to a
local proxy host forge the client IP and get past IP access lists.
Loopback now behaves as it does on master.
Correctness
- Refuse to delete a certificate that hosts still use (400, with counts
per host type). Their configs include its files, and a successful
revoke deleted them anyway, which broke nginx -t. Otherwise the
certificate is revoked and its files are removed even if the revoke
fails.
- Let non-admins clear a location's advanced config. Deleting the
location was already allowed and has the same effect, and a location
deleted and re-added at the same path arrives with an empty config,
which was refused.
- Clear proxy host grants (meta.proxy_host_ids) when visibility isn't
"user" or proxy hosts are hidden, and drop ids of deleted hosts.
Before, hidden grants came back when proxy hosts were shown again.
The backend enforces this; the permissions modal also stops sending
them.
- 404 host and redirection host modals now wait for the current user
to load, so an admin's advanced config change isn't dropped if they
submit before it loads.
Tests
- NonAdminHosts.cy.js: refused change doesn't create a certificate,
location rename and clear rules, grant clearing.
- Certificates.cy.js: deleting a certificate that is in use.
Security
- Redact certbot output before it reaches the API: strip the
certificate's DNS credential values, URL query strings and userinfo,
secret-looking key=value pairs and Bearer/Basic tokens. DNS plugins
can echo request URLs carrying API keys. The raw CommandError is no
longer attached as `previous`, since the error handler returns
`previous` to the client on certificate routes.
- Rate limit login/2FA on the admin nginx's real TCP peer, passed as
X-NPM-Peer-Addr ($realip_remote_addr), instead of X-Forwarded-For.
nginx trusts X-Real-IP from private ranges, so a client on the LAN or
Docker network could get a fresh bucket on every request. Behind
another proxy, limits now apply per account through that proxy.
- Bound rate limiter memory: hash keys over 128 chars and cap each store
at 50k entries, removing expired entries first and then the oldest.
Correctness
- Proxy host modal: send location advanced configs unchanged for
non-admins instead of looking them up by path, which dropped the
config from a renamed location.
- Location advanced config: locations that omit advanced_config now get
a config only after explicit ones are matched, so a new location at
an old path can't take the config from the renamed location.
- Certificate upload: check that the certificate matches the private
key (uploaded or stored) before writing, so a mismatched pair can't
break nginx -t.
- Certificate delete: keep the Let's Encrypt files when revoke fails and
hosts still use the certificate, so their configs still load.
Cleanup
- Make the rate-limit certbot hint first in the list, as its comment
says.
- Proxy host getCount uses the permissions access has already loaded
instead of querying user_permission again.
- Rate limiter: register the success refund listener in one place and
call it a fixed window, not a sliding one.
($http_host) forwards the raw client Host header, including the port and
any absolute-form URI mismatch, to every upstream and into the asset
cache key
Keep the incoming Host authority for default and custom locations, with the existing hostname fallback when Host is absent. Add a built-image regression that validates Host against Origin and Referer and run it after the CI image build.
When Nginx is behind another proxy server (like CloudFlare or AWS ALB), the force-SSL
feature can cause redirect loops because Nginx sees the connection as plain HTTP
while SSL is already handled upstream. This adds a new boolean option to trust
the X-Forwarded-Proto header from upstream proxies.
Changes:
- Add `trust_forwarded_proto` column to proxy_host table (migration)
- Update model and API schema to support the new boolean field
- Modify force-ssl Nginx template to check X-Forwarded-Proto/X-Forwarded-Scheme
- Add map directives in nginx.conf to validate and sanitize forwarded headers
- Add advanced option toggle in frontend UI with i18n support (EN/ZH)
- Set proxy headers from validated map variables instead of $scheme
This allows administrators to control SSL redirect behavior when Nginx is deployed
behind a TLS-terminating proxy.
This is useful when some user would want to change the default
log format for each of the service, without the need of creating a
new `log_format custom` and changing the `access_log` for each
service.
Allow custom configuration of the root config in the top of the file. This can be used to load modules, which is not possible at the end of the config file.
There is already a `http_top.conf`, so `root_top.conf` is a logical addition.
- Do not apply HTTPs redirection for challenge used by the test.
- Set the `User-Agent` to avoid 403 answer from site24x7.com.
- Handle JSON parsing failure of the received body.
- Better handling of different error cases.
nginx only uses the `ssl_protocols` directive in the `server{}` block of the first processed host config, which is the default config in `/etc/nginx/conf.d/default.conf`. in version `v2.9.20` the default ssl site was dropped by using `ssl_reject_handshake on` in the default host config. but beside the include of `conf.d/include/ssl-ciphers.conf` was removed from the default host config. that's why `tlsv1.3` isn't applied by default anymore, same thing with the defined cipher suites. npm is so broken since `2023-03-16`.
commit that broke the config -> https://github.com/NginxProxyManager/nginx-proxy-manager/commit/a7f0c3b730678ae4352ade2829d891a3ce3cd3bc
with PUID and PGID environment variables
- Detects if image is run with a user in docker command and fails if so
- Adds s6 prepare scripts for adding a 'npmuser'
- Split up and refactor the s6 prepare scripts
- Runs nginx and backend node as 'npmuser'
- Changes ownership of files required at startup
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
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.