Reviving PPP Tunnels Over Modern HTTP/2 Proxies: A Clever Hack for Firewall Evasion

In an era dominated by modern VPN protocols like WireGuard and OpenSSH tunnels, one developer has breathed new life into Point-to-Point Protocol (PPP)—the workhorse of the dial-up days. By extending the lightweight dumbproxy forward proxy server, they've enabled PPP tunnels to ride over HTTP/2 connections, offering a nostalgic yet powerful method for evading firewalls and state-level censorship.

The Backstory: From Subprocess Mode to Full Tunneling

Dumbproxy, a simple yet versatile HTTP proxy, recently gained a subprocess mode that communicates via stdin/stdout rather than traditional port listening. This feature, initially designed for seamless integration as an OpenSSH ProxyCommand, sparked an idea: why not use it to tunnel entire PPP sessions through an HTTP proxy?

The result is a setup that combines PPP's datagram forwarding with dumbproxy's strengths: TLS-secured connections via Let's Encrypt certificates, flexible authentication (including local password databases), optional active probing resistance, and proven firewall-bypass capabilities. Unlike OpenVPN's limited proxy support—which could be routed through a local dumbproxy instance—this approach pays homage to PPP while delivering direct IP forwarding over the web.

Dial-up era tunnel running over modern HTTP/2, how cool is that?

— Original author, via snawoot.github.io/ppp-over-http2

Server-Side Configuration: Routing to PPP Subprocess

The magic happens in a JavaScript routing script (-js-proxy-router option) that intercepts specific destination addresses and spawns a pppd subprocess. Here's a simplified view of the key addition to /etc/dumbproxy-route.js:

// Match 'pppd:0' and spawn local pppd subprocess
if (url.host === 'pppd:0') {
  return {
    subprocess: {
      argv: ['/usr/sbin/pppd', 'file', '/etc/ppp/options.vpn'],
      env: process.env
    }
  };
}

Server-side pppd options in /etc/ppp/options.vn include standard PPP settings like noauth, nodeflate, mtu 1400, and plugin rp-pppoe.so (optional for flexibility). To enable traffic forwarding:

# Enable IP forwarding
sysctl -w net.ipv4.ip_forward=1

# Masquerade outgoing traffic (iptables example)
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

# Persist with netfilter-persistent if using iptables-persistent
netfilter-persistent save

A cloud-init spec simplifies deployment on cloud instances (source).

Client-Side: PPP Over Proxy with dumbproxy or OpenSSL

On the client, configure a PPP peer file (/etc/ppp/peers/vpn):

pty "dumbproxy h2://LOGIN:[email protected] pppd:0"
name vpn
usepeerdns
replacedefaultroute
persist
noauth
local
mtu 1400
mru 1400
nodeflate
lock
nobsdcomp
nodefaultroute
ipparam vpn
noipdefault

Install dumbproxy (Linux amd64 binary from releases), then bring up the tunnel:

sudo pppd call vpn

# Verify with DNS echo (should show remote IP)
dig +short o-o.myaddr.l.google.com @ns1.dnsecho.net

A post-up script (/etc/ppp/ip-up.d/vpn) handles routing:

#!/bin/sh
# Add direct route to proxy host to avoid loops
ip route add vps.example.org via $5
# Set default route via PPP (preserves on disconnect)
make_default_route_via_ppp $5

For an even more retro twist, skip dumbproxy entirely. Use openssl s_client + chat to mimic modem dialing over HTTP/1.1:

pty /usr/local/bin/dialer.sh h2://LOGIN:[email protected] pppd:0
connect /usr/local/bin/dialer.sh

The dialer.sh script invokes chat with encoded credentials, trading HTTP/2 overhead for simplicity.

Performance and Real-World Impact

Benchmarks show solid throughput: ~25-30 Mbps bidirectional for the HTTP/2 variant and slightly better for HTTP/1.1, respectable for a TCP-carried tunnel. This setup shines in high-censorship environments where traditional VPNs fail, leveraging HTTP's ubiquity to blend in.

# Sample iperf3 results (bidirectional)
[ ID] Interval           Transfer     Bitrate
[  5]   0.00-10.00  sec  27.8 MBytes  23.3 Mbit/s
[  6]   0.iperf3 10.00-20.00 sec  35.2 MBytes  29.5 Mbit configs/sec

Why This Matters for DevOps and Security Pros

This hack underscores the enduring utility of foundational protocols like PPP in modern networking challenges. For DevOps engineers deploying in censored regions, it offers a lightweight, scriptable alternative to bloated VPN clients. Security researchers might adapt it for red-teaming or exfiltration testing, while developers could extend dumbproxy for custom proxying needs.

As HTTP/2 and TLS become table stakes for evasion, innovations like this remind us that old tools, when proxied cleverly, can outmaneuver sophisticated filters—keeping the internet open one tunnel at a time.