-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathwireguard-nsinit
executable file
·140 lines (116 loc) · 3.7 KB
/
wireguard-nsinit
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#!/usr/bin/env bash
set -e -o pipefail
shopt -s extglob
export LC_ALL=C
CONTAINER=""
INTER_HOSTIF=""
INTER_CONTIF=""
WG_CONFIG=""
INTERFACE=""
ADDRESSES=( )
MTU=""
DNS=( )
TABLE=""
PRE_UP=( )
POST_UP=( )
PRE_DOWN=( )
POST_DOWN=( )
SAVE_CONFIG=0
CONFIG_FILE=""
PROGRAM="${0##*/}"
ARGS=( "$@" )
die() {
echo "$PROGRAM: $*" >&2
exit 1
}
# from https://github.com/WireGuard/WireGuard/blob/master/src/tools/wg-quick/linux.bash
parse_options() {
local interface_section=0 line key value stripped
CONFIG_FILE="$1"
[[ $CONFIG_FILE =~ ^[a-zA-Z0-9_=+.-]{1,15}$ ]] && CONFIG_FILE="/etc/wireguard/$CONFIG_FILE.conf"
[[ -e $CONFIG_FILE ]] || die "\`$CONFIG_FILE' does not exist"
[[ $CONFIG_FILE =~ (^|/)([a-zA-Z0-9_=+.-]{1,15})\.conf$ ]] || die "The config file must be a valid interface name, followed by .conf"
CONFIG_FILE="$(readlink -f "$CONFIG_FILE")"
((($(stat -c '0%#a' "$CONFIG_FILE") & $(stat -c '0%#a' "${CONFIG_FILE%/*}") & 0007) == 0)) || echo "Warning: \`$CONFIG_FILE' is world accessible" >&2
INTERFACE="${BASH_REMATCH[2]}"
shopt -s nocasematch
while read -r line || [[ -n $line ]]; do
stripped="${line%%\#*}"
key="${stripped%%=*}"; key="${key##*([[:space:]])}"; key="${key%%*([[:space:]])}"
value="${stripped#*=}"; value="${value##*([[:space:]])}"; value="${value%%*([[:space:]])}"
[[ $key == "["* ]] && interface_section=0
[[ $key == "[Interface]" ]] && interface_section=1
if [[ $interface_section -eq 1 ]]; then
case "$key" in
Address) ADDRESSES+=( ${value//,/ } ); continue ;;
MTU) MTU="$value"; continue ;;
DNS) DNS+=( ${value//,/ } ); continue ;;
Table) TABLE="$value"; continue ;;
PreUp) PRE_UP+=( "$value" ); continue ;;
PreDown) PRE_DOWN+=( "$value" ); continue ;;
PostUp) POST_UP+=( "$value" ); continue ;;
PostDown) POST_DOWN+=( "$value" ); continue ;;
SaveConfig) read_bool SAVE_CONFIG "$value"; continue ;;
esac
fi
WG_CONFIG+="$line"$'\n'
done < "$CONFIG_FILE"
shopt -u nocasematch
INTERFACE="ns${INTERFACE}"
INTER_HOSTIF="veth_m$CONTAINER"
INTER_CONTIF="veth_s$CONTAINER"
}
cmd_up() {
ip link add "$INTERFACE" type wireguard
ip link set "$INTERFACE" netns "$CONTAINER"
for i in "${ADDRESSES[@]}"; do
ip -n "$CONTAINER" addr add "$i" dev "$INTERFACE"
done;
ip netns exec "$CONTAINER" wg setconf "$INTERFACE" <(echo "$WG_CONFIG")
ip -n "$CONTAINER" link set "$INTERFACE" mtu 1420 up
ip -n "$CONTAINER" route add default dev "$INTERFACE"
ip link add "$INTER_HOSTIF" type veth peer name "$INTER_CONTIF"
ip link set "$INTER_CONTIF" netns "$CONTAINER"
ip addr add "$INTER_IP_HOST" dev "$INTER_HOSTIF"
ip -n "$CONTAINER" addr add "$INTER_IP_CONT" dev "$INTER_CONTIF"
ip link set "$INTER_HOSTIF" up
ip -n "$CONTAINER" link set "$INTER_CONTIF" up
ip route add "$INTER_GATEWAY" dev "$INTER_HOSTIF"
ip -n "$CONTAINER" route add "$INTER_GATEWAY" dev "$INTER_CONTIF"
}
cmd_down() {
ip -n "$CONTAINER" route delete default
ip -n "$CONTAINER" link set "$INTERFACE" down
ip -n "$CONTAINER" link delete "$INTERFACE"
ip -n "$CONTAINER" route delete "$INTER_GATEWAY"
ip -n "$CONTAINER" link set "$INTER_CONTIF" down
ip route delete "$INTER_GATEWAY"
ip link set "$INTER_HOSTIF" down
ip link delete "$INTER_HOSTIF"
}
cmd_cleanup() {
set +e +o pipefail
cmd_down
set -e -o pipefail
}
if [[ ! $# -eq 2 ]]; then
die 'invalid number of arguments'
fi;
CMD="$1"
CONTAINER="$2"
if [[ -z "$WIREGUARD_CONF" ]] || [[ -z "$INTER_GATEWAY" ]] || [[ -z "$INTER_IP_HOST" ]] || [[ -z "$INTER_IP_CONT" ]]; then
die 'wireguard config not specified'
fi;
if [[ -z "$CONTAINER" ]]; then
die 'container not specified'
fi;
parse_options "$WIREGUARD_CONF"
if [[ $CMD == up ]]; then
cmd_up
elif [[ $CMD == down ]]; then
cmd_down
elif [[ $CMD == cleanup ]]; then
cmd_cleanup
else
exit 1
fi;