IP Tables Issue

I have asterisk on a GCP compute instance, and had followed this tutorial on setting up IPTABLES for security (since it’s not behind a router). I checked and made sure those IPTABLES were actually in place (sudo iptables -S). Everything worked fine, and I could receive calls (incoming calls only). I had to shut my instance down for a few days, and when I booted it up yesterday, I could no longer receive calls. I would get a busy signal, and in the console it wouldn’t show anything. tcpdump showed that it was rejecting the call (but I am not very well versed in reading tcpdump).

I restored the IPTABLES to the original which accepted everything:

*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
COMMIT

And now it works fine and I can receive calls fine. So it’s something in my IPTABLES. This is what I have (that’s not working):

*filter
:INPUT ACCEPT [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
:ICMPALL - [0:0]
:IPSPF - [0:0]
:ASIP - [0:0]
:DPTS - [0:0]
:RLMSET - [0:0]
-A INPUT -p tcp --dport 5060:5082 -m conntrack --ctstate RELATED,ESTABLISHED -m recent ! --rcheck --name MYSIP -j DROP
-A INPUT -m conntrack --ctstate INVALID -j DROP
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i lo -j ACCEPT
# Read below for explanation
-A INPUT -m recent --update --name RLM --seconds 600 --hitcount 1 -j DROP
-A INPUT -p icmp --icmp-type 255 -j ICMPALL
# Allow DHCP traffic
-A INPUT -p udp --sport 67:68 --dport 67:68 -j ACCEPT
-A INPUT -i ens4 -j IPSPF
# Replace YOUR_SSH_PORT with your server's SSH port!
-A INPUT -p tcp --dport 22 -j ACCEPT
-A INPUT -j ASIP
-A INPUT -j DPTS
-A INPUT -m limit --limit 10/min -j LOG
-A INPUT -j DROP
-A ICMPALL -p icmp --fragment -j DROP
-A ICMPALL -p icmp --icmp-type 0 -j ACCEPT
-A ICMPALL -p icmp --icmp-type 3 -j ACCEPT
-A ICMPALL -p icmp --icmp-type 4 -j ACCEPT
-A ICMPALL -p icmp --icmp-type 8 -j ACCEPT
-A ICMPALL -p icmp --icmp-type 11 -j ACCEPT
-A ICMPALL -p icmp -j DROP
# Drop packets FROM bogon IPv4 addresses
# Delete the line below if your server uses this range:
-A IPSPF -s 10.0.0.0/8 -j DROP
# Same as above
-A IPSPF -s 172.16.0.0/12 -j DROP
# Same as above
-A IPSPF -s 192.168.0.0/16 -j DROP
-A IPSPF -s 0.0.0.0/8 -j DROP
-A IPSPF -s 100.64.0.0/10 -j DROP
-A IPSPF -s 127.0.0.0/8 -j DROP
-A IPSPF -s 169.254.0.0/16 -j DROP
-A IPSPF -s 192.0.0.0/24 -j DROP
-A IPSPF -s 192.0.2.0/24 -j DROP
-A IPSPF -s 198.18.0.0/15 -j DROP
-A IPSPF -s 198.51.100.0/24 -j DROP
-A IPSPF -s 203.0.113.0/24 -j DROP
-A IPSPF -s 224.0.0.0/4 -j DROP
-A IPSPF -s 240.0.0.0/4 -j DROP
-A IPSPF -s 255.255.255.255 -j DROP
# Drop packets TO broadcast/multicast/loopback IPs
-A IPSPF -d 0.0.0.0/8 -j DROP
-A IPSPF -d 127.0.0.0/8 -j DROP
-A IPSPF -d 224.0.0.0/4 -j DROP
-A IPSPF -d 255.255.255.255 -j DROP
# These are some bad TCP flags used in attacks:
-A IPSPF -p tcp --tcp-flags ALL NONE -j DROP
-A IPSPF -p tcp --tcp-flags ALL ALL -j DROP
-A IPSPF -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP
-A IPSPF -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP
-A IPSPF -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
-A IPSPF -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
-A IPSPF -p tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN -j DROP
# Reject NEW TCP packets w/ ACK flag. Someone could be sending packets with your server's IP as his fake IP
-A IPSPF -p tcp --tcp-flags SYN,ACK SYN,ACK -m conntrack --ctstate NEW -j REJECT --reject-with tcp-reset
# Drop NEW TCP packets w/o SYN flag
-A IPSPF -p tcp ! --syn -m conntrack --ctstate NEW -j DROP
# Drop empty UDP packets (lengths 0 to 28)
-A IPSPF -p udp -m length --length 0:28 -j DROP
# Limit incoming NEW TCP connections to 10/sec for each IP (configurable)
-A IPSPF -p tcp --syn -m recent --update --name INSYN --seconds 1 --hitcount 11 -j DROP
-A IPSPF -p tcp --syn -m recent --set --name INSYN -j RETURN
-A IPSPF -j RETURN
# Change to ACCEPT if FTP server:
-A DPTS -p tcp --dport 21 -j DROP
# Remember to change your SSH port first!
# If you use port 22, change this to ACCEPT!
-A DPTS -p tcp --dport 22 -j ACCEPT
-A DPTS -p tcp --dport 23 -j RLMSET
# Change to ACCEPT if MAIL server:
-A DPTS -p tcp --dport 25 -j RLMSET
# Note: Port 80 and/or 443 are needed to access the FreePBX GUI.
# For added security, do NOT open them here. Use SSH port forwarding instead.
-A DPTS -p tcp --dport 80 -j DROP
-A DPTS -p tcp --dport 443 -j DROP
-A DPTS -p tcp --dport 1433 -j RLMSET
-A DPTS -p tcp --dport 3128 -j RLMSET
# Change to ACCEPT if Internet-facing MySQL server:
-A DPTS -p tcp --dport 3306 -j RLMSET
-A DPTS -p tcp --dport 3389 -j RLMSET
-A DPTS -p tcp --dport 4899 -j RLMSET
-A DPTS -p tcp --dport 5900 -j RLMSET
-A DPTS -j RETURN
-A RLMSET -m recent --set --name RLM -j DROP
-A ASIP -p tcp --dport 5060:5082 -j ACCEPT
-A ASIP -p udp --dport 5060:5082 -m recent --update --name MYSIP -j ACCEPT
-A ASIP -p udp --dport 5060:5082 -j DROP
-A ASIP -p udp --dport 10000:20000 -j ACCEPT
-A ASIP -j RETURN
COMMIT
*raw
:PREROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:BADSIP - [0:0]
:TCPSIP - [0:0]
:UDPSIP - [0:0]
:NEWSIP - [0:0]
# IMPORTANT: Replace "YOUR_HOSTNAME.no-ip.com" with the dynamic IP hostname you have set up!
-A PREROUTING -i eth+ -m recent --update --name MYSIP -j ACCEPT
-A PREROUTING -i eth+ -p tcp --dport 5060:5082 -m string --string "sip:domain.example.com" --algo bm --icase -j NEWSIP
-A PREROUTING -i eth+ -p udp --dport 5060:5082 -m string --string "sip:domain.example.com" --algo bm --to 1500 --icase -j NEWSIP
-A PREROUTING -i eth+ -m recent --update --name BADSIP -j DROP
-A PREROUTING -i eth+ -p tcp --dport 5060:5082 -j TCPSIP
-A PREROUTING -i eth+ -p udp --dport 5060:5082 -j UDPSIP
-A TCPSIP -m string --string "sundayddr" --algo bm -j BADSIP
-A TCPSIP -m string --string "sipsak" --algo bm -j BADSIP
-A TCPSIP -m string --string "sipvicious" --algo bm --icase -j BADSIP
-A TCPSIP -m string --string "friendly-scanner" --algo bm -j BADSIP
-A TCPSIP -m string --string "iWar" --algo bm -j BADSIP
-A TCPSIP -m string --string "sip-scan" --algo bm -j BADSIP
-A TCPSIP -m string --string "sipcli" --algo bm -j BADSIP
-A TCPSIP -m string --string "eyeBeam" --algo bm -j BADSIP
-A TCPSIP -m string --string "VaxSIPUserAgent" --algo bm -j BADSIP
-A TCPSIP -m string --string "sip:nm@nm" --algo bm -j BADSIP
-A TCPSIP -m string --string "sip:carol@chicago.com" --algo bm -j BADSIP
-A UDPSIP -m string --string "sundayddr" --algo bm --to 1500 -j BADSIP
-A UDPSIP -m string --string "sipsak" --algo bm --to 1500 -j BADSIP
-A UDPSIP -m string --string "sipvicious" --algo bm --icase --to 1500 -j BADSIP
-A UDPSIP -m string --string "friendly-scanner" --algo bm --to 1500 -j BADSIP
-A UDPSIP -m string --string "iWar" --algo bm --to 1500 -j BADSIP
-A UDPSIP -m string --string "sip-scan" --algo bm --to 1500 -j BADSIP
-A UDPSIP -m string --string "sipcli" --algo bm --to 1500 -j BADSIP
-A UDPSIP -m string --string "eyeBeam" --algo bm --to 1500 -j BADSIP
-A UDPSIP -m string --string "VaxSIPUserAgent" --algo bm --to 1500 -j BADSIP
-A UDPSIP -m string --string "sip:nm@nm" --algo bm --to 1500 -j BADSIP
-A UDPSIP -m string --string "sip:carol@chicago.com" --algo bm --to 1500 -j BADSIP
-A BADSIP -m recent --set --name BADSIP -j DROP
-A NEWSIP -m recent --set --name MYSIP -j ACCEPT
-A TCPSIP -m string --string "REGISTER sip:" --algo bm -m recent --set --name SIP_R
-A TCPSIP -m string --string "REGISTER sip:" --algo bm -m recent --update --seconds 10 --hitcount 20 --rttl --name SIP_R -j DROP
-A UDPSIP -m string --string "REGISTER sip:" --algo bm --to 1500 -m recent --set --name SIP_R
-A UDPSIP -m string --string "REGISTER sip:" --algo bm --to 1500 -m recent --update --seconds 10 --hitcount 20 --rttl --name SIP_R -j DROP
-A TCPSIP -m string --string "INVITE sip:" --algo bm -m recent --set --name SIP_I
-A TCPSIP -m string --string "INVITE sip:" --algo bm -m recent --update --seconds 5 --hitcount 20 --rttl --name SIP_I -j DROP
-A UDPSIP -m string --string "INVITE sip:" --algo bm --to 1500 -m recent --set --name SIP_I
-A UDPSIP -m string --string "INVITE sip:" --algo bm --to 1500 -m recent --update --seconds 5 --hitcount 20 --rttl --name SIP_I -j DROP
COMMIT

Here is tcpdump when the call is rejected (sensitive info redacted):

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens4, link-type EN10MB (Ethernet), capture size 262144 bytes
21:20:12.918973 IP 67.212.84.21.5060 > 10.142.0.3.5060: SIP: INVITE sip:15551230000@domain.example.com:5060 SIP/2.0
E.....@.0..{C.T.
.........g.INVITE sip:15551230000@domain.example.com:5060 SIP/2.0
Via: SIP/2.0/UDP 67.212.84.21:5060;branch=z9hG4bKbca2d82e78c40146b76c1b36cf684461;rport
Max-Forwards: 70
From: "Outside Caller" <sip:12345551111@67.212.84.21>;tag=977b6503b64034bbe3632275e9a8c668
To: <sip:15551230000@domain.example.com>
Call-ID: VLMCHFP1BL3H52FD9LPCGGNQL0@81.201.85.43-b2b_1-b2b_1
CSeq: 200 INVITE
Contact: Anonymous <sip:12345551111@67.212.84.21:5060>
Expires: 300
User-Agent: ACC
cisco-GUID: 2991413526-4110515609-388534775-4026314304
h323-conf-id: 2991413526-4110515609-388534775-4026314304
P-Asserted-Identity: "Outside Caller" <sip:12345551111@208.72.120.66>
X-anveo-e164: 15551230000
Content-Type: application/sdp
Content-Length: 256

v=0
o=- 68409668 68409668 IN IP4 81.201.85.71
s=session
c=IN IP4 81.201.85.71
t=0 0
m=audio 18184 RTP/AVP 0 8 101
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-16
a=ptime:20
a=maxptime:150
a=sendrecv

21:20:13.404419 IP 67.212.84.21.5060 > 10.142.0.3.5060: SIP: INVITE sip:15551230000@domain.example.com:5060 SIP/2.0
E.....@.0..{C.T.
.........g.INVITE sip:15551230000@domain.example.com:5060 SIP/2.0
Via: SIP/2.0/UDP 67.212.84.21:5060;branch=z9hG4bKbca2d82e78c40146b76c1b36cf684461;rport
Max-Forwards: 70
From: "Outside Caller" <sip:12345551111@67.212.84.21>;tag=977b6503b64034bbe3632275e9a8c668
To: <sip:15551230000@domain.example.com>
Call-ID: VLMCHFP1BL3H52FD9LPCGGNQL0@81.201.85.43-b2b_1-b2b_1
CSeq: 200 INVITE
Contact: Anonymous <sip:12345551111@67.212.84.21:5060>
Expires: 300
User-Agent: ACC
cisco-GUID: 2991413526-4110515609-388534775-4026314304
h323-conf-id: 2991413526-4110515609-388534775-4026314304
P-Asserted-Identity: "Outside Caller" <sip:12345551111@208.72.120.66>
X-anveo-e164: 15551230000
Content-Type: application/sdp
Content-Length: 256

I finally narrowed it down to this:

-A INPUT -j ASIP
-A INPUT -j DPTS
-A INPUT -m limit --limit 10/min -j LOG
-A INPUT -j DROP
-A ICMPALL -p icmp --fragment -j DROP
-A ICMPALL -p icmp --icmp-type 0 -j ACCEPT
-A ICMPALL -p icmp --icmp-type 3 -j ACCEPT
-A ICMPALL -p icmp --icmp-type 4 -j ACCEPT
-A ICMPALL -p icmp --icmp-type 8 -j ACCEPT
-A ICMPALL -p icmp --icmp-type 11 -j ACCEPT
-A ICMPALL -p icmp -j DROP

When I remove that section, it works and I can call in from outside. I am not too knowledgeable of IPTABLES. Anyone have an idea of what is happening and what I may need to do? What is ICMP and should I make it more secure?

you need to actually put your FQDN in the below lines instead of “domain.example.com”, this checks its existance in the SIP packet
-A PREROUTING -i eth+ -p tcp --dport 5060:5082 -m string --string “sip:domain.example.com” --algo bm --icase -j NEWSIP
-A PREROUTING -i eth+ -p udp --dport 5060:5082 -m string --string “sip:domain.example.com” --algo bm --to 1500 --icase -j NEWSIP

I’m not too familiar either, but it looks to me that it will only accept UDP SIP from senders from which it has recently accepted them. There doesn’t seem to be a way of getting the first acceptance.

I had actually removed that whole section (*raw and afterwards). It did not resolve my issue. Only removing ASIP to the last icmp section fixed the issue (but now I’m getting SIP scanner attacks (or something like it). Let’s say I do put my FQDN… what do I do with the section I have noted?

I also want to clarify that asterisk is running on a GCP compute instance, and my domain is pointed to the instance’s public (external) IP address. And that same domain is used in setting up a trunk in Anveo.

Also, in Google documentation, it says that FQDN is for instances communicating internally?

If you are communicating between instances in the same VPC network, you can send packets to an instance by specifying the fully qualified DNS name (FQDN) of the target instance. Google Cloud automatically resolves the name to the internal IP address of the instance.

from what i can see the below lines are what triggers the NEWSIP chain that adds the connection to the MYSIP list which is used afterward for coneection tracking, if we take “sip:domain.example.com” as the example the rule expect to see this in the SIP packet, so if you register to your asterisk with let’s say asterisk.test.com then you will need to modify the line to reflect that.

what physical interface are you using? those rules are for “eth*” interface but there is a line using “ens4”, if you are using ens4 as a physical interface you will need to update the iptables rules to reflect that, to simplify the rules you can remove the SIP TCP related stuff if you are not using that

-A PREROUTING -i eth+ -p tcp --dport 5060:5082 -m string --string “sip:domain.example.com” --algo bm --icase -j NEWSIP
-A PREROUTING -i eth+ -p udp --dport 5060:5082 -m string --string “sip:domain.example.com” --algo bm --to 1500 --icase -j NEWSIP