forked from faicker/wg-config
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathuser.sh
executable file
·173 lines (149 loc) · 3.74 KB
/
user.sh
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
#!/usr/bin/env bash
cd `dirname ${BASH_SOURCE[0]}`
. wg.def
CLIENT_TPL_FILE=client.conf.tpl
SERVER_TPL_FILE=server.conf.tpl
SAVED_FILE=.saved
AVAILABLE_IP_FILE=.available_ip
WG_TMP_CONF_FILE=.$_INTERFACE.conf
WG_CONF_FILE="/etc/wireguard/$_INTERFACE.conf"
dec2ip() {
local delim=''
local ip dec=$@
for e in {3..0}
do
((octet = dec / (256 ** e) ))
((dec -= octet * 256 ** e))
ip+=$delim$octet
delim=.
done
printf '%s\n' "$ip"
}
generate_cidr_ip_file_if() {
local cidr=${_VPN_NET}
local ip mask a b c d
IFS=$'/' read ip mask <<< "$cidr"
IFS=. read -r a b c d <<< "$ip"
local beg=$((a * 256 ** 3 + b * 256 ** 2 + c * 256 + d))
local end=$(( beg+(1<<(32-mask))-1 ))
ip=$(dec2ip $((beg+1)))
_SERVER_IP="$ip/$mask"
if [[ -f $AVAILABLE_IP_FILE ]]; then
return
fi
> $AVAILABLE_IP_FILE
local i=$((beg+2))
while [[ $i -lt $end ]]; do
ip=$(dec2ip $i)
echo "$ip/$mask" >> $AVAILABLE_IP_FILE
i=$((i+1))
done
}
get_vpn_ip() {
local ip=$(head -1 $AVAILABLE_IP_FILE)
if [[ $ip ]]; then
local mat="${ip/\//\\\/}"
sed -i "/^$mat$/d" $AVAILABLE_IP_FILE
fi
echo "$ip"
}
add_user() {
local user=$1
local template_file=${CLIENT_TPL_FILE}
local interface=${_INTERFACE}
local userdir="users/$user"
mkdir -p "$userdir"
wg genkey | tee $userdir/privatekey | wg pubkey > $userdir/publickey
# client config file
_PRIVATE_KEY=`cat $userdir/privatekey`
_VPN_IP=$(get_vpn_ip)
if [[ -z $_VPN_IP ]]; then
echo "no available ip"
exit 1
fi
eval "echo \"$(cat "${template_file}")\"" > $userdir/client.conf
qrencode -o $userdir/$user.png < $userdir/client.conf
# change wg config
local ip=${_VPN_IP%/*}/32
local public_key=`cat $userdir/publickey`
wg set $interface peer $public_key allowed-ips $ip
if [[ $? -ne 0 ]]; then
echo "wg set failed"
rm -rf $user
exit 1
fi
echo "$user $_VPN_IP $public_key" >> ${SAVED_FILE}
}
del_user() {
local user=$1
local userdir="users/$user"
local ip key
local interface=${_INTERFACE}
read ip key <<<"$(awk "/^$user /{print \$2, \$3}" ${SAVED_FILE})"
if [[ -n "$key" ]]; then
wg set $interface peer $key remove
if [[ $? -ne 0 ]]; then
echo "wg set failed"
exit 1
fi
fi
sed -i "/^$user /d" ${SAVED_FILE}
if [[ -n "$ip" ]]; then
echo "$ip" >> ${AVAILABLE_IP_FILE}
fi
rm -rf $userdir
}
generate_and_install_server_config_file() {
local template_file=${SERVER_TPL_FILE}
local ip
# server config file
eval "echo \"$(cat "${template_file}")\"" > $WG_TMP_CONF_FILE
while read user vpn_ip public_key; do
ip=${vpn_ip%/*}/32
cat >> $WG_TMP_CONF_FILE <<EOF
[Peer]
PublicKey = $public_key
AllowedIPs = $ip
EOF
done < ${SAVED_FILE}
\cp -f $WG_TMP_CONF_FILE $WG_CONF_FILE
}
do_clear() {
local interface=$_INTERFACE
wg-quick down $interface
> $WG_CONF_FILE
rm -f ${SAVED_FILE} ${AVAILABLE_IP_FILE}
}
do_user() {
generate_cidr_ip_file_if
if [[ $action == "-a" ]]; then
if [[ -d $user ]]; then
echo "$user exist"
exit 1
fi
add_user $user
elif [[ $action == "-d" ]]; then
del_user $user
fi
generate_and_install_server_config_file
}
usage() {
echo "usage: $0 [-a|-d|-c|-g] [username]"
}
# main
if [[ $EUID -ne 0 ]]; then
echo "This script must be run as root"
exit 1
fi
action=$1
user=$2
if [[ $action == "-c" ]]; then
do_clear
elif [[ $action == "-g" ]]; then
generate_cidr_ip_file_if
elif [[ ! -z "$user" && ( $action == "-a" || $action == "-d" ) ]]; then
do_user
else
usage
exit 1
fi