Skip to main content
  1. Network Articles/
  2. MPLS Articles/

LDP Session Authentication (TCP MD5)

Table of Contents

LDP Session Authentication (TCP MD5)

An LDP session runs over TCP port 646. To stop spoofed segments being injected into it, RFC 5036 specifies protection with the TCP MD5 Signature Option (RFC 2385). Only the session is protected: neither neighbour discovery nor the label bindings are authenticated. This article covers that asymmetry and the confusing state produced by configuring only one side, then confirms both in an IOS XR (XRd) lab. The basics of LDP are covered in What Is LDP.

What is protected, and what is not

RFC 2385, referenced by section 2.9.1 of RFC 5036, computes an MD5 digest from information known only to the two endpoints and attaches it to the TCP segment. The password itself never appears in the connection stream, so an attacker must obtain it as well as guess the sequence numbers.

Section 2.9.2 defines how LDP uses it.

Item Specification
Configuration unit A password (shared secret) is configured for each peer
When the comparison fails The segment is dropped without any response to the sender
A peer with no password configured Its Hellos are ignored

The limits are stated as well. Per section 5.2, Privacy, LDP does not encrypt label distribution information. Reading the label bindings off the wire is not prevented; what is prevented is the injection of spoofed segments.

Hellos (UDP 646) are not authenticated at all. The “ignore Hellos” rule of section 2.9.2 applies to peers for which no password has been configured, so Hellos from a peer that is configured are not ignored. Configuring only one side therefore leaves the adjacency visible while the session can no longer be established.

IOS XR configuration

The command sits directly under mpls ldp. A peer is named by its LDP Identifier (3.3.3.3:0, including the label space).

Scope Command
All neighbours neighbor password clear <password>
Per peer neighbor <LDP Id> password clear <password>
Disable the global password for one peer neighbor <LDP Id> password disable

clear means “a plaintext password follows”; what gets stored is encrypted.

What happens when only one side is configured

The configured side expects every arriving segment to carry a digest. The unconfigured side sends none, so the comparison fails and the segment is dropped with no response. From the sending side the peer simply appears silent, and it keeps retransmitting TCP SYNs.

Hellos keep flowing, so show mpls ldp discovery still shows the adjacency while show mpls ldp neighbor returns nothing.

Once the session is down, label exchange stops. The IGP is unaffected, so the IP routes remain and IP reachability inside the core still works while only the MPLS-borne VPN traffic fails. The routing table looks healthy, which makes the cause hard to pin down.

Lab topology

A non-redundant chain. OSPF and LDP run in the core (PE1 - P1 - P2 - PE2), and CE1 and CE2 attach to the PEs through VRF CUST-A, reachable over VPNv4. Authentication is applied to the PE1 - P1 span only.

MPLS-FILTER lab
  CE1 ------ PE1 ------ P1 ------ P2 ------ PE2 ------ CE2
(AS 65101)    |      ↑ authentication here   |    (AS 65102)
           vrf CUST-A                    vrf CUST-A
              └────── iBGP vpnv4 (between Lo0) ──────┘
Router Lo0 Role
CE1 1.1.1.1 AS 65101, 192.168.1.0/24
PE1 2.2.2.2 Ingress/egress LSR, vrf CUST-A
P1 3.3.3.3 Transit LSR
P2 4.4.4.4 Transit LSR
PE2 5.5.5.5 Ingress/egress LSR, vrf CUST-A
CE2 6.6.6.6 AS 65102, 192.168.2.0/24

Overview of the test

STEP Change What it shows
0 No authentication The session is established; ping and traceroute succeed
1 Password on PE1 only The session drops while the adjacency survives. IP works but the VPN fails
2 Same password on P1 Recovery, and the MD5 option appears on the TCP handshake
3 Removed from both sides (final state) Back to the STEP 0 state

Reachability is measured from CE1 with ping 192.168.2.1 source 192.168.1.1 count 50 timeout 1, and inside the core from PE1 with ping 5.5.5.5 source 2.2.2.2.

STEP 0: no authentication

The session between PE1 and P1 is up and seven labels have been received.

STEP 0 PE1 show mpls ldp neighbor brief
RP/0/RP0/CPU0:PE1#show mpls ldp neighbor brief
Sat Sep 12 03:23:25.251 UTC

Peer               GR  NSR  Up Time     Discovery   Addresses     Labels    
                                        ipv4  ipv6  ipv4  ipv6  ipv4   ipv6 
-----------------  --  ---  ----------  ----------  ----------  ------------
3.3.3.3:0          N   N    00:25:25    1     0     3     0     7      0    

STEP 1: password on PE1 only

Only PE1 is configured. The command entered was password clear, but what is stored is encrypted.

Configuration committed on PE1 in STEP 1
RP/0/RP0/CPU0:PE1#show configuration commit changes last 1
Sat Sep 12 03:27:29.095 UTC
!! Building configuration...
!! IOS XR Configuration 26.1.1
mpls ldp
 neighbor
  3.3.3.3:0 password encrypted 09676F332C2938354620201A
 !
!
end

The adjacency survives, only the session drops

show mpls ldp neighbor brief returns nothing.

STEP 1 PE1 show mpls ldp neighbor brief
RP/0/RP0/CPU0:PE1#show mpls ldp neighbor brief
Sat Sep 12 03:29:49.148 UTC

RP/0/RP0/CPU0:PE1#show mpls ldp neighbor

Yet show mpls ldp discovery shows the adjacency alive. It is still xmit/recv, and the Established timestamp is unbroken from before the change.

STEP 1 PE1 show mpls ldp discovery
RP/0/RP0/CPU0:PE1#show mpls ldp discovery
Sat Sep 12 03:29:49.492 UTC

Local LDP Identifier: 2.2.2.2:0
Discovery Sources:
  Interfaces:
    GigabitEthernet0/0/0/1 : xmit/recv
      VRF: 'default' (0x60000000)
      LDP Id: 3.3.3.3:0, Transport address: 3.3.3.3
          Hold time: 15 sec (local:15 sec, peer:15 sec)
          Established: Sep 12 01:59:48.900 (01:30:00 ago)

Hellos are not authenticated, so the adjacency is untouched. Looking only at show mpls ldp neighbor suggests the peer is gone, when in fact it is still visible.

IP works but the VPN fails

Traffic from CE1 to CE2 is completely lost.

STEP 1 CE1 ping (VPN traffic)
RP/0/RP0/CPU0:CE1#ping 192.168.2.1 source 192.168.1.1 count 50 timeout 1
Sat Sep 12 03:31:52.547 UTC
Type escape sequence to abort.
Sending 50, 100-byte ICMP Echos to 192.168.2.1 timeout is 1 seconds:
..................................................
Success rate is 0 percent (0/50)

At the same time, IP reachability from PE1 to PE2’s loopback is lossless.

STEP 1 PE1 ping (IP inside the core)
RP/0/RP0/CPU0:PE1#ping 5.5.5.5 source 2.2.2.2 count 50 timeout 1
Sat Sep 12 03:30:09.450 UTC
Type escape sequence to abort.
Sending 50, 100-byte ICMP Echos to 5.5.5.5 timeout is 1 seconds:
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Success rate is 100 percent (50/50), round-trip min/avg/max = 9/11/27 ms

OSPF keeps running, so the IP routes stay and only the transport LSP disappears. The routing table shows nothing wrong.

No response comes back on TCP

P1 keeps sending SYNs trying to rebuild the session. Sixty of them between 03:27:31 and 03:36:10, roughly nine minutes, all from P1, with not a single response from PE1. No.900 in the attached capture is the first.

STEP 1 No.900 SYN (P1 → PE1, tshark -V extract)
Internet Protocol Version 4, Src: 3.3.3.3, Dst: 2.2.2.2
Transmission Control Protocol, Src Port: 15439, Dst Port: 646, Seq: 0, Len: 0
    Source Port: 15439
    Destination Port: 646
    Flags: 0x002 (SYN)
        TCP Option - Maximum segment size: 1240 bytes
            Kind: Maximum Segment Size (2)
        TCP Option - Window scale: 0 (multiply by 1)
            Kind: Window Scale (3)
        TCP Option - End of Option List (EOL)
            Kind: End of Option List (0)
Download the pcap of the packet in the tshark output above (No.900 SYN)

The options are MSS and Window scale only, with no MD5 signature. PE1 cannot verify it and, per RFC 2385, drops it without responding.

What to look at when troubleshooting

The syslog differs between the two sides. Only the configured side learns the reason.

STEP 1 syslog on PE1 (the configured side)
RP/0/RP0/CPU0:Sep 12 03:27:28.434 UTC: mpls_ldp[1178]: %ROUTING-LDP-5-NBR_CHANGE : VRF 'default' (0x60000000), Neighbor 3.3.3.3:0 is DOWN (Session MD5 password changed) 
STEP 1 syslog on P1 (the unconfigured side)
RP/0/RP0/CPU0:Sep 12 03:27:28.440 UTC: mpls_ldp[1178]: %ROUTING-LDP-5-NBR_CHANGE : VRF 'default' (0x60000000), Neighbor 2.2.2.2:0 is DOWN (TCP connection closed) 

The unconfigured side is told only TCP connection closed. It cannot tell that the peer turned on authentication, so whoever does not know about the change cannot reach the cause. The things to check:

What to look at With one-sided authentication
show mpls ldp neighbor Empty. The peer appears to be gone
show mpls ldp discovery Hellos are arriving. The cause is in the session layer
show ospf neighbor / show route Normal. The IGP is unaffected
syslog (configured side) DOWN (Session MD5 password changed)
syslog (unconfigured side) DOWN (TCP connection closed)

STEP 2: the same password on both sides

Configuring P1 with the same password restores the session, and the seven labels come back.

STEP 2 PE1 show mpls ldp neighbor brief
RP/0/RP0/CPU0:PE1#show mpls ldp neighbor brief
Sat Sep 12 03:39:54.731 UTC

Peer               GR  NSR  Up Time     Discovery   Addresses     Labels    
                                        ipv4  ipv6  ipv4  ipv6  ipv4   ipv6 
-----------------  --  ---  ----------  ----------  ----------  ------------
3.3.3.3:0          N   N    00:03:21    1     0     3     0     7      0    

The SYN of the handshake now carries an MD5 signature (Kind 19). This is No.1693 in the attached capture.

STEP 2 No.1693 SYN (P1 → PE1, tshark -V extract)
Internet Protocol Version 4, Src: 3.3.3.3, Dst: 2.2.2.2
Transmission Control Protocol, Src Port: 46215, Dst Port: 646, Seq: 0, Len: 0
    Source Port: 46215
    Destination Port: 646
    Flags: 0x002 (SYN)
        TCP Option - Maximum segment size: 1216 bytes
            Kind: Maximum Segment Size (2)
        TCP Option - Window scale: 0 (multiply by 1)
            Kind: Window Scale (3)
        TCP Option - No-Operation (NOP)
            Kind: No-Operation (1)
        TCP Option - TCP MD5 signature
            Kind: MD5 Signature Option (19)
            MD5 digest: 094c51db8fb8adb70061c6cbd3df7e02
Download the pcap of the packet in the tshark output above (No.1693 SYN)

The SYN/ACK that comes back carries one too, with a different digest for the opposite direction.

STEP 2 No.1694 SYN/ACK (PE1 → P1, tshark -V extract)
Internet Protocol Version 4, Src: 2.2.2.2, Dst: 3.3.3.3
Transmission Control Protocol, Src Port: 646, Dst Port: 46215, Seq: 0, Ack: 1, Len: 0
    Source Port: 646
    Destination Port: 46215
    Flags: 0x012 (SYN, ACK)
        TCP Option - Maximum segment size: 1216 bytes
            Kind: Maximum Segment Size (2)
        TCP Option - Window scale: 0 (multiply by 1)
            Kind: Window Scale (3)
        TCP Option - No-Operation (NOP)
            Kind: No-Operation (1)
        TCP Option - TCP MD5 signature
            Kind: MD5 Signature Option (19)
            MD5 digest: b7b7fb4175fcb691ff73dfa05ab16bc2
Download the pcap of the packet in the tshark output above (No.1694 SYN/ACK)

The MSS has dropped from 1240 bytes without authentication to 1216 bytes. The MD5 signature is an 18-byte option and, with padding, consumes 24 bytes of option space.

STEP CE1 → CE2 ping
0 100% (50/50)
1 0% (0/50)
2 100% (50/50)
3 100% (50/50)

STEP 3: removing it

With the password removed from both sides, the session is rebuilt with a handshake that carries no MD5 option. The running-config of the final STEP is identical, line for line, to the lab’s start-up configuration.

Design notes

  • If both ends cannot be configured at once, decide the order in advance. A one-sided state always means a dropped session. Adding this to a production core calls for a maintenance window per span
  • The other side is told nothing useful. When changing authentication at an inter-AS boundary, the peer cannot identify the cause unless you tell them beforehand
  • Changing the password also drops the session. It goes down with Session MD5 password changed and is then rebuilt, so treat a change like an initial deployment
  • Nothing is encrypted. If the label bindings themselves must be hidden, this mechanism is not enough

Verification configs and show output

At every STEP the following was collected from all six routers, split per router. The verification config is the ..._run.txt file (the final state is the one from the last STEP).

File Contents
..._show.txt show version, show mpls ldp neighbor detail, show mpls ldp discovery detail, show mpls ldp parameters and more
..._log.txt show logging restricted to that STEP
..._run.txt show running-config at that STEP (the verification config)
..._ping.txt ping (50 packets, 1 second timeout) and traceroute for that STEP
..._trace.txt show mpls ldp trace peer / discovery and others (core routers only)
..._commit.cfg Only the configuration actually committed in that STEP, for the routers that were changed

STEP 0: no authentication

Router show syslog running-config ping trace commit
CE1 show log run ping - -
PE1 show log run ping trace -
P1 show log run ping trace -
P2 show log run ping trace -
PE2 show log run ping trace -
CE2 show log run ping - -

STEP 1: password on PE1 only

Router show syslog running-config ping trace commit
CE1 show log run ping - -
PE1 show log run ping trace cfg
P1 show log run ping trace -
P2 show log run ping trace -
PE2 show log run ping trace -
CE2 show log run ping - -

STEP 2: the same password on P1

Router show syslog running-config ping trace commit
CE1 show log run ping - -
PE1 show log run ping trace -
P1 show log run ping trace cfg
P2 show log run ping trace -
PE2 show log run ping trace -
CE2 show log run ping - -

STEP 3: removed from both sides (final state)

Router show syslog running-config ping trace commit
CE1 show log run ping - -
PE1 show log run ping trace cfg
P1 show log run ping trace cfg
P2 show log run ping trace -
PE2 show log run ping trace -
CE2 show log run ping - -

The full capture between PE1 and P1. It contains the SYN retransmissions of STEP 1, the MD5-signed handshake of STEP 2 and the teardown of STEP 3.

Download the full capture between PE1 and P1

References

Source What was checked
RFC 5036 LDP Specification Section 2.9.1 (TCP MD5 Signature Option), section 2.9.2 (per-peer passwords, dropping without response on failure, ignoring Hellos from peers with no password), section 5.2 (no encryption)
RFC 2385 Protection of BGP Sessions via the TCP MD5 Signature Option The MD5 signature TCP option (Kind 19)

The lab ran on XRd 26.1.1 under Cisco Modeling Labs.