It always bugged me that when there is no possibility of having a VPN to a remote PBS server, you will have to expose the web UI as a whole.
I even did a feature request to create an "API-only" frontend to PBS to limit the attack surface, see: https://bugzilla.proxmox.com/show_bug.cgi?id=7010
I have this running for a while now. I found that neither Caddy nor Nginx were really suitable, because they lack one critical feature that HAproxy has, namely: "option http-server-close".
If you do not have that option, the setup works partially, but on the server side, you will get log entries with "TASK ERROR: connection error: not connected". That does not happen with HAproxy.
You only need to install HAproxy on PBS via "apt install haproxy" and then create /etc/haproxy.cfg like so:
Of course you will have to copy your existing PBS cert via "cat /etc/proxmox-backup/proxy.{pem,key} >/etc/haproxy/proxy.pem", because HAproxy likes the cert and the key in one file.
This will allow only /api2, //api2 and /probe for monitoring purposes on a different port (18007). Any other path will result in an HTTP 500 error.
AFAIK, the API does not allow for any other authorisation type than tokens, so no usernames can be probed and even fingerprinting is limited to the bare minimum should the port be detected.
I even did a feature request to create an "API-only" frontend to PBS to limit the attack surface, see: https://bugzilla.proxmox.com/show_bug.cgi?id=7010
I have this running for a while now. I found that neither Caddy nor Nginx were really suitable, because they lack one critical feature that HAproxy has, namely: "option http-server-close".
If you do not have that option, the setup works partially, but on the server side, you will get log entries with "TASK ERROR: connection error: not connected". That does not happen with HAproxy.
You only need to install HAproxy on PBS via "apt install haproxy" and then create /etc/haproxy.cfg like so:
Code:
global
maxconn 5000
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
stats socket /run/haproxy/admin.sock mode 660 level admin
stats timeout 30s
user haproxy
group haproxy
daemon
nbthread 6
# hard-stop-after 15m
tune.ssl.default-dh-param 4096
nokqueue
# Default SSL material locations
ca-base /etc/ssl/certs
crt-base /etc/ssl/private
# See: [URL]https://ssl-config.mozilla.org/#server=haproxy&server-version=2.0.3&config=intermediate[/URL]
ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-CDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets
defaults
log global
mode http
option httplog
option dontlognull
timeout connect 5000
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
# Parameter
timeout client 3600s
timeout server 3600s
# PBS proxy
frontend pbs_tcp
bind :::18007 name :::18007 ssl crt /etc/haproxy/proxy.pem verify none
mode http
option httplog
option http-server-close
option forwardfor
acl https ssl_fc
http-request set-header X-Forwarded-Proto http if !https
http-request set-header X-Forwarded-Proto https if https
# timeout client 30000
# Probe direkt beantworten
acl path_probe path_beg /probe
http-request return status 200 content-type "text/plain" string "alive" if path_probe
# Nur /api2 Requests an Backend weiterleiten
acl path_api2 path_beg /api2 //api2
use_backend pbs_backend if path_api2
# Alle anderen Requests ablehnen
http-request return status 500 unless path_api2 or path_probe
backend pbs_backend
mode http
server pbs 127.0.0.1:8007 ssl verify none
Of course you will have to copy your existing PBS cert via "cat /etc/proxmox-backup/proxy.{pem,key} >/etc/haproxy/proxy.pem", because HAproxy likes the cert and the key in one file.
This will allow only /api2, //api2 and /probe for monitoring purposes on a different port (18007). Any other path will result in an HTTP 500 error.
AFAIK, the API does not allow for any other authorisation type than tokens, so no usernames can be probed and even fingerprinting is limited to the bare minimum should the port be detected.
Last edited: