diff --git a/.gitignore b/.gitignore index 03eae37..79ecd33 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,6 @@ # gitsecret hidden files infra/root/wg-cloud.conf + +# data +data/ diff --git a/docker-compose.yml b/docker-compose.yml index 8acffa6..108cfab 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,7 +1,12 @@ services: infra: build: ./infra + cap_add: - NET_ADMIN network_mode: host + + volumes: + - ./data/infra:/data:rw + restart: unless-stopped diff --git a/infra/Dockerfile b/infra/Dockerfile index 9c3f958..fdd1082 100644 --- a/infra/Dockerfile +++ b/infra/Dockerfile @@ -1,6 +1,13 @@ FROM alpine:latest -RUN apk add --no-cache --upgrade bash grep iptables ip6tables wireguard-tools +# install packages +RUN apk add --no-cache --upgrade bash grep sed curl iptables ip6tables wireguard-tools +# install wgcf +RUN curl -fsSL git.io/wgcf.sh | bash +# create data dir +RUN mkdir -p /data + +# copy root COPY /root / ENTRYPOINT ["/setup.sh"] \ No newline at end of file diff --git a/infra/root/setup.sh b/infra/root/setup.sh index 29d5000..7de6c6e 100755 --- a/infra/root/setup.sh +++ b/infra/root/setup.sh @@ -10,10 +10,12 @@ # Constants #################################################################### -WAN_INTERFACE_V4=eth1 -WAN_INTERFACE_V6=eth1 +# 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 @@ -25,29 +27,49 @@ # 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 +wg-quick down /$VPN_INTERFACE.conf +wg-quick up /$VPN_INTERFACE.conf -# default drop +# default drop forward iptables-nft -P FORWARD DROP ip6tables-nft -P FORWARD DROP -# allow forward -iptables-nft -A FORWARD -i ${VPN_INTERFACE} -j ACCEPT -ip6tables-nft -A FORWARD -i ${VPN_INTERFACE} -j ACCEPT +# 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 -iptables-nft -A FORWARD -i $WAN_INTERFACE_V4 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT -ip6tables-nft -A FORWARD -i $WAN_INTERFACE_V6 -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 -# masquerading -iptables-nft -t nat -A POSTROUTING -o $WAN_INTERFACE_V4 -j MASQUERADE -ip6tables-nft -t nat -A POSTROUTING -o $WAN_INTERFACE_V6 -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 -# clamp tcp MSS of packets out 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 @@ -84,7 +106,7 @@ ip6tables-nft -t nat -A POSTROUTING -p udp -d $dst_ipv6 -m multiport --dports $ports -j MASQUERADE } -setup_port_forward $WAN_INTERFACE_V4 $WAN_INTERFACE_V6 $WEB_SERVER_PORTS $WEB_SERVER_IPV4 $WEB_SERVER_IPV6 +setup_port_forward $WEB_LISTEN_INTERFACE $WEB_LISTEN_INTERFACE $WEB_SERVER_PORTS $WEB_SERVER_IPV4 $WEB_SERVER_IPV6 #################################################################### # iptables de-duplicate diff --git a/infra/root/start_outbound.sh b/infra/root/start_outbound.sh new file mode 100755 index 0000000..b941e5a --- /dev/null +++ b/infra/root/start_outbound.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env bash + + +echo_info() { + GREEN='\033[0;32m' + NC='\033[0m' + printf "${GREEN}$1${NC}\n" +} + + +# generate profile +cd /data + +if [ ! -e "wgcf-account.toml" ]; then + echo_info "Registering wgcf..." + + wgcf register --accept-tos +fi +if [ ! -e "wgcf-profile.conf" ]; then + echo_info "Generating config file..." + + wgcf generate +fi + +cp wgcf-profile.conf /etc/wireguard/wgcf.conf + +# table off +sed -i "/\[Interface\]/a Table = off" /etc/wireguard/wgcf.conf +# remove mtu +sed -i "/^MTU/c\\" /etc/wireguard/wgcf.conf +# remove dns +sed -i "/^DNS/c\\" /etc/wireguard/wgcf.conf + +# up +echo_info "Setting up wgcf..." +wg-quick down wgcf +wg-quick up wgcf + +# check status +echo_info "Checking wgcf network status..." +while ! curl --max-time 2 google.com; do + wg-quick down wgcf + echo_info "Sleep and retry again..." + sleep 2 + wg-quick up wgcf +done +echo_info "OK, wgcf is up"