# ThinkPad T490 Zero-Leak Edge Gateway Setup Guide
## Ubuntu Server 24.04 LTS / Debian 12 Implementation

This guide provides exhaustive, step-by-step instructions for provisioning a Lenovo ThinkPad T490 as a headless, zero-leak edge gateway connecting to an upstream Wi-Fi network (`10.0.0.0/24`) and routing gigabit traffic to a ThinkStation Proxmox VE hypervisor over direct Ethernet.

---

## 1. Prerequisites & Hardware Optimization

### 1.1 Physical Cabling & Auto-MDIX
Connect a standard Cat6 / Cat5e Ethernet patch cable directly between:
- **ThinkPad T490**: Built-in RJ-45 Gigabit Ethernet port (`enp0s31f6` / `eth0`, Intel I219-V).
- **ThinkStation Proxmox VE**: Built-in RJ-45 Gigabit Ethernet port (`eno1` / `eth0`, Intel I219-LM).

> [!NOTE]
> Modern Gigabit Ethernet PHY chips strictly require IEEE 802.3ab Auto-MDIX compliance. An older crossover cable is **not** required; a standard straight-through patch cable automatically negotiates transmit and receive pairs.

### 1.2 BIOS / UEFI Tuning (ThinkPad T490)
Reboot the T490 and press `F1` during the Lenovo splash screen:
1. **Config -> Power**:
   - `Sleep State`: Set to **Linux** (Legacy S3 / non-Modern Standby).
   - `Power On with AC Attach`: Set to **Enabled** (ensures T490 auto-boots if AC power is interrupted and restored).
2. **Config -> Network**:
   - `Wake on LAN`: Set to **Enabled on AC**.
   - `UEFI IPv4 Network Stack`: Set to **Disabled**.
3. **Security -> Intel AMT**:
   - `Intel AMT Control`: Set to **Disabled** (critical: prevents Intel Management Engine from broadcasting AMT discovery frames over Wi-Fi).

---

## 2. Base OS & Interface Networking

Install **Ubuntu Server 24.04 LTS (Noble Numbat)** or **Debian 12 (Bookworm)** minimal without a graphical desktop environment.

### 2.1 Identify Interface Predictable Names
Run:
```bash
ip link show
```
Typically:
- Gigabit Ethernet: `enp0s31f6` (or `eth0`)
- Wi-Fi 6 / AC Adapter: `wlan0` (or `wlp0s20f3`)

*(In this guide, we use `enp0s31f6` for Ethernet and `wlan0` for Wi-Fi. Adjust interface names to match your `ip link` output).*

---

### 2.2 Netplan Configuration (`/etc/netplan/01-homelab-gateway.yaml`)
Create `/etc/netplan/01-homelab-gateway.yaml`:

```yaml
network:
  version: 2
  renderer: networkd
  ethernets:
    enp0s31f6:
      description: "Transit link to ThinkStation Proxmox VE"
      dhcp4: false
      dhcp6: false
      addresses:
        - 172.16.100.1/24
      routes:
        - to: 192.168.45.0/24
          via: 172.16.100.2
          metric: 100
      link-local: []
      optional: true
  wifis:
    wlan0:
      description: "Upstream WAN link to Friend's Wi-Fi LAN"
      dhcp4: true
      dhcp4-overrides:
        route-metric: 50
        use-dns: true
      dhcp6: false
      access-points:
        "FriendsWiFiSSID":
          password: "FriendsSecureWiFiPassword"
      wakeonwlan: false
```

Apply the configuration:
```bash
sudo chmod 600 /etc/netplan/01-homelab-gateway.yaml
sudo netplan apply
```

---

## 3. Kernel Hardening & Leak Prevention Policy

Create `/etc/sysctl.d/99-homelab-gateway-hardening.conf`:

```ini
# ==============================================================================
# HOMELAB ZERO-LEAK GATEWAY KERNEL HARDENING SPECIFICATION
# ==============================================================================

# 1. IP Forwarding
net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 0

# 2. Strict IPv6 Disabling (Prevents SLAAC/RA leakage on wlan0)
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.wlan0.disable_ipv6 = 1
net.ipv6.conf.enp0s31f6.disable_ipv6 = 1

# 3. ICMP Redirect Suppression (CRITICAL: Never tell upstream router about internal routes)
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.wlan0.send_redirects = 0
net.ipv4.conf.enp0s31f6.send_redirects = 0

net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.wlan0.accept_redirects = 0
net.ipv4.conf.enp0s31f6.accept_redirects = 0

# 4. ARP Hardening & Anti-Proxy ARP (Never answer ARP for internal IPs on wlan0)
net.ipv4.conf.all.proxy_arp = 0
net.ipv4.conf.default.proxy_arp = 0
net.ipv4.conf.wlan0.proxy_arp = 0
net.ipv4.conf.enp0s31f6.proxy_arp = 0

net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.default.arp_ignore = 1
net.ipv4.conf.wlan0.arp_ignore = 1
net.ipv4.conf.enp0s31f6.arp_ignore = 1

net.ipv4.conf.all.arp_announce = 2
net.ipv4.conf.default.arp_announce = 2
net.ipv4.conf.wlan0.arp_announce = 2
net.ipv4.conf.enp0s31f6.arp_announce = 2

# 5. Strict Reverse Path Filtering (Anti-Spoofing)
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.wlan0.rp_filter = 1
net.ipv4.conf.enp0s31f6.rp_filter = 1

# 6. TCP Connection Tracking & Window Optimization
net.netfilter.nf_conntrack_max = 262144
net.ipv4.tcp_fin_timeout = 15
```

Apply immediately:
```bash
sudo sysctl -p /etc/sysctl.d/99-homelab-gateway-hardening.conf
```

---

## 4. Atomic Firewall & NAT Engine (`nftables`)

Install `nftables`:
```bash
sudo apt update && sudo apt install -y nftables
```

Edit `/etc/nftables.conf`:

```nftables
#!/usr/sbin/nft -f

flush ruleset

table inet homelab_filter {
    # Fastpath flowtable offloading for wire-speed forwarding
    flowtable fastpath {
        hook ingress priority 0;
        devices = { wlan0, enp0s31f6 };
    }

    chain input {
        type filter hook input priority filter; policy drop;

        # Local loopback
        iifname "lo" accept

        # Connection tracking: established/related
        ct state established,related accept
        ct state invalid drop

        # Transit network management & local DNS/DHCP
        iifname "enp0s31f6" ip protocol icmp accept
        iifname "enp0s31f6" udp dport { 53, 67 } accept
        iifname "enp0s31f6" tcp dport 53 accept
        iifname "enp0s31f6" ip saddr { 172.16.100.0/24, 192.168.45.0/24 } tcp dport 22 accept

        # Tailscale VPN Management
        iifname "tailscale0" accept
        udp dport 41641 accept

        # Upstream Wi-Fi: Allow DHCP replies from Friend router
        iifname "wlan0" udp sport 67 udp dport 68 accept

        # Stealth Mode: Drop all unsolicited inbound from Wi-Fi
        iifname "wlan0" drop
    }

    chain forward {
        type filter hook forward priority filter; policy drop;

        # Offload established TCP/UDP streams to kernel fastpath
        ip protocol { tcp, udp } flow offload @fastpath

        # TCP MSS Clamping to PMTU (Prevents packet fragmentation blackholes)
        tcp flags syn tcp option maxseg size set rt mtu

        ct state established,related accept
        ct state invalid drop

        # Block lateral scanning/attacks against Friend's private subnets
        iifname "enp0s31f6" oifname "wlan0" ip daddr { 10.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12 } drop

        # Allow internal homelab subnets outbound to WAN
        iifname "enp0s31f6" oifname "wlan0" ip saddr { 172.16.100.0/24, 192.168.45.0/24 } accept

        # Tailscale Forwarding
        iifname "tailscale0" oifname "enp0s31f6" accept
        iifname "enp0s31f6" oifname "tailscale0" accept

        drop
    }

    chain output {
        type filter hook output priority filter; policy accept;

        # ZERO-LEAK: Drop discovery and multicast/broadcast frames egressing wlan0
        oifname "wlan0" udp dport { 5353, 5355, 137, 138, 1900, 3702 } drop
        oifname "wlan0" tcp dport { 139, 445 } drop
        oifname "wlan0" ip daddr { 224.0.0.0/4, 255.255.255.255 } drop
    }
}

table inet homelab_nat {
    chain postrouting {
        type nat hook postrouting priority srcnat; policy accept;

        # Single Edge Source NAT: Masquerade homelab subnets leaving via Wi-Fi
        oifname "wlan0" ip saddr { 172.16.100.0/24, 192.168.45.0/24 } masquerade
    }
}
```

Enable and start `nftables`:
```bash
sudo systemctl enable --now nftables
sudo nft list ruleset
```

---

## 5. Transit DHCP & DNS Server (`dnsmasq`)

Install `dnsmasq`:
```bash
sudo apt install -y dnsmasq
```

Create `/etc/dnsmasq.d/homelab-transit.conf`:

```ini
# Strict Interface Binding Isolation
bind-interfaces
interface=enp0s31f6
interface=lo
except-interface=wlan0
no-dhcp-interface=wlan0

# Listen on transit IP
listen-address=172.16.100.1

# DHCP Scope for Transit
dhcp-range=enp0s31f6,172.16.100.10,172.16.100.50,255.255.255.0,12h
dhcp-option=enp0s31f6,3,172.16.100.1
dhcp-option=enp0s31f6,6,172.16.100.1,1.1.1.1,9.9.9.9

# DNS Forwarding & Privacy
domain-needed
bogus-priv
no-resolv
server=1.1.1.1
server=9.9.9.9
cache-size=4096
```

Restart and verify:
```bash
sudo systemctl restart dnsmasq
sudo systemctl enable dnsmasq
```

---

## 6. ThinkPad Hardware Lifecycle & Reliability Engineering

### 6.1 Lid-Closed Headless Operation
Create `/etc/systemd/logind.conf.d/homelab-lid.conf`:

```ini
[Login]
HandleLidSwitch=ignore
HandleLidSwitchExternalPower=ignore
HandleLidSwitchDocked=ignore
LidSwitchIgnoreInhibited=no
HoldoffTimeoutSec=0
```

Apply logind settings and mask all sleep targets:
```bash
sudo systemctl restart systemd-logind
sudo systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.target suspend-then-hibernate.target
```

---

### 6.2 Battery Longevity Protection (`tlp`)
Install `tlp`:
```bash
sudo apt install -y tlp tlp-rdw
```

Create `/etc/tlp.d/01-homelab-gateway.conf`:

```ini
# Lenovo ThinkPad Battery Thresholds (Prevents pouch swelling on 24/7 AC)
START_CHARGE_THRESH_BAT0=75
STOP_CHARGE_THRESH_BAT0=80

# CPU Governor & Energy Policy for Headless Gateway
CPU_SCALING_GOVERNOR_ON_AC=performance
CPU_ENERGY_PERF_POLICY_ON_AC=balance_performance
WIFI_PWR_ON_AC=off
```

Start TLP:
```bash
sudo tlp start
sudo tlp-stat -b
```

---

### 6.3 Wi-Fi Driver Power Saving Lockdown
Create `/etc/modprobe.d/iwlwifi.conf`:

```ini
options iwlwifi power_save=0 d0i3_disable=Y uapsd_disable=Y
options iwlmvm power_scheme=1
```

---

### 6.4 Resilient Wi-Fi Health Watchdog
Create `/usr/local/bin/wifi-watchdog.sh`:

```bash
#!/usr/bin/env bash
# /usr/local/bin/wifi-watchdog.sh
set -euo pipefail

GATEWAY_IP="10.0.0.1"
WAN_CHECK_IP="1.1.1.1"
LOG_TAG="wifi-watchdog"
RATE_LIMIT_FILE="/tmp/.wifi_restart_timestamp"
COOLDOWN_SEC=180

if [ -f "$RATE_LIMIT_FILE" ]; then
    LAST_RESTART=$(cat "$RATE_LIMIT_FILE")
    NOW=$(date +%s)
    if [ $((NOW - LAST_RESTART)) -lt $COOLDOWN_SEC ]; then
        exit 0
    fi
fi

if ! ping -c 2 -W 2 "$GATEWAY_IP" > /dev/null 2>&1; then
    if ! ping -c 2 -W 2 "$WAN_CHECK_IP" > /dev/null 2>&1; then
        logger -t "$LOG_TAG" "Wi-Fi gateway unreachable. Initiating soft reconnect..."
        if command -v nmcli >/dev/null 2>&1; then
            nmcli radio wifi off && sleep 3 && nmcli radio wifi on
        else
            ip link set wlan0 down && sleep 2 && ip link set wlan0 up
        fi
        echo $(date +%s) > "$RATE_LIMIT_FILE"
    fi
fi
```

Make executable:
```bash
sudo chmod +x /usr/local/bin/wifi-watchdog.sh
```

Create the systemd service `/etc/systemd/system/wifi-watchdog.service`:
```ini
[Unit]
Description=Wi-Fi Liveness Watchdog
After=network.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/wifi-watchdog.sh
```

Create the systemd timer `/etc/systemd/system/wifi-watchdog.timer`:
```ini
[Unit]
Description=Run Wi-Fi Watchdog Every Minute

[Timer]
OnBootSec=2min
OnUnitActiveSec=1min

[Install]
WantedBy=timers.target
```

Enable the timer:
```bash
sudo systemctl daemon-reload
sudo systemctl enable --now wifi-watchdog.timer
```

---

## 7. Tailscale Out-of-Band Bastion Setup

Install Tailscale:
```bash
curl -fsSL https://tailscale.com/install.sh | sh
```

Authenticate the T490 as an Out-of-Band Bastion:
```bash
sudo tailscale up --ssh --advertise-tags=tag:gateway --accept-routes=false --hostname=t490-gateway
```

> [!TIP]
> Setting `--accept-routes=false` on the T490 prevents any routing loops between Tailscale subnets and local interfaces, giving you a clean, dedicated SSH bastion into your gateway even if Proxmox is powered down.
