mirror of
https://github.com/outbackdingo/firezone.git
synced 2026-01-27 02:18:47 +00:00
By default, Docker creates network interfaces with a txqueuelen of 1000. This is pretty small and causes unnecessary packet drops when running perf tests in that setup.
96 lines
3.6 KiB
Bash
96 lines
3.6 KiB
Bash
#!/bin/bash
|
|
|
|
set -euo pipefail
|
|
|
|
# Get network configuration
|
|
INTERNAL_NET_V4=$(ip -4 --json route | jq -r '.[] | select(.dev == "internal") | select(.dst == "default" | not) | .dst')
|
|
INTERNAL_NET_V6=$(ip -6 --json route | jq -r '.[] | select(.dev == "internal") | select(.dst | startswith("fe80") | not) | select(.dst == "default" | not) | .dst')
|
|
PUBLIC_IPV4=$(ip -4 -json addr show internet | jq -r '.[0].addr_info[0].local')
|
|
PUBLIC_IPV6=$(ip -6 -json addr show internet | jq -r '.[0].addr_info[0].local')
|
|
|
|
# Validate required configuration
|
|
if [ -z "$INTERNAL_NET_V4" ]; then
|
|
echo "Error: Failed to identify internal IPv4 subnet"
|
|
exit 1
|
|
fi
|
|
|
|
if [ -z "$INTERNAL_NET_V6" ]; then
|
|
echo "Error: Failed to identify internal IPv6 subnet"
|
|
exit 1
|
|
fi
|
|
|
|
if [ -z "$PUBLIC_IPV4" ]; then
|
|
echo "Error: Failed to get public IPv4"
|
|
exit 1
|
|
fi
|
|
|
|
if [ -z "$PUBLIC_IPV6" ]; then
|
|
echo "Error: Failed to get public IPv6"
|
|
exit 1
|
|
fi
|
|
|
|
echo "INTERNAL_NET_V4 = $INTERNAL_NET_V4"
|
|
echo "INTERNAL_NET_V6 = $INTERNAL_NET_V6"
|
|
echo "PUBLIC_IPV4 = $PUBLIC_IPV4"
|
|
echo "PUBLIC_IPV6 = $PUBLIC_IPV6"
|
|
|
|
TEMPLATE_FILE="router.nft"
|
|
CONFIG_FILE="/tmp/router.nft"
|
|
|
|
# Copy template file to working config
|
|
cp "$TEMPLATE_FILE" "$CONFIG_FILE"
|
|
|
|
echo "add rule inet router postrouting ip saddr $INTERNAL_NET_V4 oifname \"internet\" masquerade ${MASQUERADE_TYPE:-}" >>"$CONFIG_FILE"
|
|
echo "add rule inet router postrouting ip6 saddr $INTERNAL_NET_V6 oifname \"internet\" masquerade ${MASQUERADE_TYPE:-}" >>"$CONFIG_FILE"
|
|
|
|
# Add port forwarding rules if specified
|
|
if [ -n "${PORT_FORWARDS:-}" ]; then
|
|
echo "$PORT_FORWARDS" | tr ',' '\n' | while IFS=' ' read -r port internal_ip protocol; do
|
|
if [ -z "$port" ] || [ -z "$internal_ip" ] || [ -z "$protocol" ]; then
|
|
continue
|
|
fi
|
|
|
|
# Determine if internal IP is IPv4 or IPv6 and append rules to config file
|
|
case "$internal_ip" in
|
|
*:*) # IPv6 address
|
|
echo "add rule inet router prerouting ip6 daddr $PUBLIC_IPV6 $protocol dport $port dnat to [$internal_ip]:$port" >>"$CONFIG_FILE"
|
|
echo "add rule inet router input ip6 daddr $internal_ip $protocol dport $port accept" >>"$CONFIG_FILE"
|
|
;;
|
|
*) # IPv4 address
|
|
echo "add rule inet router prerouting ip daddr $PUBLIC_IPV4 $protocol dport $port dnat to $internal_ip:$port" >>"$CONFIG_FILE"
|
|
echo "add rule inet router input ip daddr $internal_ip $protocol dport $port accept" >>"$CONFIG_FILE"
|
|
;;
|
|
esac
|
|
done
|
|
fi
|
|
|
|
# Add configurable latency if specified
|
|
if [ -n "${NETWORK_LATENCY_MS:-}" ]; then
|
|
LATENCY=$((NETWORK_LATENCY_MS / 2)) # Latency is only applied to outbound packets. To achieve the actual configured latency, we apply half of it to each interface.
|
|
|
|
tc qdisc add dev internet root netem delay "${LATENCY}ms"
|
|
tc qdisc add dev internal root netem delay "${LATENCY}ms"
|
|
fi
|
|
|
|
ip link set dev internal txqueuelen 100000
|
|
ip link set dev internet txqueuelen 100000
|
|
|
|
echo "-----------------------------------------------------------------------------------------------"
|
|
cat "$CONFIG_FILE"
|
|
echo "-----------------------------------------------------------------------------------------------"
|
|
|
|
nft -f "$CONFIG_FILE"
|
|
|
|
rm "$CONFIG_FILE"
|
|
|
|
for iface in internal internet; do
|
|
# Enable RPS (Receive Packet Steering) to always use CPU 1 to handle packets.
|
|
# This prevents packet reordering where otherwise the CPU which handles the interrupt would handle the packet.
|
|
echo 1 >"/sys/class/net/$iface/queues/rx-0/rps_cpus" 2>/dev/null
|
|
done
|
|
|
|
echo "1" >/tmp/setup_done # Health check marker
|
|
|
|
# Keep container running
|
|
exec tail -f /dev/null
|