Ap
Networking AWS

accel-ppp on AWS User Guide

| Product: accel-ppp

Overview

This guide covers the deployment and use of accel-ppp on AWS using cloudimg AWS Marketplace images. accel-ppp is a high performance, multithreaded PPP server for Linux. It terminates PPP sessions carried over several transports and handles authentication, IP address assignment and session accounting in a single daemon, so it is a natural fit for a self-hosted remote access VPN gateway.

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 on the build machine 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 Runs over TLS on a single TCP port, so it traverses networks and firewalls cleanly. 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 a VPC. 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. A VPC does not carry arbitrary layer 2 frames between instances, 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 instance, 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 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 the distribution'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 from linux-modules
  • l2tp_core, l2tp_ppp, l2tp_netlink from linux-modules-extra-aws, which this image installs as a tracking metapackage so it stays in lockstep with kernel upgrades exactly the way linux-image-aws does

There is no DKMS on this image and no kernel headers are required. Kernel upgrades are safe.

Per instance secrets

Nothing secret is baked into the image. On the first boot of your instance, 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 instance

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.service systemd unit, gated behind a bootstrap marker so it cannot start before first-boot provisioning has written your credentials
  • accel-ppp-firstboot.service systemd oneshot generating every per instance secret and the per instance 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:2000 telnet, 127.0.0.1:2001 tcp)
  • Per instance credentials and connection instructions at /root/accel-ppp-credentials.txt (mode 0600, root only)
  • The latest operating-system security patches applied at build time
  • 24/7 cloudimg support

Connecting to your instance

Connect over SSH on port 22 as the default login user for your operating system variant. Retrieve your per instance credentials once you are in.

OS variant SSH login user
Ubuntu 24.04 ubuntu
ssh ubuntu@<public-ip>

Prerequisites

  • An active AWS account
  • An EC2 key pair for administrative SSH access to the instance
  • A security group you are prepared to scope tightly, this is a remote access endpoint, see Step 2
  • A client that speaks SSTP (Windows has one built in; on Linux use sstp-client) or L2TP

Step 1: Launch the Instance

Launch from the AWS Marketplace listing (EC2 console) or with the CLI. m5.large is the recommended size; size for your expected concurrent session count and throughput. Allow inbound SSH (22) from your own admin address only at launch; you add the VPN port rules narrowly in Step 2.

aws ec2 run-instances \
  --image-id <ami-id> \
  --instance-type m5.large \
  --key-name your-keypair \
  --security-group-ids <security-group-id> \
  --subnet-id <subnet-id> \
  --associate-public-ip-address

Step 2: Scope the Security Group

This instance 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 CIDR with YOUR client range
aws ec2 authorize-security-group-ingress \
  --group-id <security-group-id> \
  --protocol tcp --port 443 --cidr <your-client-cidr>

# L2TP (UDP 1701), only if you intend to use L2TP
aws ec2 authorize-security-group-ingress \
  --group-id <security-group-id> \
  --protocol udp --port 1701 --cidr <your-client-cidr>

Keep SSH (22) restricted to your own admin range. A security group that opens 443 or 1701 to 0.0.0.0/0 exposes your VPN authenticator to the whole internet.

Step 3: 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 (SSTP on 0.0.0.0:443, L2TP on 0.0.0.0:1701, and the two management ports bound to 127.0.0.1 only):

udp UNCONN 0 0 0.0.0.0:1701 0.0.0.0:* users:(("accel-pppd",...))
tcp LISTEN 0 1 127.0.0.1:2000 0.0.0.0:* users:(("accel-pppd",...))
tcp LISTEN 0 1 127.0.0.1:2001 0.0.0.0:* users:(("accel-pppd",...))
tcp LISTEN 0 10 0.0.0.0:443 0.0.0.0:* users:(("accel-pppd",...))

Note the two management ports, 2000 and 2001, are reachable only from the instance itself, never from the network.

accel-ppp service active, version 1.14.0, and ss showing SSTP on 0.0.0.0:443, L2TP on 0.0.0.0:1701 and the management CLI bound to loopback only

Step 4: Read Your Per Instance Credentials

Every secret on this instance was generated at its first boot and exists nowhere else.

sudo cat /root/accel-ppp-credentials.txt

Expected output (your values will differ, they are unique to your instance):

# accel-ppp — Per-VM Credentials
VPN_USERNAME=vpn7Kq2mXfR
VPN_PASSWORD=<24-character random password>
CLI_PASSWORD=<32-character random password>
L2TP_SECRET=<32-character random secret>
SERVER_ADDRESS=<your instance public IP>
SSTP_PORT=443
L2TP_PORT=1701
VPN_GATEWAY=10.60.0.1
VPN_POOL=10.60.0.2-254
SSTP_CERT_SHA256=<the per-instance certificate fingerprint>

Record the SSTP_CERT_SHA256 fingerprint. The TLS certificate is self-signed and unique to your instance, 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 9.

Step 5: 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 6: Connect an SSTP Client

SSTP is the recommended transport. On Windows, create a VPN connection of type SSTP pointing at your instance's public IP, using the VPN_USERNAME and VPN_PASSWORD from Step 4.

On Linux, using sstp-client:

sudo apt-get install -y sstp-client

sudo sstpc --cert-warn --user 'VPN_USERNAME' --password 'VPN_PASSWORD' \
  <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. The screenshot below shows a real authenticated session, the client's assigned pool address, and a packet crossing the tunnel to the gateway.

A live authenticated PPP session: accel-cmd show sessions listing the connected user with a pool address, and a ping crossing the tunnel to the gateway 10.60.0.1

Step 7: 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 instance CLI_PASSWORD from Step 4.

sudo accel-cmd -P '<CLI_PASSWORD>' show stat

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.

The management CLI bound to loopback only, rejected authentication attempts in the auth-fail log, and the in-tree L2TP kernel module shipped by the distribution kernel package

Step 8: 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. For larger deployments, point accel-ppp at your own RADIUS server instead, cloudimg support can help.

Step 9: 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 10: 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 instance 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 instance'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 instance an egress point for every authenticated client.

Step 11: accel-ppp Components

Component Path
Daemon /usr/local/sbin/accel-pppd
Management CLI client /usr/local/bin/accel-cmd
Active config (rendered per instance) /etc/accel-ppp/accel-ppp.conf
Config template (shipped, no secrets) /etc/accel-ppp/accel-ppp.conf.template
SSTP TLS keypair (per instance) /etc/accel-ppp/ssl/
User database /etc/ppp/chap-secrets
Per instance credentials /root/accel-ppp-credentials.txt
Logs /var/log/accel-ppp/
Authentication failures /var/log/accel-ppp/auth-fail.log
Baked licence /usr/local/share/accel-ppp/LICENSE
systemd units accel-ppp.service, accel-ppp-firstboot.service

Step 12: Managing the Service

Read-only status:

systemctl status accel-ppp --no-pager

Control and logs:

sudo systemctl restart accel-ppp
sudo systemctl reload accel-ppp     # re-read chap-secrets without dropping sessions

sudo tail -f /var/log/accel-ppp/accel-ppp.log
sudo journalctl -u accel-ppp -f

Step 13: Enabling PPPoE

PPPoE is compiled in and the module is loaded, but no interface is bound, because a VPC will not carry PPPoE's layer 2 frames between instances. 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 14: Troubleshooting

A client cannot reach the server at all. Check the security group first, this is the most common cause. Confirm an inbound rule exists for the VPN port and that its source covers your client.

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 7. 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

Step 15: Security Recommendations

  • Scope the security group. 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_SHA256 fingerprint to your clients so they can pin it.
  • 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.log is the file to alert on.
  • Keep the instance patched. Unattended upgrades are enabled. Because this image uses no out-of-tree kernel modules, kernel upgrades are safe and require no rebuild.

Step 16: 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; the licence text is baked into the image at /usr/local/share/accel-ppp/LICENSE. Review the licence terms before deploying in production.

cloudimg provides 24/7 support for this image. For assistance, contact support through the AWS Marketplace listing or visit cloudimg.co.uk.