{ config, inputs, pkgs, ... }: let inherit (config.virtualisation.quadlet) volumes; inboundInterface = "wlo1"; inboundGateway = "192.168.1.1"; inboundRangeStart = "192.168.1.2"; inboundRangeStop = "192.168.1.254"; inboundRangeMask = "255.255.255.0"; inboundRangePrefix = 24; outboundInterface = "enp2s0"; in { boot.kernel.sysctl."net.ipv4.ip_forward" = 1; networking = { firewall = { interfaces.${inboundInterface} = { allowedUDPPorts = [ 53 67 ]; allowedTCPPorts = [ 53 8080 ]; }; extraCommands = '' iptables -t nat -A POSTROUTING -o ${outboundInterface} -j MASQUERADE iptables -A FORWARD -i ${outboundInterface} -o ${inboundInterface} -m state --state RELATED,ESTABLISHED -j ACCEPT iptables -A FORWARD -i ${inboundInterface} -o ${outboundInterface} -j ACCEPT iptables -t nat -A PREROUTING -i ${inboundInterface} -p udp --dport 53 -j DNAT --to-destination ${inboundGateway}:53 ''; extraStopCommands = '' iptables -t nat -D POSTROUTING -o ${outboundInterface} -j MASQUERADE || true iptables -D FORWARD -i ${outboundInterface} -o ${inboundInterface} -m state --state RELATED,ESTABLISHED -j ACCEPT || true iptables -D FORWARD -i ${inboundInterface} -o ${outboundInterface} -j ACCEPT || true iptables -t nat -D PREROUTING -i ${inboundInterface} -p udp --dport 53 -j DNAT --to-destination ${inboundGateway}:53 || true ''; }; networkmanager.unmanaged = [ "interface-name:${inboundInterface}" ]; interfaces.${inboundInterface}.ipv4 = { addresses = [ { address = inboundGateway; prefixLength = inboundRangePrefix; } ]; }; }; sops = { secrets = { "tv/network/password".sopsFile = "${inputs.secrets}/hosts/jupiter/secrets.yaml"; "tv/adguard/admin".sopsFile = "${inputs.secrets}/hosts/jupiter/secrets.yaml"; }; templates.adguard-env.content = '' ADGUARD_ADMIN_PASSWORD=${config.sops.placeholder."tv/adguard/admin"} ''; }; services.hostapd = { enable = true; radios.${inboundInterface} = { band = "2g"; channel = 2; countryCode = "GB"; networks.${inboundInterface} = { ssid = "jupiter-tv"; authentication.saePasswords = [ { passwordFile = config.sops.secrets."tv/network/password".path; } ]; }; }; }; virtualisation.quadlet = { volumes.tv-adguard = { }; containers.tv-adguard = { containerConfig = { image = "docker-archive:${pkgs.dockerImages.adguardhome}"; volumes = let config = (pkgs.formats.yaml { }).generate "config.yaml.default" { http.address = "${inboundGateway}:8080"; dns = { bind_hosts = [ inboundGateway ]; port = 53; ratelimit = 0; }; dhcp = { enabled = true; interface_name = inboundInterface; local_domain_name = "local"; dhcpv4 = { gateway_ip = inboundGateway; subnet_mask = inboundRangeMask; range_start = inboundRangeStart; range_end = inboundRangeStop; }; }; filters = [ ]; whitelist_filters = [ ]; user_rules = [ "||*^" # Personal "@@||karaolidis.com^$important" # Connectivity Check "@@||clients3.google.com^" "@@||clients.l.google.com^" "@@||connectivitycheck.gstatic.com^" "@@||connectivitycheck.android.com^" # NTP "@@||pool.ntp.org^$important" "@@||time.android.com^$important" "@@||time.akamai.com^$important" # Plex "@@||plex.tv^$important" "@@||plex.direct^$important" # YouTube "@@||youtube.com^$important" "@@||yt.be^$important" "@@||ytimg.com^$important" "@@||googlevideo.com^$important" # YouTube Extensions "@@||returnyoutubedislikeapi.com^$important" "@@||sponsor.ajay.app^$important" # Google Misc "@@||accounts.google.com^$important" "@@||www.gstatic.com^$important" "@@||content-autofill.googleapis.com^$important" # Google Play "@@||play.google.com^$important" "@@||android.googleapis.com^$important" "@@||androidtvsetupwraithfe-pa.googleapis.com^$important" "@@||play-fe.googleapis.com^$important" "@@||play-lh.googleusercontent.com^$important" "@@||play.googleapis.com^$important" "@@||android.apis.google.com^$important" "@@||playatoms-pa.googleapis.com^$important" "@@||gvt1.com^$important" # Spotify "@@||spotify.com^$important" "@@||spotify.dev^$important" "@@||scdn.co^$important" "@@||tospotify.com^$important" "@@||spotifycdn.com^$important" # Twitch "@@||twitch.tv^$important" "@@||ttvnw.net^$important" "@@||static-cdn.jtvnw.net^$important" # Cosmote TV "@@||account.cosmote.gr^$important" "@@||cosmotetvott.gr^$important" "@@||msvdn.net^$important" "@@||theplatform.eu^$important" "@@||theplatform.com^$important" ]; schema_version = 29; }; in [ "${config}:/etc/adguard/config.yaml.default" "${volumes.tv-adguard.ref}:/var/lib/adguard" ]; networks = [ "host" ]; addCapabilities = [ "NET_RAW" "NET_ADMIN" ]; environmentFiles = [ config.sops.templates.adguard-env.path ]; }; unitConfig.After = [ "sops-nix.service" ]; }; }; }