diff options
Diffstat (limited to 'src/wg-quick/linux.bash')
-rwxr-xr-x | src/wg-quick/linux.bash | 42 |
1 files changed, 24 insertions, 18 deletions
diff --git a/src/wg-quick/linux.bash b/src/wg-quick/linux.bash index 7c2c002..34fa5f9 100755 --- a/src/wg-quick/linux.bash +++ b/src/wg-quick/linux.bash @@ -16,6 +16,7 @@ INTERFACE="" ADDRESSES=( ) MTU="" DNS=( ) +DNS_SEARCH=( ) TABLE="" PRE_UP=( ) POST_UP=( ) @@ -37,7 +38,7 @@ die() { } parse_options() { - local interface_section=0 line key value stripped + local interface_section=0 line key value stripped v CONFIG_FILE="$1" [[ $CONFIG_FILE =~ ^[a-zA-Z0-9_=+.-]{1,15}$ ]] && CONFIG_FILE="/etc/wireguard/$CONFIG_FILE.conf" [[ -e $CONFIG_FILE ]] || die "\`$CONFIG_FILE' does not exist" @@ -50,18 +51,21 @@ parse_options() { stripped="${line%%\#*}" key="${stripped%%=*}"; key="${key##*([[:space:]])}"; key="${key%%*([[:space:]])}" value="${stripped#*=}"; value="${value##*([[:space:]])}"; value="${value%%*([[:space:]])}" + unstripped_value="${line#*=}"; unstripped_value="${unstripped_value##*([[:space:]])}"; unstripped_value="${unstripped_value%%*([[:space:]])}" [[ $key == "["* ]] && interface_section=0 [[ $key == "[Interface]" ]] && interface_section=1 if [[ $interface_section -eq 1 ]]; then case "$key" in Address) ADDRESSES+=( ${value//,/ } ); continue ;; MTU) MTU="$value"; continue ;; - DNS) DNS+=( ${value//,/ } ); continue ;; + DNS) for v in ${value//,/ }; do + [[ $v =~ (^[0-9.]+$)|(^.*:.*$) ]] && DNS+=( $v ) || DNS_SEARCH+=( $v ) + done; continue ;; Table) TABLE="$value"; continue ;; - PreUp) PRE_UP+=( "$value" ); continue ;; - PreDown) PRE_DOWN+=( "$value" ); continue ;; - PostUp) POST_UP+=( "$value" ); continue ;; - PostDown) POST_DOWN+=( "$value" ); continue ;; + PreUp) PRE_UP+=( "$unstripped_value" ); continue ;; + PreDown) PRE_DOWN+=( "$unstripped_value" ); continue ;; + PostUp) POST_UP+=( "$unstripped_value" ); continue ;; + PostDown) POST_DOWN+=( "$unstripped_value" ); continue ;; SaveConfig) read_bool SAVE_CONFIG "$value"; continue ;; esac fi @@ -84,10 +88,10 @@ auto_su() { add_if() { local ret - if ! cmd ip link add "$INTERFACE" type wireguard; then + if ! cmd ip link add dev "$INTERFACE" type wireguard; then ret=$? [[ -e /sys/module/wireguard ]] || ! command -v "${WG_QUICK_USERSPACE_IMPLEMENTATION:-wireguard-go}" >/dev/null && exit $ret - echo "[!] Missing WireGuard kernel module. Falling back to slow userspace implementation." + echo "[!] Missing WireGuard kernel module. Falling back to slow userspace implementation." >&2 cmd "${WG_QUICK_USERSPACE_IMPLEMENTATION:-wireguard-go}" "$INTERFACE" fi } @@ -120,7 +124,7 @@ add_addr() { } set_mtu_up() { - local mtu=0 endpoint output + local mtu=2147483647 endpoint output if [[ -n $MTU ]]; then cmd ip link set mtu "$MTU" up dev "$INTERFACE" return @@ -128,18 +132,18 @@ set_mtu_up() { while read -r _ endpoint; do [[ $endpoint =~ ^\[?([a-z0-9:.]+)\]?:[0-9]+$ ]] || continue output="$(ip route get "${BASH_REMATCH[1]}" || true)" - [[ ( $output =~ mtu\ ([0-9]+) || ( $output =~ dev\ ([^ ]+) && $(ip link show dev "${BASH_REMATCH[1]}") =~ mtu\ ([0-9]+) ) ) && ${BASH_REMATCH[1]} -gt $mtu ]] && mtu="${BASH_REMATCH[1]}" + [[ ( $output =~ mtu\ ([0-9]+) || ( $output =~ dev\ ([^ ]+) && $(ip link show dev "${BASH_REMATCH[1]}") =~ mtu\ ([0-9]+) ) ) && ${BASH_REMATCH[1]} -lt $mtu ]] && mtu="${BASH_REMATCH[1]}" done < <(wg show "$INTERFACE" endpoints) - if [[ $mtu -eq 0 ]]; then + if [[ $mtu -eq 2147483647 ]]; then read -r output < <(ip route show default || true) || true - [[ ( $output =~ mtu\ ([0-9]+) || ( $output =~ dev\ ([^ ]+) && $(ip link show dev "${BASH_REMATCH[1]}") =~ mtu\ ([0-9]+) ) ) && ${BASH_REMATCH[1]} -gt $mtu ]] && mtu="${BASH_REMATCH[1]}" + [[ ( $output =~ mtu\ ([0-9]+) || ( $output =~ dev\ ([^ ]+) && $(ip link show dev "${BASH_REMATCH[1]}") =~ mtu\ ([0-9]+) ) ) && ${BASH_REMATCH[1]} -lt $mtu ]] && mtu="${BASH_REMATCH[1]}" fi - [[ $mtu -gt 0 ]] || mtu=1500 + [[ $mtu -gt 0 && $mtu -lt 2147483647 ]] || mtu=1500 cmd ip link set mtu $(( mtu - 80 )) up dev "$INTERFACE" } resolvconf_iface_prefix() { - [[ -f /etc/resolvconf/interface-order ]] || return 0 + [[ -f /etc/resolvconf/interface-order && ! -L $(type -P resolvconf) ]] || return 0 local iface while read -r iface; do [[ $iface =~ ^([A-Za-z0-9-]+)\*$ ]] || continue @@ -150,7 +154,9 @@ resolvconf_iface_prefix() { HAVE_SET_DNS=0 set_dns() { [[ ${#DNS[@]} -gt 0 ]] || return 0 - printf 'nameserver %s\n' "${DNS[@]}" | cmd resolvconf -a "$(resolvconf_iface_prefix)$INTERFACE" -m 0 -x + { printf 'nameserver %s\n' "${DNS[@]}" + [[ ${#DNS_SEARCH[@]} -eq 0 ]] || printf 'search %s\n' "${DNS_SEARCH[*]}" + } | cmd resolvconf -a "$(resolvconf_iface_prefix)$INTERFACE" -m 0 -x HAVE_SET_DNS=1 } @@ -215,9 +221,9 @@ add_default() { fi local proto=-4 iptables=iptables pf=ip [[ $1 == *:* ]] && proto=-6 iptables=ip6tables pf=ip6 - cmd ip $proto route add "$1" dev "$INTERFACE" table $table cmd ip $proto rule add not fwmark $table table $table cmd ip $proto rule add table main suppress_prefixlength 0 + cmd ip $proto route add "$1" dev "$INTERFACE" table $table local marker="-m comment --comment \"wg-quick(8) rule for $INTERFACE\"" restore=$'*raw\n' nftable="wg-quick-$INTERFACE" nftcmd printf -v nftcmd '%sadd table %s %s\n' "$nftcmd" "$pf" "$nftable" @@ -243,7 +249,7 @@ add_default() { } set_config() { - cmd wg setconf "$INTERFACE" <(echo "$WG_CONFIG") + cmd wg addconf "$INTERFACE" <(echo "$WG_CONFIG") } save_config() { @@ -322,8 +328,8 @@ cmd_up() { local i [[ -z $(ip link show dev "$INTERFACE" 2>/dev/null) ]] || die "\`$INTERFACE' already exists" trap 'del_if; exit' INT TERM EXIT - execute_hooks "${PRE_UP[@]}" add_if + execute_hooks "${PRE_UP[@]}" set_config for i in "${ADDRESSES[@]}"; do add_addr "$i" |