tcp: Generalized TTL Security Mechanism
Subsystems (5)
PATCH 1/1 tcp: Generalized TTL Security Mechanism
This patch adds the kernel portions needed to implement RFC 5082 Generalized TTL Security Mechanism (GTSM). It is a lightweight security measure against forged packets causing DoS attacks (for BGP).
This is already implemented the same way in BSD kernels. For the necessary Quagga patch
http://www.gossamer-threads.com/lists/quagga/dev/17389
Description from Cisco
http://www.cisco.com/en/US/docs/ios/12_3t/12_3t7/feature/guide/gt_btsh.html
It does add one byte to each socket structure, but I did a little rearrangement to reuse a hole (on 64 bit), but it does grow the structure on 32 bit
This should be documented on ip(4) man page and the Glibc in.h file also needs update. IPV6_MINHOPLIMIT should also be added (although BSD doesn't support that).
Only TCP is supported, but could also be added to UDP, DCCP, SCTP if desired.
--- include/linux/in.h | 1 + include/net/inet_sock.h | 9 +++++++++ net/ipv4/ip_sockglue.c | 14 +++++++++++++- net/ipv4/tcp_ipv4.c | 2 ++ 4 files changed, 25 insertions(+), 1 deletion(-)
include/linux/in.h +2 -0
@@ -84,6 +84,8 @@ struct in_addr {#define IP_ORIGDSTADDR 20#define IP_RECVORIGDSTADDR IP_ORIGDSTADDR +#define IP_MINTTL 21 +/* IP_MTU_DISCOVER values */ #define IP_PMTUDISC_DONT 0/* Never send DF frames */ #define IP_PMTUDISC_WANT 1/* Use per route hints */
include/net/inet_sock.h +3 -1
@@ -122,10 +122,12 @@ struct inet_sock {__be32 inet_saddr;__s16 uc_ttl;__u16 cmsg_flags; -struct ip_options *opt;__be16 inet_sport;__u16 inet_id; + +struct ip_options *opt;__u8 tos; +__u8 min_ttl;__u8 mc_ttl;__u8 pmtudisc; __u8 recverr:1,
net/ipv4/ip_sockglue.c +13 -1
@@ -451,7 +451,8 @@ static int do_ip_setsockopt(struct sock (1 <<IP_TTL ) | (1 <<IP_HDRINCL ) | (1 <<IP_MTU_DISCOVER ) | (1 <<IP_RECVERR ) | (1 <<IP_ROUTER_ALERT ) | (1 <<IP_FREEBIND ) | - (1<<IP_PASSSEC) | (1<<IP_TRANSPARENT))) || + (1 <<IP_PASSSEC ) | (1 <<IP_TRANSPARENT ) | + (1<<IP_MINTTL))) || optname ==IP_MULTICAST_TTL || optname ==IP_MULTICAST_ALL || optname == IP_MULTICAST_LOOP ||
@@ -936,6 +937,14 @@ mc_msf_out: inet->transparent = !!val;break ; +case IP_MINTTL : +if (optlen <1 ) + goto e_inval; +if (val <0 || val >255 ) + goto e_inval; + inet->min_ttl = val; +break ; +default : err = -ENOPROTOOPT ;break ;
@@ -1198,6 +1207,9 @@ static int do_ip_getsockopt(struct sockcase IP_TRANSPARENT : val = inet->transparent;break ; +case IP_MINTTL : + val = inet->min_ttl; +break ;default :release_sock (sk);return -ENOPROTOOPT ;
net/ipv4/tcp_ipv4.c +3 -0
@@ -1649,6 +1649,9 @@ int tcp_v4_rcv(struct sk_buff *skb)if (!sk) goto no_tcp_socket; +if (iph->ttl <inet_sk (sk)->min_ttl) + goto discard_and_relse; + process:if (sk->sk_state ==TCP_TIME_WAIT ) goto do_time_wait;
Quoted 29 lines · Stephen Hemminger
This patch adds the kernel portions needed to implement RFC 5082 Generalized TTL Security Mechanism (GTSM). It is a lightweight security measure against forged packets causing DoS attacks (for BGP).
This is already implemented the same way in BSD kernels. For the necessary Quagga patch
http://www.gossamer-threads.com/lists/quagga/dev/17389Description from Cisco
http://www.cisco.com/en/US/docs/ios/12_3t/12_3t7/feature/guide/gt_btsh.htmlIt does add one byte to each socket structure, but I did a little rearrangement to reuse a hole (on 64 bit), but it does grow the structure on 32 bit
This should be documented on ip(4) man page and the Glibc
in.hfile also needs update.IPV6_MINHOPLIMITshould also be added (although BSD doesn't support that).Only TCP is supported, but could also be added to UDP, DCCP, SCTP if desired.
Signed-off-by Stephen Hemminger <[email protected]>
net/ipv4/tcp_ipv4.c int tcp_v4_rcv(struct sk_buff *skb) · line 1657
Quoted 9 lines
net/ipv4/tcp_ipv4.c +3
-0@@ -1649,6 +1649,9 @@ int tcp_v4_rcv(struct sk_buff *skb)if (!sk) goto no_tcp_socket; +if (iph->ttl <inet_sk (sk)->min_ttl) + goto discard_and_relse; + process:if (sk->sk_state ==TCP_TIME_WAIT ) goto do_time_wait;
Just wondering if perfoming the check at connection establishment time (SYN or SYN-ACK packet) instead of every received packet would be enough ?
Of course, for listeners waiting for connexions from different peers (and different ttl values), it would be tricky.
Check should be done at user level, if we store ttl value of SYN packet and let user application read its value by a getsockopt()
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 33 lines · On Mon, 11 Jan 2010 12:25:23 +0100 Eric Dumazet…
Quoted 32 lines · Stephen Hemminger
This patch adds the kernel portions needed to implement RFC 5082 Generalized TTL Security Mechanism (GTSM). It is a lightweight security measure against forged packets causing DoS attacks (for BGP).
This is already implemented the same way in BSD kernels. For the necessary Quagga patch
http://www.gossamer-threads.com/lists/quagga/dev/17389Description from Cisco
http://www.cisco.com/en/US/docs/ios/12_3t/12_3t7/feature/guide/gt_btsh.htmlIt does add one byte to each socket structure, but I did a little rearrangement to reuse a hole (on 64 bit), but it does grow the structure on 32 bit
This should be documented on ip(4) man page and the Glibc
in.hfile also needs update.IPV6_MINHOPLIMITshould also be added (although BSD doesn't support that).Only TCP is supported, but could also be added to UDP, DCCP, SCTP if desired.
Signed-off-by Stephen Hemminger <[email protected]>net/ipv4/tcp_ipv4.c +0
-0@@ -1649,6 +1649,9 @@ int tcp_v4_rcv(struct sk_buff *skb)if (!sk) goto no_tcp_socket;
Quoted 9 lines
net/ipv4/tcp_ipv4.c int tcp_v4_rcv(struct sk_buff *skb) · line 1657
Quoted 6 lines
net/ipv4/tcp_ipv4.c +3
-0+if (iph->ttl <inet_sk (sk)->min_ttl) + goto discard_and_relse; + process:if (sk->sk_state ==TCP_TIME_WAIT ) goto do_time_wait;Just wondering if perfoming the check at connection establishment time (SYN or SYN-ACK packet) instead of every received packet would be enough ?
We could but:
1. GTSM is trying to protect against Man in the Middle attacks to existing BGP connections
2. That is not what BSD (or other vendors) do.
Quoted 5 lines
Of course, for listeners waiting for connexions from different peers (and different ttl values), it would be tricky.
Check should be done at user level, if we store ttl value of SYN packet and let user application read its value by a
getsockopt()
I think IP_RECVTTL would work for that idea.
Quoted 4 lines · Stephen Hemminger
We could but:
1. GTSM is trying to protect against Man in the Middle attacks to existing BGP connections
2. That is not what BSD (or other vendors) do.
Yes, unfortunately, I am afraid we are forced to be compatable.
Quoted 8 lines
Quoted 6 lines
Of course, for listeners waiting for connexions from different peers (and different ttl values), it would be tricky.
Check should be done at user level, if we store ttl value of SYN packet and let user application read its value by a
getsockopt()I think
IP_RECVTTLwould work for that idea.
Yes, if it was extented to TCP somehow.
Given this is an IP level option, check could be done at IP level, so that other protocols can use it too ?
Quoted 2 lines · Eric Dumazet
Given this is an IP level option, check could be done at IP level, so that other protocols can use it too ?
Oops, this is stupid, we dont have the socket pointer at IP level :)
A message that is not in the archive (sent off-list or not yet received): [email protected]
From: Eric Dumazet <[email protected]>
Date: Mon, 11 Jan 2010 18:10:28 +0100
Quoted 5 lines · Eric Dumazet
Quoted 2 lines
Given this is an IP level option, check could be done at IP level, so that other protocols can use it too ?
Oops, this is stupid, we dont have the socket pointer at IP level :)
Right.
But we can later add a helper to place in each protocols receive path, at the point where it first has a socket to work with.
I'm going to apply Stephen's original patch.
Thanks!
David Miller
AppliedFrom: Stephen Hemminger <[email protected]>
Date: Sun, 10 Jan 2010 22:00:34 -0800
Quoted 16 lines
This patch adds the kernel portions needed to implement RFC 5082 Generalized TTL Security Mechanism (GTSM). It is a lightweight security measure against forged packets causing DoS attacks (for BGP).
This is already implemented the same way in BSD kernels. For the necessary Quagga patch
http://www.gossamer-threads.com/lists/quagga/dev/17389Description from Cisco
http://www.cisco.com/en/US/docs/ios/12_3t/12_3t7/feature/guide/gt_btsh.htmlIt does add one byte to each socket structure, but I did a little rearrangement to reuse a hole (on 64 bit), but it does grow the structure on 32 bit
Quoted 8 lines
This should be documented on ip(4) man page and the Glibc
in.hfile also needs update.IPV6_MINHOPLIMITshould also be added (although BSD doesn't support that).Only TCP is supported, but could also be added to UDP, DCCP, SCTP if desired.
Signed-off-by Stephen Hemminger <[email protected]>
Applied to net-next-2.6, thanks Stephen.
Quoted 3 lines · Stephen Hemminger
Only TCP is supported, but could also be added to UDP, DCCP, SCTP if desired.
Perhaps I'm blind, but where is the default set if the socket option is not used?
-Andi
Signature · 1 line
ak-VuQAYsv1563Yd54FQh9/[email protected] -- Speaking for myself only.
A message that is not in the archive (sent off-list or not yet received): 873a29eywq.fsf-3rXA9MLqAseW/qJFnhkgxti2O/[email protected]
From: Andi Kleen <andi-Vw/[email protected]>
Date: Thu, 14 Jan 2010 11:58:13 +0100
Quoted 7 lines
Quoted 3 lines · Stephen Hemminger
Only TCP is supported, but could also be added to UDP, DCCP, SCTP if desired.
Perhaps I'm blind, but where is the default set if the socket option is not used?
Socket allocation memset()'s it to zero.
A message that is not in the archive (sent off-list or not yet received): 20100114.030454.16178889.davem-fT/PcQaiUtIeIZ0/[email protected]
Quoted 5 lines · David Miller
From: Andi Kleen <andi-Vw/[email protected]>
Date: Thu, 14 Jan 2010 11:58:13 +0100Quoted 2 lines
Quoted 1 line · Stephen Hemminger
Quoted 7 lines
Quoted 5 lines
Quoted 2 lines
Only TCP is supported, but could also be added to UDP, DCCP, SCTP if desired.
Perhaps I'm blind, but where is the default set if the socket option is not used?
Socket allocation memset()'s it to zero.
Yes, but there's no special case for zero in the check path?
It's just
+ if (iph->ttl < inet_sk(sk)->min_ttl)
+ goto discard_and_relse;
I'm probably missing something, but naively I would expect all packets with ttl > 0 to be discarded then when min_ttl is zero.
-Andi
Signature · 1 line
ak-VuQAYsv1563Yd54FQh9/[email protected] -- Speaking for myself only.
A message that is not in the archive (sent off-list or not yet received): 20100114112216.GK12241-u0/[email protected]
From: Andi Kleen <andi-Vw/[email protected]>
Date: Thu, 14 Jan 2010 12:22:16 +0100
Quoted 7 lines
It's just
(quoted diff) +2
-0+ if (iph->ttl < inet_sk(sk)->min_ttl) + goto discard_and_relse;I'm probably missing something, but naively I would expect all packets with ttl > 0 to be discarded then when
min_ttlis zero.
Andi, the feature works from top to bottom.
The idea is that the min_ttl is set very high, so that you'll only accept packets from hosts that started with a ttl of 255 and are within a hop or two from you. (therefore you'd set min_ttl to 254 or 253, something like that)
Since the ttl can never be less than zero, the test will never hit when min_ttl is zero, and thus this is that state where the socket option is not enabled.
Quoted 5 lines · David Miller
The idea is that the
min_ttlis set very high, so that you'll only accept packets from hosts that started with a ttl of 255 and are within a hop or two from you. (therefore you'd setmin_ttlto 254 or 253, something like that)
That's not a particularly good idea:
http://www.iana.org/assignments/ip-parameters
IP TIME TO LIVE PARAMETER
The current recommended default time to live (TTL) for the Internet Protocol (IP) is 64 [RFC791, RFC1122].
===
It always bugs me that things get incorrectly labeled "security", yet cannot secure anything.
Security requires a secret.
Various folks tried all kinds of games with TTL for BGP, but the only thing that _actually_ provided security was MD5 authentication.
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 17 lines · William Allen Simpson
Quoted 5 lines · David Miller
The idea is that the
min_ttlis set very high, so that you'll only accept packets from hosts that started with a ttl of 255 and are within a hop or two from you. (therefore you'd setmin_ttlto 254 or 253, something like that)That's not a particularly good idea:
http://www.iana.org/assignments/ip-parameters
IP TIME TO LIVE PARAMETER
The current recommended default time to live (TTL) for the Internet Protocol (IP) is 64 [RFC791, RFC1122].
===
Quoted 7 lines
It always bugs me that things get incorrectly labeled "security", yet cannot secure anything.
Security requires a secret.
Various folks tried all kinds of games with TTL for BGP, but the only thing that _actually_ provided security was MD5 authentication.
Nobody forces you to use RFC 5082, I never had.
But if you use it, better read it before, and not use default ttl of 64 on devices wanting to connect to your host.
Note this TTL Security mechanism is not replacing MD5 protection
The Generalized TTL Security Mechanism (GTSM) is designed to protect a router's IP-based control plane from CPU-utilization based attacks. In particular, while cryptographic techniques can protect the router- based infrastructure (e.g., BGP [RFC4271], [RFC4272]) from a wide variety of attacks, many attacks based on CPU overload can be prevented by the simple mechanism described in this document. Note that the same technique protects against other scarce-resource attacks involving a router's CPU, such as attacks against processor- line card bandwidth.
Its only a potential protection against CPU overload.
Hi,
Quoted 4 lines · Stephen Hemminger
This patch adds the kernel portions needed to implement RFC 5082 Generalized TTL Security Mechanism (GTSM). It is a lightweight security measure against forged packets causing DoS attacks (for BGP).
...
It's nice to see this added. However, I must add that a compliant RFC 5082 implementation is required to have similar TTL treatment for ICMP errors which relate to the protected session. AFAIK this does not support that.
The experimental, earlier spec (GTSH, RFC3682) did not have this requirement. Most if not all implementations support only GTSH mode. So a backward-compatibility option may be desirable.
Signature · 3 lines
Pekka Savola "You each name yourselves king, yet the Netcore Oy kingdom bleeds." Systems. Networks. Security. -- George R.R. Martin: A Clash of Kings
Quoted 9 lines · On Thu, 18 Mar 2010 08:36:48 +0200 (EET) Pekka Savola <[email protected]> wrote:
Hi,
Quoted 4 lines · Stephen Hemminger
This patch adds the kernel portions needed to implement RFC 5082 Generalized TTL Security Mechanism (GTSM). It is a lightweight security measure against forged packets causing DoS attacks (for BGP).
...
Quoted 8 lines
It's nice to see this added. However, I must add that a compliant RFC 5082 implementation is required to have similar TTL treatment for ICMP errors which relate to the protected session. AFAIK this does not support that.
The experimental, earlier spec (GTSH, RFC3682) did not have this requirement. Most if not all implementations support only GTSH mode. So a backward-compatibility option may be desirable.
The ICMP receive error handling does need to be updated.
But any application using GTSM should be setting IP_TTL socket option to set send TTL. But, not sure if Linux TCP ever sends ICMP for existing sessions at all.
Quoted 9 lines · Stephen Hemminger
Quoted 3 lines
The experimental, earlier spec (GTSH, RFC3682) did not have this requirement. Most if not all implementations support only GTSH mode. So a backward-compatibility option may be desirable.
The ICMP receive error handling does need to be updated.
But any application using GTSM should be setting
IP_TTLsocket option to set send TTL. But, not sure if Linux TCP ever sends ICMP for existing sessions at all.
Thanks, Stephen! It's nice to see at least one compliant RFC5082 implementation ;-)
Good point that no one should should probably even be sending ICMP messages for TCP sockets, but on receive side the checks are important :-)
Signature · 3 lines
Pekka Savola "You each name yourselves king, yet the Netcore Oy kingdom bleeds." Systems. Networks. Security. -- George R.R. Martin: A Clash of Kings
Quoted 6 lines · Pekka Savola
Quoted 2 lines
But any application using GTSM should be setting
IP_TTLsocketoption
Quoted 2 lines
to set send TTL. But, not sure if Linux TCP ever sends ICMP for existing sessions at all.
Quoted 7 lines
Thanks, Stephen! It's nice to see at least one compliant RFC5082 implementation ;-)
Good point that no one should should probably even be sending ICMP messages for TCP sockets, but on receive side the checks are important
:-)
This requires that any router in the path between the client and server also respects the MINTTL when sending ICMP. Not sure how practical it is...
net/ipv4/tcp_ipv4.c +3 -0
@@ -367,6 +367,9 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info)if (sock_owned_by_user (sk))NET_INC_STATS_BH (net,LINUX_MIB_LOCKDROPPEDICMPS ); +if (iph->ttl <inet_sk (sk)->min_ttl) + goto out; +if (sk->sk_state ==TCP_CLOSE ) goto out;
Quoted 3 lines · Eric Dumazet
This requires that any router in the path between the client and server also respects the MINTTL when sending ICMP. Not sure how practical it is...
You're correct that with multihop GTSM, ICMP becomes trickier. I'm not sure how applicable GTSM is really in multihop scenarios, though. I would not recommend using it to secure e.g. with minttl=250 or something that uncontrollable. Your comment relates mainly to ICMP soft/hard errors which are not critical for correct operation. http://tools.ietf.org/html/draft-ietf-tcpm-icmp-attacks-11 discusses this.
Signature · 3 lines
Pekka Savola "You each name yourselves king, yet the Netcore Oy kingdom bleeds." Systems. Networks. Security. -- George R.R. Martin: A Clash of Kings