17 printf "warning: $@" >&2
21 function install_deps
()
23 if ! which wg
>/dev
/null
; then
24 echo "wireguard not found, installing:"
26 sudo apt
install wireguard
30 function check_cidr_addr
()
33 [[ "$addr" =~ ^
(0|
[1-9][0-9]*)'.'(0|
[1-9][0-9]*)'.'(0|
[1-9][0-9]*)'.'(0|
[1-9][0-9]*)'/'(0|
[1-9][0-9]*)$
]] \
34 || fail
"can't parse IPv4 CIDR address: %q" "$addr"
35 ((${BASH_REMATCH[1]} <= 255 &&
36 ${BASH_REMATCH[2]} <= 255 &&
37 ${BASH_REMATCH[3]} <= 255 &&
38 ${BASH_REMATCH[4]} <= 255 &&
39 ${BASH_REMATCH[5]} <= 32)) \
40 || fail
"invalid IPv4 CIDR address: %s" "$addr"
43 function init_server
()
45 local server_iface_name
="$1" listen_port
="$2" server_iface_addr
="$3"
46 check_cidr_addr
"$server_iface_addr"
48 local private_key
="$(wg genkey)"
49 local config_contents
="[Interface]
50 PrivateKey = $private_key
51 ListenPort = $listen_port
52 Address = $server_iface_addr
55 echo "$config_contents" > "/etc/wireguard/$server_iface_name.conf"
56 echo "Created config for $server_iface_name"
57 echo "You need to allow UDP port $listen_port through your firewall"
62 local server_iface_name
="$1" server_public_addr
="$2" client_config
="$3" client_iface_addr
="$4"
63 check_cidr_addr
"$client_iface_addr"
64 if [[ " $(wg show interfaces) " =~
" $server_iface_name " ]]; then
65 fail
"You need to shutdown interface %s first:\nwg-quick down %s\nor:\nsystemctl stop wg-quick@%s" \
66 "$server_iface_name" "$server_iface_name" "$server_iface_name"
68 local server_iface_conf
="/etc/wireguard/$server_iface_name.conf"
69 local lines line key eq_value value section
="" server_private_key
=""
70 local server_iface_addr
="" server_listen_port
=""
71 mapfile
-t lines
< "$server_iface_conf"
72 for line
in "${lines[@]}"; do
73 line
="${line%%#*}" # remove comments
74 [[ "$line" =~ ^
([^
=]*)('='(.
*))?$
]] || fail
"regex failed -- not supposed to happen"
75 key
="${BASH_REMATCH[1]}"
76 eq_value
="${BASH_REMATCH[2]}"
77 value
="${BASH_REMATCH[3]}"
78 key
="${key#"${key%%[![:space:]]*}"}" # remove leading whitespace
79 key
="${key%"${key##*[![:space:]]}"}" # remove trailing whitespace
80 value
="${value#"${value%%[![:space:]]*}"}" # remove leading whitespace
81 value
="${value%"${value##*[![:space:]]}"}" # remove trailing whitespace
82 [[ "$key" == "" && "$eq_value" == "" ]] && continue
83 if [[ "$key" =~ ^
'['(.
+)']'$
&& "$eq_value" == "" ]]; then
84 section
="${BASH_REMATCH[1]}"
89 warn
"unknown config section %s" "$key"
92 elif [[ "$section" == "Interface" ]]; then
95 [[ "$value" == "" ]] && fail
"empty [Interface] PrivateKey value"
96 server_private_key
="$value"
99 [[ "$value" == "" ]] && fail
"empty [Interface] Address value"
100 [[ "$server_iface_addr" != ""
101 ||
"$value" =~
[[:space
:],] ]] && \
102 fail
"multiple [Interface] Address values not supported"
103 server_iface_addr
="$value"
104 check_cidr_addr
"$server_iface_addr"
107 [[ "$value" =~ ^
[1-9][0-9]* ]] || \
108 fail
"invalid [Interface] ListenPort value: %s" "$value"
109 server_listen_port
="$value"
111 'SaveConfig'|
'FwMark'|
'DNS'|
'MTU')
113 'Table'|
'PreUp'|
'PreDown'|
'PostUp'|
'PostDown')
116 warn
"unknown config key [Interface] %s" "$key"
119 elif [[ "$section" == "Peer" ]]; then
121 'AllowedIPs'|
'PublicKey'|
'PresharedKey'|
'Endpoint'|
'PersistentKeepalive')
124 warn
"unknown config key [Peer] %s" "$key"
129 [[ "$server_iface_addr" != "" ]] || fail
"missing [Interface] Address config key"
130 [[ "$server_private_key" != "" ]] || fail
"missing [Interface] PrivateKey config key"
131 [[ "$server_listen_port" != "" ]] || fail
"missing [Interface] ListenPort config key"
132 if ((any_warnings
)); then
133 echo -n "Warnings generated, do you want to continue? [y/N]: " >&2
136 if [[ "$cont" != "y" ]]; then
140 local client_private_key
="$(wg genkey)"
141 local server_public_key
="$(wg pubkey <<<"$server_private_key")"
142 local client_public_key
="$(wg pubkey <<<"$client_private_key")"
143 local preshared_key
="$(wg genpsk)"
144 local client_config_contents
="[Interface]
145 PrivateKey = $client_private_key
146 Address = $client_iface_addr
150 PublicKey = $server_public_key
151 PresharedKey = $preshared_key
152 AllowedIPs = $server_iface_addr
153 Endpoint = $server_public_addr:$server_listen_port
154 PersistentKeepalive = 25
157 echo "$client_config_contents" > "$client_config"
159 local server_config_new_peer
="
161 PublicKey = $client_public_key
162 PresharedKey = $preshared_key
163 AllowedIPs = $client_iface_addr
164 PersistentKeepalive = 25
166 echo "$server_config_new_peer" >> "$server_iface_conf"
169 Move $client_config to /etc/wireguard/<client-interface>.conf on the client,
170 making sure that it is owned by root and has mode 600. Make sure it is NOT
171 left lying around since it contains the private key for the client, as well
172 as the preshared key.
174 Once you did that, run on the server:
175 wg-quick up $server_iface_name
177 systemctl start wg-quick@$server_iface_name
178 and run on the client:
179 wg-quick up <client-interface>
181 systemctl start wg-quick@<client-interface>
196 Usage: $0 init-server <server-iface-name> <listen-port> <server-iface-addr>
197 or: $0 add-client <server-iface-name> <server-public-addr> <client-config.conf> <client-iface-addr>
199 init-server: create a new wireguard config for the server, writes to
200 '/etc/wireguard/<server-iface-name>.conf'
202 add-client: add a client to the wireguard config for the server at
203 '/etc/wireguard/<server-iface-name>.conf'
204 Writes the generated client config to <client-config.conf>.
205 The client will connect to the server through
206 public IP or DNS address <server-public-addr>.