-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathmnf
282 lines (235 loc) · 7.79 KB
/
mnf
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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
#!/bin/env bash
# ---------------------------
# CONFIG VARIABLES YOU SHOULD CHANGE
RULES_DIR=$HOME/LINUX/VPN/ # Path to where mullvad.rules file is located IMPORTANT: ADD THE ENDING SLASH FOR THE DIRECTORY.
EXCLUDE_COUNTRY_CODES='(us|ca|jp|au|hk|gb)' # Country codes to avoid, set to '' for allowing all.
RULES_FILE="mullvad.rules"
NFT_TABLENAME="mullvad-ts"
# ----------------------------
usage() {
echo "usage: ./$(basename "$0") <action> [options]"
printf "\nAction: up\n"
upusage
echo "-------------------------------------"
printf "\nAction: down\n"
downusage
echo "-------------------------------------"
printf "\nAction: conf\n"
confusage
exit 0
}
upusage() {
echo "Apply nftables configuration and connect to Mullvad and Tailscale/Zerotier."
echo ""
echo "$(basename "$0") up [-OPTIONS]:"
echo " -h, --help: Show this help message."
echo " -r, --ram: No-disk/RAM only Mullvad relays (default: all servers)"
echo " -z, --zerotier: Use Zerotier instead of Tailscale"
echo " -d, --dns: Set custom Mullvad DNS Server (i.e. -d 1.1.1.1)"
echo " -c, --country: Specify a country code to connect to (i.e. -c gb)"
echo " -f, --file: Specify a particular NFT rules file (default: $RULES_FILE)"
}
downusage() {
echo "Bring down Mullvad and remove nftables configuration."
echo ""
echo "$(basename "$0") down [-OPTIONS]:"
echo " -h, --help: Show this help message."
echo " -a, --all: Stop Mullvad and Tailscale/Zerotier (default: only stop Mullvad)"
echo " -z, --zerotier: Use Zerotier instead of Tailscale"
echo " -t, --table: Indicate the nft tablename to bring down (default: $NFT_TABLENAME)"
}
confusage() {
echo "Apply nftables configuration so Mullvad and Tailscale/Zerotier can work together and do nothing more."
echo ""
echo "$(basename "$0") conf [-OPTIONS]:"
echo " -u: Remove the nftables configuration."
echo " -h: Show this help message."
}
# Get the action to perform
actions=("up" "down" "conf")
if [ ! -z "$1" ]; then
action="$1"
if [[ ! " ${actions[*]} " =~ " ${action} " ]]; then
printf "> USAGE GUIDE <\n\n"
usage
exit 0
fi
else
printf "> USAGE GUIDE <\n\n"
usage
exit 0
fi
# Get options and flags
echo $a
ARGS=$(getopt -a --options d:f:c:t:auhzr --long "dns:,file:,table:,country:,all,unconf,zerotier,help,ram" -- "$@")
eval set -- "$ARGS"
help=false
all=false
unconf=false
zerotier=false
dns=false
ram=false
country_code=false
while true; do
case "$1" in
-d|--dns)
dns="$2"
shift 2;;
-f|--file)
RULES_FILE="$2"
RULES_DIR=""
shift 2;;
-c|--country)
country_code="$2"
shift 2;;
-t|--table)
NFT_TABLENAME="$2"
shift 2;;
-r|--ram)
ram=true
shift;;
-a|--all)
all=true
shift;;
-u|--unconf)
unconf=true
shift;;
-z|--zerotier)
zerotier=true
shift;;
-h|--help)
help=true
shift;;
--)
break;;
*)
printf "Unknown option %s\n" "$1"
exit 1;;
esac
done
case "$action" in
"up")
if [ "$help" = true ]; then
upusage
exit 0
fi
if $ts ; then
bash $0 down -a || echo "Ignoring error..."
else
bash $0 down -a -z || echo "Ignoring error..."
fi
mullvad relay update
if [ ! $country_code = false ] ; then
MULLVAD_RELAYS=( $(mullvad relay list | grep -E '(wireguard|wg)' | awk '{ print $1 }' | grep "$country_code" ) )
size=${#MULLVAD_RELAYS[@]}
if [ $size -lt 1 ]; then
printf "\n[ERROR]: Country code '"$country_code"' is not valid!"
exit 1
fi
else
MULLVAD_RELAYS=( $(mullvad relay list | grep -E '(wireguard|wg)' | awk '{ print $1 }' | grep -Ev "$EXCLUDE_COUNTRY_CODES") )
fi
if [ $ram = true ] ; then
echo "Getting RAM-only servers..."
MULLVAD_RELAYS=( $(echo "$MULLVAD_RELAYS" | grep -E '(wg)' | awk '{ print $1 }' ) )
fi
# Pick a random country code.
size=${#MULLVAD_RELAYS[@]}
index=$(($RANDOM % $size))
relay=${MULLVAD_RELAYS[$index]}
if [ "$dns" = false ] ; then
mullvad dns set default
else
echo "[INFO] Setting up Mullvad DNS to "$dns"..."
mullvad dns set custom "$dns"
fi
if [ "$zerotier" = false ] ; then
echo "[INFO] Restarting tailscale connection..."
sudo tailscale down
sudo tailscale up
else
echo "[INFO] Restarting zerotier-one connection..."
sudo systemctl start zerotier-one.service
sudo systemctl restart zerotier-one.service
fi
if [ "$zerotier" = false ]; then
echo "[INFO] Applying nft rules..."
sudo nft -f "$RULES_DIR""$RULES_FILE"
fi
if [ "$zerotier" = true ]; then
echo "[INFO] Applying nft rules..."
# This repetition is necessary. If not used it does not work wiht ZT.
# I need to investigate, but this is a workaround for the time being.
sudo nft -f "$RULES_DIR""$RULES_FILE"
sudo nft add table inet "$NFT_TABLENAME"
sleep .5
sudo nft delete table inet "$NFT_TABLENAME" 2>/dev/null || echo "[WARN] The table $NFT_TABLENAME does not exist or there is an error."
sleep .5
sudo nft -f "$RULES_DIR""$RULES_FILE"
sudo nft add table inet "$NFT_TABLENAME"
fi
echo "[INFO] Connecting to server "$relay"..."
mullvad relay set hostname "$relay"
mullvad connect -w
mullvad disconnect
mullvad connect -w
if [ "$zerotier" = true ]; then
echo "[INFO] Applying nft rules..."
# This repetition is necessary. If not used it does not work wiht ZT.
# I need to investigate, but this is a workaround for the time being.
sudo nft -f "$RULES_DIR""$RULES_FILE"
sudo nft add table inet "$NFT_TABLENAME"
sleep .5
sudo nft delete table inet "$NFT_TABLENAME" 2>/dev/null || echo "[WARN] The table $NFT_TABLENAME does not exist or there is an error."
sleep .5
sudo nft -f "$RULES_DIR""$RULES_FILE"
sudo nft add table inet "$NFT_TABLENAME"
sleep 6 &
PID=$!
i=1
echo -n 'Progress: '
while [ -d /proc/$PID ]
do
for s in █ █ █; do echo -ne "$s"; sleep .1; done;
done
fi
if [ "$zerotier" = true ]; then
printf "\n\nDone! You may need to wait a few seconds for the connection to be ready."
fi
exit 0
;;
"down")
if [ "$help" = true ]; then
downusage
exit 0
fi
if [ $all = true ]; then
if [ "$zerotier" = true ]; then
sudo systemctl stop zerotier-one
echo "[INFO] Zerotier-one disconnected."
else
sudo tailscale down
echo "[INFO] Tailscale disconnected."
fi
fi
echo "[INFO] Mullvad disconnected..."
mullvad disconnect
echo "[INFO] Removing nftables config..."
sudo nft delete table inet "$NFT_TABLENAME" 2>/dev/null || echo "[WARN] The table $NFT_TABLENAME does not exist or there is an error."
echo "[OK]"
exit 0
;;
"conf")
if [ "$help" = true ]; then
confusage
exit 0
fi
if [ $unconf = true ]; then
sudo nft delete table inet "$NFT_TABLENAME"
exit 0
fi
echo "[INFO] Applying nft rules..."
sudo nft -f $RULES_DIR/$RULES_FILE
exit 0
;;
esac