Deployment guide

accel-ppp VPN Server 1.14.0

Overview

accel-ppp is a fast, multithreaded PPP access server for Linux. It terminates remote access VPN sessions (SSTP, L2TP and PPPoE), authenticates users against a local secrets file or RADIUS, and hands each client an address from a pool.

This SecureAnyCloud image runs accel-ppp 1.14.0 on Ubuntu 24.04 on Amazon EC2 as a remote access VPN endpoint using SSTP. SSTP carries PPP inside TLS on TCP 443. The built-in Windows VPN client and sstp-client on Linux both speak it, and it passes through most firewalls because it looks like HTTPS.

This version is one of several in the SecureAnyCloud Hardened WireGuard VPN & VPN, Proxy and Remote Access AMIs listing on AWS Marketplace. You select it as the software version when you subscribe and launch. The other servers in the listing are described on the listing's guide hub.

What you get:

  • accel-ppp 1.14.0 (accel-ppp.service) with SSTP on TCP 443 and a self-signed TLS certificate generated on your instance's first boot
  • Built from the upstream 1.14.0 source tarball (checksum pinned) with no out-of-tree kernel modules. PPP, PPPoE and L2TP support comes from Ubuntu's own kernel modules package, so unattended security upgrades can move the kernel safely
  • One VPN user with a random 24-character password, created on first boot in /etc/accel-ppp/chap-secrets
  • MS-CHAPv2 and CHAP authentication only (PAP and MS-CHAPv1 are not loaded); only listed users can connect
  • The accel-ppp management CLI on 127.0.0.1:2001 only, protected by a per-instance password, and the accel-cli wrapper
  • A self-test, accel-ppp-selftest, that logs in over SSTP from the instance itself
  • No metadata access: accel-ppp.service cannot reach the instance metadata service, and VPN clients cannot route to it
  • L2TP and PPPoE built in as documented opt-ins (Steps 11 and 12)

Default user: ubuntu | Architecture: x86_64 | Root volume: 8 GiB gp3

Security posture

  • No default credential. The image ships with no VPN user, no rendered configuration, no management password and no TLS key. First boot generates the VPN username and password, the management CLI password, an L2TP tunnel secret and the SSTP certificate for this instance only, and writes them to /root/accel-ppp-credentials.txt (root only).
  • Strong authentication only. Clients authenticate with MS-CHAPv2 (Windows) or CHAP. Cleartext PAP and MS-CHAPv1 are not loaded, and any-login=0 means only users in chap-secrets get a session. Wrong passwords and unknown users are refused by the server.
  • TLS 1.2 and 1.3 only on port 443. A request that is not SSTP gets no HTTP answer.
  • The listing security group opens SSH only. Port 443 stays closed until you open it to your own client address ranges (Step 7).
  • Management stays local. The accel-ppp CLI listens on 127.0.0.1:2001 only and needs this instance's CLI password; the telnet CLI is off. sudo accel-cli reads the password from the root-only configuration and passes it on standard input, so it never appears in a process listing or in /var/log/auth.log.
  • Private endpoint by default. IP forwarding is off and no NAT rule exists, so a connected client reaches this instance only, not your VPC or the internet, until you choose to make it a gateway (Step 10). That also means a VPN client cannot reach the instance metadata service through the tunnel.
  • No SSRF to instance credentials. accel-ppp.service carries an IPAddressDeny rule for the metadata addresses (169.254.169.254, fd00:ec2::254, 168.63.129.16), and the AMI is registered IMDSv2 only.
  • Fails closed. accel-ppp starts only after first boot has written this instance's configuration and a ready marker, and a start-up check refuses to run it without the per-instance password, user and certificate. If first boot cannot finish, accel-ppp stays stopped and first boot tries again on the next boot.
  • Durable across kernel upgrades. accel-ppp's optional out-of-tree drivers (IPoE, VLAN monitor, PPTP accelerator) are not built, so nothing breaks when Ubuntu moves the kernel.
  • Per-instance identity. SSH host keys and the machine ID are generated fresh on every instance.

Prerequisites

  • An AWS account and permission to launch EC2 instances
  • An EC2 key pair in the Region you launch in
  • The public IP ranges your VPN clients connect from

Recommended instance type: m5.large. A VPN endpoint for a small team runs comfortably on t3.small or larger.

Connecting to your instance

Version: accel-ppp VPN Server 1.14.0 on Ubuntu 24.04

Operating system: Ubuntu 24.04 LTS | SSH user: ubuntu

1

Launch the instance

Option A: AWS Marketplace console

  • Open the SecureAnyCloud Hardened WireGuard VPN & VPN, Proxy and Remote Access AMIs listing on AWS Marketplace. Choose View purchase options, then Subscribe. One subscription covers every version in the listing.
  • Once the subscription is active, choose Launch your software.
  • Choose One-click launch from AWS Marketplace, or Launch from EC2 Console for the full launch wizard. In Version, select accel-ppp VPN Server 1.14.0 on Ubuntu 24.04, then choose your Region.
  • Pick an instance type and your key pair. m5.large is recommended. The software charge is $0.04 per vCPU per hour.
  • Review the security group. The listing's default group allows SSH (22) only, so restrict it to your own IP address. You open TCP 443 to your VPN clients in Step 7.
  • Choose your VPC and a public subnet, or attach an Elastic IP later. Leave the metadata defaults, because the image already requires IMDSv2. Then choose Launch.

Option B: AWS CLI

Run these commands on your own workstation. They create a security group that allows SSH from your management address and SSTP from your client ranges only, then launch the instance.

Replace the AMI ID with the one shown for your Region on the Marketplace launch page. Replace the VPC, subnet, key pair and CIDR ranges with your own.

SG=$(aws ec2 create-security-group --group-name accel-ppp-vpn \
  --description "accel-ppp SSTP VPN" --vpc-id vpc-0123456789abcdef0 \
  --query GroupId --output text)
aws ec2 authorize-security-group-ingress --group-id "$SG" --protocol tcp --port 22 --cidr <your-mgmt-cidr>
aws ec2 authorize-security-group-ingress --group-id "$SG" --protocol tcp --port 443 --cidr <your-client-cidr>
aws ec2 run-instances \
  --image-id ami-0123456789abcdef0 \
  --instance-type m5.large \
  --key-name my-key-pair \
  --security-group-ids "$SG" \
  --subnet-id subnet-0123456789abcdef0 \
  --associate-public-ip-address \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=accel-ppp-vpn}]'

You do not need --metadata-options: the AMI already makes IMDSv2 required.

2

Connect and read the connection details

Connect as ubuntu with the key pair you chose:

ssh -i ~/.ssh/my-key-pair.pem ubuntu@<public-ip>

First boot finishes within a minute of launch. It creates this instance's VPN user and passwords, issues the SSTP certificate for the instance's public address and public DNS name, and starts accel-ppp.

The details are in /root/accel-ppp-credentials.txt, readable only by root. Run this command to print everything except the three secret lines:

sudo grep -vE '^(VPN_PASSWORD|CLI_PASSWORD|L2TP_SECRET)=' /root/accel-ppp-credentials.txt
# accel-ppp 1.14.0 VPN server - generated on first boot by accel-ppp-firstboot.service
# These values are unique to this instance. Nothing here was baked into the image. SERVER_ADDRESS=18.206.117.157 SSTP_PORT=443 VPN_USERNAME=vpnhbirhrec SSTP_CERT_SHA256=84:BF:BF:19:06:58:FD:14:2B:98:2F:8A:70:FB:E4:3D:A1:A1:E8:C3:6C:EF:37:D6:00:53:38:F3:F2:A0:E4:F1 VPN_GATEWAY=10.60.0.1 VPN_POOL=10.60.0.2-10.60.0.254
# Connect with SSTP (Windows built-in VPN client, sstp-client on Linux) to SERVER_ADDRESS on TCP 443 after you open
# TCP 443 in the security group to your client address ranges only. The certificate is self-signed and unique to
# this instance: trust /etc/accel-ppp/ssl/sstp-cert.pem on the client or check SSTP_CERT_SHA256.
# Add users: /etc/accel-ppp/chap-secrets, then
sudo systemctl restart accel-ppp
# Management CLI:
sudo accel-cli show sessions (loopback only; the CLI password is read from the config)
# Self-test:
sudo accel-ppp-selftest
# Guide: https://secureanycloud.com/stacks/accel-ppp-vpn-server-1-14-0/

Print the VPN password itself only when you need it, with sudo sed -n 's/^VPN_PASSWORD=//p' /root/accel-ppp-credentials.txt.

3

Confirm accel-ppp is running

Run the commands below to check the service. Expect accel-ppp.service to be active and first boot to be complete.

accel-ppp listens on TCP 443 on every interface (SSTP) and on 127.0.0.1:2001 (management CLI). Nothing listens on UDP 1701, because L2TP is off by default.

systemctl is-active accel-ppp.service accel-ppp-firstboot.service /usr/local/sbin/accel-pppd --version sudo ss -Htlnp '( sport = :443 or sport = :2001 )' echo "UDP 1701 listeners: $(sudo ss -Hulnp 'sport = :1701' | wc -l)"
active active accel-ppp 1.14.0 LISTEN 0 10 0.0.0.0:443 0.0.0.0:* users:(("accel-pppd",pid=1031,fd=21)) LISTEN 0 1 127.0.0.1:2001 0.0.0.0:* users:(("accel-pppd",pid=1031,fd=20)) UDP 1701 listeners: 0
4

Run the self-test

Run the shipped self-test. It connects to 127.0.0.1:443 exactly as a VPN client would.

The test checks that the certificate served is this instance's own. It runs the SSTP handshake, PPP negotiation and CHAP authentication with the first-boot user, gets an address from the pool, pings the VPN gateway and opens a TCP connection across the tunnel. It confirms that the instance metadata service is not reachable through the tunnel. It also proves that a wrong password and an unknown user are refused, and that the management CLI answers only to the right password. No password is printed.

sudo accel-ppp-selftest
TLS TLSv1.3 on 127.0.0.1:443 serves this instance's certificate (SHA-256 84bfbf190658fd14) SSTP + CHAP-MD5 login accepted for user vpnhbirhrec tunnel up: client address 10.60.0.2 from the pool, gateway 10.60.0.1 data plane: the gateway 10.60.0.1 answered a ping across the tunnel control: TCP to 10.60.0.1:443 through the tunnel is answered (SYN-ACK) metadata: 169.254.169.254:80 is unreachable from the VPN client (no answer in 6 s; IP forwarding is off) management CLI: 'show sessions' lists the session of vpnhbirhrec refused as expected: the right user with a wrong password (CHAP code 4 from the server) refused as expected: an unknown user (CHAP code 4 from the server) management CLI: answers with this instance's password, silent for a wrong one SELFTEST_OK SSTP login, tunnel, refusals and CLI proven
5

Use the management CLI

Use accel-cli to run one accel-ppp CLI command with this instance's CLI password. show stat prints the daemon's counters. show sessions lists connected users and is empty until a client connects.

sudo accel-cli show stat | head -4 sudo accel-cli show sessions
uptime: 0.00:00:39 cpu: 0% mem(rss/virt): 7928/243736 kB core: ifname | username | calling-sid | ip | type | comp | state | uptime --------+----------+-------------+----+------+------+-------+--------

Other useful commands are sudo accel-cli help, sudo accel-cli terminate if ppp0 (disconnect one session) and sudo accel-cli show sessions ifname,username,ip,uptime.

6

Check the certificate your clients will see

Inspect the certificate that clients will see. It is self-signed and unique to this instance, and it names the instance's public IPv4 address, its private address and its public DNS name.

sudo openssl x509 -in /etc/accel-ppp/ssl/sstp-cert.pem -noout -subject -ext subjectAltName -enddate sudo openssl x509 -in /etc/accel-ppp/ssl/sstp-cert.pem -noout -fingerprint -sha256
subject=CN = 18.206.117.157 X509v3 Subject Alternative Name: IP Address:18.206.117.157, IP Address:172.31.86.50, DNS:ec2-18-206-117-157.compute-1.amazonaws.com notAfter=Oct 23 16:13:31 2036 GMT sha256 Fingerprint=84:BF:BF:19:06:58:FD:14:2B:98:2F:8A:70:FB:E4:3D:A1:A1:E8:C3:6C:EF:37:D6:00:53:38:F3:F2:A0:E4:F1

A client must connect with one of those names. Copy the certificate to each client, for example from your workstation with ssh -i ~/.ssh/my-key-pair.pem ubuntu@<public-ip> sudo cat /etc/accel-ppp/ssl/sstp-cert.pem > sstp-cert.pem. The directory is root only, and the certificate itself is public. Never copy the key: it stays on the instance.

If the public address changes, for example because the instance was stopped without an Elastic IP, re-issue the certificate as shown in Step 13. Do the same if you want clients to use your own DNS name.

7

Open SSTP to your clients and connect

Add an inbound rule for TCP 443 to the instance's security group, only from the public ranges your clients connect from:

aws ec2 authorize-security-group-ingress --group-id <sg-id> --protocol tcp --port 443 --cidr <your-client-cidr>

Windows 10 and 11 (built-in VPN client). Import sstp-cert.pem into Local Computer > Trusted Root Certification Authorities (Manage computer certificates > Import).

Then go to Settings > Network & internet > VPN > Add VPN and fill in the form:

  • VPN provider: Windows (built-in)
  • Server name or address: SERVER_ADDRESS from Step 2, or the public DNS name
  • VPN type: Secure Socket Tunneling Protocol (SSTP)
  • Type of sign-in info: User name and password, using VPN_USERNAME and the VPN password

A self-signed certificate has no revocation list, so Windows may refuse it with a revocation error. Microsoft's documented setting for that case is the NoCertRevocationCheck DWORD set to 1 under HKLM\SYSTEM\CurrentControlSet\Services\Sstpsvc\Parameters. Alternatively, use a certificate from a public CA (Step 13).

Linux (sstp-client). Put the credential in the client's /etc/ppp/chap-secrets (<VPN_USERNAME> * <password> *, mode 0600) so it never appears on a command line. Then connect with the copied certificate:

sudo sstpc --ca-cert sstp-cert.pem --save-server-route --user <VPN_USERNAME> <SERVER_ADDRESS> \
  require-mschap-v2 noauth noipdefault nodefaultroute nobsdcomp nodeflate

Each client gets an address from 10.60.0.2-10.60.0.254 and reaches the server at 10.60.0.1. With the default settings a client reaches the VPN server only. To route clients onward to your VPC or the internet, see Step 10.

8

Add VPN users

Users live in /etc/accel-ppp/chap-secrets (root only), one per line: <username> * <password> *.

The block below creates a user vpnuser2 with a random password inside a root shell, so the password never appears on a sudo command line or in /var/log/auth.log. It then tells accel-ppp to re-read its files and logs the new user in with the self-test, which takes the password on standard input.

sudo bash -c 'F=/etc/accel-ppp/chap-secrets; KEEP="$(grep -v "^vpnuser2[[:space:]]" "$F")" PW="$(openssl rand -base64 33 | tr -dc A-Za-z0-9 | cut -c1-24)" printf "%s\nvpnuser2\t*\t%s\t*\n" "$KEEP" "$PW" > "$F" systemctl reload accel-ppp sleep 2 printf "%s\n" "$PW" | accel-ppp-selftest --user vpnuser2 | tail -1' sudo awk '!/^#/ && NF {print $1}' /etc/accel-ppp/chap-secrets
SELFTEST_OK user vpnuser2 vpnhbirhrec vpnuser2

Give the user their password through a secure channel. To remove a user, delete their line and run sudo systemctl reload accel-ppp.

For more than a handful of users, point accel-ppp at your RADIUS server instead. The radius module is built in; see man accel-ppp.conf.

9

Metadata access is blocked

accel-ppp.service carries an IPAddressDeny rule for the metadata addresses, and IP forwarding is off. As a result, neither the daemon nor a VPN client can reach the instance metadata service. The self-test in Step 4 proves the client side. Confirm the settings:

systemctl show -p IPAddressDeny accel-ppp.service sysctl net.ipv4.ip_forward
IPAddressDeny=168.63.129.16/32 fd00:ec2::254/128 169.254.169.254/32 net.ipv4.ip_forward = 0
10

Route clients onward (optional)

By default a client reaches the VPN server only. To make the instance a gateway into your VPC or to the internet, turn on forwarding and NAT the client pool out of the instance's interface.

Also keep VPN clients away from the metadata service. Drop forwarded traffic to 169.254.169.254, and set the instance's metadata hop limit to 1 so a forwarded request can never get an IMDSv2 token. Replace ens5 with your interface name (ip route show default).

echo 'net.ipv4.ip_forward = 1' | sudo tee /etc/sysctl.d/90-vpn-gateway.conf
sudo sysctl -p /etc/sysctl.d/90-vpn-gateway.conf
sudo iptables -I FORWARD -d 169.254.169.254 -j DROP
sudo iptables -t nat -A POSTROUTING -s 10.60.0.0/24 -o ens5 -j MASQUERADE
sudo apt-get install -y iptables-persistent && sudo netfilter-persistent save aws ec2 modify-instance-metadata-options --instance-id <instance-id> --http-tokens required --http-put-response-hop-limit 1

If clients should resolve names through the VPN, add a dns1= and a dns2= line under [dns] in /etc/accel-ppp/accel-ppp.conf. For example, use the VPC resolver, which is the VPC base address plus two. Then run sudo systemctl restart accel-ppp.

11

L2TP (optional, not encrypted on its own)

L2TP is built in but off. L2TP without IPsec carries PPP in clear text. Use it only on private networks or inside your own IPsec or site-to-site tunnel. The built-in L2TP clients on Windows, macOS and iOS require IPsec and will not connect to it.

To enable it, add l2tp under [modules], open UDP 1701 to the peers that need it, and restart. The per-instance tunnel secret is already in the [l2tp] section (L2TP_SECRET in the credentials file).

sudo sed -i '/^\[modules\]$/a l2tp' /etc/accel-ppp/accel-ppp.conf
sudo systemctl restart accel-ppp
sudo ss -Hulnp 'sport = :1701'
12

PPPoE (optional, needs your own layer-2 network)

PPPoE is a layer-2 protocol, and an AWS VPC does not carry PPPoE frames between instances. It is therefore useful only over a layer-2 path you provide, for example a GRE or VXLAN tunnel to your site.

The pppoe module is loaded with no interface. Bind one at run time with sudo accel-cli pppoe interface add <ifname>. To bind it permanently, add an interface=<ifname> line under [pppoe], then run sudo systemctl restart accel-ppp.

13

Re-issue the certificate (Elastic IP or your own DNS name)

Run accel-ppp-sstp-cert to replace the self-signed certificate. With no argument it reads the current public address and DNS name from the instance metadata. With arguments it uses the names you give, for example your own DNS name.

The command restarts accel-ppp, updates SSTP_CERT_SHA256 in the credentials file and prints the new fingerprint. Re-import the new certificate on your clients afterwards.

sudo accel-ppp-sstp-cert | head -1 sudo accel-ppp-selftest | tail -1
SSTP certificate re-issued for IP:18.206.117.157,DNS:ec2-18-206-117-157.compute-1.amazonaws.com,IP:172.31.86.50 SELFTEST_OK SSTP login, tunnel, refusals and CLI proven

To use a certificate from a public or internal CA instead, copy its full chain to /etc/accel-ppp/ssl/sstp-cert.pem and its key to /etc/accel-ppp/ssl/sstp-key.pem (mode 0600, owner root). Then run sudo systemctl restart accel-ppp. Clients that trust that CA need no certificate import.

14

How the fail-closed start works

accel-ppp starts only once first boot has written /var/lib/sac/data/accel-ppp-ready. Every start also runs a check. The check refuses to start accel-ppp without this instance's CLI password, VPN user file, SSTP key and certificate, or if any of those files is readable by other users. Inspect the start conditions and file modes:

systemctl cat accel-ppp.service | grep -E '^(ConditionPathExists|ExecStartPre)='
sudo stat -c '%a %U:%G %n' /etc/accel-ppp/accel-ppp.conf /etc/accel-ppp/chap-secrets /etc/accel-ppp/ssl/sstp-key.pem /root/accel-ppp-credentials.txt
ConditionPathExists=/var/lib/sac/data/accel-ppp-ready ExecStartPre=/usr/local/sbin/accel-ppp-preflight 600 root:root /etc/accel-ppp/accel-ppp.conf 600 root:root /etc/accel-ppp/chap-secrets 600 root:root /etc/accel-ppp/ssl/sstp-key.pem 600 root:root /root/accel-ppp-credentials.txt
15

Security recommendations

  • Keep TCP 443 open only to the ranges your clients connect from, and TCP 22 only to your management addresses.
  • Give every person their own VPN user (Step 8) and remove users who leave. Alternatively, use RADIUS for central control.
  • Prefer a certificate your clients already trust (Step 13) over importing the self-signed one.
  • If you route clients onward (Step 10), keep the metadata drop rule and the hop limit of 1.
  • Leave unattended security upgrades on, and reboot after kernel updates. accel-ppp needs no rebuild after a kernel update.
  • Session and authentication logs are in /var/log/accel-ppp/ (no passwords are logged).

Support and licensing

accel-ppp is free software maintained by the accel-ppp project and its contributors. It is distributed under the GNU General Public License, version 2 (GPL-2.0), and the license text is at /usr/local/share/doc/accel-ppp/COPYING. This image builds the unmodified 1.14.0 release.

SecureAnyCloud provides the packaging, the secure defaults, the per-instance credentials and certificate, the metadata block, the fail-closed start, the self-test and 24/7 support.

SecureAnyCloud is not affiliated with or endorsed by the accel-ppp project. accel-ppp is used here only to identify the software. Windows is a trademark of Microsoft Corporation.

For help with deployment or configuration, email sales@secureanycloud.com or visit SecureAnyCloud support.

Deploy on AWS

Launch accel-ppp VPN Server 1.14.0 on Ubuntu 24.04 on AWS with 24/7 support from SecureAnyCloud.

View on Marketplace

Need Help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on AWS