#!/bin/bash
### BEGIN INIT INFO
# Provides:          scriptname
# Required-Start:    $network
# Required-Stop:     $network
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: iptables
# Description:       Enable firewall rules
### END INIT INFO

exec 1> >(logger -s -t $(basename $0)) 2>&1

case $1 in
   start)
        echo -n "firewall start..."
     ### IPv4
        iptables -P INPUT ACCEPT
        iptables -F INPUT
       ## unencrypted traffic
        iptables -A INPUT                                                   -p esp                                                   -j ACCEPT   -m comment --comment "ipsec"
        iptables -A INPUT                                                   -p udp   --dport    500 --sport  500                     -j ACCEPT   -m comment --comment "ipsec"
        iptables -A INPUT                                                   -p udp   --dport   4500 --sport 4500                     -j ACCEPT   -m comment --comment "ipsec"
        iptables -A INPUT                                                   -p icmp                                                  -j ACCEPT   -m comment --comment "allow pings"

       ## local ceph osd services
        iptables -A INPUT -i lo                           -m multiport      -p tcp   --sports  6800:7300                             -j ACCEPT   -m comment --comment "local ceph osd traffic"
        iptables -A INPUT -i lo                           -m multiport      -p tcp   --dports  6800:7300                             -j ACCEPT   -m comment --comment "local ceph osd traffic"

       ## traffic we want to see encrypted over the VPN
        iptables -A INPUT -m policy --pol ipsec --dir in  -m multiport      -p tcp   --dports  6800:7300                             -j ACCEPT   -m comment --comment "ceph osd traffic"
        iptables -A INPUT -m policy --pol ipsec --dir in  -m multiport      -p tcp   --sports  6800:7300                             -j ACCEPT   -m comment --comment "ceph osd traffic"
        iptables -A INPUT -m policy --pol ipsec --dir in                    -p tcp   --dport   6789                                  -j ACCEPT   -m comment --comment "ceph mon traffic"
        iptables -A INPUT -m policy --pol ipsec --dir in                    -p tcp   --sport   6789                                  -j ACCEPT   -m comment --comment "ceph mon traffic"
        iptables -A INPUT -m policy --pol ipsec --dir in                    -p udp   --dport   4789                                  -j ACCEPT   -m comment --comment "vxlan traffic"
        iptables -A INPUT -m policy --pol ipsec --dir in                    -p udp   --sport    123                                  -j ACCEPT   -m comment --comment "ntp replies for bastion"
        iptables -A INPUT -m policy --pol ipsec --dir in                    -p udp   --sport     53                                  -j ACCEPT   -m comment --comment "dns replies for bastion"
        iptables -A INPUT -m policy --pol ipsec --dir in                    -p tcp   --dport     22                                  -j ACCEPT   -m comment --comment "ssh if coming over the VPN"

       ## external services we depend upon
        iptables -A INPUT -s 170.199.216.1                                  -p tcp   --sport   2379                                  -j ACCEPT   -m comment --comment "etcd replies stackapi"
        iptables -A INPUT -s 170.199.216.13                                 -p tcp   --sport     25                                  -j ACCEPT   -m comment --comment "allow email smart host"

       ## rules for edge nodes, shouldn't ever end up matching on "normal nodes"
        iptables -A INPUT -i up+                                            -p gre                                                   -j ACCEPT   -m comment --comment "gre tunnels from other sites"
        iptables -A INPUT -i up+            -m ttl --ttl-eq 1               -p tcp   --dport    179                                  -j ACCEPT   -m comment --comment "upstream to public bgp"
        iptables -A INPUT -i up+            -m ttl --ttl-eq 1               -p tcp   --sport    179                                  -j ACCEPT   -m comment --comment "upstream from public bgp"
        iptables -A INPUT -i customer+      -m ttl --ttl-eq 1               -p tcp   --dport    179                                  -j ACCEPT   -m comment --comment "downstream bgp for dedicated customer"
        iptables -A INPUT -i customer+      -m ttl --ttl-eq 1               -p tcp   --sport    179                                  -j ACCEPT   -m comment --comment "downstream bgp for dedicated customers"

       ### mgmt
        iptables -A INPUT -i mgmt                                           -p tcp   --dport  22                                     -j ACCEPT   -m comment --comment "ssh on mgmt vrf"
        iptables -A INPUT -i mgmt -m state --state ESTABLISHED,RELATED                                                               -j ACCEPT   -m comment --comment "stateful mgmt vrf"

       ### DROP the rest
        iptables -P INPUT DROP


       ## this may only be needed on edge in some cases. needs to be tweaked once we have a network again spaning multiple regions
        #iptables -t mangle -A FORWARD -p tcp -m tcp -o usw1 --tcp-flags SYN,RST SYN -m tcpmss --mss 1437:10000 -j TCPMSS --set-mss 1436


       #special tables
        iptables -F FORWARD
        iptables -F OUTPUT
        iptables -t mangle -F
        iptables -t nat -F
        iptables -t raw -F


       # this matters on all boxes
        iptables -t raw -A PREROUTING -i mgmt1    -j ACCEPT       -m comment --comment "DO track mgmt vrf"
        iptables -t raw -A OUTPUT     -o mgmt     -j ACCEPT       -m comment --comment "DO track mgmt vrf"
        iptables -t raw -A PREROUTING             -j NOTRACK      -m comment --comment "do NOT track the rest"
        iptables -t raw -A OUTPUT                 -j NOTRACK      -m comment --comment "do NOT track the rest"



     #### IPv6
        ip6tables -P INPUT ACCEPT
        ip6tables -F INPUT
       ## unencrypted traffic
        ip6tables -A INPUT                                                   -p esp                                       -j ACCEPT   -m comment --comment "ipsec"
        ip6tables -A INPUT                                                   -p udp   --dport   500 --sport  500          -j ACCEPT   -m comment --comment "ipsec"
        ip6tables -A INPUT                                                   -p udp   --dport  4500 --sport 4500          -j ACCEPT   -m comment --comment "ipsec"
        ip6tables -A INPUT                                                   -p ipv6-icmp                                 -j ACCEPT   -m comment --comment "icmp"
        ip6tables -A INPUT -s fe80::/10        -i feth+   -m hl --hl-eq 1    -p tcp   --sport   179                       -j ACCEPT   -m comment --comment "bgp (allow init as well as responding)"
        ip6tables -A INPUT -s fe80::/10        -i feth+   -m hl --hl-eq 1    -p tcp   --dport   179                       -j ACCEPT   -m comment --comment "bgp (allow init as well as responding)"

       ## external services we depend upon
        ip6tables -A INPUT -s 2604:bbc0:1:20::a001                           -p tcp   --sport   443                       -j ACCEPT   -m comment --comment "# mirrors.wit.com"

       ## ceph
        ip6tables -A INPUT -i lo                                             -p tcp   --dport   6789                      -j ACCEPT   -m comment --comment "ceph mon traffic"
        ip6tables -A INPUT -i lo                                             -p tcp   --sport   6789                      -j ACCEPT   -m comment --comment "ceph mon traffic"
        ip6tables -A INPUT -m policy --pol ipsec --dir in                    -p tcp   --dport   6789                      -j ACCEPT   -m comment --comment "ceph mon traffic"
        ip6tables -A INPUT -m policy --pol ipsec --dir in                    -p tcp   --sport   6789                      -j ACCEPT   -m comment --comment "ceph mon traffic"
        ip6tables -A INPUT -i lo                           -m multiport      -p tcp   --dports  6800:7300                 -j ACCEPT   -m comment --comment "ceph osd traffic"
        ip6tables -A INPUT -i lo                           -m multiport      -p tcp   --sports  6800:7300                 -j ACCEPT   -m comment --comment "ceph osd traffic"
        ip6tables -A INPUT -m policy --pol ipsec --dir in  -m multiport      -p tcp   --dports  6800:7300                 -j ACCEPT   -m comment --comment "ceph osd traffic"
        ip6tables -A INPUT -m policy --pol ipsec --dir in  -m multiport      -p tcp   --sports  6800:7300                 -j ACCEPT   -m comment --comment "ceph osd traffic"

       ## traffic we want to see encrypted over the VPN
        ip6tables -A INPUT -m policy --pol ipsec --dir in                    -p tcp   --dport     22                      -j ACCEPT   -m comment --comment "ssh if coming over the VPN"
        ip6tables -A INPUT -m policy --pol ipsec --dir in                    -p udp   --sport     53                      -j ACCEPT   -m comment --comment "dns replies from anything over the VPN"
        ip6tables -A INPUT -m policy --pol ipsec --dir in                    -p tcp   --sport     80                      -j ACCEPT   -m comment --comment "http replies for bastion"
        ip6tables -A INPUT -m policy --pol ipsec --dir in                    -p udp   --sport    123                      -j ACCEPT   -m comment --comment "ntp if coming over the VPN"
        ip6tables -A INPUT -m policy --pol ipsec --dir in  -m multiport      -p tcp   --dports 49152:49215                -j ACCEPT   -m comment --comment "libvirt live migration"
        ip6tables -A INPUT -m policy --pol ipsec --dir in  -m multiport      -p tcp   --sports 49152:49215                -j ACCEPT   -m comment --comment "libvirt live migration"

       ## rules for edge nodes, these should be more specific but for now, it'll do
        ip6tables -A INPUT -s fe80::/10     -i gre+      -m hl --hl-eq 1     -p tcp  --sport   179                        -j ACCEPT   -m comment --comment "bgp (allow init as well as responding)"
        ip6tables -A INPUT -s fe80::/10     -i gre+      -m hl --hl-eq 1     -p tcp  --dport   179                        -j ACCEPT   -m comment --comment "bgp (allow init as well as responding)"
        ip6tables -A INPUT -s fe80::/10     -i ibgp+     -m hl --hl-eq 1     -p tcp  --sport   179                        -j ACCEPT   -m comment --comment "bgp (allow init as well as responding)"
        ip6tables -A INPUT -s fe80::/10     -i ibgp+     -m hl --hl-eq 1     -p tcp  --dport   179                        -j ACCEPT   -m comment --comment "bgp (allow init as well as responding)"
        ip6tables -A INPUT -i up+                        -m hl --hl-eq 1     -p tcp  --dport   179                        -j ACCEPT   -m comment --comment "bgp to public peer"
        ip6tables -A INPUT -i up+                        -m hl --hl-eq 1     -p tcp  --sport   179                        -j ACCEPT   -m comment --comment "bgp from public peer"
        ip6tables -A INPUT -i customer+                  -m hl --hl-eq 1     -p tcp  --dport   179                        -j ACCEPT   -m comment --comment "downstream bgp for dedicated customer"
        ip6tables -A INPUT -i customer+                  -m hl --hl-eq 1     -p tcp  --sport   179                        -j ACCEPT   -m comment --comment "downstream bgp for dedicated customers"

       ### mgmt
        ip6tables -A INPUT -i mgmt1 -s fe80::/10         -p udp  --dport   546                                            -j ACCEPT   -m comment --comment "dhcp replys, unlcear why physical if not vrf"
        ip6tables -A INPUT -i mgmt                       -p tcp  --dport    22                                            -j ACCEPT   -m comment --comment "ssh for mgmt vrf"
        ip6tables -A INPUT -i mgmt   -m state --state ESTABLISHED,RELATED                                                 -j ACCEPT   -m comment --comment "stateful mgmt vrf"

       ### DROP the rest
        ip6tables -P INPUT DROP


       #special tables
        ip6tables -F FORWARD
        ip6tables -F OUTPUT
        ip6tables -t mangle -F
        ip6tables -t nat -F
        ip6tables -t raw -F


       # manage conntrack
        ip6tables -t raw -A PREROUTING -i mgmt1    -j ACCEPT       -m comment --comment "DO track mgmt vrf"
        ip6tables -t raw -A OUTPUT     -o mgmt     -j ACCEPT       -m comment --comment "DO track mgmt vrf"
        ip6tables -t raw -A PREROUTING             -j NOTRACK      -m comment --comment "do NOT track default vrf"
        ip6tables -t raw -A OUTPUT                 -j NOTRACK      -m comment --comment "do NOT track default vrf"


       #some boxes get special addon rules
        [ -e /etc/init.d/firewall-addon ] && source /etc/init.d/firewall-addon

        ;;

   stop)
        echo -n "firewall stop..."

        #### Firewall rules
        iptables -P INPUT ACCEPT
        iptables -F
        iptables -t raw -F
        iptables -t nat -F
        iptables -t mangle -F

        ip6tables -P INPUT ACCEPT
        ip6tables -F
        ip6tables -t raw -F
        ip6tables -t nat -F
        ip6tables -t mangle -F

        echo " done"
        ;;

   restart)
        #$0 stop
        $0 start
        ;;

   *)
        echo "use $0 [start|stop|restart]"
        ;;

esac

exit 0