Safeguard
Supply Chain Security•

PPPoE Explained: Broadband Session Discovery, Auth and Security

PPPoE runs PPP over Ethernet so ISPs can log in each line. How discovery, PAP/CHAP, IPCP, the 1492 MTU and RADIUS work, and how to secure the setup.

Safeguard Security Team
47 min read

PPPoE (PPP over Ethernet, RFC 2516, February 1999) runs a dial up style login over Ethernet. Your router finds the provider's access concentrator with a four packet discovery exchange (PADI, PADO, PADR, PADS) and gets a session ID, then runs PPP inside that session to authenticate with PAP or CHAP and receive its IPv4 address and IPv6 settings.

Securing it comes down to a handful of habits: refuse PAP when the provider supports CHAP, treat the PPPoE username and password as a real credential that leaks through configuration backups, accept offers only from the access concentrator you expect, clamp TCP MSS so the 8 byte PPPoE overhead does not break large transfers, and keep the router software that runs all of this patched.

This post goes one level deeper than our look at how a home router is made and our explainers on DHCP and IPv6 address autoconfiguration. It walks the discovery stage packet by packet, follows a PPP session from LCP to IPv6 prefix delegation, works through the MTU arithmetic with numbers, describes the provider side (BNG, RADIUS and VLAN design from Broadband Forum TR-101), lists the real security weaknesses, and ends with a Linux and OpenWrt lab you can run.

Key takeaways

  • PPPoE has two stages. Discovery uses EtherType 0x8863 and five packet types (PADI 0x09, PADO 0x07, PADR 0x19, PADS 0x65, PADT 0xa7). The session stage uses EtherType 0x8864 and carries PPP frames tagged with the session ID.
  • Inside the session, PPP runs LCP to set up the link, then authentication (PAP, CHAP, MS-CHAPv2 or EAP), then IPCP for IPv4 and IPv6CP for an IPv6 interface identifier. Global IPv6 usually arrives through router advertisements and DHCPv6 prefix delegation.
  • PPPoE costs 8 bytes per packet (6 byte PPPoE header plus 2 byte PPP protocol field), which is why the default PPP MTU is 1492 and the IPv4 TCP MSS is 1452. RFC 4638 (September 2006) lets both ends agree on a larger MRU when the Ethernet path supports 1508 byte frames.
  • The protocol itself has almost no security. Discovery packets are unauthenticated broadcasts, PADT teardown carries no proof of origin, and PAP sends the password in clear text. The provider's access network design (one VLAN per line, access loop identification) does most of the protecting.
  • The provider side is a Broadband Network Gateway (BNG, older name BRAS) that terminates sessions and asks a RADIUS server (RFC 2865) whether the credentials are valid. RADIUS over UDP depends on MD5, and the 2024 Blast RADIUS forgery issue (CVE-2024-3596) is a reminder to use Message-Authenticator and TLS transport where possible.
  • Your PPPoE password sits in your router configuration. Configuration exports, support bundles and screenshots leak it more often than any network attack does.

What PPPoE is, and why it is still everywhere

The problem PPPoE solved

In the dial up era, PPP (RFC 1661, July 1994, Internet Standard STD 51) was how a computer and an ISP agreed to talk over a serial line. PPP gave the ISP exactly what it wanted for a subscriber business: a login per user, a point in the protocol where the user is accepted or refused, a clean start and stop for every session that can be logged for billing, and a way to hand the user an IP address and DNS servers.

When DSL arrived, the cheapest way to connect several computers at a customer site to a modem was Ethernet. Ethernet, though, is a shared broadcast medium with no idea of a login. RFC 2516 states the goal plainly: connect many hosts over "a simple bridging access device" to a remote access concentrator, while keeping access control and billing "on a per-user, rather than a per-site, basis". The trick is to keep PPP and run it over Ethernet. To do that, each PPP session has to learn the MAC address of the remote peer and agree on a unique session identifier, so RFC 2516 adds a small discovery protocol in front of PPP.

Why DSL and many fibre ISPs still use it

Twenty five years on, PPPoE is still common on DSL and on a fair share of fibre networks. The reasons are operational rather than technical:

  • The back office already speaks PPP and RADIUS. Provisioning systems, RADIUS policy, accounting records and support scripts were built around a username per line. Moving to a different session model means changing all of them at once.
  • Explicit session start and stop. A PPP session has a clear beginning (authentication succeeds) and end (LCP terminates or PADT arrives). Accounting and lawful logging map neatly onto that.
  • Wholesale and resale. In many markets one company owns the access network and several retail ISPs sell service over it. A login domain such as the retailer.example in user@retailer.example lets the wholesale network steer each session to the right retailer. TR-101's reference architecture shows network service providers reached through L2TP, and notes that in a wholesale environment the access loop identifier can be passed on to the retailer.
  • Portable credentials. A subscriber can move a router between lines, or an ISP can identify a customer by login rather than by line, which some providers prefer for support.

How it differs from IPoE with DHCP

The main alternative is IPoE: plain IP over Ethernet, with the router getting its address from DHCP (DHCPv4 and DHCPv6) instead of from PPP. The Broadband Forum's TR-146 "Subscriber Sessions" (Issue 1, May 2013) describes how a provider builds the same per subscriber control on top of IPoE: a subscriber session is recognised from DHCP and the access line rather than from a PPP login, and liveness is checked with techniques such as BFD echo or IPv6 neighbour unreachability detection instead of LCP echo.

In practice:

  • IPoE identifies the line, PPPoE identifies the login. With IPoE the provider usually authenticates the physical port or VLAN, often using the access loop identifier that the access node inserts into DHCP. With PPPoE the user also presents a username and password.
  • IPoE has no extra header. There is no 8 byte PPPoE overhead, so the full 1500 byte MTU is available.
  • PPPoE carries its own keepalive and teardown. IPoE relies on DHCP leases and external liveness checks.
  • The two models need different tooling. IPoE sessions are built from DHCP, relay agent options and liveness checks; PPPoE sessions come with their own login, keepalive and teardown built in.

Neither model is "the secure one". Both depend on the access network isolating customers from each other.

Timeline: the standards behind a PPPoE session

Every date below was checked against the RFC Editor or the Broadband Forum's own documents.

DateDocumentWhat it added
May 1992RFC 1332IPCP, the PPP control protocol that negotiates an IPv4 address
October 1992RFC 1334PAP and the first CHAP definition
July 1994RFC 1661 (STD 51)The Point to Point Protocol: LCP, link phases, MRU default of 1500
December 1995RFC 1877IPCP options for DNS and NBNS server addresses
August 1996RFC 1994CHAP as used today (obsoletes the CHAP part of RFC 1334)
February 1999RFC 2516PPP over Ethernet: discovery stage, session stage, EtherTypes 0x8863 and 0x8864
January 2000RFC 2759MS-CHAPv2, Microsoft's CHAP variant with mutual authentication
June 2000RFC 2865, RFC 2866, RFC 2869RADIUS authentication, RADIUS accounting, RADIUS extensions including Message-Authenticator
August 2001RFC 3162RADIUS attributes for IPv6 (Framed-IPv6-Prefix and others)
August 1999RFC 2661L2TP, used to carry PPP sessions from a wholesale access network to a retail ISP
June 2004RFC 3748EAP, the extensible authentication framework, PPP protocol 0xc227
April 2006Broadband Forum TR-101 Issue 1Ethernet based broadband aggregation, VLAN models, PPPoE Intermediate Agent
September 2006RFC 4638PPP-Max-Payload tag for PPPoE MRU above 1492
September 2006RFC 4679DSL Forum RADIUS attributes such as Agent-Circuit-Id
April 2007RFC 4818RADIUS Delegated-IPv6-Prefix attribute
September 2007RFC 5072IPv6 over PPP and IPv6CP
July 2011Broadband Forum TR-101 Issue 2Additional access technologies in the aggregation model
May 2012RFC 6614RADIUS over TLS (Experimental)
August 2012Microsoft Security Advisory 2743314Warns that exploit code was published for known MS-CHAPv2 weaknesses
May 2013Broadband Forum TR-146Subscriber sessions for IPoE
November 2018RFC 8415Consolidated DHCPv6, including prefix delegation (IA_PD)
July 2024CVE-2024-3596RADIUS/UDP response forgery through an MD5 chosen prefix collision
April 2025RFC 9765RADIUS/1.1 over TLS, removing MD5 (Experimental)

How the discovery stage works

The PPPoE header

Every PPPoE frame, discovery or session, starts with the same 6 byte header after the Ethernet header:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  VER  | TYPE  |      CODE     |          SESSION_ID           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|            LENGTH             |           payload             ~
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

VER and TYPE are both 4 bits and both set to 1. CODE identifies the packet type. SESSION_ID is a 16 bit unsigned value that, together with the two MAC addresses, defines the session; RFC 2516 reserves 0xffff. LENGTH is the length of the PPPoE payload, not counting the Ethernet or PPPoE headers.

The EtherType tells a receiver which stage it is looking at: 0x8863 for discovery and 0x8864 for the PPP session. RFC 2516 notes that the IEEE assigned both values for PPPoE.

Tags

Discovery payloads are a list of tags, each a type, length and value. The ones you will see in a capture:

TagTypeWhat it does
End-Of-List0x0000Marks the end of the tag list (optional)
Service-Name0x0101The service requested or offered; zero length means "any service"
AC-Name0x0102The access concentrator's name, a string chosen by the operator
Host-Uniq0x0103An opaque value the host includes so it can match replies to its own requests
AC-Cookie0x0104An opaque value from the access concentrator, echoed back in PADR
Vendor-Specific0x0105Vendor data; RFC 2516 lets implementations ignore it. TR-101 uses it for line identification
Relay-Session-Id0x0110Added by a relay agent so it can route replies
PPP-Max-Payload0x0120Added by RFC 4638 to signal support for MRU above 1492
Service-Name-Error0x0201The requested service cannot be provided
AC-System-Error0x0202The concentrator hit an internal error
Generic-Error0x0203Any other error

RFC 2516 says unknown tags must be ignored, which is how later additions such as PPP-Max-Payload stay compatible with old equipment.

The four step handshake and the teardown

PADI (Initiation, code 0x09). The host broadcasts a PADI to ff:ff:ff:ff:ff:ff with session ID 0x0000. It must contain exactly one Service-Name tag and usually a Host-Uniq. The whole PADI must not exceed 1484 bytes so that a relay agent has room to add a Relay-Session-Id tag.

PADO (Offer, code 0x07). Every access concentrator that can serve the request answers with a unicast PADO to the host's MAC. It must carry an AC-Name tag and the same Service-Name, and may carry an AC-Cookie. A concentrator that cannot serve the request must stay silent.

PADR (Request, code 0x19). Because the PADI was broadcast, the host may receive several PADOs. It picks one, by AC-Name, by service or simply the first to arrive, and sends a unicast PADR to that concentrator's MAC, echoing any cookie.

PADS (Session confirmation, code 0x65). The chosen concentrator generates a unique session ID and returns it in a PADS. From this moment both sides know the pair of MAC addresses and the session ID, and the PPP session stage begins. If the concentrator does not like the requested service it returns a PADS with a Service-Name-Error tag and session ID 0x0000.

PADT (Terminate, code 0xa7). Either side can send a PADT at any time after the session exists, unicast, with the session ID of the session to end. No tags are required. After a PADT, no more PPP traffic may use that session, not even normal PPP termination packets. RFC 2516 says peers should normally close the session with PPP itself and use PADT only when PPP cannot be used.

If no PADO arrives, the host resends the PADI and doubles its wait each time. The same back off applies while waiting for a PADS, and after enough failed PADR attempts the host goes back to sending PADIs.

What the provider adds in between

On a modern access network the PADI does not reach the concentrator untouched. Broadband Forum TR-101 requires the access node (the DSLAM or OLT that terminates your line) to act as a PPPoE Intermediate Agent (requirement R-143). It intercepts upstream PADI, PADR and PADT frames, leaves the MAC addresses alone, and adds a Vendor-Specific tag carrying the Broadband Forum's enterprise number (3561, 0x0DE9) with an Agent Circuit ID and an Agent Remote ID. Those identify the physical line the request came in on. The BNG can use that line identity to decide whether discovery is allowed at all, independently of the PPP login that comes later, and must strip the tag before sending PADO, PADS or downstream PADT back to the user (R-144).

This is one of the most important security facts about PPPoE in practice: on a well run network, the provider knows which line a session came from even if someone else's username and password are being used.

What happens inside the PPP session

Once PADS arrives, every frame is unicast with EtherType 0x8864, code 0x00 and the fixed session ID. The PPPoE payload is a PPP frame that starts with the 2 byte PPP protocol field. From here on the session behaves like PPP over any other link and moves through the phases RFC 1661 defines: Link Dead, Link Establishment, Authentication, Network Layer Protocol and Link Termination.

LCP: setting up the link

The Link Control Protocol (PPP protocol 0xc021) negotiates link options with Configure-Request, Configure-Ack, Configure-Nak and Configure-Reject messages. The options that matter on PPPoE:

  • Maximum Receive Unit (MRU). PPP's default MRU is 1500, but RFC 2516 forbids negotiating more than 1492 on PPPoE unless both sides opted in through RFC 4638.
  • Authentication Protocol. The side that wants the other to authenticate names the method it requires: PAP (0xc023), CHAP (0xc223, with an algorithm byte, 5 for MD5) or EAP (0xc227). The peer can Nak with a method it prefers.
  • Magic Number. RFC 2516 recommends it. It helps detect looped links and is carried in LCP Echo messages.

RFC 2516 also tells implementations not to request, and to reject, options that only made sense on serial lines: FCS alternatives, Address and Control Field Compression and the async control character map. Protocol Field Compression is "NOT RECOMMENDED".

LCP Echo-Request and Echo-Reply are PPPoE's keepalive. RFC 2516 recommends that the concentrator send them occasionally because otherwise a host that vanishes without a Terminate-Request leaves a dead session behind. On Linux the lcp-echo-interval and lcp-echo-failure options of pppd control the client side; OpenWrt exposes the same pair as keepalive, with a default of 5 1 (five failures, one second apart), plus an adaptive mode that suppresses echoes while traffic is flowing.

Authentication: PAP, CHAP, MS-CHAPv2 and EAP

PAP (RFC 1334, October 1992) is a two way handshake. The client sends its username and password in a single Authenticate-Request, and the server answers Ack or Nak. RFC 1334 is blunt: "PAP is not a strong authentication method." Passwords cross the link in the clear, and there is no protection from playback or repeated trial and error. PAP survives because it is the simplest thing that works with any RADIUS back end: the BNG can forward the password in the RADIUS User-Password attribute and the server can check it against any password store.

CHAP (RFC 1994, August 1996) is a three way handshake. The authenticator sends a Challenge containing a one octet identifier and a random value. The peer replies with an MD5 hash over the identifier, the shared secret and the challenge. The authenticator computes the same hash and compares. The password never crosses the wire, and a new challenge every time prevents simple replay. CHAP also allows rechallenges during the session. Its costs are that the authenticator must hold the secret in a form equivalent to plain text, that it is one way unless negotiated in both directions, and that anyone who records a challenge and response can attempt an offline guessing attack against a weak password. MD5 itself is not the main issue here; the strength of the password is.

MS-CHAPv2 (RFC 2759, January 2000, Informational) is Microsoft's CHAP dialect. It adds mutual authentication: the server proves knowledge of the password back to the client in an authenticator response. It is built on the NT password hash. In August 2012, Microsoft Security Advisory 2743314 warned that detailed exploit code had been published for known weaknesses in MS-CHAPv2 and said unencapsulated MS-CHAPv2, used as the sole authentication method in PPTP VPNs, was affected. Some broadband equipment supports MS-CHAPv2, but residential ISPs rarely require it.

EAP (RFC 3748, June 2004) is a framework rather than a method. Over PPP it runs as protocol 0xc227, and the actual method (for example a TLS based one) is negotiated inside. EAP is common on Wi-Fi and 802.1X, but uncommon on consumer PPPoE.

IPCP: getting an IPv4 address

After authentication succeeds, PPP enters the network layer phase. IPCP (RFC 1332, protocol 0x8021) negotiates IPv4. The client sends the IP-Address option (option 3) in a way that asks the peer to provide an address; RFC 1332 says the peer answers by Naking the option with a valid address, the client requests again with that address, and the server Acks. By default no address is assigned. RFC 1877 (December 1995) adds options 129 and 131 for the primary and secondary DNS servers, which is what pppd's usepeerdns asks for.

Notice that there is no subnet mask and no broadcast domain. The link is point to point. Your router gets a single address and a peer address, and the default route points at the peer. This is also why PPPoE customers never see their neighbours' ARP traffic at the IP layer.

IPv6CP, router advertisements and DHCPv6 prefix delegation

IPv6 over PPP (RFC 5072, September 2007) uses IPv6CP, protocol 0x8057. IPv6CP negotiates only one thing that matters: a 64 bit interface identifier for each side, which must be unique on the link. That gives each end a link local address. It does not hand out a global address or a prefix.

Global IPv6 arrives in two further steps, both outside PPP:

  1. A WAN address. The BNG sends router advertisements on the PPP link, and the router forms a global address with SLAAC, or the router asks for one with DHCPv6 IA_NA. Many providers skip a global WAN address entirely and route the delegated prefix to the router's link local address.
  2. A LAN prefix. The router runs a DHCPv6 client on the PPP interface and asks for a prefix with IA_PD (identity association for prefix delegation), defined today in RFC 8415 (November 2018). The BNG answers with a /56, /60 or /48, and the router carves /64s from it for each LAN.

On the provider side, RADIUS can carry these values. RFC 3162 (August 2001) defines Framed-IPv6-Prefix and Framed-Interface-Id, and RFC 4818 (April 2007) defines Delegated-IPv6-Prefix, so the prefix can stay with the subscriber's account rather than changing every time the session restarts.

Teardown

A normal end of session is an LCP Terminate-Request and Terminate-Ack, followed by a PADT. If the line drops without either, the side that keeps sending LCP echoes notices the missing replies and tears the session down. A router that comes back up starts again from PADI, which is why a reboot can bring a new IPv4 address and, with some providers, a new IPv6 prefix.

Why the MTU is 1492, and what MSS clamping does

The arithmetic

Ethernet without jumbo frames carries at most 1500 bytes of payload. PPPoE adds a 6 byte header and PPP adds a 2 byte protocol field, so 8 bytes are gone before any IP packet starts. RFC 2516 spells out the result: the PPP MTU must not be greater than 1492.

Worked example 1: IPv4 TCP over standard PPPoE.

  • Ethernet payload: 1500 bytes
  • Minus PPPoE header (6) and PPP protocol field (2): 1492 bytes available for the IP packet
  • Minus IPv4 header (20) and TCP header without options (20): 1452 bytes of TCP payload, so MSS should be 1452

Worked example 2: IPv6 TCP over the same link.

  • 1492 bytes for the IP packet
  • Minus IPv6 header (40) and TCP header (20): 1432 bytes, so the IPv6 MSS should be 1432

Worked example 3: on the wire. A full size session frame with an 802.1Q VLAN tag, as many fibre providers require, is 14 bytes of Ethernet header, 4 bytes of VLAN tag, 6 bytes of PPPoE, 2 bytes of PPP and 1492 bytes of IP, which is 1518 bytes before the 4 byte frame check sequence. The VLAN tag sits outside the 1500 byte payload, so it does not reduce the MTU, provided every switch on the path accepts tagged frames.

Why it breaks things

A PC on your LAN believes its link MTU is 1500 and announces an MSS of 1460 in its TCP SYN. The remote server then sends 1500 byte packets. When they reach the BNG, which can forward only 1492 bytes into your session, one of two things happens. If the packet allows fragmentation, the BNG fragments it, which is slow but works. If the Don't Fragment bit is set, as it nearly always is for TCP today, the BNG drops it and sends back an ICMP "fragmentation needed" message. If a firewall anywhere on the path drops that ICMP message, Path MTU Discovery fails silently: the TCP handshake works, small requests work, and the first large response hangs. IPv6 never fragments in the network, so it depends entirely on ICMPv6 "packet too big" getting through.

MSS clamping

MSS clamping fixes the TCP part of the problem at the router. As each SYN or SYN-ACK passes through, the router rewrites the MSS option so that it never exceeds what the outbound path can carry. The nftables project documents the rule tcp option maxseg size set rt mtu, which takes the value from the route's MTU (available since Linux 4.14 and nftables 0.9), and notes that it is equivalent to the iptables TCPMSS target's clamp to PMTU option. The same page works the fixed value through for PPPoE: 1500 minus 20 minus 20 minus 8 gives 1452. It also points out that MSS is not negotiated and can differ in each direction, so you should rewrite both the SYN and the SYN-ACK.

On OpenWrt, the firewall zone option mtu_fix turns on MSS clamping, and the documentation lists its default as 1 for the WAN zone and 0 for the LAN zone.

MSS clamping only helps TCP. UDP based protocols, including QUIC and most VPNs, need either correct Path MTU Discovery or their own MTU setting.

RFC 4638: running the full 1500 inside PPPoE

RFC 4638 (September 2006) removes the 1492 limit when both ends can handle bigger Ethernet frames. The client adds a PPP-Max-Payload tag (0x0120, 2 bytes, the maximum PPP payload it supports) to its PADI and PADR. A server that supports larger payloads echoes the tag in PADO and PADS. Then LCP may negotiate an MRU above 1492, with the server's ceiling calculated as the smaller of the tag value and its interface MTU minus 8. If the tag is missing or below 1492, the old limit stays. RFC 4638 also recommends sending MRU sized LCP Echo-Requests after the session opens and dropping back to 1492 if they get no reply.

Worked example 4: baby jumbo frames. Set the physical WAN interface MTU to 1508. The client advertises PPP-Max-Payload 1500. The server's ceiling is min(1500, 1508 minus 8) = 1500, LCP agrees on 1500, and the PPP interface carries full 1500 byte IP packets. IPv4 MSS goes back to 1460 and no clamping is needed for 1500 byte LAN hosts. This works only if your provider supports RFC 4638 and every device between your router and the BNG passes 1508 byte payloads; the echo test exists precisely because that is often untrue.

What the ISP side looks like

BRAS and BNG

The access concentrator in RFC 2516 is, in carrier language, a Broadband Remote Access Server (BRAS) or, in Broadband Forum terms since TR-101, a Broadband Network Gateway (BNG). It terminates thousands of PPPoE sessions, runs the PPP state machines, enforces per subscriber policy (rate limits, filters, quality of service), assigns addresses and prefixes, and sends accounting records. It is the first IP hop for every PPPoE customer.

RADIUS

The BNG almost never stores passwords itself. It acts as a RADIUS client (in RADIUS terms, a Network Access Server) and asks a RADIUS server. RFC 2865 (June 2000) defines the exchange over UDP port 1812:

  • The BNG sends an Access-Request containing User-Name and either User-Password (for PAP, hidden with an MD5 based scheme keyed by a shared secret between BNG and RADIUS server) or CHAP-Password and the challenge (for CHAP).
  • The server returns Access-Accept with attributes such as Framed-IP-Address, or Access-Reject.
  • RFC 2866 (June 2000) adds accounting: start, interim and stop records that carry byte counts and session time.

With TR-101 line identification, the BNG also copies the access loop identifiers into RADIUS. RFC 4679 (September 2006) defines the DSL Forum vendor specific attributes for that purpose, including Agent-Circuit-Id, Agent-Remote-Id and the actual upstream and downstream data rates, under vendor ID 3561. That is how a provider can tie a login to the line it came from, or refuse a session from the wrong line.

RADIUS over UDP has a long known weak point: its integrity protection is MD5 keyed by the shared secret. In July 2024, CVE-2024-3596 was published; the NVD description says a local attacker able to modify traffic between client and server can forge any valid response "using a chosen-prefix collision attack against MD5 Response Authenticator signature". The defences are to require the Message-Authenticator attribute (an HMAC-MD5 over the whole packet, defined in RFC 2869) on every Access-Request and response, to keep RADIUS on a private, isolated management network, and to move to RADIUS over TLS (RFC 6614, May 2012, Experimental) or RADIUS/1.1 (RFC 9765, April 2025, Experimental), which removes MD5 entirely. This is a provider side concern; your home router never speaks RADIUS.

VLANs on DSL and fibre access

TR-101 (Issue 1 April 2006, Issue 2 July 2011) describes how providers moved from ATM to Ethernet aggregation and defines two VLAN models:

ModelWhat TR-101 means by itEffect on PPPoE
1:1 VLANOne VLAN per user port, usually as an S-Tag and C-Tag pair (IEEE 802.1ad stacking)Each line is its own broadcast domain. A PADI from one customer cannot reach another customer
N:1 VLANMany user ports share one VLANTR-101 requires the access node and aggregation network to maintain user isolation, and line identification has to come from the access node because the VLAN alone does not identify the line

On fibre services the provider often expects your router to tag its PPPoE frames with a specific VLAN ID on the WAN port. The provider tells you the ID; if you replace their router you have to configure it. On DSL the VLAN or ATM virtual circuit is usually configured on the modem side.

Security issues and how to handle them

PPPoE was designed in 1999 for a network the operator controlled end to end. RFC 2516's security section deals only with denial of service against the concentrator (the AC-Cookie tag) and with not revealing services to unauthenticated hosts. Everything else depends on PPP authentication and the access network around it.

PAP sends the password in clear text

Anyone who can see the frames between your router and the BNG can read a PAP password. On a 1:1 VLAN access network that should be only the provider. On a shared segment, an apartment building switch, a misconfigured bridge or a lab network, it may be others. If your provider supports CHAP, refuse PAP. With pppd that is the refuse-pap option; if the provider accepts only PAP, the session will fail and you will see it in the log, which is useful information in itself.

Remember that CHAP protects the password on the wire, not the session. Nothing in PPP or PPPoE encrypts your traffic. Encryption comes from TLS, a VPN or another layer above.

Rogue access concentrators answering PADI

The PADI is a broadcast, and the host picks among whichever PADOs arrive. RFC 2516 says the choice "can be based on the AC-Name or the Services offered", and many clients simply take the first. Nothing in a PADO proves who sent it. On a shared Ethernet segment, any device can run PPPoE server software, answer first, and receive the host's PPP session. If the host then offers PAP, the rogue server receives the password in clear text. With CHAP it receives a challenge response pair that can be attacked offline if the password is weak.

Defences on the client side:

  • Pin the access concentrator: pppd's pppoe-ac option (or OpenWrt's ac) and, more strictly, pppoe-mac (OpenWrt ac_mac) to accept only the expected concentrator. The AC-Name and MAC are not secrets, so this stops accidents and lazy attacks rather than determined ones.
  • Refuse PAP so a rogue server never receives a reusable password.
  • Watch the AC-Name and the BNG MAC in your logs. A change you did not expect is worth a support call.

Defences on the provider side are stronger: 1:1 VLANs or port isolation so customers never share a broadcast domain, and the PPPoE Intermediate Agent so the BNG knows the real line.

Forged PADT and session teardown

A PADT needs only the right destination MAC and session ID. RFC 2516 gives it no authentication. Anyone who can see a session's frames learns both values from any session packet, and can inject a PADT that ends the session. Any session layer protocol without authentication has the same weakness; TCP resets are the familiar parallel. The result is denial of service, not a takeover, and on an isolated 1:1 VLAN only the provider's equipment can see your session IDs. Keep persist (pppd) or the equivalent reconnect behaviour on, and check logs if sessions drop repeatedly with PADTs you did not send.

Credentials in router configuration and backups

This is the most common real world leak. The PPPoE username and password are stored in the router's configuration: in OpenWrt, as the username and password options of the WAN interface in /etc/config/network; with pppd, in /etc/ppp/pap-secrets or /etc/ppp/chap-secrets (or, less wisely, in the peer file itself). They then travel with:

  • configuration backup files exported from a web interface and kept in a downloads folder or a shared drive
  • support bundles uploaded to forums or tickets
  • screenshots of the WAN settings page
  • old routers sold or recycled without a reset
  • version controlled infrastructure repositories for home labs

With some providers, those credentials are enough to bring up a session from another line or to log into the provider's account portal. Treat them like any other password: keep backups encrypted, redact them before sharing, rotate them with the provider if they leak, and wipe old hardware before it leaves the house.

Denial of service against the concentrator

A flood of PADIs from random source MACs can exhaust session state on a concentrator. RFC 2516's AC-Cookie lets the concentrator issue a cookie derived from the host MAC (the RFC suggests an HMAC with a key only the concentrator knows) and accept only PADRs that return it, so it can confirm the MAC is reachable and limit concurrent sessions per address. Production BNGs add per port and per VLAN rate limits. This is a provider problem, but it explains why a router stuck in a fast PADI loop can get its line rate limited.

Replacing the ISP router

Many people replace the provider's router to get better firmware, faster updates or a homelab firewall. To do that with PPPoE you need, from the provider or the old router:

  • the PPPoE username and password
  • the WAN VLAN ID, if any, and whether frames need an 802.1p priority value
  • whether the provider supports RFC 4638 (MTU 1500 inside PPPoE)
  • how IPv6 is delivered: IPv6CP plus router advertisements, DHCPv6 IA_NA, IA_PD and the prefix size
  • whether there is a fixed IPv4 address or a routed subnet

Then the replacement router becomes your responsibility to patch. Our home router security checklist and the guide to building a home firewall on a mini PC cover the rest of that job. The PPP daemon, the DHCPv6 client and the firewall are software, and they get vulnerabilities and fixes like anything else.

Step by step: PPPoE on Linux and OpenWrt, a capture and MSS clamping

These steps assume a lab or your own connection. Run captures only on networks you own or are authorised to monitor.

1. Check the interface and, if needed, add the provider VLAN

# Find the WAN interface name and confirm it has link
ip -br link

# Only if your provider requires a VLAN tag on the WAN (example VLAN 100):
sudo ip link add link eth1 name eth1.100 type vlan id 100
sudo ip link set eth1 up
sudo ip link set eth1.100 up

Use eth1.100 in place of eth1 in the steps below if you created a VLAN interface.

2. Probe for access concentrators without logging in

The ppp project ships pppoe-discovery, which sends a PADI and prints the access concentrators that reply with a PADO.

sudo pppoe-discovery -I eth1

It prints the name of each access concentrator that answers, with details from its PADO. If you see more than one concentrator on a home connection, ask your provider why before you connect.

3. Capture the discovery stage

In a second terminal, start a capture before you connect. tcpdump's pppoed filter matches EtherType 0x8863 and pppoes matches 0x8864.

# Discovery only, with link layer headers and verbose tag decoding
sudo tcpdump -i eth1 -e -n -vv pppoed

# Or write discovery and session traffic to a file for later analysis
sudo tcpdump -i eth1 -e -n -w pppoe-lab.pcap 'pppoed or pppoes'

When the session comes up you will see a broadcast PADI, a PADO with an AC-Name, a PADR, a PADS with the new session ID, then session frames carrying LCP, the authentication exchange, IPCP and IPv6CP. If the provider uses PAP, the capture contains your password; treat the file accordingly and delete it when you are done.

4. Configure pppd with the PPPoE plugin

Install the ppp package from your distribution. Upstream development happens in the ppp project on GitHub, whose latest release at the time of writing is v2.5.4 (15 September 2026). The PPPoE plugin is loaded with plugin pppoe.so, and the interface name can be given with a nic- prefix.

Put the credentials in the secrets files, readable only by root:

# Create the files if missing (does not overwrite existing entries) and restrict them to root
sudo touch /etc/ppp/chap-secrets /etc/ppp/pap-secrets
sudo chmod 600 /etc/ppp/chap-secrets /etc/ppp/pap-secrets
echo '"user@isp.example" * "your-password" *' | sudo tee -a /etc/ppp/chap-secrets > /dev/null
echo '"user@isp.example" * "your-password" *' | sudo tee -a /etc/ppp/pap-secrets > /dev/null

Keep the PAP line only if your provider requires PAP. Then create the peer file /etc/ppp/peers/isp:

plugin pppoe.so
nic-eth1
user "user@isp.example"
# Refuse PAP if the ISP supports CHAP; remove this line only if login fails
refuse-pap
# Do not require the ISP to authenticate to us
noauth
defaultroute
usepeerdns
+ipv6
persist
maxfail 0
mtu 1492
mru 1492
lcp-echo-interval 10
lcp-echo-failure 6
# Optional pinning, values from pppoe-discovery
# pppoe-ac "ExpectedACName"
# pppoe-mac 00:11:22:33:44:55

Bring the session up in the foreground the first time so you can read the negotiation:

sudo pppd call isp nodetach debug

Look for the LCP options agreed, the authentication method (CHAP authentication succeeded or PAP authentication succeeded), the local and remote IP addresses from IPCP, and the IPv6 link local addresses from IPv6CP. Then check the result:

ip addr show ppp0
ip route show default
ip -6 addr show dev ppp0

For RFC 4638, raise the physical interface MTU to 1508 and set mtu 1500 and mru 1500 in the peer file. If the provider does not echo the PPP-Max-Payload tag, LCP stays at 1492.

For the LAN prefix, run a DHCPv6 client on ppp0 that requests IA_PD. Configuration varies by client; the point to check is that it runs on the PPP interface, asks for a prefix, and assigns /64s to LAN interfaces.

5. Clamp MSS with nftables

sudo nft add table inet mssclamp
sudo nft add chain inet mssclamp forward '{ type filter hook forward priority mangle; policy accept; }'
# Rewrite MSS on SYN and SYN-ACK in both directions through ppp0
sudo nft add rule inet mssclamp forward oifname "ppp0" tcp flags '&' '(syn|rst)' == syn tcp option maxseg size set rt mtu
sudo nft add rule inet mssclamp forward iifname "ppp0" tcp flags '&' '(syn|rst)' == syn tcp option maxseg size set rt mtu
sudo nft list table inet mssclamp

If your nftables or kernel cannot use rt mtu, set a fixed value instead: 1452 for IPv4 on a 1492 link. A fixed IPv4 value is too large for IPv6 (1432), which is one reason to prefer rt mtu. To verify, capture a SYN leaving ppp0 and read the MSS option:

sudo tcpdump -i ppp0 -n -v 'tcp[tcpflags] & tcp-syn != 0' -c 4

You should see mss 1452 on IPv4 and mss 1432 on IPv6 rather than 1460 or 1440.

6. The same on OpenWrt

OpenWrt's PPPoE support needs the ppp, kmod-pppoe and ppp-mod-pppoe packages; its documentation installs them with opkg. With UCI:

uci set network.wan.proto='pppoe'
uci set network.wan.username='user@isp.example'
uci set network.wan.password='your-password'
uci set network.wan.ipv6='auto'
# Optional: only connect to the expected concentrator
# uci set network.wan.ac='ExpectedACName'
# uci set network.wan.ac_mac='00:11:22:33:44:55'
# Optional: pass pppd options such as refusing PAP
uci set network.wan.pppd_options='refuse-pap'
uci commit network
/etc/init.d/network restart

The documented keepalive default is 5 1, defaultroute and peerdns default to on, and ipv6 auto enables IPv6 on the PPP link with a DHCPv6 client. If your provider needs a VLAN, point the WAN interface at the tagged device (for example eth1.100) in the device settings for your release. For MSS clamping, check that the WAN firewall zone has mtu_fix set:

uci show firewall | grep mtu_fix
logread | grep -i -E 'pppd|pppoe' | tail -40

Remember that /etc/config/network now holds your PPPoE password in clear text, and a configuration backup archive will carry it too.

Comparison: PPPoE, IPoE with DHCP, L2TP and static addressing

PropertyPPPoEIPoE with DHCPL2TP (PPP over L2TP to the provider)Static addressing
Who or what is authenticatedA username and password per session (PAP, CHAP, MS-CHAPv2, EAP), often plus the line IDUsually the line or VLAN, using access loop IDs in DHCP; sometimes MAC addressThe PPP login inside the tunnel, plus tunnel authentication between L2TP endpointsNothing at the protocol level; the provider's port configuration
Overhead per packet8 bytes (PPPoE 6, PPP 2); MTU 1492 unless RFC 4638None; MTU 1500L2TP, UDP and outer IP headers plus PPP; depends on transportNone
Session start and stopExplicit: discovery, LCP, PADTImplicit: DHCP lease and liveness checksExplicit: L2TP control channel plus PPPNone
IPv4 assignmentIPCPDHCPv4IPCPManual
IPv6 supportIPv6CP interface ID, then RA and DHCPv6 IA_PDRA plus DHCPv6 IA_NA and IA_PDIPv6CP, then RA and DHCPv6Manual prefixes
Operator controlHigh: per login policy, accounting, wholesale steering by login domainHigh with line identification; less per userHigh; common in wholesale handoff between networksLow; configuration per port
Main security weaknessUnauthenticated discovery and PADT; PAP in clear textDHCP spoofing on shared segments without access node protectionTunnel security depends on the transport; PPP inside has the same auth issuesAddress spoofing if the access network does not filter

L2TP (RFC 2661, August 1999) here means the provider side pattern in which an access network forwards PPP sessions inside L2TP tunnels to a retail ISP's network server, the L2TP access concentrator and network server roles that appear in TR-101's architecture. As a customer you rarely configure it yourself, but it is why PPPoE sessions can end up on a different company's equipment than the one that owns your line.

Where Safeguard fits

The fit here is indirect, and it is worth saying so plainly. Safeguard does not inspect PPPoE traffic, scan router firmware, manage devices or monitor RADIUS. What it does is software supply chain security for code you build and ship: it scans repositories, container images and SBOM files for vulnerable open source components, shows which projects carry a given component and version, and can open fix pull requests. That matters on the edges of this topic. Network automation repositories that template BNG or router configurations, containerised RADIUS servers and their plugins, and the custom images homelab users build for software routers are all assembled from open source packages that need tracking and patching like any other code.

Common mistakes

  • Setting MTU 1500 on the PPP interface without RFC 4638. LCP will not agree to it, or traffic will black hole. Use 1492 unless the provider echoes PPP-Max-Payload.
  • Forgetting MSS clamping on a custom router. Small pages load and big ones hang. Clamp both SYN and SYN-ACK, for both directions, or use OpenWrt's mtu_fix.
  • Clamping to 1452 for IPv6 too. IPv6 needs 1432 on a 1492 link. Use rt mtu so each family gets the right value.
  • Leaving PAP enabled when CHAP works. If the provider supports CHAP, refuse-pap costs nothing.
  • Accepting any concentrator. On shared or lab segments, pin the AC-Name or MAC and investigate unexpected changes.
  • Sharing configuration backups or screenshots with credentials in them. Redact the username and password, or rotate them afterwards.
  • Keeping the PPPoE password in the peer file or a world readable script. Use /etc/ppp/chap-secrets with mode 600.
  • Missing the WAN VLAN. If discovery shows no PADO at all, the provider probably expects a tagged frame.
  • Running a DHCPv6 client on the physical interface instead of the PPP interface. Prefix delegation happens over ppp0, not eth1.
  • Assuming PPPoE encrypts anything. It does not. Protect your traffic with TLS or a VPN.
  • Never updating the replacement router. pppd, the DHCPv6 client, the firewall and the web interface all receive security fixes; a router that is never updated keeps old bugs forever.

FAQ

What is PPPoE in simple terms?

PPPoE is a way for your router to log in to your internet provider over an Ethernet connection. It finds the provider's access concentrator, gets a session number, then runs PPP inside that session to check your username and password and hand your router an IP address.

Why does my internet connection use a username and password?

Because your provider uses PPPoE, which carries PPP's per user login. The provider's BNG passes your credentials to a RADIUS server, which decides whether to accept the session and which address and policy to apply.

Is PPPoE secure?

The protocol itself provides little security. Discovery packets and PADT have no authentication, and PAP sends passwords in clear text. Real protection comes from the provider's access network isolating each line, from using CHAP rather than PAP, and from encrypting your own traffic with TLS or a VPN.

Why is my MTU 1492 instead of 1500?

PPPoE adds a 6 byte header and PPP adds a 2 byte protocol field inside the 1500 byte Ethernet payload, leaving 1492 bytes for IP. RFC 2516 sets this limit. RFC 4638 allows 1500 if both your router and the provider support larger Ethernet frames.

What MSS should I use with PPPoE?

1452 for IPv4 and 1432 for IPv6 on a standard 1492 byte PPPoE link. The simplest approach is to clamp to the route MTU (nftables rt mtu), which calculates the right value for each family.

What is the difference between PPPoE and DHCP (IPoE)?

PPPoE authenticates a login and adds an 8 byte header with explicit session start and stop. IPoE uses DHCP on plain Ethernet, usually authenticates the line rather than a user, and keeps the full 1500 byte MTU.

Can I replace my ISP's router if they use PPPoE?

Usually yes, if you get the PPPoE username and password, any WAN VLAN ID, and how IPv6 is delivered. Check your provider's terms. After that, keeping the new router updated is your job.

Does PPPoE support IPv6?

Yes. IPv6CP (RFC 5072) negotiates interface identifiers on the PPP link, then router advertisements and DHCPv6 prefix delegation (RFC 8415) provide a global address and a LAN prefix.

What do PADI, PADO, PADR, PADS and PADT mean?

Initiation, Offer, Request, Session confirmation and Terminate. The host broadcasts PADI, concentrators reply with PADO, the host asks one of them with PADR, that concentrator assigns a session ID in PADS, and either side can end the session with PADT.

Can someone on my network see my PPPoE password?

With PAP, anyone who can capture frames between your router and the provider can read it. With CHAP, the password itself is not sent, but a captured challenge and response can be attacked offline if the password is weak. Configuration backups and screenshots are a more common leak than either.

Fix it without waiting for upstream

PPPoE is a protocol, but the systems around it are ordinary software: the PPP daemons and DHCPv6 clients in router images, the RADIUS servers that providers and labs run in containers, and the scripts that generate router configuration are all built from open source components. When one of those components has a vulnerability, the fix path is the same as for any other code you build, so the habits below apply to network software as much as to product code.

Whatever the vulnerability, most of the risk sits in two gaps. The first is the time between a fix being published and that fix actually running in your production builds. The second, and worse, is the time before any fix exists at all, while a maintainer works out a patch and a release schedule. Waiting through both gaps is a habit, not a requirement. Safeguard gives teams three ways to close them.

1. Autonomous remediation: pull requests, not tickets

When a fixed version exists, Safeguard's Griffin models open a tested, policy gated pull request that moves the affected dependency to the safe version. You can run it on one repository or in bulk across every project that carries the vulnerable version. Remediation covers eight categories, including dependencies, licenses, security posture and findings. Reachability analysis ranks the vulnerable code paths your application actually calls first, so the first pull requests you merge are the ones that matter most. Autonomous remediation ships switched off, with every category set to Manual, so your team decides how much runs on its own and what still needs a human approval.

2. Gold Open Source: the safe version in seconds, free

gold.safeguard.sh is free and needs no login. Search any CVE or package to see affected and fixed versions, CVSS, EPSS, CISA KEV status and a recommended safe version, or use the "Am I affected?" checker. The same data is available through a free read API, README status badges and RSS threat feeds. The safeguard-sh/gold-scan-action GitHub Action can fail a build on a known exploited vulnerability, on any known vulnerability, or never, so a version you have just removed cannot quietly come back in next week's merge.

3. Gold Registry: start from components that are already fixed

registry.safeguard.sh provides hardened, drop in replacements for upstream packages and container images. Every Gold artifact is held continuously to zero exploitable critical or high CVEs, zero malware and a completed license check, with SLSA L3 or higher provenance, a Sigstore signature and a public evidence page you can hand to an auditor. An artifact loses its Gold badge if it regresses. Teams can point their own package directory at the registry so hardened equivalents resolve without changing how developers install anything.

When upstream has no fix yet, or will not ship one, Safeguard first works to get the fix accepted upstream. If the issue is severe or upstream will not move, Safeguard builds a fork, fixes the vulnerability there and publishes a hardened Gold build, so you are not stuck on a maintainer's release schedule. You can also request a hardened, compatibility tested build of a specific package. This fork and patch flow is in early access today, so ask which packages it covers before you plan around it.

Your situationWhat to use
A fixed version existsAutonomous remediation opens the upgrade pull request; Gold Open Source confirms the safe version
You need to know today whether you are affectedGold Open Source lookup and "Am I affected?" checker, free and without login
You want vulnerable versions to stop shippingThe Gold scan GitHub Action in CI, plus Safeguard policies and gates
Upstream has no fix yet, or will not ship oneA custom Gold request; fork and patch (early access)
You want to start clean on new projectsPull hardened components and images from Gold Registry

One honest limit: when the vulnerable code lives in a vendor appliance, a hosted service or an operating system runtime you do not build yourself, the fix still has to come from that vendor or distribution. The steps above apply to the open source dependencies and container images you build and ship, which is where most teams carry the largest and least tracked share of their exposure.

See how Safeguard would help

The first demo is a real session with the Safeguard CLI. The assistant reads a finding and its advisory, asks before each command, upgrades a dependency, runs the tests and pushes nothing. The same flow applies when a library inside a router configuration generator or a containerised RADIUS service needs an upgrade.

Click through it at your own pace, or open it full screen.

The second demo sets up the Safeguard runner on your own machine, approves it with a device code and then scans from the terminal. Network automation repositories and custom router images often live on internal hosts, and the runner lets you scan them from a machine you control.

Click through it at your own pace, or open it full screen.

The third demo connects Claude to the Safeguard MCP server with OAuth and lets you choose which tools Claude can use. Granting a narrow set of tools follows the same rule as pinning your router to one access concentrator: accept only the party you expect, with only the access it needs.

Click through it at your own pace, or open it full screen.

Download the apps at safeguard.sh/download and read the CLI docs at docs.safeguard.sh/docs/cli.

Quick check

Your provider supports RFC 4638 and you set the WAN interface MTU to 1508. What PPP MTU and IPv4 MSS do you get?

The router sends PPP-Max-Payload 1500 in PADI and PADR. The server's ceiling is the smaller of 1500 and 1508 minus 8, which is 1500, so LCP can agree on an MRU of 1500. The IPv4 MSS is 1500 minus 20 minus 20, which is 1460, the same as plain Ethernet.

Your router logs show it connected to a different AC-Name than usual, and authentication used PAP. What should you do?

Treat the password as exposed. A different concentrator name may be a provider change, but it may also be a rogue concentrator on a shared segment, and PAP sends the password in clear text. Ask the provider to confirm the concentrator, rotate the PPPoE password, set refuse-pap if CHAP is supported, and pin the expected AC-Name or MAC.

Sources

Last reviewed: 24 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.