33set -e
44
55
6+ cleanup () {
7+ if [[ $openvpn_child ]]; then
8+ kill SIGTERM " $openvpn_child "
9+ fi
10+
11+ sleep 0.5
12+ rm -f " $modified_config_file "
13+ echo " info: exiting"
14+ exit 0
15+ }
16+
617is_enabled () {
718 [[ ${1,,} =~ ^(true| t| yes| y| 1| on| enable| enabled)$ ]]
819}
@@ -64,6 +75,7 @@ echo "info: original configuration file: $original_config_file"
6475
6576# Create a new configuration file to modify so the original is left untouched.
6677modified_config_file=vpn/openvpn.$( tr -dc A-Za-z0-9 < /dev/urandom | head -c8) .conf
78+ trap cleanup SIGTERM
6779
6880echo " info: modified configuration file: $modified_config_file "
6981grep -Ev ' (^up\s|^down\s)' " $original_config_file " > " $modified_config_file "
@@ -73,76 +85,126 @@ sed -i 's/\r$//g' "$modified_config_file"
7385
7486
7587default_gateway=$( ip -4 route | grep ' default via' | awk ' {print $3}' )
76- if is_enabled " $KILL_SWITCH " ; then
77- echo " info: kill switch is on"
78-
79- nftables_config_file=config/nftables.conf
80-
81- local_subnet=$( ip -4 route | grep ' scope link' | awk ' {print $1}' )
82-
83- printf ' %s\n' \
84- ' #!/usr/bin/nft' ' ' \
85- ' flush ruleset' ' ' \
86- ' # base ruleset' \
87- ' add table inet killswitch' ' ' \
88- ' add chain inet killswitch incoming { type filter hook input priority 0; policy drop; }' \
89- ' add rule inet killswitch incoming ct state established,related accept' \
90- ' add rule inet killswitch incoming iifname lo accept' ' ' \
91- ' add chain inet killswitch outgoing { type filter hook output priority 0; policy drop; }' \
92- ' add rule inet killswitch outgoing ct state established,related accept' \
93- ' add rule inet killswitch outgoing oifname lo accept' ' ' > $nftables_config_file
94-
95- printf ' %s\n' \
96- ' # allow traffic to/from the Docker subnet' \
97- " add rule inet killswitch incoming ip saddr $local_subnet accept" \
98- " add rule inet killswitch outgoing ip daddr $local_subnet accept" ' ' >> $nftables_config_file
99-
100- if [[ $SUBNETS ]]; then
101- printf ' # allow traffic to/from the specified subnets\n' >> $nftables_config_file
102- for subnet in ${SUBNETS// ,/ } ; do
103- ip route add " $subnet " via " $default_gateway " dev eth0
104- printf ' %s\n' \
105- " add rule inet killswitch incoming ip saddr $subnet accept" \
106- " add rule inet killswitch outgoing ip daddr $subnet accept" ' ' >> $nftables_config_file
107- done
108- fi
10988
110- global_port=$( grep " ^port " " $modified_config_file " | awk ' {print $2}' )
111- global_protocol=$( grep " ^proto " " $modified_config_file " | awk ' {print $2}' ) # {$2 = substr($2, 1, 3)} 2
112- remotes=$( grep " ^remote " " $modified_config_file " | awk ' {print $2, $3, $4}' )
113-
114- printf ' # allow traffic to the VPN server(s)\n' >> $nftables_config_file
115- ip_regex=' ^(([1-9]?[0-9]|1[0-9][0-9]|2([0-4][0-9]|5[0-5]))\.){3}([1-9]?[0-9]|1[0-9][0-9]|2([0-4][0-9]|5[0-5]))$'
116- while IFS= read -r line; do
117- IFS=' ' read -ra remote <<< " $line"
118- address=${remote[0]}
119- port=${remote[1]:- ${global_port:- 1194} }
120- protocol=${remote[2]:- ${global_protocol:- udp} }
121-
122- if [[ $address =~ $ip_regex ]]; then
123- printf ' %s\n' \
124- " add rule inet killswitch outgoing oifname eth0 ip daddr $address $protocol dport $port accept" >> $nftables_config_file
125- else
126- for ip in $( dig -4 +short " $address " ) ; do
89+ case " $KILL_SWITCH " in
90+ ' iptables' )
91+ echo " info: kill switch is using iptables"
92+
93+ iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
94+ iptables -A INPUT -i lo -j ACCEPT
95+ iptables -A OUTPUT -o lo -j ACCEPT
96+
97+ local_subnet=$( ip -4 route | grep ' scope link' | awk ' {print $1}' )
98+ iptables -A INPUT -s " $local_subnet " -j ACCEPT
99+ iptables -A OUTPUT -d " $local_subnet " -j ACCEPT
100+
101+ if [[ $SUBNETS ]]; then
102+ for subnet in ${SUBNETS// ,/ } ; do
103+ ip route add " $subnet " via " $default_gateway " dev eth0
104+ iptables -A INPUT -s " $subnet " -j ACCEPT
105+ iptables -A OUTPUT -d " $subnet " -j ACCEPT
106+ done
107+ fi
108+
109+ global_port=$( grep " ^port " " $modified_config_file " | awk ' {print $2}' )
110+ global_protocol=$( grep " ^proto " " $modified_config_file " | awk ' {print $2}' ) # {$2 = substr($2, 1, 3)} 2
111+ remotes=$( grep " ^remote " " $modified_config_file " | awk ' {print $2, $3, $4}' )
112+ ip_regex=' ^(([1-9]?[0-9]|1[0-9][0-9]|2([0-4][0-9]|5[0-5]))\.){3}([1-9]?[0-9]|1[0-9][0-9]|2([0-4][0-9]|5[0-5]))$'
113+ while IFS= read -r line; do
114+ IFS=' ' read -ra remote <<< " $line"
115+ address=${remote[0]}
116+ port=${remote[1]:- ${global_port:- 1194} }
117+ protocol=${remote[2]:- ${global_protocol:- udp} }
118+
119+ if [[ $address =~ $ip_regex ]]; then
120+ iptables -A OUTPUT -o eth0 -d " $address " -p " $protocol " --dport " $port " -j ACCEPT
121+ else
122+ for ip in $( dig -4 +short " $address " ) ; do
123+ iptables -A OUTPUT -o eth0 -d " $ip " -p " $protocol " --dport " $port " -j ACCEPT
124+ printf " %s %s\n" " $ip " " $address " >> /etc/hosts
125+ done
126+ fi
127+ done <<< " $remotes"
128+ iptables -A INPUT -i tun0 -j ACCEPT
129+ iptables -A OUTPUT -o tun0 -j ACCEPT
130+ iptables -P INPUT DROP
131+ iptables -P OUTPUT DROP
132+ iptables -P FORWARD DROP
133+ iptables-save > config/iptables.conf
134+ ;;
135+
136+ ' nftables' )
137+ echo " info: kill switch is using nftables"
138+ nftables_config_file=config/nftables.conf
139+
140+ printf ' %s\n' \
141+ ' #!/usr/bin/nft' ' ' \
142+ ' flush ruleset' ' ' \
143+ ' # base ruleset' \
144+ ' add table inet killswitch' ' ' \
145+ ' add chain inet killswitch incoming { type filter hook input priority 0; policy drop; }' \
146+ ' add rule inet killswitch incoming ct state established,related accept' \
147+ ' add rule inet killswitch incoming iifname lo accept' ' ' \
148+ ' add chain inet killswitch outgoing { type filter hook output priority 0; policy drop; }' \
149+ ' add rule inet killswitch outgoing ct state established,related accept' \
150+ ' add rule inet killswitch outgoing oifname lo accept' ' ' > $nftables_config_file
151+
152+ local_subnet=$( ip -4 route | grep ' scope link' | awk ' {print $1}' )
153+ printf ' %s\n' \
154+ ' # allow traffic to/from the Docker subnet' \
155+ " add rule inet killswitch incoming ip saddr $local_subnet accept" \
156+ " add rule inet killswitch outgoing ip daddr $local_subnet accept" ' ' >> $nftables_config_file
157+
158+ if [[ $SUBNETS ]]; then
159+ printf ' # allow traffic to/from the specified subnets\n' >> $nftables_config_file
160+ for subnet in ${SUBNETS// ,/ } ; do
161+ ip route add " $subnet " via " $default_gateway " dev eth0
127162 printf ' %s\n' \
128- " add rule inet killswitch outgoing oifname eth0 ip daddr $ip $protocol dport $port accept" >> $nftables_config_file
129- printf " %s %s\n " " $ip " " $address " >> /etc/hosts
163+ " add rule inet killswitch incoming ip saddr $subnet accept" \
164+ " add rule inet killswitch outgoing ip daddr $subnet accept " ' ' >> $nftables_config_file
130165 done
131166 fi
132- done <<< " $remotes"
133167
134- printf ' %s\n' \
135- ' ' ' # allow traffic over the VPN interface' \
136- " add rule inet killswitch incoming iifname tun0 accept" \
137- " add rule inet killswitch outgoing oifname tun0 accept" >> $nftables_config_file
168+ global_port=$( grep " ^port " " $modified_config_file " | awk ' {print $2}' )
169+ global_protocol=$( grep " ^proto " " $modified_config_file " | awk ' {print $2}' ) # {$2 = substr($2, 1, 3)} 2
170+ remotes=$( grep " ^remote " " $modified_config_file " | awk ' {print $2, $3, $4}' )
138171
139- nft -f $nftables_config_file
140- else
141- echo " info: kill switch is off"
142- for subnet in ${SUBNETS// ,/ } ; do
143- ip route add " $subnet " via " $default_gateway " dev eth0
144- done
145- fi
172+ printf ' # allow traffic to the VPN server(s)\n' >> $nftables_config_file
173+ ip_regex=' ^(([1-9]?[0-9]|1[0-9][0-9]|2([0-4][0-9]|5[0-5]))\.){3}([1-9]?[0-9]|1[0-9][0-9]|2([0-4][0-9]|5[0-5]))$'
174+ while IFS= read -r line; do
175+ IFS=' ' read -ra remote <<< " $line"
176+ address=${remote[0]}
177+ port=${remote[1]:- ${global_port:- 1194} }
178+ protocol=${remote[2]:- ${global_protocol:- udp} }
179+
180+ if [[ $address =~ $ip_regex ]]; then
181+ printf ' %s\n' \
182+ " add rule inet killswitch outgoing oifname eth0 ip daddr $address $protocol dport $port accept" >> $nftables_config_file
183+ else
184+ for ip in $( dig -4 +short " $address " ) ; do
185+ printf ' %s\n' \
186+ " add rule inet killswitch outgoing oifname eth0 ip daddr $ip $protocol dport $port accept" >> $nftables_config_file
187+ printf " %s %s\n" " $ip " " $address " >> /etc/hosts
188+ done
189+ fi
190+ done <<< " $remotes"
191+
192+ printf ' %s\n' \
193+ ' ' ' # allow traffic over the VPN interface' \
194+ " add rule inet killswitch incoming iifname tun0 accept" \
195+ " add rule inet killswitch outgoing oifname tun0 accept" >> $nftables_config_file
196+
197+ nft -f $nftables_config_file
198+ ;;
199+
200+ * )
201+ echo " info: kill switch is off"
202+ for subnet in ${SUBNETS// ,/ } ; do
203+ ip route add " $subnet " via " $default_gateway " dev eth0
204+ done
205+ ;;
206+
207+ esac
146208
147209if is_enabled " $HTTP_PROXY " ; then
148210 scripts/run-http-proxy.sh &
@@ -174,4 +236,7 @@ if [[ $VPN_AUTH_SECRET ]]; then
174236 openvpn_args+=(" --auth-user-pass" " /run/secrets/$VPN_AUTH_SECRET " )
175237fi
176238
177- exec openvpn " ${openvpn_args[@]} "
239+ openvpn " ${openvpn_args[@]} " &
240+ openvpn_child=$!
241+
242+ wait $openvpn_child
0 commit comments