All of lore.kernel.org
 help / color / mirror / Atom feed
* `iptables -m tcp --syn` doesn't do what the man says
@ 2012-03-30 20:58 Artyom Gavrichenkov
  2012-03-30 21:19 ` Eric Dumazet
  2012-04-01 17:42 ` Pablo Neira Ayuso
  0 siblings, 2 replies; 6+ messages in thread
From: Artyom Gavrichenkov @ 2012-03-30 20:58 UTC (permalink / raw)
  To: netfilter-devel

[-- Attachment #1: Type: text/plain, Size: 5517 bytes --]

Hi all,

The iptables(8) manpage says:

--- [cut here] ---
   tcp
       These extensions can be used if `--protocol tcp' is specified. It provides the following options:
       [!] --syn
              Only  match  TCP packets with the SYN bit set and the ACK,RST and FIN bits cleared.  Such packets are used to request TCP connection initia‐
              tion; for example, blocking such packets coming in an interface will prevent incoming TCP connections, but outgoing TCP connections will  be
              unaffected.   It  is  equivalent  to  --tcp-flags  SYN,RST,ACK,FIN  SYN.   If  the "!" flag precedes the "--syn", the sense of the option is
              inverted.
--- [cut here] ---

Unfortunately, with current stable Linux kernel release (as well as
with most of the previous versions) blocking TCP packets with the SYN
bit set and the ACK,RST and FIN bits cleared won't prevent incoming
TCP connections.

Currently Linux TCP stack considers an incoming TCP segment to be a
connection initiation request if the segment only has SYN flag set and
ACK and RST flags cleared. You can easily check it yourself with your
nearest Linux box, as well as on the netfilter.org (213.95.27.115):

# hping3 -c 2 -n -FS -p 80 netfilter.org
HPING netfilter.org (wlan0 213.95.27.115): SF set, 40 headers + 0 data bytes
len=44 ip=213.95.27.115 ttl=52 DF id=0 sport=80 flags=SA seq=0 win=5840 rtt=58.8 ms
len=44 ip=213.95.27.115 ttl=52 DF id=0 sport=80 flags=SA seq=1 win=5840 rtt=51.1 ms

--- netfilter.org hping statistic ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 51.1/55.0/58.8 ms
# 

As you see, the netfilter.org server sends SYN/ACK in response to an
incoming SYN/FIN, indicating that a connection is being established.
It is only a matter of a few checks to make sure that the indication
is correct and the connection is indeed initialized.

This might be a Linux bug as well to accept SYN/FIN as a connection
initiation attempt. However, there could as well be a reason for kernel
developers to do this, because such thing as T/TCP (RFC 1644) allows a
TCP server to act like this, and though this RFC is experimental and
obsolete, as far as I know, it is still implemented somewhere, for
example, in FreeBSD.

I guess that most iptables setups probably are not affected by this
behaviour, because `iptables -m tcp --syn' is often used for something
in lines of this:

iptables -A INPUT -p tcp -m tcp --dport 22 --syn -j ACCEPT
iptables -A INPUT -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -j DROP

In this case, SYN/FIN segments will be dropped, because they are not
considered plain SYN and they are not associated with an established
connection. My guess is that, for example, kernel.org is set up like that:

# hping3 -c 2 -n -FS -p 80 kernel.org
HPING kernel.org (wlan0 149.20.4.69): SF set, 40 headers + 0 data bytes

--- kernel.org hping statistic ---
2 packets transmitted, 0 packets received, 100% packet loss
round-trip min/avg/max = 0.0/0.0/0.0 ms
#

However, there are cases when this behaviour produces clear security
breach, for example, when one is trying to prevent incoming TCP
connections from a certain IP (as manpage suggests) or when one is
trying to limit the rate of connection establishment attempts. In
this case attacker can send SYN/FIN packets which would pass all the
rules containing --syn and would establish a connection.

The patch to fix this is trivial (it is attached below), however, it
might be a good idea to discuss reasons first and find the best
solution possible.

P. S. Sorry for being so verbose, I'm new to this mailing list and I'm
trying to explain everything as clear as I can.

-- 
| Artyom Gavrichenkov
| gpg: fa1c670e
| mailto: ximaera@gmail.com
| xmpp: ximaera@gmail.com
| skype: xima_era
| tel. no: +7 916 515 49 58

-- Signed-off-by: Artyom Gavrichenkov <ximaera@gmail.com>

diff --git a/extensions/libxt_tcp.c b/extensions/libxt_tcp.c
index e849fa2..3af03c4 100644
--- a/extensions/libxt_tcp.c
+++ b/extensions/libxt_tcp.c
@@ -169,7 +169,7 @@ tcp_parse(int c, char **argv, int invert, unsigned int *flags,
                        xtables_error(PARAMETER_PROBLEM,
                                   "Only one of `--syn' or `--tcp-flags' "
                                   " allowed");
-               parse_tcp_flags(tcpinfo, "SYN,RST,ACK,FIN", "SYN", invert);
+               parse_tcp_flags(tcpinfo, "SYN,RST,ACK", "SYN", invert);
                *flags |= TCP_FLAGS;
                break;
 
diff --git a/extensions/libxt_tcp.man b/extensions/libxt_tcp.man
index 7a16118..e1698df 100644
--- a/extensions/libxt_tcp.man
+++ b/extensions/libxt_tcp.man
@@ -31,12 +31,12 @@ will only match packets with the SYN flag set, and the ACK, FIN and
 RST flags unset.
 .TP
 [\fB!\fP] \fB\-\-syn\fP
-Only match TCP packets with the SYN bit set and the ACK,RST and FIN bits
+Only match TCP packets with the SYN bit set and the ACK and RST bits
 cleared.  Such packets are used to request TCP connection initiation;
 for example, blocking such packets coming in an interface will prevent
 incoming TCP connections, but outgoing TCP connections will be
 unaffected.
-It is equivalent to \fB\-\-tcp\-flags SYN,RST,ACK,FIN SYN\fP.
+It is equivalent to \fB\-\-tcp\-flags SYN,RST,ACK SYN\fP.
 If the "!" flag precedes the "\-\-syn", the sense of the
 option is inverted.
 .TP


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: `iptables -m tcp --syn` doesn't do what the man says
  2012-03-30 20:58 `iptables -m tcp --syn` doesn't do what the man says Artyom Gavrichenkov
@ 2012-03-30 21:19 ` Eric Dumazet
  2012-03-30 21:40   ` Artyom Gavrichenkov
  2012-04-01 17:42 ` Pablo Neira Ayuso
  1 sibling, 1 reply; 6+ messages in thread
From: Eric Dumazet @ 2012-03-30 21:19 UTC (permalink / raw)
  To: Artyom Gavrichenkov; +Cc: netfilter-devel

On Sat, 2012-03-31 at 00:58 +0400, Artyom Gavrichenkov wrote:
> Hi all,
> 
> The iptables(8) manpage says:
> 
> --- [cut here] ---
>    tcp
>        These extensions can be used if `--protocol tcp' is specified. It provides the following options:
>        [!] --syn
>               Only  match  TCP packets with the SYN bit set and the ACK,RST and FIN bits cleared.  Such packets are used to request TCP connection initia‐
>               tion; for example, blocking such packets coming in an interface will prevent incoming TCP connections, but outgoing TCP connections will  be
>               unaffected.   It  is  equivalent  to  --tcp-flags  SYN,RST,ACK,FIN  SYN.   If  the "!" flag precedes the "--syn", the sense of the option is
>               inverted.
> --- [cut here] ---
> 
> Unfortunately, with current stable Linux kernel release (as well as
> with most of the previous versions) blocking TCP packets with the SYN
> bit set and the ACK,RST and FIN bits cleared won't prevent incoming
> TCP connections.
> 
> Currently Linux TCP stack considers an incoming TCP segment to be a
> connection initiation request if the segment only has SYN flag set and
> ACK and RST flags cleared. You can easily check it yourself with your
> nearest Linux box, as well as on the netfilter.org (213.95.27.115):
> 
> # hping3 -c 2 -n -FS -p 80 netfilter.org
> HPING netfilter.org (wlan0 213.95.27.115): SF set, 40 headers + 0 data bytes
> len=44 ip=213.95.27.115 ttl=52 DF id=0 sport=80 flags=SA seq=0 win=5840 rtt=58.8 ms
> len=44 ip=213.95.27.115 ttl=52 DF id=0 sport=80 flags=SA seq=1 win=5840 rtt=51.1 ms
> 
> --- netfilter.org hping statistic ---
> 2 packets transmitted, 2 packets received, 0% packet loss
> round-trip min/avg/max = 51.1/55.0/58.8 ms
> # 
> 
> As you see, the netfilter.org server sends SYN/ACK in response to an
> incoming SYN/FIN, indicating that a connection is being established.
> It is only a matter of a few checks to make sure that the indication
> is correct and the connection is indeed initialized.
> 
> This might be a Linux bug as well to accept SYN/FIN as a connection
> initiation attempt. However, there could as well be a reason for kernel
> developers to do this, because such thing as T/TCP (RFC 1644) allows a
> TCP server to act like this, and though this RFC is experimental and
> obsolete, as far as I know, it is still implemented somewhere, for
> example, in FreeBSD.
> 

FYI current linux kernel just drops this kind of message (SYN+FIN)

git describe --contains fdf5af0daf8019cec2396cdef8fb042d80fe71fa
v3.3-rc1~182^2~365

commit fdf5af0daf8019cec2396cdef8fb042d80fe71fa
Author: Eric Dumazet <eric.dumazet@gmail.com>
Date:   Fri Dec 2 23:41:42 2011 +0000

    tcp: drop SYN+FIN messages
    
    Denys Fedoryshchenko reported that SYN+FIN attacks were bringing his
    linux machines to their limits.
    
    Dont call conn_request() if the TCP flags includes SYN flag
    
    Reported-by: Denys Fedoryshchenko <denys@visp.net.lb>
    Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>

diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 78dd38c..0cbb440 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -5811,6 +5811,8 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
 			goto discard;
 
 		if (th->syn) {
+			if (th->fin)
+				goto discard;
 			if (icsk->icsk_af_ops->conn_request(sk, skb) < 0)
 				return 1;
 



> I guess that most iptables setups probably are not affected by this
> behaviour, because `iptables -m tcp --syn' is often used for something
> in lines of this:
> 
> iptables -A INPUT -p tcp -m tcp --dport 22 --syn -j ACCEPT
> iptables -A INPUT -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT
> iptables -A INPUT -j DROP
> 
> In this case, SYN/FIN segments will be dropped, because they are not
> considered plain SYN and they are not associated with an established
> connection. My guess is that, for example, kernel.org is set up like that:
> 

Or it runs linux 3.3

> # hping3 -c 2 -n -FS -p 80 kernel.org
> HPING kernel.org (wlan0 149.20.4.69): SF set, 40 headers + 0 data bytes
> 
> --- kernel.org hping statistic ---
> 2 packets transmitted, 0 packets received, 100% packet loss
> round-trip min/avg/max = 0.0/0.0/0.0 ms
> #
> 
> However, there are cases when this behaviour produces clear security
> breach, for example, when one is trying to prevent incoming TCP
> connections from a certain IP (as manpage suggests) or when one is
> trying to limit the rate of connection establishment attempts. In
> this case attacker can send SYN/FIN packets which would pass all the
> rules containing --syn and would establish a connection.
> 
> The patch to fix this is trivial (it is attached below), however, it
> might be a good idea to discuss reasons first and find the best
> solution possible.
> 
> P. S. Sorry for being so verbose, I'm new to this mailing list and I'm
> trying to explain everything as clear as I can.
> 

Thats perfect, thanks !

> -- 
> | Artyom Gavrichenkov
> | gpg: fa1c670e
> | mailto: ximaera@gmail.com
> | xmpp: ximaera@gmail.com
> | skype: xima_era
> | tel. no: +7 916 515 49 58
> 
> -- Signed-off-by: Artyom Gavrichenkov <ximaera@gmail.com>
> 
> diff --git a/extensions/libxt_tcp.c b/extensions/libxt_tcp.c
> index e849fa2..3af03c4 100644
> --- a/extensions/libxt_tcp.c
> +++ b/extensions/libxt_tcp.c
> @@ -169,7 +169,7 @@ tcp_parse(int c, char **argv, int invert, unsigned int *flags,
>                         xtables_error(PARAMETER_PROBLEM,
>                                    "Only one of `--syn' or `--tcp-flags' "
>                                    " allowed");
> -               parse_tcp_flags(tcpinfo, "SYN,RST,ACK,FIN", "SYN", invert);
> +               parse_tcp_flags(tcpinfo, "SYN,RST,ACK", "SYN", invert);
>                 *flags |= TCP_FLAGS;
>                 break;
>  
> diff --git a/extensions/libxt_tcp.man b/extensions/libxt_tcp.man
> index 7a16118..e1698df 100644
> --- a/extensions/libxt_tcp.man
> +++ b/extensions/libxt_tcp.man
> @@ -31,12 +31,12 @@ will only match packets with the SYN flag set, and the ACK, FIN and
>  RST flags unset.
>  .TP
>  [\fB!\fP] \fB\-\-syn\fP
> -Only match TCP packets with the SYN bit set and the ACK,RST and FIN bits
> +Only match TCP packets with the SYN bit set and the ACK and RST bits
>  cleared.  Such packets are used to request TCP connection initiation;
>  for example, blocking such packets coming in an interface will prevent
>  incoming TCP connections, but outgoing TCP connections will be
>  unaffected.
> -It is equivalent to \fB\-\-tcp\-flags SYN,RST,ACK,FIN SYN\fP.
> +It is equivalent to \fB\-\-tcp\-flags SYN,RST,ACK SYN\fP.
>  If the "!" flag precedes the "\-\-syn", the sense of the
>  option is inverted.
>  .TP
> 


--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: `iptables -m tcp --syn` doesn't do what the man says
  2012-03-30 21:19 ` Eric Dumazet
@ 2012-03-30 21:40   ` Artyom Gavrichenkov
  2012-03-30 21:50     ` Eric Dumazet
  0 siblings, 1 reply; 6+ messages in thread
From: Artyom Gavrichenkov @ 2012-03-30 21:40 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: netfilter-devel

[-- Attachment #1: Type: text/plain, Size: 338 bytes --]

31.03.2012 01:19, Eric Dumazet написал:
> FYI current linux kernel just drops this kind of message (SYN+FIN)

OK, thanks for clarification, I should have missed this commit.

-- 
| Artyom Gavrichenkov
| gpg: fa1c670e
| mailto: ximaera@gmail.com
| xmpp: ximaera@gmail.com
| skype: xima_era
| tel. no: +7 916 515 49 58


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: `iptables -m tcp --syn` doesn't do what the man says
  2012-03-30 21:40   ` Artyom Gavrichenkov
@ 2012-03-30 21:50     ` Eric Dumazet
  0 siblings, 0 replies; 6+ messages in thread
From: Eric Dumazet @ 2012-03-30 21:50 UTC (permalink / raw)
  To: Artyom Gavrichenkov; +Cc: netfilter-devel

On Sat, 2012-03-31 at 01:40 +0400, Artyom Gavrichenkov wrote:
> 31.03.2012 01:19, Eric Dumazet написал:
> > FYI current linux kernel just drops this kind of message (SYN+FIN)
> 
> OK, thanks for clarification, I should have missed this commit.
> 

You're welcome.

I just realize I made a typo in the Changelog...

Dont call conn_request() if the TCP flags includes SYN flag

->

Dont call conn_request() if the TCP flags includes FIN flag


--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: `iptables -m tcp --syn` doesn't do what the man says
  2012-03-30 20:58 `iptables -m tcp --syn` doesn't do what the man says Artyom Gavrichenkov
  2012-03-30 21:19 ` Eric Dumazet
@ 2012-04-01 17:42 ` Pablo Neira Ayuso
  2012-04-01 17:53   ` Eric Dumazet
  1 sibling, 1 reply; 6+ messages in thread
From: Pablo Neira Ayuso @ 2012-04-01 17:42 UTC (permalink / raw)
  To: Artyom Gavrichenkov; +Cc: netfilter-devel

On Sat, Mar 31, 2012 at 12:58:54AM +0400, Artyom Gavrichenkov wrote:
> Hi all,
> 
> The iptables(8) manpage says:
> 
> --- [cut here] ---
>    tcp
>        These extensions can be used if `--protocol tcp' is specified. It provides the following options:
>        [!] --syn
>               Only  match  TCP packets with the SYN bit set and the ACK,RST and FIN bits cleared.  Such packets are used to request TCP connection initia‐
>               tion; for example, blocking such packets coming in an interface will prevent incoming TCP connections, but outgoing TCP connections will  be
>               unaffected.   It  is  equivalent  to  --tcp-flags  SYN,RST,ACK,FIN  SYN.   If  the "!" flag precedes the "--syn", the sense of the option is
>               inverted.
> --- [cut here] ---
> 
> Unfortunately, with current stable Linux kernel release (as well as
> with most of the previous versions) blocking TCP packets with the SYN
> bit set and the ACK,RST and FIN bits cleared won't prevent incoming
> TCP connections.
> 
> Currently Linux TCP stack considers an incoming TCP segment to be a
> connection initiation request if the segment only has SYN flag set and
> ACK and RST flags cleared. You can easily check it yourself with your
> nearest Linux box, as well as on the netfilter.org (213.95.27.115):
> 
> # hping3 -c 2 -n -FS -p 80 netfilter.org
> HPING netfilter.org (wlan0 213.95.27.115): SF set, 40 headers + 0 data bytes
> len=44 ip=213.95.27.115 ttl=52 DF id=0 sport=80 flags=SA seq=0 win=5840 rtt=58.8 ms
> len=44 ip=213.95.27.115 ttl=52 DF id=0 sport=80 flags=SA seq=1 win=5840 rtt=51.1 ms
> 
> --- netfilter.org hping statistic ---
> 2 packets transmitted, 2 packets received, 0% packet loss
> round-trip min/avg/max = 51.1/55.0/58.8 ms
> # 
> 
> As you see, the netfilter.org server sends SYN/ACK in response to an
> incoming SYN/FIN, indicating that a connection is being established.
> It is only a matter of a few checks to make sure that the indication
> is correct and the connection is indeed initialized.
> 
> This might be a Linux bug as well to accept SYN/FIN as a connection
> initiation attempt. However, there could as well be a reason for kernel
> developers to do this, because such thing as T/TCP (RFC 1644) allows a
> TCP server to act like this, and though this RFC is experimental and
> obsolete, as far as I know, it is still implemented somewhere, for
> example, in FreeBSD.
> 
> I guess that most iptables setups probably are not affected by this
> behaviour, because `iptables -m tcp --syn' is often used for something
> in lines of this:
> 
> iptables -A INPUT -p tcp -m tcp --dport 22 --syn -j ACCEPT
> iptables -A INPUT -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT
> iptables -A INPUT -j DROP
> 
> In this case, SYN/FIN segments will be dropped, because they are not
> considered plain SYN and they are not associated with an established
> connection. My guess is that, for example, kernel.org is set up like that:
> 
> # hping3 -c 2 -n -FS -p 80 kernel.org
> HPING kernel.org (wlan0 149.20.4.69): SF set, 40 headers + 0 data bytes
> 
> --- kernel.org hping statistic ---
> 2 packets transmitted, 0 packets received, 100% packet loss
> round-trip min/avg/max = 0.0/0.0/0.0 ms
> #
> 
> However, there are cases when this behaviour produces clear security
> breach, for example, when one is trying to prevent incoming TCP
> connections from a certain IP (as manpage suggests) or when one is
> trying to limit the rate of connection establishment attempts. In
> this case attacker can send SYN/FIN packets which would pass all the
> rules containing --syn and would establish a connection.

I understand your concern, but the info in the manpage is correct:
basically, it can be extracted from it that --syn will not match
SYN+FIN packets.

As you point in your patch, you have to use:

--tcp-flags  SYN,RST,ACK  SYN

in your rule-set for the situation that you describe.

Changing the default behaviour of --syn to catch this case is
delicate, I don't want to break backward compatibility.
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: `iptables -m tcp --syn` doesn't do what the man says
  2012-04-01 17:42 ` Pablo Neira Ayuso
@ 2012-04-01 17:53   ` Eric Dumazet
  0 siblings, 0 replies; 6+ messages in thread
From: Eric Dumazet @ 2012-04-01 17:53 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: Artyom Gavrichenkov, netfilter-devel

On Sun, 2012-04-01 at 19:42 +0200, Pablo Neira Ayuso wrote:

> I understand your concern, but the info in the manpage is correct:
> basically, it can be extracted from it that --syn will not match
> SYN+FIN packets.
> 
> As you point in your patch, you have to use:
> 
> --tcp-flags  SYN,RST,ACK  SYN
> 
> in your rule-set for the situation that you describe.
> 
> Changing the default behaviour of --syn to catch this case is
> delicate, I don't want to break backward compatibility.

Agreed.

With TCP Fast Open, it might be possible to send a SYN+FIN+cookies+DATA
in a single frame.




^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2012-04-01 17:53 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-03-30 20:58 `iptables -m tcp --syn` doesn't do what the man says Artyom Gavrichenkov
2012-03-30 21:19 ` Eric Dumazet
2012-03-30 21:40   ` Artyom Gavrichenkov
2012-03-30 21:50     ` Eric Dumazet
2012-04-01 17:42 ` Pablo Neira Ayuso
2012-04-01 17:53   ` Eric Dumazet

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.