router: route imgur via WireGuard tunnel
This commit is contained in:
parent
d8d8400519
commit
bfdd0ebc44
2 changed files with 75 additions and 0 deletions
74
services/imgur-vpn.nix
Normal file
74
services/imgur-vpn.nix
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
# services/imgur-vpn.nix — route imgur out a WireGuard tunnel, network-wide
|
||||
#
|
||||
# imgur geo-blocks UK IPs, so LAN clients need a non-UK exit for imgur only.
|
||||
# imgur.com / i.imgur.com / api.imgur.com all resolve to two Fastly anycast
|
||||
# /24s; we send just those prefixes down the tunnel and leave everything else
|
||||
# on eno1.
|
||||
#
|
||||
# ponytail: static prefixes, not a DNS-driven nftset. Other Fastly customers
|
||||
# sharing these /24s ride the tunnel too — harmless, just a longer path. If
|
||||
# that ever matters, add dnsmasq `nftset=` + fwmark policy routing instead.
|
||||
#
|
||||
# Setup (one-off, on the mediaserver):
|
||||
# 1. Fill in peerPublicKey / peerEndpoint / tunnelAddress below from your
|
||||
# VPN provider's WireGuard config (pick a non-UK exit).
|
||||
# 2. Write the private key, no trailing newline, readable by systemd-network:
|
||||
# install -m600 -o systemd-network -g systemd-network \
|
||||
# /dev/stdin /var/secrets/wg-imgur.key <<< '<PRIVATE_KEY>'
|
||||
# 3. Rebuild. Verify: curl --interface wg-imgur https://api.imgur.com/
|
||||
{ config, lib, ... }:
|
||||
let
|
||||
# --- provider details: fill these in ---
|
||||
peerPublicKey = "@PEER_PUBLIC_KEY@";
|
||||
peerEndpoint = "@HOST_OR_IP@:51820";
|
||||
tunnelAddress = "@TUNNEL_IP@/32"; # address the provider assigned us
|
||||
|
||||
# imgur's Fastly anycast prefixes.
|
||||
imgurNets = [ "199.232.192.0/24" "199.232.196.0/24" ];
|
||||
in
|
||||
{
|
||||
config = lib.mkIf (config.networking.hostName == "FredOS-Mediaserver") {
|
||||
|
||||
systemd.network = {
|
||||
netdevs."30-wg-imgur" = {
|
||||
netdevConfig = {
|
||||
Name = "wg-imgur";
|
||||
Kind = "wireguard";
|
||||
};
|
||||
# Key read at runtime — keeps flake eval pure (hosts build from Forgejo).
|
||||
wireguardConfig.PrivateKeyFile = "/var/secrets/wg-imgur.key";
|
||||
wireguardPeers = [{
|
||||
PublicKey = peerPublicKey;
|
||||
Endpoint = peerEndpoint;
|
||||
# Doubles as the tunnel's crypto-routing scope: only imgur goes in.
|
||||
AllowedIPs = imgurNets;
|
||||
PersistentKeepalive = 25;
|
||||
}];
|
||||
};
|
||||
|
||||
networks."30-wg-imgur" = {
|
||||
matchConfig.Name = "wg-imgur";
|
||||
address = [ tunnelAddress ];
|
||||
# Plain main-table routes: destination-based, so no fwmark/ip-rule
|
||||
# machinery and no rp_filter breakage on the reply path.
|
||||
routes = map (n: { Destination = n; }) imgurNets;
|
||||
linkConfig.RequiredForOnline = "no";
|
||||
};
|
||||
};
|
||||
|
||||
# LAN sources must be NAT'd to the tunnel address, and TCP MSS clamped —
|
||||
# the tunnel's 1420 MTU otherwise black-holes full-size segments.
|
||||
networking.nftables.tables.router-nat.content = lib.mkAfter ''
|
||||
chain wg_imgur_postrouting {
|
||||
type nat hook postrouting priority 101; policy accept;
|
||||
oifname "wg-imgur" masquerade
|
||||
}
|
||||
'';
|
||||
networking.nftables.tables.filter.content = lib.mkAfter ''
|
||||
chain wg_imgur_mss {
|
||||
type filter hook forward priority 0; policy accept;
|
||||
oifname "wg-imgur" tcp flags syn tcp option maxseg size set rt mtu
|
||||
}
|
||||
'';
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue