I have come to realise my IPv6 ports are not going through iptables, and thus are accessible for attacks. I haven't seen any yet, but I'm sure its only a matter of time. As such, I'm trying to shore up the firewall for ipv6. I came across this script that configures the ip6tables
rules:
#!/bin/bash
# ip6tables single-host firewall script
# Define your command variables
ipt6="/sbin/ip6tables"
# Flush all rules and delete all chains
# for a clean startup
$ipt6 -F
$ipt6 -X
# Zero out all counters
$ipt6 -Z
# Default policies: deny all incoming
# Unrestricted outgoing
$ipt6 -P INPUT DROP
$ipt6 -P FORWARD DROP
$ipt6 -P OUTPUT ACCEPT
# Must allow loopback interface
$ipt6 -A INPUT -i lo -j ACCEPT
# Reject connection attempts not initiated from the host
$ipt6 -A INPUT -p tcp --syn -j DROP
# Allow return connections initiated from the host
$ipt6 -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# Accept all ICMP v6 packets
$ipt6 -A INPUT -p ipv6-icmp -j ACCEPT
# Optional rules to allow other LAN hosts access to services. Delete $ipt6 -A INPUT -p tcp --syn -j DROP
# Allow DHCPv6 from LAN only
$ipt6 -A INPUT -m state --state NEW -m udp -p udp -s fe80::/10 --dport 546 -j ACCEPT
# Allow connections from SSH clients
$ipt6 -A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
# Allow HTTP and HTTPS traffic
$ipt6 -A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
$ipt6 -A INPUT -m state --state NEW -m tcp -p tcp --dport 443 -j ACCEPT
# Allow access to SMTP, POP3, and IMAP
$ipt6 -A INPUT -m state --state NEW -p tcp -m multiport --dport 25,110,143 -j ACCEPT
While this does stop what I wanted, it also seems to not allow 80 and 443 ports?
$ipt6 -A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
$ipt6 -A INPUT -m state --state NEW -m tcp -p tcp --dport 443 -j ACCEPT
It simply hangs when I try and access from another server:
curl -v -6 http://backups.foo.org:80
* Rebuilt URL to: http://backups.foo.org:80/
* Trying 2a00:1098:80:a1::1...
* TCP_NODELAY set
ipv4 works fine:
curl -v -4 http://backups.foo.org:80
* Rebuilt URL to: http://backups.foo.org:80/
* Trying 93.93.135.111...
* TCP_NODELAY set
* Connected to backups.foo.org (93.93.135.169) port 80 (#0)
> GET / HTTP/1.1
> Host: backups.foo.org
> User-Agent: curl/7.58.0
> Accept: */*
>
< HTTP/1.1 301 Moved Permanently
< Server: nginx
< Date: Tue, 23 Feb 2021 07:52:32 GMT
< Content-Type: text/html
< Content-Length: 162
< Connection: keep-alive
< Location: https://backups.foo.org/
<
<html>
<head><title>301 Moved Permanently</title></head>
<body>
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx</center>
</body>
</html>
* Connection #0 to host backups.foo.org left intact
What am I missing? Basically, I just want to block ipv6 ports on services that are sensitive (MySQL, Exim, SMTP etc).
UPDATE: As suggested, I have removed:
$ipt6 -A INPUT -p tcp --syn -j DROP
Then run the script again, and the ip6tables
looks like this now:
root@backups:~# ip6tables --list -n
Chain INPUT (policy DROP)
target prot opt source destination
ACCEPT all ::/0 ::/0
ACCEPT all ::/0 ::/0 ctstate RELATED,ESTABLISHED
ACCEPT icmpv6 ::/0 ::/0
ACCEPT udp fe80::/10 ::/0 state NEW udp dpt:546
ACCEPT tcp ::/0 ::/0 state NEW tcp dpt:22
ACCEPT tcp ::/0 ::/0 state NEW tcp dpt:80
ACCEPT tcp ::/0 ::/0 state NEW tcp dpt:443
ACCEPT tcp ::/0 ::/0 state NEW multiport dports 25,110,143
Chain FORWARD (policy DROP)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
I have tested it:
curl -6 backups.foo.org
curl: (7) Failed to connect to backups.foo.org port 80: Connection refused
Again, it works with -4
. The weird thing is that it does work from here:
https://tools.keycdn.com/ipv6-ping
I can ping from the same server, and it works fine:
ping backups.foo.org
PING backups.chambresdhotes.org(2a00:1098:80:a1::1 (2a00:1098:80:a1::1)) 56 data bytes
64 bytes from 2a00:1098:80:a1::1 (2a00:1098:80:a1::1): icmp_seq=1 ttl=59 time=1.08 ms
64 bytes from 2a00:1098:80:a1::1 (2a00:1098:80:a1::1): icmp_seq=2 ttl=59 time=1.03 ms
^X^C
As requested, the output of ip6tables-save
as well:
ip6tables-save
# Generated by ip6tables-save v1.6.1 on Tue Feb 23 08:57:59 2021
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [78:6090]
-A INPUT -i lo -j ACCEPT
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p ipv6-icmp -j ACCEPT
-A INPUT -s fe80::/10 -p udp -m state --state NEW -m udp --dport 546 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m multiport --dports 25,110,143 -j ACCEPT
COMMIT
UPDATE 2:
As requested, the output from ss -lnpt
. Interestingly, I don't see port 80 in there.
LISTEN 0 100 [::]:993 [::]:*
LISTEN 0 100 [::]:995 [::]:*
LISTEN 0 128 [::]:22122 [::]:*
LISTEN 0 100 [::]:110 [::]:*
LISTEN 0 128 ::1]:783 [::]:*
LISTEN 0 100 [::]:143 [::]:*
LISTEN 0 128 [::]:55413 [::]:*
LISTEN 0 128 *:8181 *:*
LISTEN 0 128 ::1]:53 [::]:*
LISTEN 0 128 [::]:55414 [::]:*
LISTEN 0 128 [::]:22 [::]:*
LISTEN 0 128 [::1]:8953 [::]:*
Interestingly though, it shows up with netstat
:
sudo netstat -tulpan | grep nginx
tcp 0 0 0.0.0.0:9183 0.0.0.0:* LISTEN 1133/nginx: master
tcp 0 0 93.93.135.169:80 0.0.0.0:* LISTEN 1161/nginx: master
tcp 0 0 127.0.0.1:8084 0.0.0.0:* LISTEN 1161/nginx: master
tcp 0 0 93.93.135.169:443 0.0.0.0:* LISTEN 1161/nginx: master
tcp6 0 0 :::80 :::* LISTEN 1161/nginx: master
tcp6 0 0 :::443 :::* LISTEN 1161/nginx: master
udp 0 0 127.0.0.1:51104 127.0.0.53:53 ESTABLISHED 1135/nginx: worker