120 Commits
Author SHA1 Message Date
Jamie Curnow 5b7e34eb67 Fix second round of review findings from PR #6029
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.
2026-11-09 23:39:26 +10:00
Jamie Curnow 04c1f5ae76 Fix review findings from PR #6029
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.
2026-11-09 22:53:53 +10:00
Jamie Curnow fff2b0d097 Fix for changing the upstream Host from $host to $forward_host
($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
2026-11-09 22:09:34 +10:00
Jamie Curnow 0cde59a8ad Fix for rate limiter only trusts X-Forwarded-For when the socket is
loopback, and the admin nginx sets that header to its own $remote_addr
2026-11-09 22:00:26 +10:00
jc21 18fc758b4f Merge pull request #5934 from lennondotw/fix/preserve-host-port
fix(proxy): preserve client ports in forwarded Host headers
2026-11-05 10:15:05 +10:00
Askhat AkhtanovandClaude Opus 5.5 c23a1cb343 fix: remove stale nginx pid file before starting nginx
When /run/nginx is already owned by PUID:PGID, the ownership step skips
it, so a leftover nginx.pid owned by root stays in place and nginx,
running as PUID:PGID, fails with "Permission denied" on every start.

Nginx is not running yet during prepare, so remove the pid file there.

Fixes #5964

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 13:33:27 +05:00
lennondotw 3a455595e7 fix(proxy): isolate cached assets by forwarded authority 2026-10-14 14:48:22 +08:00
lennondotw 6b26999e34 fix(proxy): preserve client ports in forwarded Host headers
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.
2026-10-08 15:50:24 +08:00
xJayMorex 4725153962 fix: only chown /data/keys.json if necessary 2026-09-25 11:49:17 +02:00
carlosalbertorg 4282d6c6e9 feat: Add a Logs viewer to the admin UI
Nginx Proxy Manager had no way to inspect application or nginx logs
from the web UI - admins had to shell into the container or read
`docker logs`. This adds an admin-only Logs page that can tail:

- the backend application log, now also mirrored to
  /data/logs/backend.log (in addition to stdout) and rotated by the
  logrotate timer that already runs every 2 days
- the Let's Encrypt/certbot log, which certbot already writes to
  /data/logs/letsencrypt.log via its existing --logs-dir flag
- per-host nginx access/error logs (proxy, redirection, 404 and
  stream hosts), with the file path always resolved server-side from
  a validated host_type enum + numeric host_id, never from client
  input

Reads use a reverse chunked scan (64KB chunks, capped at 5MB scanned
per request) instead of loading whole files into memory, and the
frontend polls every 5s only while the tab is focused and "Live" is
on, so this stays cheap on both CPU and memory. No new runtime
dependencies were added on either side.

Purely additive: two new admin-only endpoints
(GET /api/logs/sources, GET /api/logs/tail), no existing behaviour
changed.
2026-09-22 13:11:38 -03:00
vgoer b7772016ba fix: Ensure JWT key file ownership matches PUID/PGID at startup 2026-08-24 09:30:36 +00:00
Jamie Curnow a62c2a6dc3 Adds support for custom admin port via env var #3808
and documentation
2026-06-10 11:24:53 +10:00
Jamie Curnow 0d832092a5 Only modify files in startup when they aren't mounted 2026-06-02 22:09:21 +10:00
Jamie Curnow 03c70e3902 Fixes for upgraded debian trixie
- Adds request logging in debug mode for some endpoints
- Moves certbot version determination to the startup scripts and removes
  bash script encapsulation when installing plugins
- Revert loose domain validation, which was there for a specific reason
  addressing CVE's
- Fix Cypress suite for cert generation
- Adds Cypress test that iterates over the entire certbot plugins list
  and installs each one, ensuring at the very least that the install
  works
- Fixed some plugins based on this
- (!) Still some work to do on this, hostinger is still broken at least
- Improved cypress tests for custom certs; they will generate on each
  run instead of being baked in. The baked ones were due to expire soon
2026-05-25 07:37:24 +10:00
Jamie Curnow 67d40e186f Attempt to fix #5335 by allowing resovler generation to be opt-out with a env var 2026-02-26 08:32:02 +10:00
William Mahoney 7241869a9e Fix silent config corruption in 50-ipv6.sh on NFS volumes
Replace unsafe `echo "$(sed ...)" > $FILE` with atomic temp-file write.

The current pattern reads a file with sed inside a command substitution,
then writes the result back via echo redirection. If sed reads an empty
or momentarily unreadable file (e.g., NFS transient issue during
container recreation by Watchtower or similar tools), it produces no
output. The echo then writes exactly 1 byte (a newline) to the config
file, silently destroying its contents.

The fix writes sed output to a temp file first, checks it's non-empty
with `[ -s ]`, then atomically replaces the original via `mv`. If sed
produces empty output, the original file is preserved and a warning is
logged to stderr.
2026-02-20 21:24:40 -07:00
jerry-yuan eeab425ea4 fix: unknown "trust_forwarded_proto" variable error when run with already created old virtual hosts 2026-02-10 10:53:17 +00:00
Jerry 232b5b759a fix: make variable name meaningful 2026-02-01 00:16:17 +08:00
jerry-yuan 187d21a0d5 feat: add trust_forwarded_proto option for SSL redirect handling in reverse proxy scenarios
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.
2026-01-31 13:11:47 +00:00
Jamie Curnow 534afe6067 Implement suggestion from #5216 hopefully rectifying https -> forced https hosts 2026-01-28 14:04:32 +10:00
Alex Kitsul aeb44244a7 Added logging for streams based on port 2025-12-30 21:44:29 -08:00
Jamie Curnow 5b7013b8d5 Moved certrbot plugin list to backend
frontend doesn't include when building in react version
adds swagger for existing dns-providers endpoint
2025-10-26 00:28:03 +10:00
Jamie Curnow fadec9751e React 2025-10-02 08:10:42 +10:00
Jamie Curnow 54d463ac36 Safer and flexible boolean env vars 2025-07-09 21:27:50 +10:00
Jamie Curnow a23dc24021 Tweak ownership output 2025-07-09 21:01:21 +10:00
Jamie Curnow 4f9df893c8 Ownership script shakeup
- Don't touch a file to determine if we need to run
- Instead, check ownership of each location and skip it if we are happy
- Keeping SKIP_CERTBOT_OWNERSHIP flag
- More vebose logging of outcomes
2025-07-09 20:30:27 +10:00
Jamie Curnow 304b38e82b Fix ownership if statement 2025-07-09 18:19:50 +10:00
Jamie Curnow 9a0383bc73 Move SKIP_CERTBOT_OWNERSHIP check around the entire certbot code 2025-07-09 16:30:45 +10:00
Jamie Curnow 1357774f21 Add SKIP_CERTBOT_OWNERSHIP env var support to skip certbot folder ownership 2025-07-09 13:14:27 +10:00
Jamie Curnow 3735f3c11d Formating for ownership script 2025-07-08 09:44:10 +10:00
Aditya 0cab720f23 fix: optimize certbot ownership script to reduce container startup time
Replace inefficient find/execdir implementation that was causing 3+ minute
startup delays with a more efficient approach that:

1. Uses a flag file to skip redundant operations on container restarts
2. Processes site-packages directories with bulk chown operations instead
   of individual file checks and changes
3. Maintains the same functionality while dramatically improving performance

This change should significantly reduce container startup time while ensuring
all necessary file permissions are still properly set.
2025-04-20 20:38:54 +10:00
jbowring 3091c21cae Add SSL certificate to TCP streams if certificate in database 2025-02-04 17:12:04 +10:00
irexyc a0b26b9e98 Add woff2 format to assets.conf for Cache Assets 2024-11-04 20:01:39 +08:00
CoffeeCHN 0042726477 Update nginx-proxy-manager
Fix Nginx not restarting correctly.
2024-08-20 15:36:21 +08:00
jc21 120d50e5c0 Merge pull request #3766 from kroegerama/kroegerama-patch-1
Add include for `root_top.conf` in the nginx.conf
2024-07-01 15:23:43 +10:00
Brendon Mendicino b4560d7dde feat: changing log_format proxy default location
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.
2024-06-16 15:44:52 +02:00
kroegerama 3ce477d350 add include for root_top.conf in the nginx.conf
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.
2024-05-19 15:53:02 +02:00
woodmichl a5b21d0306 replaxed chown with find -not -user ... chown
chown -R tries to chown all files. find -not -user -execdir only chowns files not owned by PUID
2024-03-10 01:55:18 +01:00
Jamie Curnow db23c9a52f Refactor certbot plugins install
- Added a script to install every single plugin, used in development and debugging
- Improved certbot plugin install commands
- Adjusted some version for plugins to install properly
- It's noted that some plugins require deps that do not match other plugins,
  however these use cases should be extremely rare
2024-01-18 12:26:55 +10:00
Jamie Curnow e69684919c Use nginxproxymanager/nginx-full image base
which has been updated with bookworm, python 3.8, certbot 2.8.0 and node 20

Moved rootfs scripts as /bin is a symlink in bookworm
2024-01-10 12:59:51 +10:00
Jamie Curnow a7fe687bae Fix permission recursiveness 2024-01-10 09:22:34 +10:00
jc21 459b7a2223 Merge pull request #3361 from timob/improve-container-start
Improve container startup time
2024-01-09 08:15:33 +10:00
Jocelyn Le Sage 388fff84f2 Fixes for the server reachability test.
- 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.
2023-12-19 17:22:33 -05:00
Tim O'Brien 33dbffb974 Improve container startup time
See https://github.com/NginxProxyManager/nginx-proxy-manager/issues/2991

Removes uneeded file permission changes in rootfs certbot install. Tested installing custom DNS provider plugins for certbot, works correctly.
2023-12-02 14:56:48 +11:00
FibreTTP 4867db078c Remove explicit user and group - add su directive for default user (npm). 2023-09-27 14:58:19 +10:00
FibreTTP 6b565e628f Change perms on logrotated logs to npm user 2023-09-27 14:25:04 +10:00
jc21 aee93a2f6f Merge pull request #2932 from nietzscheanic/patch-1
Fix for ignored ssl_protocols and ssl_ciphers directive in conf.d/inc…
2023-07-20 12:25:09 +10:00
xrh0905 63ee69f432 Fix device or resource busy when patching IPv6 settings 2023-06-15 11:17:02 +08:00
nietzscheanic 81054631f9 Fix for ignored ssl_protocols and ssl_ciphers directive in conf.d/include/ssl-ciphers.conf
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
2023-05-19 14:13:29 +02:00
Jamie Curnow 05307aa253 Fix certbot plugins install when using PUID/PGID 2023-05-10 14:39:08 +10:00