Running Behind A Reverse Proxy - edmozley/freeitsm GitHub Wiki
Running behind a reverse proxy
Most production installs don't let people reach FreeITSM directly. Something sits in front and handles HTTPS: nginx, Caddy, Traefik, Cloudflare, an AWS or Azure load balancer. It then passes each request on to FreeITSM over plain HTTP.
That works well, with one catch: FreeITSM only sees plain HTTP. Unless you tell it a proxy is in front, it believes it's running on http:// and builds its addresses that way.
The one setting
Turn on TRUST_PROXY_HTTPS.
Docker - in docker-compose.yml, uncomment:
environment:
- TRUST_PROXY_HTTPS=1
then docker compose up -d.
Everything else - in config.php:
define('TRUST_PROXY_HTTPS', true);
What your proxy must send
One header: X-Forwarded-Proto, set to https for visitors who came in over HTTPS. Most proxies send it without being asked. nginx does not, so add it:
location / {
proxy_pass http://freeitsm:80;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
Pass the Host header through as well ($http_host keeps a port number, if you have one). FreeITSM builds addresses from it.
Chained proxies, such as Cloudflare in front of nginx, are fine. They send https, http, and FreeITSM reads the first value, which comes from the proxy that faced the visitor.
What goes wrong without it
Everything that shows or sends a full address comes out as http://:
- Single sign-on fails. The redirect address sent to Entra, Google or Okta starts with
http://, and they refuse it. Entra's error is AADSTS50011. - System → Single Sign-On shows the wrong address to register.
- Links in password reset, self-service and satisfaction survey emails start with
http://. - The session cookie is sent without its
Secureflag. - In Docker, following an old
/login.phplink, or a folder address without its final/, lands on an error page. Apache sends the browser tohttp://on the HTTPS port.
Links in emails sent with nobody at the keyboard (from cron, by workflows, or for SLA warnings) can't take their address from a request at all. Set the public web address for those, whether or not you're behind a proxy.
⚠️ Only turn it on when the proxy is the only way in
Any visitor can send an X-Forwarded-Proto header themselves. That's why FreeITSM ignores it unless you set TRUST_PROXY_HTTPS.
With the setting on, make sure nobody can reach FreeITSM without going through the proxy. In Docker that means not publishing the container's own port to the network, or at least firewalling it. In the Docker image, the setting also makes Apache's own redirects use https, so anyone browsing the container directly on http:// would be bounced to an HTTPS address it doesn't answer.
Apache's own redirects, outside Docker
A few redirects are made by Apache itself, not by FreeITSM: /login.php to /login, and adding the / to a folder address. The Docker image handles these when TRUST_PROXY_HTTPS is set. On your own Apache behind a proxy, do the same by adding a scheme to the ServerName inside the site's <VirtualHost>:
<VirtualHost *:80>
ServerName https://itsm.example.com
...
</VirtualHost>
On a global ServerName, outside the <VirtualHost>, the scheme has no effect. Or have the proxy fix them: in nginx, proxy_redirect http:// https://;.
Checking it
- Open System → Single Sign-On. The redirect address shown should start with
https://. - Sign in, open your browser's developer tools, and look at the
PHPSESSIDcookie. It should be marked Secure.
If the address still says http://, the proxy isn't sending X-Forwarded-Proto, or TRUST_PROXY_HTTPS isn't set where FreeITSM reads it. In Docker, check with:
docker compose exec app printenv TRUST_PROXY_HTTPS
See also
- Behind a reverse proxy, the SSO redirect address said http (#152) - how this was found and fixed
- Running on nginx - nginx serving FreeITSM directly, rather than in front of it
- Public web address
- Single sign-on
- Installation