Luigit
repositories / bugabinga.net

bugabinga.net

personal infrastructure for bugabinga!

owned by admin

scripts/local/test-wireguard-mtu.sh

Raw
#!/usr/bin/env bash
set -euo pipefail

repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
remote="$repo_root/scripts/remote/apply-wireguard-mtu.sh"
scratch_root=/var/tmp/pufferpanel-fork/auto-mtu-tests
install -d -m 0700 "$scratch_root"
scratch="$(mktemp -d "$scratch_root/run.XXXXXX")"
trap 'rm -rf -- "$scratch"' EXIT

mkdir -p "$scratch/bin" "$scratch/state"
cat >"$scratch/bin/ip" <<'IP'
#!/usr/bin/env bash
set -euo pipefail
state="${MOCK_STATE:?}"
case "$*" in
  '-o link show dev wg0')
    [[ ! -e "$state/absent" ]] || exit 1
    flags=POINTOPOINT
    [[ "$(<"$state/up")" = UP ]] && flags+=',UP,LOWER_UP'
    printf '7: wg0: <%s> mtu %s\n' "$flags" "$(<"$state/mtu")" ;;
  'link set dev wg0 mtu '*)
    mtu="$6"
    printf '%s' "$mtu" >"$state/mtu"
    if [[ -e "$state/fail-link" && "$mtu" = 1392 ]]; then printf DOWN >"$state/up"; exit 1; fi ;;
  *) printf 'unexpected mock ip: %s\n' "$*" >&2; exit 1 ;;
esac
IP
chmod 0700 "$scratch/bin/ip"

prepare() {
  printf '1280' >"$scratch/state/mtu"
  printf UP >"$scratch/state/up"
  rm -f "$scratch/state/absent" "$scratch/state/fail-link"
  printf '[Interface]\nPrivateKey = test-only\n[Peer]\nPublicKey = test-only\n' >"$scratch/wg0.conf"
  chmod 0600 "$scratch/wg0.conf"
}
run_remote() {
  PATH="$scratch/bin:$PATH" MOCK_STATE="$scratch/state" WG_AUTO_MTU_TEST=1 WG_AUTO_MTU_CONFIG="$scratch/wg0.conf" "$remote" "$@"
}
expect_failure() {
  if "$@" >"$scratch/stdout" 2>"$scratch/stderr"; then
    echo 'expected failure' >&2
    exit 1
  fi
}

prepare
[[ "$(run_remote 1392 --check)" = 1392 ]]
[[ "$(<"$scratch/state/mtu")" = 1280 ]]
[[ ! -e /var/tmp/WG-auto-mtu.invalid ]]

prepare
before="$(<"$scratch/wg0.conf")"
run_remote 1392 >/dev/null
[[ "$(<"$scratch/state/mtu")" = 1392 ]]
[[ "$(<"$scratch/wg0.conf")" = $'[Interface]\nPrivateKey = test-only\nMTU = 1392\n[Peer]\nPublicKey = test-only' ]]

prepare
printf '[Interface]\nPrivateKey = test-only\nMTU = 1420\n# keep this exact\n[Peer]\nPublicKey = test-only\n' >"$scratch/wg0.conf"
run_remote 1392 >/dev/null
[[ "$(<"$scratch/wg0.conf")" = $'[Interface]\nPrivateKey = test-only\nMTU = 1392\n# keep this exact\n[Peer]\nPublicKey = test-only' ]]

prepare
printf '[Interface]\nMTU = 1392\nPrivateKey = test-only\n[Peer]\nPublicKey = test-only\n' >"$scratch/wg0.conf"
printf 1392 >"$scratch/state/mtu"
before="$(<"$scratch/wg0.conf")"
[[ "$(run_remote 1392)" = 1392 ]]
[[ "$(<"$scratch/wg0.conf")" = "$before" && "$(<"$scratch/state/mtu")" = 1392 ]]

prepare
printf '[Interface]\nMTU = nope\n' >"$scratch/wg0.conf"
expect_failure run_remote 1392 --check
prepare
printf '[Interface]\nMTU = 1280\nMTU = 1281\n' >"$scratch/wg0.conf"
expect_failure run_remote 1392 --check
prepare
printf '[Interface]\nSaveConfig = TRUE # persisted by wg-quick\n' >"$scratch/wg0.conf"
expect_failure run_remote 1392 --check
prepare
printf DOWN >"$scratch/state/up"
expect_failure run_remote 1392 --check
prepare
expect_failure run_remote 1421 --check

prepare
before="$(<"$scratch/wg0.conf")"
touch "$scratch/state/fail-link"
expect_failure run_remote 1392
[[ "$(<"$scratch/state/mtu")" = 1280 && "$(<"$scratch/wg0.conf")" = "$before" ]]
backup="$(awk '/Rollback evidence retained at/ { print $NF }' "$scratch/stderr")"
[[ -d "$backup" && -f "$backup/wg0.conf.before" ]]
rm -rf -- "$backup"

prepare
cat >"$scratch/bin/ssh" <<'SSH'
#!/usr/bin/env bash
set -euo pipefail
[[ "$#" = 5 && "$1" = -oBatchMode=yes && "$2" = -p && "$3" = 22 && "$4" = root@testhost && "$5" = 'bash -s -- 1392' ]] || exit 1
exec bash -s -- 1392
SSH
chmod 0700 "$scratch/bin/ssh"
PATH="$scratch/bin:$PATH" MOCK_STATE="$scratch/state" WG_AUTO_MTU_TEST=1 WG_AUTO_MTU_CONFIG="$scratch/wg0.conf" "$repo_root/scripts/local/deploy-wireguard-mtu.sh" testhost 22 1392 >/dev/null
[[ "$(<"$scratch/state/mtu")" = 1392 ]]
expect_failure env PATH="$scratch/bin:$PATH" "$repo_root/scripts/local/deploy-wireguard-mtu.sh" testhost 22 1392 extra
printf '%s\n' 'wireguard fixed-MTU config, rollback, read-only, and SSH transport tests passed'