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: which are handled by this tool:
.IP \(bu .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. to be assigned to the interface. May be specified multiple times.
.IP \(bu .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 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 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. 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 PreUp, PostUp, PreDown, PostDown \(em script snippets which will be executed by
.BR bash (1) .BR bash (1)
before/after setting up/tearing down the interface, most commonly used 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 .IP \(bu
SaveConfig \(em if set to `true', the configuration is saved from the current state of the SaveConfig \(em if set to `true', the configuration is saved from the current state of the
interface upon shutdown. interface upon shutdown.
@ -98,9 +106,7 @@ traffic:
.br .br
\fBAddress = 10.200.100.8/24\fP \fBAddress = 10.200.100.8/24\fP
.br .br
\fBPostUp = echo nameserver 10.200.100.1 | resolvconf -a tun.%i -m 0 -x\fP \fBDNS = 10.200.100.1\fP
.br
\fBPostDown = resolvconf -d tun.%i\fP
.br .br
PrivateKey = oK56DE9Ue9zK76rAc8pBl6opph+1v36lm7cXXsQKrQM= PrivateKey = oK56DE9Ue9zK76rAc8pBl6opph+1v36lm7cXXsQKrQM=
.br .br
@ -117,12 +123,11 @@ traffic:
Endpoint = demo.wireguard.com:51820 Endpoint = demo.wireguard.com:51820
.br .br
Notice that the `PostUp` and `PostDown` commands are used here to configure DNS using The `Address` field is added here in order to set up the address for the interface. The `DNS` field
.BR resolvconf (8), indicates that a DNS server for the interface should be configured via
which is one of the many options for DNS configuration. The `Address` field is added .BR resolvconf (8).
here in order to set up the address for the interface. The peer's allowed IPs entry The peer's allowed IPs entry implies that this interface should be configured as the default gateway,
implies that this interface should be configured as the default gateway, which this which this script does.
script does.
Here is a more complicated example, fit for usage on a server: 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-link (8),
.BR ip-address (8), .BR ip-address (8),
.BR ip-route (8), .BR ip-route (8),
.BR ip-rule (8). .BR ip-rule (8),
.BR resolvconf (8).
.SH AUTHOR .SH AUTHOR
.B wg-quick .B wg-quick

View file

@ -14,6 +14,7 @@ WG_CONFIG=""
INTERFACE="" INTERFACE=""
ADDRESSES=( ) ADDRESSES=( )
MTU="" MTU=""
DNS=( )
PRE_UP="" PRE_UP=""
POST_UP="" POST_UP=""
PRE_DOWN="" PRE_DOWN=""
@ -41,6 +42,7 @@ parse_options() {
case "$key" in case "$key" in
Address) ADDRESSES+=( ${value//,/ } ); continue ;; Address) ADDRESSES+=( ${value//,/ } ); continue ;;
MTU) MTU="$value"; continue ;; MTU) MTU="$value"; continue ;;
DNS) DNS+=( ${value//,/ } ); continue ;;
PreUp) PRE_UP="$value"; continue ;; PreUp) PRE_UP="$value"; continue ;;
PreDown) PRE_DOWN="$value"; continue ;; PreDown) PRE_DOWN="$value"; continue ;;
PostUp) POST_UP="$value"; continue ;; PostUp) POST_UP="$value"; continue ;;
@ -128,6 +130,14 @@ set_mtu() {
cmd ip link set mtu $(( mtu - 80 )) dev "$INTERFACE" 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() { add_route() {
if [[ $1 == 0.0.0.0/0 || $1 =~ ^[0:]+/0$ ]]; then if [[ $1 == 0.0.0.0/0 || $1 =~ ^[0:]+/0$ ]]; then
add_default "$1" add_default "$1"
@ -168,6 +178,9 @@ save_config() {
for address in ${BASH_REMATCH[1]}; do for address in ${BASH_REMATCH[1]}; do
new_config+="Address = $address"$'\n' new_config+="Address = $address"$'\n'
done 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' [[ -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' [[ $SAVE_CONFIG -eq 0 ]] || new_config+=$'SaveConfig = true\n'
[[ -z $PRE_UP ]] || new_config+="PreUp = $PRE_UP"$'\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 - 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. 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. - MTU: an optional MTU for the interface; if unspecified, auto-calculated.
- PreUp, PostUp, PreDown, PostDown: script snippets which will be executed - PreUp, PostUp, PreDown, PostDown: script snippets which will be executed
by bash(1) at the corresponding phases of the link, most commonly used by bash(1) at the corresponding phases of the link, most commonly used
@ -226,6 +240,7 @@ cmd_up() {
done done
set_mtu set_mtu
up_if 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 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" [[ $(ip route get "$i" 2>/dev/null) == *dev\ $INTERFACE\ * ]] || add_route "$i"
done 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" [[ -n $(ip link show dev "$INTERFACE" type wireguard 2>/dev/null) ]] || die "\`$INTERFACE' is not a WireGuard interface"
execute_hook "$PRE_DOWN" execute_hook "$PRE_DOWN"
[[ $SAVE_CONFIG -eq 0 ]] || save_config [[ $SAVE_CONFIG -eq 0 ]] || save_config
unset_dns
del_if del_if
execute_hook "$POST_DOWN" execute_hook "$POST_DOWN"
} }