#!/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   # ipsec
        iptables -A INPUT                                                   -p udp   --dport    500 --sport  500                     -j ACCEPT   # ipsec
        iptables -A INPUT                                                   -p udp   --dport   4500 --sport 4500                     -j ACCEPT   # ipsec
        iptables -A INPUT                                                   -p icmp                                                  -j ACCEPT   # allow pings

       ## local ceph osd services
        iptables -A INPUT -i lo                           -m multiport      -p tcp   --sports  6800:7300                             -j ACCEPT   # local ceph osd traffic
        iptables -A INPUT -i lo                           -m multiport      -p tcp   --dports  6800:7300                             -j ACCEPT   # 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   # ceph osd traffic
        iptables -A INPUT -m policy --pol ipsec --dir in  -m multiport      -p tcp   --sports  6800:7300                             -j ACCEPT   # ceph osd traffic
        iptables -A INPUT -m policy --pol ipsec --dir in                    -p tcp   --dport   6789                                  -j ACCEPT   # ceph mon traffic
        iptables -A INPUT -m policy --pol ipsec --dir in                    -p tcp   --sport   6789                                  -j ACCEPT   # ceph mon traffic
        iptables -A INPUT -m policy --pol ipsec --dir in                    -p udp   --dport   4789                                  -j ACCEPT   # vxlan traffic
        iptables -A INPUT -m policy --pol ipsec --dir in                    -p udp   --sport    123                                  -j ACCEPT   # ntp replies for anything over the VPN
        iptables -A INPUT -m policy --pol ipsec --dir in                    -p udp   --sport     53                                  -j ACCEPT   # dns replies from anything over the VPN
        iptables -A INPUT -m policy --pol ipsec --dir in                    -p tcp   --dport     22                                  -j ACCEPT   # ssh if coming over the VPN

       ## external services we deplend upon
        iptables -A INPUT -s 170.199.217.0                                  -p tcp   --dport     22                                  -j ACCEPT   # ssh from bastion
        iptables -A INPUT -s 170.199.217.0                                  -p udp   --sport     53                                  -j ACCEPT   # dns replies from bastion
        iptables -A INPUT -s 10.1.19.1                                      -p tcp   --dport     22                                  -j ACCEPT   # ssh from bastion
        iptables -A INPUT -s 10.1.19.11                                     -p tcp   --dport     22                                  -j ACCEPT   # ssh from bastion2
        iptables -A INPUT -s 170.199.216.1                                  -p tcp   --sport   2379                                  -j ACCEPT   # etcd replies stackapi
        iptables -A INPUT -s 170.199.216.13                                 -p tcp   --sport    443                                  -j ACCEPT   # mirrors.wit.com
        iptables -A INPUT -s 170.199.216.13                                 -p tcp   --sport     25                                  -j ACCEPT   # allow email smart host

       ## rules for edge nodes, these should be more specific but for now, it'll do
        iptables -A INPUT -i up+                                            -p gre                                                   -j ACCEPT   # gre tunnels from other sites
        iptables -A INPUT -i up+                                            -p tcp   --dport    179                                  -j ACCEPT   # upstream to public bgp
        iptables -A INPUT -i up+                                            -p tcp   --sport    179                                  -j ACCEPT   # upstream from public bgp

       ### mgmt
        iptables -A INPUT -i mgmt                                           -p tcp   --dport  22                                     -j ACCEPT
        iptables -A INPUT -i mgmt -m state --state ESTABLISHED,RELATED                                                               -j ACCEPT

       ### DROP the rest
        iptables -P INPUT DROP


       ## some rules for bastion boxes to protect the mgmt networks
        iptables -F FORWARD
        iptables -A FORWARD -o mgmtgw1 -m state --state ESTABLISHED,RELATED      -j ACCEPT
        iptables -A FORWARD -o mgmtgw1 -j DROP
        iptables -A FORWARD -i ipmigw1 -j DROP
        iptables -A FORWARD -o ipmigw1 -j DROP


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


       # this matters only on bastion boxes
        iptables -t raw -A PREROUTING -i mgmtgw1  -j ACCEPT
        iptables -t raw -A OUTPUT     -o mgmtgw1  -j ACCEPT
        iptables -t raw -A PREROUTING -i ipmigw1  -j ACCEPT
        iptables -t raw -A OUTPUT     -o ipmigw1  -j ACCEPT
       # this matters on all boxes
        iptables -t raw -A PREROUTING -i mgmt1 -j ACCEPT
        iptables -t raw -A OUTPUT     -o mgmt  -j ACCEPT
        iptables -t raw -A PREROUTING          -j NOTRACK
        iptables -t raw -A OUTPUT              -j NOTRACK



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

        ip6tables -A INPUT -s 2604:bbc0:0:113::1                             -p tcp   --dport    22                       -j ACCEPT   # ssh from bastion
        ip6tables -A INPUT -s 2604:bbc0:0:113::1                             -p udp   --sport    53                       -j ACCEPT   # dns replies from bastion
        ip6tables -A INPUT -s 2604:bbc0:0:113::b                             -p tcp   --dport    22                       -j ACCEPT   # ssh from bastion2
        ip6tables -A INPUT -s 2604:bbc0:0:113::b                             -p udp   --sport    53                       -j ACCEPT   # dns replies from bastion2
        ip6tables -A INPUT -s 2001:67c:1560:8003::c7                         -p udp   --sport   123                       -j ACCEPT   # ntp
        ip6tables -A INPUT -s 2001:67c:1560:8003::c8                         -p udp   --sport   123                       -j ACCEPT   # ntp

       ## traffic we want to see encrypted over the VPN
        ip6tables -A INPUT -m policy --pol ipsec --dir in                    -p tcp   --dport    22                       -j ACCEPT   # ssh if coming over the VPN
        ip6tables -A INPUT -m policy --pol ipsec --dir in                    -p udp   --sport   123                       -j ACCEPT   # ntp if coming over the VPN
        ip6tables -A INPUT -m policy --pol ipsec --dir in  -m multiport      -p tcp   --dports 49152:49215                -j ACCEPT   # libvirt live migration
        ip6tables -A INPUT -m policy --pol ipsec --dir in  -m multiport      -p tcp   --sports 49152:49215                -j ACCEPT   # 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+   -p tcp  --sport   179                                            -j ACCEPT   # bgp (allow init as well as responding)
        ip6tables -A INPUT -s fe80::/10        -i gre+   -p tcp  --dport   179                                            -j ACCEPT   # bgp (allow init as well as responding)
        ip6tables -A INPUT -i up+                        -p tcp  --dport   179                                            -j ACCEPT   # bgp to public peer
        ip6tables -A INPUT -i up+                        -p tcp  --sport   179                                            -j ACCEPT   # bgp from public peer

       ### mgmt
        ip6tables -A INPUT -i mgmt1 -s fe80::/10         -p udp  --dport   546                                            -j ACCEPT   # allow dhcp replys, unlcear why but needs the physical interface not vrf
        ip6tables -A INPUT -i mgmt                       -p tcp  --dport    22                                            -j ACCEPT   # allow ssh from mgmt
        ip6tables -A INPUT -i mgmt   -m state --state ESTABLISHED,RELATED                                                 -j ACCEPT   # allow stateful connections over mgmt

       ### DROP the rest
        ip6tables -P INPUT DROP


       ## some rules for bastion boxes to protect the mgmt networks
        ip6tables -F FORWARD
        ip6tables -A FORWARD -o mgmtgw1 -m state --state ESTABLISHED,RELATED      -j ACCEPT
        ip6tables -A FORWARD -o mgmtgw1 -j DROP
        ip6tables -A FORWARD -i ipmigw1 -j DROP
        ip6tables -A FORWARD -o ipmigw1 -j DROP


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


       # this matters only on bastion boxes
        ip6tables -t raw -A PREROUTING -i mgmtgw1  -j ACCEPT
        ip6tables -t raw -A OUTPUT     -o mgmtgw1  -j ACCEPT
        ip6tables -t raw -A PREROUTING -i ipmigw1  -j ACCEPT
        ip6tables -t raw -A OUTPUT     -o ipmigw1  -j ACCEPT
       # this matters on all boxes
        ip6tables -t raw -A PREROUTING -i mgmt1    -j ACCEPT
        ip6tables -t raw -A OUTPUT     -o mgmt     -j ACCEPT
        ip6tables -t raw -A PREROUTING             -j NOTRACK
        ip6tables -t raw -A OUTPUT                 -j NOTRACK


       #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