Load Balancing
Load balancing web console
All hosts in a Pritunl cluster can be used to access the web console. For high demand clusters that handle a lot of single sign-on users it is best to setup a Pritunl host dedicated for web console access that does not host any vpn servers. A single dedicated web console Pritunl server should handle almost all high demand configurations but if additional capacity or high availability is required a load balancer can be used. To do this enable the reverse proxy option, this will configure the server to read the X-Forwarded-For and X-Forwarded-Proto headers. If X-Forwarded-Proto is equal to http the client will always be redirected to HTTPS even if the Pritunl server is running with SSL off and on port 80. Load balancers can be configured to proxy both HTTP and HTTPS traffic to the Pritunl server and as long as the load balancer sets the X-Forwarded-Proto header the Pritunl server will handle HTTPS redirection. The /check handler will return 200 if the Pritunl server is online and connected to the database.
sudo pritunl set app.reverse_proxy true
sudo pritunl set app.redirect_server false
sudo pritunl set app.server_ssl false
sudo pritunl set app.server_port 80Domain Configuration
When configuring a load balancer configure the relevant domains as documented below.
Hosts Tab
Host Public Address: The public IPv4 address or domain of the Pritunl host. This should always be the public IP of the host for all configurations even when using a load balancer.
Host Public IPv6 Address: The public IPv6 address or domain of the Pritunl host. This should always be the public IP of the host for all configurations even when using a load balancer.
Host Sync Address: In the advanced host settings. The public address or domain that the web server of the Pritunl servers can be accessed from. If a load balancer is configured that address should be set here.
Top Right Settings
Connection Single Sign-On Domain: Only shown when using single sign-on connection authentication. The public address or domain that is used to validate single sign-on requests through the Pritunl web server for a new VPN connection. If a load balancer is configured that address should be set here. Requires valid SSL certificate.
Configuration Sync
When configuring load balancing the clients will not be able to access the hosts directly to sync the configuration. This is fixed by setting the Sync Address in the host settings to the domain name of the load balancer.
HAProxy Configuration
Below is an example HAProxy configuration for Pritunl. This requires a certificate at /etc/ssl/haproxy.pem.
global
    log 127.0.0.1 local2
    chroot /var/lib/haproxy
    pidfile /var/run/haproxy.pid
    maxconn 4000
    user haproxy
    group haproxy
    daemon
    stats socket /var/lib/haproxy/stats
    tune.ssl.default-dh-param 2048
defaults
    mode http
    log global
    option httplog
    option dontlognull
    option http-server-close
    option forwardfor
    retries 3
    timeout http-request 10s
    timeout queue 1m
    timeout connect 10s
    timeout client 1m
    timeout server 1m
    timeout http-keep-alive 10s
    timeout check 10s
    maxconn 4000
frontend http
    bind :::80 v4v6
    reqadd X-Forwarded-Proto:\ http
    default_backend backend
frontend https
    bind :::443 v4v6 ssl crt /etc/ssl/haproxy.pem
    reqadd X-Forwarded-Proto:\ https
    default_backend backend
backend backend
    balance roundrobin
    server pritunl0 <PRITUNL0_IP>:80 check
    server pritunl1 <PRITUNL1_IP>:80 checkNginx Configuration
The Nginx configuration below uses SSL for the upstream connection. In this configuration the Pritunl server should be configured with SSL.
sudo pritunl set app.reverse_proxy true
sudo pritunl set app.redirect_server false
sudo pritunl set app.server_ssl true
sudo pritunl set app.server_port 8443Configure the Nginx configuration and self-signed certificate for unmatched domains. Replace 123.123.123.123 with the IP address of the Pritunl server and demo.pritunl.com with the domain name of the server.
sudo openssl req -x509 -nodes -days 18250 -newkey rsa:2048 -keyout /etc/nginx/ssl/notfound.key -out /etc/nginx/ssl/notfound.crt
sudo tee /etc/nginx/nginx.conf << EOF
user nginx;
worker_processes auto;
worker_cpu_affinity auto;
worker_rlimit_nofile 400000;
pcre_jit on;
events {
    worker_connections 20000;
    multi_accept on;
    use epoll;
}
http {
    server_tokens off;
    charset utf-8;
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    access_log off;
    client_header_timeout 45;
    client_body_timeout 45;
    keepalive_timeout 65;
    connection_pool_size 1024;
    request_pool_size 8k;
    client_header_buffer_size 2k;
    client_body_buffer_size 32k;
    server_names_hash_bucket_size 512;
    server_names_hash_max_size 1024;
    types_hash_max_size 2048;
    server {
        listen 80;
        listen [::]:80;
        server_name _;
        return 404;
    }
    server {
        listen 443 ssl;
        listen [::]:443 ssl;
        ssl_certificate /etc/nginx/ssl/notfound.crt;
        ssl_certificate_key /etc/nginx/ssl/notfound.key;
        server_name _;
        return 404;
    }
    include /etc/nginx/conf.d/*.conf;
}
EOF
sudo tee /etc/nginx/conf.d/pritunl-vpn.conf << EOF
upstream pritunl-vpn {
    server 123.123.123.123:8443;
}
server {
    listen 80;
    listen [::]:80;
    root /usr/share/nginx/html;
    server_name demo.pritunl.com;
    location / {
        return 301 https://demo.pritunl.com\$request_uri;
    }
}
server {
    listen 443 ssl;
    listen [::]:443 ssl;
    ssl_certificate /etc/nginx/ssl/demo.pritunl.com.crt;
    ssl_certificate_key /etc/nginx/ssl/demo.pritunl.com.key;
    server_name demo.pritunl.com;
    location / {
        proxy_pass https://pritunl-vpn;
        proxy_ssl_verify off;
        proxy_set_header Host \$http_host;
        proxy_set_header X-Forwarded-For \$remote_addr;
        proxy_set_header X-Real-IP \$remote_addr;
    }
}
EOFBelow is a certbot script to generate a LetsEncrypt certificate for the server.
sudo dnf -y install certbot
sudo tee /etc/systemd/system/certbot.target << EOF
[Unit]
Description=Cerbot target
StopWhenUnneeded=yes
EOF
sudo tee /etc/systemd/system/certbot.timer << EOF
[Unit]
Description=Cerbot timer
[Timer]
OnCalendar=*-*-* 8:00:00
Unit=certbot.target
[Install]
WantedBy=basic.target
EOF
sudo tee /etc/systemd/system/certbot.service << EOF
[Unit]
Description=Cerbot
Wants=certbot.timer
[Service]
ExecStart=/usr/bin/certbot-nginx
[Install]
WantedBy=certbot.target
EOF
sudo tee /usr/bin/certbot-nginx << EOF
#!/bin/bash
getcert () {
  echo "Getting certificate email=\$1 domain=\$2"
  /usr/bin/certbot --webroot --agree-tos --non-interactive --webroot-path /usr/share/nginx/html --preferred-challenges http --email \$1 -d \$2 certonly
  /usr/bin/cp -f /etc/letsencrypt/live/\$2/fullchain.pem /etc/nginx/ssl/\$2.crt
  /usr/bin/chown nginx:nginx /etc/nginx/ssl/\$2.crt
  /usr/bin/cp -f /etc/letsencrypt/live/\$2/privkey.pem /etc/nginx/ssl/\$2.key
  /usr/bin/chown nginx:nginx /etc/nginx/ssl/\$2.key
}
getcert "contact@pritunl.com" "demo.pritunl.net"
/usr/bin/chown -R nginx:nginx /etc/nginx/ssl
/usr/bin/chmod 600 /etc/nginx/ssl/*
/usr/sbin/restorecon -R -v /etc/nginx
/usr/bin/systemctl reload nginx
EOF
sudo chmod +x /usr/bin/certbot-nginxGenerate the initial certificate and start the server.
sudo /usr/bin/certbot-nginx
sudo systemctl daemon-reload
sudo systemctl enable certbot.service
sudo systemctl enable certbot.timer
sudo systemctl start certbot.timer
sudo systemctl restart nginx
sudo systemctl enable nginxLast updated

