Simple reverse proxy - check and question

So I have Caddy running for a few years on an RPI3 and did not touch anything for years either. The usecase is simple: I have multiple servers running and do not want to open up multiple ports on my router.

My caddyfile looks like this:

internet.gerard.com {
    proxy / https://192.168.1.42:8443 {
        insecure_skip_verify
        transparent
        websocket
    }
tls gerard@gerard.com
}

bi.gerard.com {
    proxy / http://192.168.1.40:99 {
        transparent
    }
tls gerard@gerard.com
log caddybi.log
}

This works fine.

However, I two questions:

  • Is this indeed a ‘safe’ configuration or should I have used other configuration parameters for this simple use case?
  • My firewall (firewalla) sends me notifications when my network performs abnormal uploads to the outside worls. This is great. But for the 2 servers that are ‘gated’ by Caddy I only get the name of the Caddy Server back (eg “Caddy Proxy has uploaded 30mb to 113.161.194.198 at 9:19AM”) instead of the actual server that is uploading (eg bi.gerard.com for instance). I guess that is because my firewall is presented the encrypted data and only sees the caddy server as the sender. Is there any configuration parameter I can add so my firewall can actually see which server (behind caddy) that is uploading traffic?

I would recommend upgrading to Caddy 2 right away: Upgrading to Caddy 2 — Caddy Documentation

Then we can address the rest of your questions :smiley: (v1 is no longer supported)

1 Like

Indeed, sounds like a good idea. Will take me a few weeks before I have time to do this; Any immediate security risk?

Probably plenty. You’re missing over 3 years worth of security fixes. Caddy v1 has been EOL for nearly two years now. Upgrade immediately.

1 Like

Spend the last few hours trying to get upgraded but not getting far. Pls note that I did several searches but can’t find the solution. p.s. as I had a spare RPI I’m trying to get v2 running first and then swap with my old v1 RPI.

What I did:

  • Clean RPI3 image for headless use > working
  • Updated rasbian
  • Installed caddy via:
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddy
  • Got a message which I did not write down but related to not being able to bind to localhost:2019
  • Tried to modify caddyfile in ect/caddy > no succes, created root user , logged in as root and could change caddyfile
  • When I try to reload I get “reload: sending configuration to instance: performing request: Post “http://localhost:2019/load”: dial tcp [::1]:2019: connect: connection refused”

So there seems the api cannot be called (and caddyfile cannot be loaded) due to issue with port 2019

Suggestions for next step?

How are you trying to run Caddy? Did you try to run caddy run in your terminal after installing the package? You shouldn’t do that because Caddy will already be running as a systemd service. See the instructions here for how to use Caddy as a service:

1 Like

Ah. That was indeed the case. Was trying to run it twice…thanks for the pointer.

So now I have part of my v2 config working. Below two sites work:

bi.gerard.com {
	reverse_proxy 192.168.1.40:99
  	log {
    		format console
    		output file /var/log/caddy/blueiris.log
  	}

}
internet.gerard.com {
	reverse_proxy 192.168.1.42:8443 {
		transport http {
			tls_insecure_skip_verify
		}
	}
  	log {
    		format console
    		output file /var/log/caddy/unifi.log
  	}
}

However struggling with my other entry to homeassistant v1 config:

https://ha.gerard.com {       
         header / {
                Strict-Transport-Security "max-age=31536000; includeSubdomains"
                X-XSS-Protection "1; mode=block"
                X-Content-Type-Options "nosniff"
                X-Frame-Options "SAMEORIGIN"
                Referrer-Policy "same-origin"
        }
        proxy / 192.168.1.39:8123 {
                websocket
                header_upstream Host {host}
                header_upstream X-Real-IP {remote}
                header_upstream X-Forwarded-For {remote}
                header_upstream X-Forwarded-Proto {scheme}
        }
        log /var/log/caddy-access.log {
                rotate_size 20
                rotate_age  14
                rotate_keep 4
                rotate_compress
        }
        errors stderr
}


Tried below v2 but no luck


https://ha.gerard.com {
	reverse_proxy /* {
		to 192.168.1.39:8123
  			transport http {
				tls
				tls_insecure_skip_verify
 			}
	}
	header {
		Strict-Transport-Security "max-age=31536000; includeSubdomains"
		X-XSS-Protection "1; mode=block"
		X-Content-Type-Options "nosniff"
		X-Frame-Options "SAMEORIGIN"
		Referrer-Policy "same-origin"
	}
  	log {
    		format console
    		output file /var/log/caddy/ha.log
  	}

}

Are you sure you need tls for this one? Try without.

You can shorten it to this:

reverse_proxy 192.168.1.39:8123

Otherwise, please show your logs. Just saying “no luck” tells us absolutely nothing about what’s wrong, so we can only make guesses. Please be specific about what isn’t working.

I will try removing the TLS references but my assumption is that it has to do with below part from v1:

                websocket
                header_upstream Host {host}
                header_upstream X-Real-IP {remote}
                header_upstream X-Forwarded-For {remote}
                header_upstream X-Forwarded-Proto {scheme}

If I look at the logs of the V2 version (which I feel a bit uncomfortable posting on a public website) Homeassisitant sees the the incoming but refuses it. My assumption is due to missing information in the incoming request like the real IP address (remote IP) of the proxy which I know Homeassistant wants to see to allow a connection.

Could you help with the V2 syntax of above V1 settings?

Update: Also tried below version which -i might wrongly assume- includes the correct v2 syntax (replicating my v1 version that works) but connection is still refused, getting a 400 bad request


hass.gerard.com {
	reverse_proxy 192.168.1.39:8123 {
		header_up Host {host}
		header_up X-Real-IP {remote}
		header_up X-Forwarded-For {remote}
		header_up X-Forwarded-Proto {scheme}
	}

  	log {
    		format console
    		output file /var/log/caddy/hass.log
  	}
	header {
		Strict-Transport-Security "max-age=31536000; includeSubdomains"
		X-XSS-Protection "1; mode=block"
		X-Content-Type-Options "nosniff"
		X-Frame-Options "SAMEORIGIN"
		Referrer-Policy "same-origin"
	}

}

You definitely don’t need any of those header_up for Home Assistant, Caddy already sets them correctly. If you use those lines, you end up clobbering Caddy’s own automatic behaviour.

You just need to change a bit of configuration in HA to have it trust requests coming from an upstream proxy. See the HA docs for running it behind a reverse proxy.

I also had already tried without the header_up additions. I added them (per v1) as without them it’s also not working.

On the homeassistant side there is not that much to configure. See below screenshot from documentation.

My config (with IP of trusted proxies changed to new caddy v2 IP):

http:
  base_url: http://192.168.1.39:8123 #Caddy v1 worked with this here. Tried with and without as docs show without
  use_x_forwarded_for: true
  trusted_proxies:
   # - 192.168.1.41 #Caddy v1
    - 192.168.1.181 #Caddy v2
    - 172.30.33.0/24 #Tried with and without, was not needed for Caddy v1 anyway. Tries with and without

With trail and error I finally got below working:


https://hass.gerard.com {
	reverse_proxy 192.168.1.39:8123 {
		header_up X-Real-IP {remote}
	}

  	log {
    		format console
    		output file /var/log/caddy/hass.log
  	}
	header {
		Strict-Transport-Security "max-age=31536000; includeSubdomains"
		X-XSS-Protection "1; mode=block"
		X-Content-Type-Options "nosniff"
		X-Frame-Options "SAMEORIGIN"
		Referrer-Policy "same-origin"
	}

}

So now finally upgraded to v2; Back to my original questions. With below config:

#
bi.gerard.com {
	reverse_proxy 192.168.1.40:99
  	log {
    		format console
    		output file /var/log/caddy/blueiris.log
  	}

}
internet.gerard.com {
	reverse_proxy 192.168.1.42:8443 {
		transport http {
			tls_insecure_skip_verify
		}
	}
  	log {
    		format console
    		output file /var/log/caddy/unifi.log
  	}
}
https://hass.gerard.com {
	reverse_proxy 192.168.1.39:8123 {
		header_up X-Real-IP {remote}
	}

  	log {
    		format console
    		output file /var/log/caddy/hass.log
  	}
	header {
		Strict-Transport-Security "max-age=31536000; includeSubdomains"
		X-XSS-Protection "1; mode=block"
		X-Content-Type-Options "nosniff"
		X-Frame-Options "SAMEORIGIN"
		Referrer-Policy "same-origin"
	}

}

  • Is this indeed a ‘safe’ configuration or should I have used other configuration parameters for this simple use case?
  • My firewall (firewalla) sends me notifications when my network performs abnormal uploads to the outside worls. This is great. But for the 2 servers that are ‘gated’ by Caddy I only get the name of the Caddy Server back (eg “Caddy Proxy has uploaded 30mb to 113.161.194.198 at 9:19AM”) instead of the actual server that is uploading (eg bi.gerard.com for instance). I guess that is because my firewall is presented the encrypted data and only sees the caddy server as the sender. Is there any configuration parameter I can add so my firewall can actually see which server (behind caddy) that is uploading traffic?

I’m certain you can remove X-Real-IP. Caddy sends X-Forwarded-For which has the same information, and you configured HA to read from that header already.

Probably not, because it’s encrypted. Just watch Caddy’s logs, I guess.

This topic was automatically closed after 30 days. New replies are no longer allowed.