Skip to content

Commit db2341a

Browse files
added global lock to linux wg quick, fixed race condition when 2 wg interfaces wanted to have the same table number
Signed-off-by: Andrew Aladjev <[email protected]>
1 parent 13f4ac4 commit db2341a

File tree

1 file changed

+26
-3
lines changed

1 file changed

+26
-3
lines changed

src/wg-quick/linux.bash

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,17 @@ CONFIG_FILE=""
2727
PROGRAM="${0##*/}"
2828
ARGS=( "$@" )
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+
3041
cmd() {
3142
echo "[#] $*" >&2
3243
"$@"
@@ -210,16 +221,22 @@ remove_firewall() {
210221

211222
HAVE_SET_FIREWALL=0
212223
add_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

Comments
 (0)