Luke Granger-Brown
fee02312d3
Previously, the public/internal interfaces were VLANned onto the same NIC. For some reason, sometime the Emulex adapters seem to end up not getting configured properly, which causes me no end of pain when I spend time trying to debug why none of my VMs can see the internet anymore. Instead of doing this, put the public interface onto its own actual virtual network interface.
265 lines
7.5 KiB
Nix
265 lines
7.5 KiB
Nix
# SPDX-FileCopyrightText: 2020 Luke Granger-Brown <depot@lukegb.com>
|
|
#
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
|
|
{ depot, lib, pkgs, rebuilder, config, ... }:
|
|
let
|
|
inherit (depot.ops) secrets;
|
|
in {
|
|
imports = [
|
|
../lib/blade-router.nix
|
|
../lib/blade.nix
|
|
../lib/fup.nix
|
|
];
|
|
|
|
boot.loader.grub.device = "/dev/disk/by-id/usb-USB_SanDisk_3.2Gen1_0101cabb1ebdbdc0fd7b18edd207d43717c39c4a59d1b138b363e315841eca15743400000000000000000000443273100087260091558107b6a8e06e-0:0";
|
|
|
|
# Networking!
|
|
networking = {
|
|
hostName = "blade-tuvok";
|
|
hostId = "525229f7";
|
|
firewall.allowedTCPPorts = [ 80 443 ];
|
|
firewall.allowedUDPPorts = [
|
|
# Wireguard
|
|
51820 51821
|
|
];
|
|
localCommands = ''
|
|
# Check if we already have our little minicontainer setup
|
|
ip netns list | grep -q wg-endpoint || (
|
|
ip netns add wg-endpoint
|
|
ip link add ve-wg-endpoint type veth peer name ve-int netns wg-endpoint
|
|
ip link set dev ve-wg-endpoint master br-public
|
|
ip link set dev ve-wg-endpoint up
|
|
ip -n wg-endpoint link set dev ve-int up
|
|
ip -n wg-endpoint addr add 92.118.28.252/24 dev ve-int
|
|
ip -n wg-endpoint addr add 2a09:a441::f00f/48 dev ve-int
|
|
ip -n wg-endpoint route add default via 92.118.28.1
|
|
ip -n wg-endpoint route add default via 2a09:a441::1
|
|
ip netns exec wg-endpoint sysctl net.ipv4.ip_forward=1 net.ipv6.conf.all.forwarding=1 net.ipv6.conf.default.forwarding=1
|
|
)
|
|
'';
|
|
nat.extraCommands = ''
|
|
iptables -w -t nat -A nixos-nat-post -m mark --mark 0x1 -o vl-linx -j SNAT --to-source 92.118.28.1
|
|
'';
|
|
};
|
|
my.ip.tailscale = "100.119.123.33";
|
|
my.blade.bay = 6;
|
|
my.blade.macAddress = {
|
|
internal = "e4:11:5b:ac:e3:fe";
|
|
storage = "e4:11:5b:ac:e4:02";
|
|
internet = "e4:11:5b:ac:e3:ff";
|
|
public = "e4:11:5b:ac:e4:00";
|
|
};
|
|
|
|
services.ceph = {
|
|
mon.enable = true;
|
|
osd = {
|
|
enable = true;
|
|
daemons = [ "3" ];
|
|
};
|
|
};
|
|
|
|
services.nginx = {
|
|
enable = true;
|
|
recommendedTlsSettings = true;
|
|
recommendedGzipSettings = true;
|
|
virtualHosts."objdump.zxcvbnm.ninja" = {
|
|
useACMEHost = "objdump.zxcvbnm.ninja";
|
|
default = true;
|
|
forceSSL = true;
|
|
locations."/" = {
|
|
proxyPass = "http://localhost:7480";
|
|
extraConfig = ''
|
|
proxy_redirect off;
|
|
client_max_body_size 0;
|
|
proxy_buffering off;
|
|
'';
|
|
};
|
|
};
|
|
};
|
|
security.acme = {
|
|
acceptTerms = true;
|
|
email = "letsencrypt@lukegb.com";
|
|
certs."objdump.zxcvbnm.ninja" = {
|
|
group = config.services.nginx.group;
|
|
dnsProvider = "cloudflare";
|
|
credentialsFile = secrets.cloudflareCredentials;
|
|
extraDomainNames = [
|
|
"*.objdump.zxcvbnm.ninja"
|
|
];
|
|
};
|
|
};
|
|
my.fup.listen = [
|
|
"0.0.0.0" "[::]"
|
|
];
|
|
|
|
my.blade-router = {
|
|
addresses.linknet = {
|
|
v4 = { local = "195.74.55.21"; remote = "195.74.55.20"; };
|
|
v6 = {
|
|
local = "2a03:ee40:8080:9:1::2";
|
|
remote = "2a03:ee40:8080:9:1::1";
|
|
};
|
|
};
|
|
|
|
addresses.br-public = {
|
|
v4.addr = "92.118.28.254";
|
|
v6.addr = "2a09:a441::ffff";
|
|
};
|
|
|
|
linx.enable = true;
|
|
|
|
vrrp.priority = 100;
|
|
};
|
|
|
|
networking.wireguard = let
|
|
ifBase = {
|
|
listenPort = null;
|
|
allowedIPsAsRoutes = false;
|
|
socketNamespace = "wg-endpoint";
|
|
};
|
|
peerBase.allowedIPs = [
|
|
"0.0.0.0/0"
|
|
"::/0"
|
|
];
|
|
swannBase = ifBase // {
|
|
privateKey = secrets.wireguard.tuvok-swann.tuvok.privateKey;
|
|
peers = [(peerBase // {
|
|
endpoint = null; # dynamic
|
|
publicKey = secrets.wireguard.tuvok-swann.swann.publicKey;
|
|
})];
|
|
};
|
|
in {
|
|
enable = true;
|
|
interfaces.wg-swann-vm = swannBase // {
|
|
ips = [
|
|
"2a09:a442::1:2/112"
|
|
"92.118.30.1/31"
|
|
];
|
|
listenPort = 51820;
|
|
};
|
|
interfaces.wg-swann-ee = swannBase // {
|
|
ips = [
|
|
"2a09:a442::2:2/112"
|
|
"92.118.30.3/31"
|
|
];
|
|
listenPort = 51821;
|
|
};
|
|
};
|
|
environment.etc."bird/bird-wg-endpoint.conf".source = pkgs.writeTextFile {
|
|
name = "bird-wg-endpoint.conf";
|
|
text = ''
|
|
router id 92.118.28.252;
|
|
protocol kernel {
|
|
persist;
|
|
ipv4 {
|
|
import none;
|
|
export all;
|
|
};
|
|
};
|
|
protocol kernel {
|
|
persist;
|
|
ipv6 {
|
|
import none;
|
|
export all;
|
|
};
|
|
};
|
|
protocol device {};
|
|
|
|
protocol static export4 {
|
|
ipv4 {};
|
|
route 92.118.30.0/24 via 92.118.30.0 bfd {
|
|
# Virgin Media
|
|
preference = 100;
|
|
};
|
|
route 92.118.30.0/24 via 92.118.30.2 bfd {
|
|
# EE
|
|
preference = 10;
|
|
};
|
|
};
|
|
protocol static export6 {
|
|
ipv6 {};
|
|
route 2a09:a443::/32 via 2a09:a442::1:1 bfd {
|
|
# Virgin Media
|
|
preference = 100;
|
|
};
|
|
route 2a09:a443::/32 via 2a09:a442::2:1 bfd {
|
|
# EE
|
|
preference = 10;
|
|
};
|
|
};
|
|
|
|
protocol bfd {
|
|
interface "*" {
|
|
min rx interval 10ms;
|
|
min tx interval 50ms;
|
|
idle tx interval 1s;
|
|
multiplier 20;
|
|
};
|
|
neighbor 92.118.30.0;
|
|
neighbor 2a09:a442::1:1;
|
|
neighbor 92.118.30.2;
|
|
neighbor 2a09:a442::2:1;
|
|
};
|
|
'';
|
|
checkPhase = ''
|
|
${pkgs.bird2}/bin/bird -d -p -c $out
|
|
'';
|
|
};
|
|
systemd.services.bird-wg-endpoint = {
|
|
wantedBy = [ "multi-user.target" ];
|
|
reloadIfChanged = true;
|
|
|
|
description = "BIRD inside wg-endpoint netns";
|
|
after = [ "network.target" ];
|
|
restartTriggers = [ config.environment.etc."bird/bird-wg-endpoint.conf".source ];
|
|
|
|
serviceConfig = {
|
|
Type = "forking";
|
|
Restart = "on-failure";
|
|
CapabilityBoundingSet = [ "CAP_CHOWN" "CAP_FOWNER" "CAP_DAC_OVERRIDE" "CAP_SETUID" "CAP_SETGID"
|
|
# see bird/sysdep/linux/syspriv.h
|
|
"CAP_NET_BIND_SERVICE" "CAP_NET_BROADCAST" "CAP_NET_ADMIN" "CAP_NET_RAW" ];
|
|
ProtectSystem = "full";
|
|
ProtectHome = "yes";
|
|
SystemCallFilter="~@cpu-emulation @debug @keyring @module @mount @obsolete @raw-io";
|
|
MemoryDenyWriteExecute = "yes";
|
|
|
|
ExecStop = "${pkgs.bird2}/bin/birdc -s /var/run/bird-wg-endpoint.ctl down";
|
|
ExecStart = "${pkgs.bird2}/bin/bird -c /etc/bird/bird-wg-endpoint.conf -u bird2 -g bird2 -s /var/run/bird-wg-endpoint.ctl";
|
|
ExecReload = "/bin/sh -c '${pkgs.bird2}/bin/bird -c /etc/bird/bird-wg-endpoint.conf -p && ${pkgs.bird2}/bin/birdc -s /var/run/bird-wg-endpoint.ctl configure'";
|
|
NetworkNamespacePath = "/var/run/netns/wg-endpoint";
|
|
};
|
|
};
|
|
# It is at this point he realises it would've been easier if he'd used NixOS containers instead.
|
|
systemd.services.bird-wg-endpoint-exporter = {
|
|
after = [ "bird-wg-endpoint.service" "network.target" ];
|
|
wantedBy = [ "multi-user.target" ];
|
|
serviceConfig = {
|
|
DynamicUser = true;
|
|
User = "bird-exporter";
|
|
Group = "bird-exporter";
|
|
PrivateTmp = true;
|
|
Restart = "always";
|
|
WorkingDirectory = "/tmp";
|
|
SupplementaryGroups = "bird2";
|
|
ExecStart = ''
|
|
${depot.pkgs.prometheus-bird-exporter-lfty}/bin/bird_exporter \
|
|
-web.listen-address 0.0.0.0:9325 \
|
|
-bird.socket /var/run/bird-wg-endpoint.ctl \
|
|
-bird.v2=true \
|
|
-format.new=true
|
|
'';
|
|
};
|
|
};
|
|
my.prometheus.additionalExporterPorts.bird-wg-endpoint-exporter = 9325;
|
|
services.lukegbgp.config.export = {
|
|
v4Extra = ''
|
|
route 92.118.30.0/24 via 92.118.28.252;
|
|
'';
|
|
v6Extra = ''
|
|
route 2a09:a443::/32 via 2a09:a441::f00f;
|
|
'';
|
|
};
|
|
|
|
}
|