@@ -27,6 +27,17 @@ CONFIG_FILE=""
2727PROGRAM=" ${0##*/ } "
2828ARGS=( " $@ " )
2929
30+ LOCK_DIR_PATH=" /var/lock"
31+ mkdir -p " $LOCK_DIR_PATH "
32+
33+ WG_QUICK_LOCK_PATH=" ${LOCK_DIR_PATH} /wg-quick.lock"
34+
35+ get_lock () {
36+ exec {FD}> " $WG_QUICK_LOCK_PATH " || exit 1
37+ flock -x " $FD " || exit 1
38+ trap " rm -f $WG_QUICK_LOCK_PATH " EXIT
39+ }
40+
3041cmd () {
3142 echo " [#] $* " >&2
3243 " $@ "
@@ -210,16 +221,22 @@ remove_firewall() {
210221
211222HAVE_SET_FIREWALL=0
212223add_default () {
213- local table line
224+ local proto=-4 iptables=iptables pf=ip
225+ [[ $1 == * :* ]] && proto=-6 iptables=ip6tables pf=ip6
226+
227+ local table
214228 if ! get_fwmark table; then
229+ # We are trying to get next global table number and use it with default route.
230+ # This process should be globaly locked.
231+ get_lock
232+
215233 table=51820
216234 while [[ -n $( ip -4 route show table $table 2> /dev/null) || -n $( ip -6 route show table $table 2> /dev/null) ]]; do
217235 (( table++ ))
218236 done
219237 cmd wg set " $INTERFACE " fwmark $table
220238 fi
221- local proto=-4 iptables=iptables pf=ip
222- [[ $1 == * :* ]] && proto=-6 iptables=ip6tables pf=ip6
239+
223240 cmd ip $proto rule add not fwmark $table table $table
224241 cmd ip $proto rule add table main suppress_prefixlength 0
225242 cmd ip $proto route add " $1 " dev " $INTERFACE " table $table
@@ -229,20 +246,26 @@ add_default() {
229246 printf -v nftcmd ' %sadd chain %s %s preraw { type filter hook prerouting priority -300; }\n' " $nftcmd " " $pf " " $nftable "
230247 printf -v nftcmd ' %sadd chain %s %s premangle { type filter hook prerouting priority -150; }\n' " $nftcmd " " $pf " " $nftable "
231248 printf -v nftcmd ' %sadd chain %s %s postmangle { type filter hook postrouting priority -150; }\n' " $nftcmd " " $pf " " $nftable "
249+
250+ local line
232251 while read -r line; do
233252 [[ $line =~ .* inet6? \ ([0-9a-f:.]+)/[0-9]+.* ]] || continue
234253 printf -v restore ' %s-I PREROUTING ! -i %s -d %s -m addrtype ! --src-type LOCAL -j DROP %s\n' " $restore " " $INTERFACE " " ${BASH_REMATCH[1]} " " $marker "
235254 printf -v nftcmd ' %sadd rule %s %s preraw iifname != "%s" %s daddr %s fib saddr type != local drop\n' " $nftcmd " " $pf " " $nftable " " $INTERFACE " " $pf " " ${BASH_REMATCH[1]} "
236255 done < <( ip -o $proto addr show dev " $INTERFACE " 2> /dev/null)
256+
237257 printf -v restore ' %sCOMMIT\n*mangle\n-I POSTROUTING -m mark --mark %d -p udp -j CONNMARK --save-mark %s\n-I PREROUTING -p udp -j CONNMARK --restore-mark %s\nCOMMIT\n' " $restore " $table " $marker " " $marker "
238258 printf -v nftcmd ' %sadd rule %s %s postmangle meta l4proto udp mark %d ct mark set mark \n' " $nftcmd " " $pf " " $nftable " $table
239259 printf -v nftcmd ' %sadd rule %s %s premangle meta l4proto udp meta mark set ct mark \n' " $nftcmd " " $pf " " $nftable "
260+
240261 [[ $proto == -4 ]] && cmd sysctl -q net.ipv4.conf.all.src_valid_mark=1
262+
241263 if type -p nft > /dev/null; then
242264 cmd nft -f <( echo -n " $nftcmd " )
243265 else
244266 echo -n " $restore " | cmd $iptables -restore -n
245267 fi
268+
246269 HAVE_SET_FIREWALL=1
247270 return 0
248271}
0 commit comments