Proxying: HAProxy config - scottlamb/moonfire-nvr GitHub Wiki

Below is a HAProxy config file for Moonfire NVR, as an alternative to the nginx config in the Securing Moonfire NVR and exposing it to the Internet guide. It was originally contributed by @Bobberty in #134. @scottlamb made a few tweaks to the forwarding headers as discussed in that PR. It hasn't been tried out in its current state; if you use it, please look at the /api/request endpoint and make sure the addr and secure lines look correct. Fixes welcome!


#
# This is an example file for providing moonfire-nvr TLS connection support using IPv6.
# Additionally, this example provides client certificate authentication.

# This example will allow users on the same /64 subnet to access moonfire-nvr 
# without a client certificate.
#
# For this to work properly, the server requires a FQDN assigned to the IPv6
# address for the server certificate.
#
# Please replace MYSERVERCERT, MYROOT_CA, MYSUBJECTDNCHECK as apropiate.
# And ensure rights are proper for accessing the certificaates.
# 
# For my usage, I utilize a DDNS service and a Cert/Key management system.
# 
# The IPv6 local check depends on the network prefix with a /64.  Replace
# MYIPv6NetworkSubnet with the local network prefix.
#
# This is running on an RPI4/RaspberryPI OS running multiple cameras at a remote site.
# Source build without Docker.
# 
# Note:  I have modified the Systemd unit file to reflect binding to [::1]:8080
#
# As with anything else, this may be a starting place.  Improvements are a necessity for life.
#



global
	log /dev/log	local0
	log /dev/log	local1 notice
	chroot /var/lib/haproxy
	stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
	stats timeout 30s
	user haproxy
	group haproxy
	daemon

	# Default SSL material locations
	ca-base /etc/ssl/certs
	crt-base /etc/ssl/private

	# Default ciphers to use on SSL-enabled listening sockets.
	# For more information, see ciphers(1SSL). This list is from:
	#  https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/
	# An alternative list with additional directives can be obtained from
	#  https://mozilla.github.io/server-side-tls/ssl-config-generator/?server=haproxy
	ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS
	ssl-default-bind-options no-sslv3

defaults
	log	global
	mode	http
	option	httplog
	option	dontlognull
        timeout connect 5000
        timeout client  50000
        timeout server  50000
	errorfile 400 /etc/haproxy/errors/400.http
	errorfile 403 /etc/haproxy/errors/403.http
	errorfile 408 /etc/haproxy/errors/408.http
	errorfile 500 /etc/haproxy/errors/500.http
	errorfile 502 /etc/haproxy/errors/502.http
	errorfile 503 /etc/haproxy/errors/503.http
	errorfile 504 /etc/haproxy/errors/504.http


frontend https
        bind :::443 v6only ssl crt *MYSERVERCERT*.pem verify optional ca-file *MYROOT_CA*.pem crt-ignore-err all ca-ignore-err all 

# Testing for Client Certificate used
        acl clientssl ssl_c_used
        acl clientssl ssl_c_s_dn(OU) "*MYSUBJECTDNCHECK*" 

# Testing for local IPv6
	acl LocalIPv6 src *MYIPv6NetworkSubnet*::/64

# Standard Interface test
	use_backend moonfire if LocalIPv6
	use_backend moonfire if clientssl 

# Fail if not local and no client cert provided
	http-request deny if !LocalIPv6 !clientssl


backend moonfire
        server ipv6 [::1]:8080
        http-request add-header X-Forwarded-Proto https
        option forwardfor header X-Real-IP