#!/bin/bash

echo_info() {
    GREEN='\033[0;32m'
    NC='\033[0m'
    printf "${GREEN}$1${NC}\n"
}

####################################################################
# Constants
####################################################################

# vpn --> outbound
VPN_INTERFACE=wg-cloud
OUTBOUND_INTERFACE=wgcf

# forward --> web server
WEB_LISTEN_INTERFACE=br-web
WEB_SERVER_IPV4=10.254.0.2
WEB_SERVER_IPV6=fd99:23eb:1682:fe::2

WEB_SERVER_PORTS=80,443,10000:11000,51820

####################################################################
# wireguard setup
# wireguard -> X forwarding
# wireguard -> $WAN_INTERFACE SNAT
####################################################################

echo_info "Set up outbound..."

./start_outbound.sh

echo_info "Set up wireguard..."

wg-quick down /$VPN_INTERFACE.conf
wg-quick up /$VPN_INTERFACE.conf

# default drop forward
iptables-nft  -P FORWARD DROP
ip6tables-nft -P FORWARD DROP

# allow establishing connection from vpn
iptables-nft  -A FORWARD -i $VPN_INTERFACE -j ACCEPT
ip6tables-nft -A FORWARD -i $VPN_INTERFACE -j ACCEPT
# allow only established connection from outside
iptables-nft  -A FORWARD -i $OUTBOUND_INTERFACE -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
ip6tables-nft -A FORWARD -i $OUTBOUND_INTERFACE -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# DNAT all outbound connections
iptables-nft  -t nat -A POSTROUTING -o $OUTBOUND_INTERFACE -j MASQUERADE
ip6tables-nft -t nat -A POSTROUTING -o $OUTBOUND_INTERFACE -j MASQUERADE

# clamp tcp MSS of packets out all tunnels
iptables-nft  -t mangle -A POSTROUTING -o $VPN_INTERFACE      -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
ip6tables-nft -t mangle -A POSTROUTING -o $VPN_INTERFACE      -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

iptables-nft  -t mangle -A POSTROUTING -o $OUTBOUND_INTERFACE -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
ip6tables-nft -t mangle -A POSTROUTING -o $OUTBOUND_INTERFACE -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

# setup routing rules (vpn --> outbound)
ip r flush table 100
ip r add   table 100 default dev $OUTBOUND_INTERFACE

ip ru add iif $VPN_INTERFACE lookup 100 priority 100


ip -6 r flush table 100
ip -6 r add   table 100 default dev $OUTBOUND_INTERFACE

ip -6 ru add iif $VPN_INTERFACE lookup 100 priority 100


####################################################################
# Port forwarding
####################################################################

echo_info "Set up port forwarding to web server..."

setup_port_forward() {
    interface_name_v4=$1
    interface_name_v6=$2
    ports=$3
    dst_ipv4=$4
    dst_ipv6=$5

    interface_ipv4=`ip -4 addr show $interface_name_v4 | grep -oP '(?<=inet\s)\d+(\.\d+){3}' -m 1`
    interface_ipv6=`ip -6 addr show $interface_name_v6 | grep -oP '(?<=inet6\s)[\da-f:]+' -m 1`

    # ipv4 forwarding
    iptables-nft -t nat -A PREROUTING  -p tcp  -d $interface_ipv4 -m multiport --dports $ports -j DNAT --to-destination $dst_ipv4
    iptables-nft -A FORWARD -p tcp             -d $dst_ipv4       -m multiport --dports $ports -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
    iptables-nft -t nat -A POSTROUTING -p tcp  -d $dst_ipv4       -m multiport --dports $ports -j MASQUERADE
    
    iptables-nft -t nat -A PREROUTING  -p udp  -d $interface_ipv4 -m multiport --dports $ports -j DNAT --to-destination $dst_ipv4
    iptables-nft -A FORWARD -p udp             -d $dst_ipv4       -m multiport --dports $ports -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
    iptables-nft -t nat -A POSTROUTING -p udp  -d $dst_ipv4       -m multiport --dports $ports -j MASQUERADE

    # ipv6 forwarding
    ip6tables-nft -t nat -A PREROUTING  -p tcp -d $interface_ipv6 -m multiport --dports $ports -j DNAT --to-destination $dst_ipv6
    ip6tables-nft -A FORWARD -p tcp            -d $dst_ipv6       -m multiport --dports $ports -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
    ip6tables-nft -t nat -A POSTROUTING -p tcp -d $dst_ipv6       -m multiport --dports $ports -j MASQUERADE

    ip6tables-nft -t nat -A PREROUTING  -p udp -d $interface_ipv6 -m multiport --dports $ports -j DNAT --to-destination $dst_ipv6
    ip6tables-nft -A FORWARD -p udp            -d $dst_ipv6       -m multiport --dports $ports -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
    ip6tables-nft -t nat -A POSTROUTING -p udp -d $dst_ipv6       -m multiport --dports $ports -j MASQUERADE
}

setup_port_forward $WEB_LISTEN_INTERFACE $WEB_LISTEN_INTERFACE $WEB_SERVER_PORTS $WEB_SERVER_IPV4 $WEB_SERVER_IPV6

####################################################################
# iptables de-duplicate
####################################################################

echo_info "De-duplicating iptables..."

iptables-nft-save | awk '/^COMMIT$/ { delete x; }; !x[$0]++' > /tmp/iptables.conf
iptables-nft -F
iptables-nft-restore < /tmp/iptables.conf

ip6tables-nft-save | awk '/^COMMIT$/ { delete x; }; !x[$0]++' > /tmp/iptables.conf
ip6tables-nft -F
ip6tables-nft-restore < /tmp/iptables.conf

####################################################################
####################################################################

echo_info "Infra setup complete!"

sleep infinity &

wait
