(moved from SO)

I have iptables protecting a sip server. It blocks all IPs except ones I specifically opened, and it seems to work for almost everyone. I have tested from lots of ip addresses that are not white listed and they all get dropped as they should.

BUT, I have picked up a "hacker" who seems able to bypass the iptables rules. His probing INVITEs make it through, and I have no idea how, or that it was even possible. In 10 years I've not seen this before.

I suppose it must be something I've done, but I can't see it.

iptables created like this (MYIP defined at the top - redacted):

iptables -F
iptables -X
iptables -N ALLOWEDSIP
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -p tcp -d $MYIP --dport 22 -j ACCEPT
iptables -t filter -A INPUT -j ALLOWEDSIP

# This is my white list.
iptables -A ALLOWEDSIP -j RETURN

Now, with NOTHING in the ALLOWEDSIP, all I should be able to do is SSH in (which I can). If I throw calls at it they all get dropped. But wireshark shows me this (my ip redacted) :

89.163.146.25 -> x.x.x.x SIP/SDP 805 Request: INVITE sip:[email protected] |
x.x.x.x -> 89.163.146.25 SIP 417 Status: 100 Giving a try |
x.x.x.x -> 89.163.146.25 SIP 875 Status: 407 Proxy Authentication Required |

His calls hit my switch and, though rejected ultimately by the ACL, they should never get there. Nothing else gets through. Pulling my hair out. Anyone know?

Just for completeness, here's the result of iptables -L :

# iptables -L --line-numbers -v
Chain INPUT (policy DROP 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1       10   640 ACCEPT     all  --  any    any     anywhere             anywhere             state RELATED,ESTABLISHED
2        0     0 ACCEPT     all  --  lo     any     anywhere             anywhere
3        0     0 ACCEPT     tcp  --  any    any     anywhere             <redacted>.com  tcp dpt:6928
4        0     0 ALLOWEDSIP  all  --  any    any     anywhere             anywhere

Chain FORWARD (policy DROP 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 6 packets, 544 bytes)
num   pkts bytes target     prot opt in     out     source               destination

Chain ALLOWEDSIP (1 references)
num   pkts bytes target     prot opt in     out     source               destination
1        0     0 RETURN     all  --  any    any     anywhere             anywhere

EDIT : just seen this from wireshark. Could they be doing something horrible like getting established some other way then playing on the established rule? Maybe they are playing on some hole in RELATED?

89.163.146.25 -> <redacted> RTCP 806 Source port: tag-pm  Destination port: sip

EDIT 2 : UDP is the key here. When I set OpenSIPS to only listen for TCP, the problem seems to go away. None of their attempts get through any more, though they are sending more of those "tag-pm" messages. Doesn't explain why the packets are even getting to opensips though. iptables should have stopped them first. Would love to know what I've done wrong here.

EDIT 3 : If I remove RELATED I stop replying to them, so it's something to do with that. But I think I need related. Any tips on workarounds?


Solution 1:

The only plausible explanation how it could work is, that the offending UDP datagrams somehow pass --state ESTABLISHED,RELATED.

Given that UDP is a stateless protocol, I doubt that the state module has effective tracking over it.

To sort out the issue, I'd limit the state check to the TCP protocol by:

-A INPUT -m tcp -m state -p tcp --state ESTABLISHED,RELATED -j ACCEPT`

And pre-filter ALLOWEDSIP with UDP protocol (and preferably, with the destination port too):

iptables -t filter -A INPUT -m udp -p udp --dport 5060 -j ALLOWEDSIP