netns: nsenter в topology.sh, netns_common и документации (#56)
- topology.sh: ns_exec для всех ip -n <ns> и ip netns exec, коды 0/1/3/4. - netns_common.py: ns_exec_mode()/ns_exec_direct(), addrs/links/link_is_up через ns_sh. - docker-compose.test.yml: проброс AWG_NS_EXEC_MODE в netns-сервис. - tests/netns/README.md: режимы входа в netns, коды возврата, новый pitfall. Refs #21, Refs #15, Refs #56
This commit is contained in:
+33
-25
@@ -15,6 +15,11 @@ HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
# shellcheck source=tests/netns/lib.sh
|
||||
source "$HERE/lib.sh"
|
||||
|
||||
# Контракт кодов возврата (issue #56): 0 — ок, 1 — проверка не прошла,
|
||||
# 3 — заблокировано окружением, 4 — ошибка стенда. Всё остальное, что прилетает
|
||||
# от утилит (например 255 от `ip netns exec`), нормализуем в 4.
|
||||
trap 'rc=$?; case "$rc" in 0|1|3|4) exit "$rc" ;; *) warn "topology.sh: непредвиденный код ${rc} — трактую как ошибку стенда (4)"; exit 4 ;; esac' ERR
|
||||
|
||||
topology_present() {
|
||||
ns_exists "$AWG_NS_CLIENT" && ns_exists "$AWG_NS_GW" && ns_exists "$AWG_NS_UPLINK"
|
||||
}
|
||||
@@ -38,6 +43,9 @@ topology_up() {
|
||||
require_cmd ip
|
||||
require_cmd python3
|
||||
require_netns_capability
|
||||
NS_EXEC_RESOLVED="$(select_ns_exec_mode)"
|
||||
export AWG_NS_EXEC_MODE="$NS_EXEC_RESOLVED"
|
||||
log "вход в netns: ${NS_EXEC_RESOLVED}"
|
||||
|
||||
log "создаю netns: client=$AWG_NS_CLIENT gw=$AWG_NS_GW uplink=$AWG_NS_UPLINK"
|
||||
topology_down quiet
|
||||
@@ -45,44 +53,44 @@ topology_up() {
|
||||
local ns
|
||||
for ns in "$AWG_NS_CLIENT" "$AWG_NS_GW" "$AWG_NS_UPLINK"; do
|
||||
ip netns add "$ns"
|
||||
ip -n "$ns" link set lo up
|
||||
ns_exec "$ns" ip link set lo up
|
||||
done
|
||||
|
||||
# --- client <-> gw (LAN) --------------------------------------------------
|
||||
ip link add "$AWG_VETH_CLIENT" type veth peer name "$AWG_VETH_GW_LAN"
|
||||
ip link set "$AWG_VETH_CLIENT" netns "$AWG_NS_CLIENT"
|
||||
ip link set "$AWG_VETH_GW_LAN" netns "$AWG_NS_GW"
|
||||
ip -n "$AWG_NS_CLIENT" addr add "${AWG_CLIENT_IP}/24" dev "$AWG_VETH_CLIENT"
|
||||
ip -n "$AWG_NS_CLIENT" link set "$AWG_VETH_CLIENT" up
|
||||
ip -n "$AWG_NS_GW" addr add "${AWG_GW_LAN_IP}/24" dev "$AWG_VETH_GW_LAN"
|
||||
ip -n "$AWG_NS_GW" link set "$AWG_VETH_GW_LAN" up
|
||||
ns_exec "$AWG_NS_CLIENT" ip addr add "${AWG_CLIENT_IP}/24" dev "$AWG_VETH_CLIENT"
|
||||
ns_exec "$AWG_NS_CLIENT" ip link set "$AWG_VETH_CLIENT" up
|
||||
ns_exec "$AWG_NS_GW" ip addr add "${AWG_GW_LAN_IP}/24" dev "$AWG_VETH_GW_LAN"
|
||||
ns_exec "$AWG_NS_GW" ip link set "$AWG_VETH_GW_LAN" up
|
||||
|
||||
# --- gw <-> uplink (WAN) --------------------------------------------------
|
||||
ip link add "$AWG_VETH_GW_WAN" type veth peer name "$AWG_VETH_UPLINK"
|
||||
ip link set "$AWG_VETH_GW_WAN" netns "$AWG_NS_GW"
|
||||
ip link set "$AWG_VETH_UPLINK" netns "$AWG_NS_UPLINK"
|
||||
ip -n "$AWG_NS_GW" addr add "${AWG_GW_WAN_IP}/24" dev "$AWG_VETH_GW_WAN"
|
||||
ip -n "$AWG_NS_GW" link set "$AWG_VETH_GW_WAN" up
|
||||
ip -n "$AWG_NS_UPLINK" addr add "${AWG_UPLINK_IP}/24" dev "$AWG_VETH_UPLINK"
|
||||
ip -n "$AWG_NS_UPLINK" link set "$AWG_VETH_UPLINK" up
|
||||
ns_exec "$AWG_NS_GW" ip addr add "${AWG_GW_WAN_IP}/24" dev "$AWG_VETH_GW_WAN"
|
||||
ns_exec "$AWG_NS_GW" ip link set "$AWG_VETH_GW_WAN" up
|
||||
ns_exec "$AWG_NS_UPLINK" ip addr add "${AWG_UPLINK_IP}/24" dev "$AWG_VETH_UPLINK"
|
||||
ns_exec "$AWG_NS_UPLINK" ip link set "$AWG_VETH_UPLINK" up
|
||||
|
||||
# --- forwarding и rp_filter в шлюзе ---------------------------------------
|
||||
ip netns exec "$AWG_NS_GW" sysctl -q -w net.ipv4.ip_forward=1
|
||||
ns_exec "$AWG_NS_GW" sysctl -q -w net.ipv4.ip_forward=1
|
||||
# loose rp_filter: маркированная политика даёт асимметрию reverse-пути
|
||||
ip netns exec "$AWG_NS_GW" sysctl -q -w net.ipv4.conf.all.rp_filter=2
|
||||
ip netns exec "$AWG_NS_GW" sysctl -q -w "net.ipv4.conf.${AWG_VETH_GW_LAN}.rp_filter=2"
|
||||
ip netns exec "$AWG_NS_GW" sysctl -q -w "net.ipv4.conf.${AWG_VETH_GW_WAN}.rp_filter=2"
|
||||
ns_exec "$AWG_NS_GW" sysctl -q -w net.ipv4.conf.all.rp_filter=2
|
||||
ns_exec "$AWG_NS_GW" sysctl -q -w "net.ipv4.conf.${AWG_VETH_GW_LAN}.rp_filter=2"
|
||||
ns_exec "$AWG_NS_GW" sysctl -q -w "net.ipv4.conf.${AWG_VETH_GW_WAN}.rp_filter=2"
|
||||
|
||||
# --- маршруты -------------------------------------------------------------
|
||||
ip -n "$AWG_NS_CLIENT" route add default via "$AWG_GW_LAN_IP" dev "$AWG_VETH_CLIENT"
|
||||
ip -n "$AWG_NS_GW" route add default via "$AWG_UPLINK_IP" dev "$AWG_VETH_GW_WAN" metric 100
|
||||
ip -n "$AWG_NS_UPLINK" route add "$AWG_NET_CLIENT" via "$AWG_GW_WAN_IP" dev "$AWG_VETH_UPLINK"
|
||||
ns_exec "$AWG_NS_CLIENT" ip route add default via "$AWG_GW_LAN_IP" dev "$AWG_VETH_CLIENT"
|
||||
ns_exec "$AWG_NS_GW" ip route add default via "$AWG_UPLINK_IP" dev "$AWG_VETH_GW_WAN" metric 100
|
||||
ns_exec "$AWG_NS_UPLINK" ip route add "$AWG_NET_CLIENT" via "$AWG_GW_WAN_IP" dev "$AWG_VETH_UPLINK"
|
||||
# «публичный» адрес-приманка для детектора утечки (RFC 5737 TEST-NET-2)
|
||||
ip -n "$AWG_NS_UPLINK" addr add "${AWG_LEAK_IP}/32" dev lo
|
||||
ns_exec "$AWG_NS_UPLINK" ip addr add "${AWG_LEAK_IP}/32" dev lo
|
||||
|
||||
# --- policy routing: fwmark 51820 -> table 51820 -> аплинк ----------------
|
||||
ip -n "$AWG_NS_GW" route add default via "$AWG_UPLINK_IP" dev "$AWG_VETH_GW_WAN" table "$AWG_ROUTE_TABLE"
|
||||
ip -n "$AWG_NS_GW" rule add fwmark "$AWG_FWMARK" table "$AWG_ROUTE_TABLE"
|
||||
ns_exec "$AWG_NS_GW" ip route add default via "$AWG_UPLINK_IP" dev "$AWG_VETH_GW_WAN" table "$AWG_ROUTE_TABLE"
|
||||
ns_exec "$AWG_NS_GW" ip rule add fwmark "$AWG_FWMARK" table "$AWG_ROUTE_TABLE"
|
||||
|
||||
# --- netfilter: метки + kill-switch ---------------------------------------
|
||||
fw_setup
|
||||
@@ -102,18 +110,18 @@ topology_status() {
|
||||
local ns
|
||||
for ns in "$AWG_NS_CLIENT" "$AWG_NS_GW" "$AWG_NS_UPLINK"; do
|
||||
printf '\n[%s] links:\n' "$ns"
|
||||
ip -n "$ns" -br addr show || rc=1
|
||||
ns_exec "$ns" ip -br addr show || rc=1
|
||||
done
|
||||
printf '\n[%s] ip rule:\n' "$AWG_NS_GW"
|
||||
ip -n "$AWG_NS_GW" rule show
|
||||
ns_exec "$AWG_NS_GW" ip rule show
|
||||
printf '\n[%s] table %s:\n' "$AWG_NS_GW" "$AWG_ROUTE_TABLE"
|
||||
ip -n "$AWG_NS_GW" route show table "$AWG_ROUTE_TABLE"
|
||||
ns_exec "$AWG_NS_GW" ip route show table "$AWG_ROUTE_TABLE"
|
||||
printf '\n[%s] netfilter:\n' "$AWG_NS_GW"
|
||||
if [ "$(fw_kind)" = nft ]; then
|
||||
ip netns exec "$AWG_NS_GW" nft list table inet "$NFT_TABLE" 2>/dev/null || rc=1
|
||||
ns_exec "$AWG_NS_GW" nft list table inet "$NFT_TABLE" 2>/dev/null || rc=1
|
||||
else
|
||||
ip netns exec "$AWG_NS_GW" iptables -t mangle -S 2>/dev/null || rc=1
|
||||
ip netns exec "$AWG_NS_GW" iptables -t filter -S FORWARD 2>/dev/null || rc=1
|
||||
ns_exec "$AWG_NS_GW" iptables -t mangle -S 2>/dev/null || rc=1
|
||||
ns_exec "$AWG_NS_GW" iptables -t filter -S FORWARD 2>/dev/null || rc=1
|
||||
fi
|
||||
return $rc
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user