Skip to content

feat: add use_http_host option to preserve port in Host header#5551

Open
mcarbonneaux wants to merge 1 commit into
NginxProxyManager:developfrom
mcarbonneaux:develop
Open

feat: add use_http_host option to preserve port in Host header#5551
mcarbonneaux wants to merge 1 commit into
NginxProxyManager:developfrom
mcarbonneaux:develop

Conversation

@mcarbonneaux
Copy link
Copy Markdown

Closes #3981

Adds a per-proxy-host boolean toggle "Use $http_host (Preserve Port)" in the Details tab
of the proxy host modal. When enabled, nginx sends proxy_set_header Host $http_host and
proxy_set_header X-Forwarded-Host $http_host instead of the default proxy_set_header Host $host.
When disabled (default), behaviour is identical to today — zero impact on existing setups.

Why

The nginx variable $host does not preserve the original client port, which breaks applications
that validate the full Host header including port (e.g. ESPHome behind NAT port forwarding,
see also esphome/issues#4327).

Previously, users could not work around this via the Advanced Config field because the default
headers are written after the advanced config block, making override impossible.

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update
  • Code refactoring
  • API changes
  • Performance improvement
  • Test addition or update

AI Usage

  • AI was used to write this
  • AI was used to review this

@nginxproxymanagerci
Copy link
Copy Markdown

CI Error:

/bin/bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8): No such file or directory
certbot-node: Pulling from nginxproxymanager/nginx-full
Digest: sha256:47d894c72fda25ad3687ee2cfbb78ecd18826e9eb7b3da582d21b6dd925d5693
Status: Image is up to date for nginxproxymanager/nginx-full:certbot-node
docker.io/nginxproxymanager/nginx-full:certbot-node
�[1;34m❯ �[1;36mBuilding Frontend ...�[0m
yarn install v1.22.22
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
warning " > @uiw/react-textarea-code-editor@3.1.1" has unmet peer dependency "@babel/runtime@>=7.10.0".
[4/4] Building fresh packages...
Done in 53.59s.
yarn run v1.22.22
$ biome lint
Checked 226 files in 87ms. No fixes applied.
Done in 0.15s.
yarn run v1.22.22
$ formatjs compile-folder src/locale/src src/locale/lang
Done in 0.31s.
yarn run v1.22.22
$ /app/frontend/node_modules/.bin/vitest run --no-color

 RUN  v4.1.6 /app/frontend

$ formatjs compile-folder src/locale/src src/locale/lang

$ ./src/locale/scripts/locale-sort.sh
Sorting bg.json
Sorting cs.json
Sorting de.json
Sorting en.json
Sorting es.json
Sorting et.json
Sorting fr.json
Sorting ga.json
Sorting hu.json
Sorting id.json
Sorting it.json
Sorting ja.json
Sorting ko.json
Sorting nl.json
Sorting no.json
Sorting pl.json
Sorting pt.json
Sorting ru.json
Sorting sk.json
Sorting tr.json
Sorting vi.json
Sorting zh.json

 ✓ src/locale/Utils.test.tsx (10 tests) 10ms

 Test Files  1 passed (1)
      Tests  10 passed (10)
   Start at  16:20:52
   Duration  1.27s (transform 202ms, setup 65ms, import 927ms, tests 10ms, environment 181ms)

Done in 1.55s.
yarn run v1.22.22
$ tsc && vite build
src/hooks/useProxyHost.ts(6,26): error TS2352: Conversion of type '{ id: number; createdOn: string; modifiedOn: string; ownerUserId: number; domainNames: never[]; forwardHost: string; forwardPort: number; accessListId: number; certificateId: number; sslForced: false; ... 10 more ...; trustForwardedProto: false; }' to type 'ProxyHost' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
  Property 'useHttpHost' is missing in type '{ id: number; createdOn: string; modifiedOn: string; ownerUserId: number; domainNames: never[]; forwardHost: string; forwardPort: number; accessListId: number; certificateId: number; sslForced: false; ... 10 more ...; trustForwardedProto: false; }' but required in type 'ProxyHost'.
error Command failed with exit code 2.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

@mcarbonneaux
Copy link
Copy Markdown
Author

mcarbonneaux commented May 18, 2026

@jc21 The last two tests, which are still showing errors, are not related to my PR::


[2026-05-18T16:57:33.049Z] cypress-1  |        Spec                                              Tests  Passing  Failing  Pending  Skipped  
[2026-05-18T16:57:33.049Z] cypress-1  |   ┌────────────────────────────────────────────────────────────────────────────────────────────────┐
[2026-05-18T16:57:33.049Z] cypress-1  |   │ ✖  Certificates.cy.js                       00:02        3        2        1        -        - │
[2026-05-18T16:57:33.049Z] cypress-1  |   ├────────────────────────────────────────────────────────────────────────────────────────────────┤
[2026-05-18T16:57:33.049Z] cypress-1  |   │ ✔  Dashboard.cy.js                          931ms        1        1        -        -        - │
[2026-05-18T16:57:33.049Z] cypress-1  |   ├────────────────────────────────────────────────────────────────────────────────────────────────┤
[2026-05-18T16:57:33.049Z] cypress-1  |   │ ✖  FullCertProvision.cy.js                  00:04        2        1        1        -        - │
[2026-05-18T16:57:33.049Z] cypress-1  |   ├────────────────────────────────────────────────────────────────────────────────────────────────┤
[2026-05-18T16:57:33.049Z] cypress-1  |   │ ✔  Health.cy.js                             466ms        3        3        -        -        - │
[2026-05-18T16:57:33.049Z] cypress-1  |   ├────────────────────────────────────────────────────────────────────────────────────────────────┤
[2026-05-18T16:57:33.049Z] cypress-1  |   │ ✔  Ldap.cy.js                                 0ms        -        -        -        -        - │
[2026-05-18T16:57:33.049Z] cypress-1  |   ├────────────────────────────────────────────────────────────────────────────────────────────────┤
[2026-05-18T16:57:33.049Z] cypress-1  |   │ ✔  OAuth.cy.js                                0ms        -        -        -        -        - │
[2026-05-18T16:57:33.049Z] cypress-1  |   ├────────────────────────────────────────────────────────────────────────────────────────────────┤
[2026-05-18T16:57:33.049Z] cypress-1  |   │ ✔  ProxyHosts.cy.js                         00:01        2        2        -        -        - │
[2026-05-18T16:57:33.049Z] cypress-1  |   ├────────────────────────────────────────────────────────────────────────────────────────────────┤
[2026-05-18T16:57:33.049Z] cypress-1  |   │ ✔  Settings.cy.js                           00:01        7        7        -        -        - │
[2026-05-18T16:57:33.049Z] cypress-1  |   ├────────────────────────────────────────────────────────────────────────────────────────────────┤
[2026-05-18T16:57:33.049Z] cypress-1  |   │ ✔  Streams.cy.js                            01:12        5        5        -        -        - │
[2026-05-18T16:57:33.049Z] cypress-1  |   ├────────────────────────────────────────────────────────────────────────────────────────────────┤
[2026-05-18T16:57:33.049Z] cypress-1  |   │ ✔  SwaggerSchema.cy.js                      922ms        1        1        -        -        - │
[2026-05-18T16:57:33.049Z] cypress-1  |   ├────────────────────────────────────────────────────────────────────────────────────────────────┤
[2026-05-18T16:57:33.049Z] cypress-1  |   │ ✔  Users.cy.js                              00:01        3        3        -        -        - │
[2026-05-18T16:57:33.049Z] cypress-1  |   └────────────────────────────────────────────────────────────────────────────────────────────────┘
[2026-05-18T16:57:33.049Z] cypress-1  |     ✖  2 of 11 failed (18%)                     01:25       27       25        2        -        -  

IA analyse of this fail:

Fix 1 — Certificates.cy.js test failing (CVE-2024-46256 / CVE-2024-46257)

Root cause: Commit 7330d044 ("Loose validation on certificate domain names") removed the
regex pattern from common.json#/properties/domain_names/items, stripping the only validation
that blocked shell injection characters in domain names. The CVE test (Certificates.cy.js)
submits a malicious domain string containing ", |, and spaces and expects the API to return
HTTP 400 with an AJV validation error message containing data/domain_names/0 must match pattern.
Without the pattern, AJV passes validation and the backend tries to call certbot with the
unsanitized input, which crashes with a 500.

Fix: In backend/schema/paths/nginx/certificates/post.json, replace the $ref for
domain_names in the request body schema with an inline definition that includes a strict pattern:

"domain_names": {
    "description": "Domain Names array",
    "type": "array",
    "uniqueItems": true,
    "items": {
        "type": "string",
        "pattern": "^[^&| @!#%^();:/\\}{=+?<>,~`'\"]+$"
    },
    "example": ["example.com", "www.example.com"]
}

This keeps common.json loose (needed for proxy hosts which accept wildcards like *.example.com)
while enforcing strict validation on the certificate creation endpoint specifically, where injection
into certbot arguments is a real attack vector.


Fix 2 — FullCertProvision.cy.js PowerDNS test failing

Root cause: In backend/certbot/dns-plugins.json, the PowerDNS plugin entry has
"dependencies": "PyYAML==5.3.1". This is a strict pin to a very old version of PyYAML that
fails to install under Python 3.12+ because it requires compiling a C extension that is no longer
compatible. When the backend tries to provision a DNS certificate using the PowerDNS provider, it
first calls installPlugin("powerdns"), which runs
pip install PyYAML==5.3.1 certbot-dns-powerdns~=0.2.1. The pip install fails, the plugin is
never installed, and the certificate request returns 500.

Fix: In backend/certbot/dns-plugins.json, change the pinned PyYAML version in the PowerDNS
entry from an exact pin to a minimum version:

"dependencies": "PyYAML>=5.4"

PyYAML 5.4+ properly supports Python 3.12+ and is compatible with certbot-dns-powerdns ~=0.2.1.

her is the commit in private branch 23ecfa0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

make the posibility to choose the way the host and x-forward-x are set in _location.conf

1 participant