Tangible Bytes

A Web Developer’s Blog

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