This guide explains how to install OpenVPN Access Server on Ubuntu 24 and publish it safely behind Nginx. It includes a production-style reverse proxy layout with generic hostnames so it can be reused in public documentation.
The deployment separates web management traffic and VPN tunnel traffic:
This keeps VPN tunnel encapsulation path efficient while preserving application-layer controls for web management endpoints.
sudo apt-get update
sudo apt-get install -y ca-certificates wget gnupg
wget -qO - https://as-repository.openvpn.net/as-repo-public.gpg | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/as-repo-public.gpg >/dev/null
echo "deb [arch=amd64 signed-by=/etc/apt/trusted.gpg.d/as-repo-public.gpg] http://as-repository.openvpn.net/as/debian noble main" | sudo tee /etc/apt/sources.list.d/openvpn-as-repo.list >/dev/null
sudo apt-get update
sudo apt-get install -y openvpn-as
Verify service and ports:
sudo systemctl status openvpnas --no-pager
sudo ss -tulpn | grep -E ':(943|443|1194)\\b' || true
Create a site file such as /etc/nginx/sites-available/vpn.example.com:
server {
listen 80;
server_name vpn.example.com;
location ^~ /.well-known/acme-challenge/ {
root /var/www/letsencrypt;
default_type "text/plain";
allow all;
}
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
server_name vpn.example.com;
ssl_certificate /etc/letsencrypt/live/vpn.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/vpn.example.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
# Optional: security headers snippet
# include /etc/nginx/snippets/security-headers.conf;
# Keep admin UI private from internet via proxy
location ^~ /admin {
return 403;
}
# API endpoints required by OpenVPN web portal
location ^~ /api/ {
# If WAF is enabled globally, avoid false positives on API JSON payloads
# modsecurity off;
proxy_pass https://10.0.0.10:943;
proxy_http_version 1.1;
proxy_ssl_protocols TLSv1.3;
proxy_ssl_server_name on;
proxy_ssl_name vpn.example.com;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_read_timeout 60s;
proxy_send_timeout 60s;
}
location / {
proxy_pass https://10.0.0.10:943;
proxy_http_version 1.1;
proxy_ssl_protocols TLSv1.3;
proxy_ssl_server_name on;
proxy_ssl_name vpn.example.com;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_read_timeout 60s;
proxy_send_timeout 60s;
}
}
Enable and validate:
sudo ln -s /etc/nginx/sites-available/vpn.example.com /etc/nginx/sites-enabled/vpn.example.com
sudo nginx -t
sudo systemctl reload nginx
Recommended forwarding model:
OpenVPN Access Server is installed on Ubuntu 24 and safely published behind Nginx using a generic, reusable reverse proxy pattern suitable for public documentation, with VPN tunnel traffic and web management traffic clearly separated.