accel-ppp on Ubuntu 24.04 on Azure User Guide
Overview
This guide covers the deployment and configuration of accel-ppp on Ubuntu 24.04 on Azure using cloudimg Azure Marketplace images. accel-ppp is a high performance PPP server for Linux. It terminates PPP sessions carried over several transports and handles authentication, IP address assignment and session accounting in a single multi threaded daemon.
The image builds accel-ppp 1.14.0 from the upstream source tag (commit 048d31cb, dated 25 January 2026), verified against a pinned commit hash at build time. accel-ppp is GPL-2.0 licensed, confirmed from the COPYING file in that source tree.
Which transports this image ships, and why
accel-ppp supports more transports than this image enables. The selection is deliberate:
| Transport | Shipped | Why |
|---|---|---|
| SSTP (TCP 443) | Yes — the recommended mode on Azure | Runs over TLS on a single TCP port, so it traverses the Azure virtual network and most restrictive client networks. Works with the Windows built in SSTP client and with sstp-client on Linux. |
| L2TP (UDP 1701) | Yes | Runs over IP, so it works normally on Azure. Note that raw L2TP is not encrypted on its own — see the security section. |
| PPPoE (layer 2) | Yes, but no interface is bound by default | PPPoE is a layer 2 protocol. The Azure virtual network does not carry arbitrary layer 2 frames between VMs, so PPPoE is only usable if you supply your own layer 2 path. |
| IPoE, VLAN monitoring | No | These require out of tree kernel modules. See the note below. |
| PPTP | No | PPTP's MS-CHAPv2 and MPPE construction is considered broken and should not be used for new deployments. |
No out of tree kernel modules
This matters for the long term health of your VM, so it is worth being explicit.
accel-ppp can build three out of tree kernel modules (ipoe, vlan_mon and an optional pptp accelerator). Out of tree modules are compiled against one specific kernel version. If they were shipped in an image, they would work on first boot and then stop working the first time Ubuntu's unattended upgrades moved the kernel — a failure that arrives weeks later, with no obvious cause.
All three are opt in in accel-ppp's build system, and this image does not build any of them. Everything accel-ppp needs from the kernel here is in tree and ships inside Ubuntu's own kernel module packages, which apt upgrades in the same transaction that moves the kernel:
ppp_generic(provides/dev/ppp),pppox,pppoe,ppp_mppe— fromlinux-modulesl2tp_core,l2tp_ppp,l2tp_netlink— fromlinux-modules-extra-azure, which this image installs as a tracking metapackage so it stays in lockstep with kernel upgrades exactly the waylinux-image-azuredoes
There is no DKMS on this image and no kernel headers are required. Kernel upgrades are safe.
Per VM secrets
Nothing secret is baked into the image. On the first boot of your VM, accel-ppp-firstboot.service generates:
- a random VPN username and a 24 character password, written to
/etc/ppp/chap-secrets(mode 0600, root only) - a 32 character password for the accel-ppp management CLI
- a 32 character L2TP tunnel secret
- a fresh self signed SSTP TLS keypair, unique to your VM
The published image ships /etc/ppp/chap-secrets with zero users and the TLS key directory empty. The build verifies this with five independent checks and refuses to publish the image if anything is found there.
What is included:
-
accel-ppp 1.14.0 built from the pinned upstream source tag, installed to
/usr/local -
accel-ppp.servicesystemd unit, gated behind a bootstrap marker so it cannot start before first boot provisioning has written your credentials -
accel-ppp-firstboot.servicesystemd oneshot generating every per VM secret and the per VM SSTP TLS keypair -
SSTP listener on TCP 443 with your own TLS certificate, and L2TP listener on UDP 1701
-
PPPoE support available for customer supplied layer 2 topologies, with no interface bound by default
-
Password protected management CLI bound to loopback only (
127.0.0.1:2000telnet,127.0.0.1:2001tcp) -
Per VM credentials and connection instructions at
/root/accel-ppp-credentials.txt(mode 0600, root only) -
Ubuntu 24.04 LTS base with latest security patches applied at build time
-
Azure Linux Agent for seamless cloud integration and SSH key injection
-
24/7 cloudimg support with guaranteed 24 hour response SLA
Prerequisites
-
An active Azure subscription
-
An SSH keypair for administrative access to the VM
-
A Network Security Group you are prepared to scope tightly — this is a remote access endpoint, see Step 3
-
A client that speaks SSTP (Windows has one built in; on Linux use
sstp-client) or L2TP
Step 1: Deploy from the Azure Portal
-
In the Azure Portal, search the Marketplace for accel-ppp VPN Server on Ubuntu 24.04 LTS and select the cloudimg offering.
-
Choose Standard_B2s or larger. accel-ppp is efficient, but size for your expected concurrent session count and throughput.
-
Set the administrator username and upload your SSH public key.
-
On the Networking tab, allow inbound SSH (22) from your own admin address only. Do not open 443 or 1701 to the internet here — add those rules narrowly in Step 3.
-
Review and create.
Step 2: Deploy from the Azure CLI
az group create --name accel-ppp-rg --location eastus
az vm create \
--resource-group accel-ppp-rg \
--name accel-ppp-vm \
--image cloudimg:accel-ppp-ubuntu-24-04:default:latest \
--size Standard_B2s \
--admin-username azureuser \
--generate-ssh-keys \
--public-ip-sku Standard
Step 3: Scope the Network Security Group
This VM terminates VPN sessions. Exposing it broadly invites credential stuffing against your PPP authenticator. Open the VPN ports only to the source ranges your clients actually connect from.
# SSTP (TCP 443) — replace the source prefix with YOUR client range
az network nsg rule create \
--resource-group accel-ppp-rg \
--nsg-name accel-ppp-vmNSG \
--name allow-sstp \
--priority 300 \
--source-address-prefixes 203.0.113.0/24 \
--destination-port-ranges 443 \
--protocol Tcp --access Allow
# L2TP (UDP 1701) — only if you intend to use L2TP
az network nsg rule create \
--resource-group accel-ppp-rg \
--nsg-name accel-ppp-vmNSG \
--name allow-l2tp \
--priority 310 \
--source-address-prefixes 203.0.113.0/24 \
--destination-port-ranges 1701 \
--protocol Udp --access Allow
A fresh Azure NSG does not open 443 or 1701 for you. You are adding these rules, so add them narrowly.
Step 4: Connect via SSH
ssh azureuser@<vm-public-ip>
Step 5: Verify the accel-ppp Service
systemctl is-active accel-ppp.service
sudo /usr/local/sbin/accel-pppd --version
Expected output:
active
accel-ppp 1.14.0
Confirm the daemon is listening where it should be, and — just as importantly — where it should not be:
sudo ss -tulnp | grep accel-pppd
Expected output:
udp UNCONN 0 0 0.0.0.0:1701 0.0.0.0:* users:(("accel-pppd",pid=14005,fd=23))
tcp LISTEN 0 1 127.0.0.1:2000 0.0.0.0:* users:(("accel-pppd",pid=14005,fd=20))
tcp LISTEN 0 1 127.0.0.1:2001 0.0.0.0:* users:(("accel-pppd",pid=14005,fd=21))
tcp LISTEN 0 10 0.0.0.0:443 0.0.0.0:* users:(("accel-pppd",pid=14005,fd=22))
Note the two management ports, 2000 and 2001, are bound to 127.0.0.1 — they are reachable only from the VM itself, never from the network.

Step 6: Read Your Per VM Credentials
Every secret on this VM was generated at its first boot and exists nowhere else.
sudo cat /root/accel-ppp-credentials.txt
Expected output (your values will differ — these are unique to your VM):
# accel-ppp — Per-VM Credentials
# Generated on first boot: 2026-07-20T02:02:59Z
# These values are unique to THIS VM. Nothing here was baked into the image.
VPN_USERNAME=vpn7Kq2mXfR
VPN_PASSWORD=<24-character random password>
CLI_PASSWORD=<32-character random password>
L2TP_SECRET=<32-character random secret>
SERVER_ADDRESS=20.85.234.122
SSTP_PORT=443
L2TP_PORT=1701
VPN_GATEWAY=10.60.0.1
VPN_POOL=10.60.0.2-254
SSTP_CERT_SHA256=48:48:B0:90:83:04:FB:7A:90:AC:06:72:E1:31:31:E8:7E:B9:EE:91:73:04:59:C1:A2:94:B6:4D:87:3F:5E:04
Record the SSTP_CERT_SHA256 fingerprint. The TLS certificate is self signed and unique to your VM, so your clients should verify it by this fingerprint rather than trusting it blindly. Replacing it with a CA issued certificate is covered in Step 11.

Step 7: Confirm the User Database
The image ships with no users at all. First boot creates exactly one.
sudo grep -vE '^\s*(#|$)' /etc/ppp/chap-secrets
Expected output — one line, four columns (client, server, secret, permitted addresses):
vpn7Kq2mXfR * <your 24-character password> *
Step 8: Connect an SSTP Client
SSTP is the recommended transport on Azure. On Windows, create a VPN connection of type SSTP pointing at your VM's public IP, using the VPN_USERNAME and VPN_PASSWORD from Step 6.
On Linux, using sstp-client:
sudo apt-get install -y sstp-client
sudo sstpc --cert-warn --user '<VPN_USERNAME>' --password '<VPN_PASSWORD>' \
<vm-public-ip>:443 \
noauth nodetach usepeerdns require-mschap-v2 noipdefault defaultroute
Once connected, the client receives an address from the 10.60.0.2-254 pool and can reach the server at 10.60.0.1.
Step 9: Verify Sessions with the Management CLI
accel-ppp ships a management CLI. On this image it is bound to loopback only and protected with your per VM CLI_PASSWORD.
sudo accel-cmd -P '<CLI_PASSWORD>' show stat
Expected output:
uptime: 0.00:01:32
cpu: 0%
mem(rss/virt): 7996/113340 kB
core:
mempool_allocated: 134245
mempool_available: 132605
thread_count: 4
thread_active: 1
context_count: 5
sessions:
starting: 0
active: 0
To list live sessions:
sudo accel-cmd -P '<CLI_PASSWORD>' show sessions
A note on accel-cmd and wrong passwords. If you supply an incorrect password, accel-cmd prints nothing and still exits with status 0 — it does not report the authentication failure. The server is enforcing authentication correctly; it is the client tool that is quiet about it. If a command returns no output, check your password first. Do not build scripts that treat accel-cmd's exit code as proof of success.

Step 10: Add More VPN Users
Add one line per user to /etc/ppp/chap-secrets, in the same four column format, then reload:
# client server secret permitted-addresses
echo -e "alice\t*\t$(openssl rand -base64 24 | tr -dc 'A-Za-z0-9' | cut -c1-24)\t*" | sudo tee -a /etc/ppp/chap-secrets
sudo systemctl reload accel-ppp
Keep the file at mode 0600 owned by root. Passwords are stored in plaintext in this file, which is why its permissions matter.
Step 11: Replace the SSTP Certificate (Recommended for Production)
The first boot certificate is self signed. For production, install a certificate issued for a hostname your clients trust:
sudo cp fullchain.pem /etc/accel-ppp/ssl/sstp-cert.pem
sudo cp privkey.pem /etc/accel-ppp/ssl/sstp-key.pem
sudo chmod 0600 /etc/accel-ppp/ssl/sstp-key.pem /etc/accel-ppp/ssl/sstp-cert.pem
sudo chown root:root /etc/accel-ppp/ssl/sstp-key.pem /etc/accel-ppp/ssl/sstp-cert.pem
sudo systemctl restart accel-ppp
Then verify what is actually being served:
echo | openssl s_client -connect 127.0.0.1:443 2>/dev/null | openssl x509 -noout -subject -dates
Step 12: Enable Internet Egress for Clients (Optional)
By design this image is a private remote access endpoint, not an open internet gateway. IP forwarding and NAT are deliberately switched off, so connected clients can reach the VM and each other but do not get internet egress through it.
Turn it into a full tunnel gateway only if that is what you want:
# Enable forwarding
echo 'net.ipv4.ip_forward = 1' | sudo tee /etc/sysctl.d/99-accel-ppp.conf
sudo sysctl -p /etc/sysctl.d/99-accel-ppp.conf
# NAT client traffic out of the VM's primary interface
WAN=$(ip route show default | awk '{print $5; exit}')
sudo iptables -t nat -A POSTROUTING -s 10.60.0.0/24 -o "$WAN" -j MASQUERADE
sudo iptables -A FORWARD -s 10.60.0.0/24 -j ACCEPT
Persist the rules with iptables-persistent if you want them to survive a reboot. Understand that this makes your VM an egress point for every authenticated client.
Step 13: accel-ppp Components
| Component | Path |
|---|---|
| Daemon | /usr/local/sbin/accel-pppd |
| Management CLI client | /usr/local/bin/accel-cmd |
| Active config (rendered per VM) | /etc/accel-ppp/accel-ppp.conf |
| Config template (shipped, no secrets) | /etc/accel-ppp/accel-ppp.conf.template |
| SSTP TLS keypair (per VM) | /etc/accel-ppp/ssl/ |
| User database | /etc/ppp/chap-secrets |
| Per VM credentials | /root/accel-ppp-credentials.txt |
| Logs | /var/log/accel-ppp/ |
| Authentication failures | /var/log/accel-ppp/auth-fail.log |
| systemd units | accel-ppp.service, accel-ppp-firstboot.service |
Step 14: Managing the Service
# Status and control
systemctl status accel-ppp
sudo systemctl restart accel-ppp
sudo systemctl reload accel-ppp # re-read chap-secrets without dropping sessions
# Logs
sudo tail -f /var/log/accel-ppp/accel-ppp.log
sudo tail -f /var/log/accel-ppp/auth-fail.log
sudo journalctl -u accel-ppp -f
Step 15: Enabling PPPoE
PPPoE is compiled in and the module is loaded, but no interface is bound, because Azure's virtual network will not carry PPPoE's layer 2 frames between VMs. Bind it only if you have supplied your own layer 2 path — a VXLAN or GRE overlay, a nested virtualisation lab, or an on premises bridge.
sudo sed -i 's/^ac-name=cloudimg-accel-ppp/ac-name=cloudimg-accel-ppp\ninterface=<your-l2-interface>/' \
/etc/accel-ppp/accel-ppp.conf
sudo systemctl restart accel-ppp
Authentication, address assignment and accounting behave exactly as they do for SSTP and L2TP — the same chap-secrets database and the same address pool.
Step 16: Troubleshooting
A client cannot reach the server at all. Check the NSG first — this is the most common cause. Confirm the rule exists and that its source prefix covers your client:
az network nsg rule list --resource-group accel-ppp-rg --nsg-name accel-ppp-vmNSG -o table
The TLS handshake succeeds but authentication fails. Check the authentication failure log, which records every rejected attempt:
sudo tail -20 /var/log/accel-ppp/auth-fail.log
Then confirm the username exists and the password matches /etc/ppp/chap-secrets.
accel-cmd returns nothing. Almost always a wrong CLI_PASSWORD — see the note in Step 9. Re read it from /root/accel-ppp-credentials.txt.
L2TP clients cannot establish a tunnel. Some clients, including the Windows built in L2TP/IPsec client, cannot supply an L2TP tunnel secret. If yours cannot, comment out the secret= line and restart. PPP level authentication still gates every session:
sudo sed -i 's/^secret=/#secret=/' /etc/accel-ppp/accel-ppp.conf
sudo systemctl restart accel-ppp
The service will not start after a config edit. Check the daemon's own error log:
sudo tail -30 /var/log/accel-ppp/core.log
sudo journalctl -u accel-ppp -n 40 --no-pager

Step 17: Security Recommendations
-
Scope the NSG. Restrict TCP 443 and UDP 1701 to the source ranges your clients actually use, and keep SSH restricted to your admin range. This is the single most important control on a VPN endpoint.
-
Prefer SSTP over raw L2TP. SSTP is carried inside TLS. Raw L2TP without IPsec is not encrypted — if you use L2TP, put it inside IPsec or treat the traffic as though it were on the open internet.
-
Replace the self signed SSTP certificate with a CA issued one for production, or distribute the
SSTP_CERT_SHA256fingerprint to your clients so they can pin it. A client configured to ignore certificate errors is vulnerable to interception. -
Protect
/etc/ppp/chap-secrets. It holds plaintext passwords. Keep it 0600 root owned, and use distinct passwords per user so one compromise does not expose the rest. -
Leave IP forwarding off unless you specifically need full tunnel egress. An egress gateway is a much larger blast radius than a private remote access endpoint.
-
Watch the authentication failure log. Repeated failures against valid usernames indicate credential stuffing.
/var/log/accel-ppp/auth-fail.logis the file to alert on. -
Keep the VM patched. Unattended upgrades are enabled. Because this image uses no out of tree kernel modules, kernel upgrades are safe and require no rebuild.
Step 18: Support and Licensing
accel-ppp is licensed under the GNU General Public License, version 2, confirmed from the COPYING file in the 1.14.0 source tree. Review the licence terms before deploying in production.
cloudimg provides 24/7 support for this image with a guaranteed 24 hour response SLA. For assistance, contact support through the Azure Marketplace listing or visit cloudimg.co.uk.