Laravel Https Behind a Proxy
Yesterday I thought I’d fixed my https links on Laravel running in Kubernetes - but I had a nagging feeling that I’d just followed some random blog posts and missed something …
Unfortunately what I had looked for was force laravel to use https
When what I really needed was Configuring Trusted Proxies
My Setup
My Laravel instance runs in Kubernetes
There are two proxies
The nginx-ingress takes https traffic from the outside and passes http traffic to my pod.
The pod has two containers - an nginx instance that serves static assets directly and passes php requests to a php-fpm container within the same pod.
My Laravel application sees http requests that originate from 12.0.0.1 which various headers relating to the original request.
Kubernetes
It took me a while to (mostly) understand the Kubernetes networking side.
This is worth a read K8s – Node IPs vs Pod IPs vs Cluster IPs vs NodePort
I was confused because the thing I understood was clusterIP addresses but that isn’t what I was seeing in logs
You can see the podIP for every pod via
kubectl get pods -A --template '{{range $index, $pod := .items }}{{.status.podIP}} {{.metadata.name}}{{"\n"}}{{end}}'
I’m still not clear how stable the podIPs are - pods are ephemeral but I’m assuming that the network itself is stable.
Solution
So I have configured app/Http/Middleware/TrustProxies.php to trust the whole network
protected $proxies = [
'127.0.0.1', // nginx connecting to phpfpm
'10.214.0.0/24', // k8s nginx ingress
];
I don’t like embedding this in code and there doesn’t currently seem to be a way to configure this,
But it seems there will be a way in Laravel 11
[11.x] Improves Trust Proxies Configuration #49600
How it works
By trusting the proxies Laravel reads the http headers they set - including those saying the original request was https