[PR #2019] [MERGED] fix(nginx): x-forwarded-* headers #9331

Closed
opened 2026-02-05 14:02:48 +03:00 by OVERLORD · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/immich-app/immich/pull/2019
Author: @michelheusschen
Created: 3/19/2023
Status: Merged
Merged: 3/22/2023
Merged by: @alextran1502

Base: mainHead: fix/nginx-x-forwarded-headers


📝 Commits (2)

  • 45342c8 fix(nginx): x-forwarded-* headers
  • 3e3aa21 change category / add link to nginx config

📊 Changes

4 files changed (+39 additions, -9 deletions)

View changed files

docs/docs/administration/reverse-proxy.md (+22 -0)
📝 nginx/templates/default.conf.template (+14 -8)
📝 server/apps/immich/src/main.ts (+1 -1)
📝 web/entrypoint.sh (+2 -0)

📄 Description

Fixes issues surrounding X-Forwarded-* headers for both server and web:

  1. Invalid login attempts are logged on the server with the wrong IP address
  2. Cookies are never set with the Secure flag
  3. URL.protocol is always http and URL.host doesn't include the port
  4. app.set('trust proxy') on the server doesn't have a value so X-Forwarded-* headers are ignored

These issues have been resolved. Below some more details and choices that have been made for the various headers. I've also added a guide to the documentation regarding reverse proxies.

Host / X-Forwarded-Host
Changed to $http_host which also includes the port while $host strips the port. Removing the port leads to issues when using a different port than 80 or 443.

X-Forwarded-Proto
Nginx only listens on HTTP so the value is always http. Often, another reverse proxy handles TLS termination and sets the 'X-Forwarded-Proto' header, allowing us to reuse that value while using '$scheme' as a fallback.

X-Forwarded-For
This is the most tricky header, because getting it wrong means the user can supply any IP. The header contains a comma-separated list of IP addresses, with the first IP in the list being the original client IP, followed by any intermediary proxies.

One common method for extracting the correct client IP address from the X-Forwarded-For header, is to supply the proxy depth and then extract the IP address accordingly. However, this requires manual configuration by every user and is therefore more error-prone.

The second method works by getting the first public IP address when checking the list from right to left. This method is incompatible with SvelteKit, but we don't need the client's IP there. I've chosen this method only for ease of configuration.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/immich-app/immich/pull/2019 **Author:** [@michelheusschen](https://github.com/michelheusschen) **Created:** 3/19/2023 **Status:** ✅ Merged **Merged:** 3/22/2023 **Merged by:** [@alextran1502](https://github.com/alextran1502) **Base:** `main` ← **Head:** `fix/nginx-x-forwarded-headers` --- ### 📝 Commits (2) - [`45342c8`](https://github.com/immich-app/immich/commit/45342c8dfcee9a5479b19b3bf25afd910253f546) fix(nginx): x-forwarded-* headers - [`3e3aa21`](https://github.com/immich-app/immich/commit/3e3aa217441a961e419e388773380adf82dc566c) change category / add link to nginx config ### 📊 Changes **4 files changed** (+39 additions, -9 deletions) <details> <summary>View changed files</summary> ➕ `docs/docs/administration/reverse-proxy.md` (+22 -0) 📝 `nginx/templates/default.conf.template` (+14 -8) 📝 `server/apps/immich/src/main.ts` (+1 -1) 📝 `web/entrypoint.sh` (+2 -0) </details> ### 📄 Description Fixes issues surrounding X-Forwarded-* headers for both server and web: 1. Invalid login attempts are logged on the server with the wrong IP address 2. Cookies are never set with the `Secure` flag 3. URL.protocol is always `http` and URL.host doesn't include the port 4. `app.set('trust proxy')` on the server doesn't have a value so X-Forwarded-* headers are ignored These issues have been resolved. Below some more details and choices that have been made for the various headers. I've also added a guide to the documentation regarding reverse proxies. **Host / X-Forwarded-Host** Changed to `$http_host` which also includes the port while `$host` strips the port. Removing the port leads to issues when using a different port than `80` or `443`. **X-Forwarded-Proto** Nginx only listens on HTTP so the value is always `http`. Often, another reverse proxy handles TLS termination and sets the 'X-Forwarded-Proto' header, allowing us to reuse that value while using '$scheme' as a fallback. **X-Forwarded-For** This is the most tricky header, because getting it wrong means the user can supply any IP. The header contains a comma-separated list of IP addresses, with the first IP in the list being the original client IP, followed by any intermediary proxies. One common method for extracting the correct client IP address from the X-Forwarded-For header, is to supply the proxy depth and then extract the IP address accordingly. However, this requires manual configuration by every user and is therefore more error-prone. The second method works by getting the first public IP address when checking the list from right to left. This method is incompatible with SvelteKit, but we don't need the client's IP there. I've chosen this method only for ease of configuration. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
OVERLORD added the pull-request label 2026-02-05 14:02:48 +03:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: immich-app/immich#9331