9

(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:521088972597572280@x.x.x.x |
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?

David Wylie
  • 191
  • 1
  • 4
  • 1
    `ESTABLISHED` should work for UDP. It looks that the packet flow and accepts replies to (outgoing) requests. Do your "hackers" have static IPs? ;-) If so, check /proc/net/nf_conntrack to see what the state table contains about them when they are currently /not/ connected... `RELATED` is a more tricky thing... Don't know what it does for SIP. Does `modprobe` maybe show an ipt_sip module or something loaded that would do "magic" stuff? – Marki Apr 10 '16 at 12:41
  • @Marki - thanks for that tip. /proc/net/nf_conntrack doesn't exist (centos 7) so I'll need to find out what/why/where. – David Wylie Apr 11 '16 at 06:44
  • Simplistically, RELATED will open up RTP ports (for audio) after the sip signalling port 5060 has established a dialogue. Useful so you don't have to leave huge port ranges permanently open, though less so if this is the consequence... – David Wylie Apr 11 '16 at 06:50
  • yeah on newer systems there are tools/extra commands to view the tables instead of the files in /proc. Look for them. – Marki Apr 11 '16 at 11:05
  • 2
    "conntrack-tools" is the thing, installable from the repo, then running "conntrack -L" seems to list them. Going to see what that yields. Typical though, he's stopped. Hopefully just a pause. – David Wylie Apr 11 '16 at 14:48
  • 1
    If possible: Try to limit `RELATED` to `-p icmp`. Maybe this solves it (or is a suitable work around which does not require from you to read about conntrack helpers). – corny Apr 17 '16 at 14:25
  • Have you tried to load nf_conntrack_sip module? If not - do so and recheck. – Tomek Sep 09 '17 at 21:31
  • Try adding this as the last rule. iptables -A INPUT -j DROP I have discovered sometimes the policy fails to engage. You could also try echo 0 >/proc/sys/net/netfilter/nf_conntrack_tcp_loose – cybernard Jan 02 '18 at 03:13
  • 1
    You messed things around by adding a chain. If ACCEPT chains are checked before your custom ALLOWEDSIP, then ALLOWEDSIP can be useless. – Overmind Jan 04 '18 at 08:16
  • Did you load *`SIP`* modules into kernel for netfilter:`modprobe nf_conntrack_sip` and maybe `modprobe nf_nat_sip` ? This my help giving some light on your problem! – F. Hauri - Give Up GitHub Jul 27 '19 at 11:40

2 Answers2

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
asdmin
  • 2,020
  • 16
  • 28
-3

You could nullroute. This should bypass iptables.

route add 89.163.146.25 gw 127.0.0.1 lo

Check it

netstat -nr

OR

route -n