Skip to content

📡 Add PPP over Hysteria2 (experimental)#1523

Open
luunarrr wants to merge 1 commit intoapernet:masterfrom
luunarrr:master
Open

📡 Add PPP over Hysteria2 (experimental)#1523
luunarrr wants to merge 1 commit intoapernet:masterfrom
luunarrr:master

Conversation

@luunarrr
Copy link

@luunarrr luunarrr commented Feb 24, 2026

Summary

Add PPP over Hysteria2, making Hysteria2 a true VPN server.

Motivation

Hysteria2 is an application proxy, even under TUN mode. It proxies IPv4 and IPv6 with simple authentication, and that's it.
We want a full VPN solution that utilises existing ISP and telecom ecosystems, all over the existing Hysteria2 protocol.

What's New

  • PPP session support in the Hysteria2 - clients can now initiate a PPP session with pppd over Hysteria2, opening up true VPN-style connectivity with dual-stack and non-IP payload support.
  • Data transport modes:
    • Datagram mode: data transported as QUIC datagrams
    • Multi-stream mode: N parallel QUIC streams with per-flow hashing
  • Termination modes:
    • Local mode: Hysteria2 terminates PPP session with pppd
    • BRAS/BNG/LAC mode: Hysteria2 terminates the the Hysteria2 connection and forwards PPP to LNS (standard LAC-LNS topology) with realm-based routing and load balancing
  • SSTP bridge - a local SSTP server to bridge Windows built-in VPN clients to Hysteria2
  • MLPPP on SSTP bridge - the bridge handles MLPPP and expose a regular SSTP server

Tested With

  • Client: Windows 11 built-in SSTP client (IPv4 and IPv6) with datagram mode. Server: local termination
  • Client: Windows 11 built-in SSTP client (IPv4 and IPv6) with multi-stream mode. Server: local termination
  • Client: Windows 11 built-in SSTP client (IPv4 and IPv6) with data mode x2 (MLPPP). Server: local termination

Not Tested Yet But Plan To

  • LAC-LNS

Example 1

Client (Windows)

server: myserver.example.com:443-10000-50000

auth: myuser:mypass

ppp:
  sstp:  // Windows only have native SSTP client. Omit if you do not need SSTP bridge.
    certDir: "D:\\.hysteria-ppp"
    endpoint: main    //no MLPPP: omit
    user: <ppp user name>
    password: <ppp password>
  dataStreams: 128  // datagram mode: 0 or omit

Open Manage Computer Certificate, import the generated ca.crt as Trusted Root, then create a new SSTP connection points to 127.0.0.1:8443.
Hysteria2 client needs to run with admin privilege for auto server route pining.

Server (Linux)

listen: :443

acme:
  domains:
    - myserver.example.com
  email: me@myserver.example.com

auth:
  type: userpass
  userpass:
    myuser: mypass

// <whatever standard configs you want>
// ACL, outbounds are not supported

ppp:
  enabled: true
  sudo: true
  ipv4Pool: "10.99.0.0/24"
  dns:
    - 8.8.8.8
    - 1.1.1.1

/etc/ppp/pap-secrets

* * hysteria *

If you want IPv6: /etc/ppp/ipv6-up.d/radvd

#!/bin/sh
IFACE="$1"
NUM="${IFACE#ppp}"
PREFIX="fd00:abcd:1234:${NUM}"

ip -6 addr add ${PREFIX}::1/64 dev "$IFACE"
ip -6 route add ${PREFIX}::/64 dev "$IFACE"

cat > /tmp/radvd-${IFACE}.conf <<EOF
interface ${IFACE}
{
    AdvSendAdvert on;
    prefix ${PREFIX}::/64
    {
        AdvOnLink on;
        AdvAutonomous on;
    };
    RDNSS 2001:4860:4860::8888 2001:4860:4860::8844
    {
        AdvRDNSSLifetime 300;
    };

};
EOF
radvd -C /tmp/radvd-${IFACE}.conf -p /tmp/radvd-${IFACE}.pid -n &

If you want the client to access the Internet, you need something like:

sysctl -w net.ipv4.ip_forward=1

iptables -t nat -A PREROUTING -i eth1 -p udp --dport 10000:50000 -j REDIRECT --to-ports 443
ip6tables -t nat -A PREROUTING -i eth1 -p udp --dport 10000:50000 -j REDIRECT --to-ports 443

ip6tables -A FORWARD -i ppp+ -o eth0 -j ACCEPT
ip6tables -A FORWARD -i eth0 -o ppp+ -m state --state RELATED,ESTABLISHED -j ACCEPT
ip6tables -t nat -A POSTROUTING -s fd00:abcd:1234::/48 -o eth0 -j MASQUERADE

ip route replace <ip eth1>/24 dev eth1 scope link table rt_eth1
ip route replace default via <ip eth1> dev eth1 src 172.19.1.4 table rt_eth1
ip -6 route replace <ip6 eth1>/64 dev eth1 table rt_eth1
ip -6 route replace default via <ip6 eth1> dev eth1 table rt_eth1
ip rule add pref 100 from <ip eth1>/32 lookup rt_eth1
ip -6 rule add pref 100 from <ip6 eth1>/128 lookup rt_eth1

iptables -A FORWARD -i ppp+ -o eth0 -j ACCEPT
iptables -A FORWARD -i eth0 -o ppp+ -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

@luunarrr luunarrr changed the title WIP: Add PPP over Hysteria2 📡 Add PPP over Hysteria2 (WIP) Feb 24, 2026
@luunarrr luunarrr changed the title 📡 Add PPP over Hysteria2 (WIP) 📡 Add PPP over Hysteria2 (experiment) Feb 25, 2026
@luunarrr luunarrr changed the title 📡 Add PPP over Hysteria2 (experiment) 📡 Add PPP over Hysteria2 (experimental) Feb 25, 2026
@luunarrr luunarrr force-pushed the master branch 3 times, most recently from 08102d1 to 5605643 Compare February 27, 2026 17:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant