wg-quick: add explicit support for common DNS usage

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
Jason A. Donenfeld 2017-07-26 03:09:48 +02:00
parent 41e50edbe5
commit 6b27d0d0f0
2 changed files with 34 additions and 12 deletions

View file

@ -62,9 +62,16 @@ sub-command, with the exception of the following additions to the \fIInterface\f
which are handled by this tool:
.IP \(bu
Address \(em a comma-separated list of ip (v4 or v6) addresses (optionally with CIDR masks)
Address \(em a comma-separated list of IP (v4 or v6) addresses (optionally with CIDR masks)
to be assigned to the interface. May be specified multiple times.
.IP \(bu
DNS \(em a comma-separated list of IP (v4 or v6) addresses to be set as the interface's
DNS servers. May be specified multiple times. Upon bringing the interface up, this runs
`resolvconf -a tun.\fIINTERFACE\fP -m 0 -x` and upon bringing it down, this runs
`resolvconf -d tun.\fIINTERFACE\fP`. If these particular invocations of
.BR resolvconf (8)
are undesirable, the PostUp and PostDown keys below may be used instead.
.IP \(bu
MTU \(em if not specified, the MTU is automatically determined from the endpoint addresses
or the system default route, which is usually a sane choice. However, to manually specify
an MTU to override this automatic discovery, this value may be specified explicitly.
@ -72,7 +79,8 @@ an MTU to override this automatic discovery, this value may be specified explici
PreUp, PostUp, PreDown, PostDown \(em script snippets which will be executed by
.BR bash (1)
before/after setting up/tearing down the interface, most commonly used
to configure DNS. The special string `%i' is expanded to \fIINTERFACE\fP.
to configure custom DNS options or firewall rules. The special string `%i'
is expanded to \fIINTERFACE\fP.
.IP \(bu
SaveConfig \(em if set to `true', the configuration is saved from the current state of the
interface upon shutdown.
@ -98,9 +106,7 @@ traffic:
.br
\fBAddress = 10.200.100.8/24\fP
.br
\fBPostUp = echo nameserver 10.200.100.1 | resolvconf -a tun.%i -m 0 -x\fP
.br
\fBPostDown = resolvconf -d tun.%i\fP
\fBDNS = 10.200.100.1\fP
.br
PrivateKey = oK56DE9Ue9zK76rAc8pBl6opph+1v36lm7cXXsQKrQM=
.br
@ -117,12 +123,11 @@ traffic:
Endpoint = demo.wireguard.com:51820
.br
Notice that the `PostUp` and `PostDown` commands are used here to configure DNS using
.BR resolvconf (8),
which is one of the many options for DNS configuration. The `Address` field is added
here in order to set up the address for the interface. The peer's allowed IPs entry
implies that this interface should be configured as the default gateway, which this
script does.
The `Address` field is added here in order to set up the address for the interface. The `DNS` field
indicates that a DNS server for the interface should be configured via
.BR resolvconf (8).
The peer's allowed IPs entry implies that this interface should be configured as the default gateway,
which this script does.
Here is a more complicated example, fit for usage on a server:
@ -184,7 +189,8 @@ This will load the configuration file `/etc/wireguard/wgnet0.conf'.
.BR ip-link (8),
.BR ip-address (8),
.BR ip-route (8),
.BR ip-rule (8).
.BR ip-rule (8),
.BR resolvconf (8).
.SH AUTHOR
.B wg-quick

View file

@ -14,6 +14,7 @@ WG_CONFIG=""
INTERFACE=""
ADDRESSES=( )
MTU=""
DNS=( )
PRE_UP=""
POST_UP=""
PRE_DOWN=""
@ -41,6 +42,7 @@ parse_options() {
case "$key" in
Address) ADDRESSES+=( ${value//,/ } ); continue ;;
MTU) MTU="$value"; continue ;;
DNS) DNS+=( ${value//,/ } ); continue ;;
PreUp) PRE_UP="$value"; continue ;;
PreDown) PRE_DOWN="$value"; continue ;;
PostUp) POST_UP="$value"; continue ;;
@ -128,6 +130,14 @@ set_mtu() {
cmd ip link set mtu $(( mtu - 80 )) dev "$INTERFACE"
}
set_dns() {
[[ ${#DNS[@]} -eq 0 ]] || printf 'nameserver %s\n' "${DNS[@]}" | cmd resolvconf -a "tun.$INTERFACE" -m 0 -x
}
unset_dns() {
[[ ${#DNS[@]} -eq 0 ]] || cmd resolvconf -d "tun.$INTERFACE"
}
add_route() {
if [[ $1 == 0.0.0.0/0 || $1 =~ ^[0:]+/0$ ]]; then
add_default "$1"
@ -168,6 +178,9 @@ save_config() {
for address in ${BASH_REMATCH[1]}; do
new_config+="Address = $address"$'\n'
done
while read -r address; do
[[ $address =~ ^nameserver\ ([a-zA-Z0-9_=+:%.-]+)$ ]] && new_config+="DNS = ${BASH_REMATCH[1]}"$'\n'
done < <(resolvconf -l "tun.$INTERFACE" 2>/dev/null)
[[ -n $MTU && $(ip link show dev "$INTERFACE") =~ mtu\ ([0-9]+) ]] && new_config+="MTU = ${BASH_REMATCH[1]}"$'\n'
[[ $SAVE_CONFIG -eq 0 ]] || new_config+=$'SaveConfig = true\n'
[[ -z $PRE_UP ]] || new_config+="PreUp = $PRE_UP"$'\n'
@ -203,6 +216,7 @@ cmd_usage() {
- Address: may be specified one or more times and contains one or more
IP addresses (with an optional CIDR mask) to be set for the interface.
- DNS: an optional DNS server to use while the device is up.
- MTU: an optional MTU for the interface; if unspecified, auto-calculated.
- PreUp, PostUp, PreDown, PostDown: script snippets which will be executed
by bash(1) at the corresponding phases of the link, most commonly used
@ -226,6 +240,7 @@ cmd_up() {
done
set_mtu
up_if
set_dns
for i in $(while read -r _ i; do for i in $i; do [[ $i =~ ^[0-9a-z:.]+/[0-9]+$ ]] && echo "$i"; done; done < <(wg show "$INTERFACE" allowed-ips) | sort -nr -k 2 -t /); do
[[ $(ip route get "$i" 2>/dev/null) == *dev\ $INTERFACE\ * ]] || add_route "$i"
done
@ -237,6 +252,7 @@ cmd_down() {
[[ -n $(ip link show dev "$INTERFACE" type wireguard 2>/dev/null) ]] || die "\`$INTERFACE' is not a WireGuard interface"
execute_hook "$PRE_DOWN"
[[ $SAVE_CONFIG -eq 0 ]] || save_config
unset_dns
del_if
execute_hook "$POST_DOWN"
}