-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwg-conf
executable file
·185 lines (148 loc) · 3.77 KB
/
wg-conf
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
#!/usr/bin/env bash
#
# generate a WireGuard configuration to allow multiple clients access to the internet via a server
#
# Copyright (C) 2019 Christian Garbs <mitch@cgarbs.de>
# licensed under GNU GPL v3 or later
### REMINDER: generate private keys with `wg genkey`
### TODO: don't depend on tput presence, use shell function
### TODO: more colors
set -e
# print a column from the clients file
# $1 = column to read
read_client_column()
{
local COLUMN="$1"
awk "{ print \$$COLUMN }" wg-conf.clients
}
# print the public key to a private key
# $1 = private key
pubkey()
{
local PRIVKEY="$1"
echo "$PRIVKEY" | wg pubkey
}
# print the array index of a client name
# exits with failure if name does not exist
# $1 = client name
get_client_index_by_name()
{
local NAME="$1"
for IDX in "${!CLIENT_NAME[@]}"; do
if [ "$NAME" = "${CLIENT_NAME[$IDX]}" ]; then
echo "$IDX"
return
fi
done
echo "unknown client name \`$NAME'" >&2
exit 1
}
# convert subnet size like /24 to netmask like 255.255.255.0
# $1 = subnet size
convert_to_netmask()
{
local NETWORK_BITS="${1#/}"
local BINARY=
while [ ${#BINARY} -lt "$NETWORK_BITS" ]; do
BINARY="${BINARY}1"
done
while [ ${#BINARY} -lt 32 ]; do
BINARY="${BINARY}0"
done
echo $((2#${BINARY:0:8})).$((2#${BINARY:8:8})).$((2#${BINARY:16:8})).$((2#${BINARY:24:8}))
}
# print help text
show_help()
{
cat <<EOF
wgconf <command> [<option> [...]]
available commands:
help show help
clients list all known clients
client show configuration of a client
qr show configuration of a client as QR code
server show server configuration
EOF
}
# print all client names
show_clients()
{
for NAME in "${CLIENT_NAME[@]}"; do
echo "$NAME"
done
}
# print a client configuration
# $1 = client name
show_client_conf()
{
local NAME="$1" IDX IP PRIVKEY SERVER_PUBKEY
IDX="$(get_client_index_by_name "$NAME")"
IP="${CLIENT_IP[$IDX]}"
PRIVKEY="${CLIENT_PRIVKEY[$IDX]}"
SERVER_PUBKEY=$(pubkey "$SERVER_PRIVKEY")
cat <<EOF
[Interface]
Address = ${IP}${VPN_SUBNET_SIZE}
PrivateKey = ${PRIVKEY}
DNS = ${DNS_IP}
[Peer]
PublicKey = ${SERVER_PUBKEY}
AllowedIPs = 0.0.0.0/0, ::/0
Endpoint = ${SERVER_EXTERN_IP}:${SERVER_EXTERN_PORT}
EOF
}
# print server configuration
show_server_conf()
{
tput sgr0
echo "put this into /etc/network/interfaces.d/${SERVER_VPN_INTERFACE}.cfg"
tput bold
cat <<EOF
## WireGuard configuration for ${SERVER_VPN_INTERFACE}
auto ${SERVER_VPN_INTERFACE}
iface ${SERVER_VPN_INTERFACE} inet static
address ${SERVER_VPN_IP}
netmask ${VPN_SUBNET_NETMASK}
pre-up wg-quick up \$IFACE
post-down wg-quick down \$IFACE
EOF
tput sgr0
echo "put this into /etc/wireguard/${SERVER_VPN_INTERFACE}.conf"
tput bold
cat <<EOF
[Interface]
PrivateKey = ${SERVER_PRIVKEY}
ListenPort = ${SERVER_EXTERN_PORT}
EOF
local IDX IP NAME PUBKEY
for IDX in "${!CLIENT_NAME[@]}"; do
NAME="${CLIENT_NAME[$IDX]}"
IP="${CLIENT_IP[$IDX]}"
PUBKEY=$(pubkey "${CLIENT_PRIVKEY[$IDX]}")
cat <<EOF
[Peer]
PublicKey = ${PUBKEY}
AllowedIPs = ${IP}/32
EOF
done
tput sgr0
echo "don't forget, there is a private key in there:"
tput bold
cat<<EOF
chown root:root /etc/wireguard/${SERVER_VPN_INTERFACE}.conf
chmod 600 /etc/wireguard/${SERVER_VPN_INTERFACE}.conf
EOF
tput sgr0
}
source wg-conf.server
VPN_SUBNET_NETMASK=$(convert_to_netmask $VPN_SUBNET_SIZE)
mapfile -t CLIENT_NAME < <( read_client_column 1 )
mapfile -t CLIENT_IP < <( read_client_column 2 )
mapfile -t CLIENT_PRIVKEY < <( read_client_column 3 )
case "$1" in
client) show_client_conf "$2";;
qr) show_client_conf "$2" | qrencode -t utf8;;
clients) show_clients;;
server) show_server_conf;;
*) show_help;;
esac