{ config, lib, this, ... }: with lib; let cfg = config.nixfiles.modules.ipfs; swarmDefaultPort = 4001; apiDefaultPort = 5001; gatewayDefaultPort = 6001; in { options.nixfiles.modules.ipfs = { enable = mkEnableOption "IPFS daemon"; domain = mkOption { description = "Domain name sans protocol scheme."; type = with types; str; default = "ipfs.${config.networking.fqdn}"; }; swarmPort = mkOption { description = "Swarm port."; type = with types; port; default = if this.isHeadless then swarmDefaultPort + 990 else swarmDefaultPort; }; apiPort = mkOption { description = "API port."; type = with types; port; default = if this.isHeadless then apiDefaultPort + 990 else apiDefaultPort; }; gatewayPort = mkOption { description = "Gateway port."; type = with types; port; default = if this.isHeadless then gatewayDefaultPort + 990 else gatewayDefaultPort; }; }; config = mkIf cfg.enable (mkMerge [ { services.ipfs = { enable = true; user = my.username; inherit (config.my) group; dataDir = "${config.dirs.data}/ipfs"; swarmAddress = let port = toString cfg.swarmPort; in if this.isHeadless then [ "/ip4/127.0.0.1/tcp/${port}" "/ip4/127.0.0.1/udp/${port}/quic" ] else [ "/ip4/0.0.0.0/tcp/${port}" "/ip6/::/tcp/${port}" "/ip4/0.0.0.0/udp/${port}/quic" "/ip6/::/udp/${port}/quic" ]; apiAddress = "/ip4/127.0.0.1/tcp/${toString cfg.apiPort}"; gatewayAddress = "/ip4/127.0.0.1/tcp/${toString cfg.gatewayPort}"; autoMigrate = true; autoMount = true; emptyRepo = true; enableGC = true; extraConfig = mkMerge [ (let filterAddresses = [ "/ip4/100.64.0.0/ipcidr/10" "/ip4/169.254.0.0/ipcidr/16" "/ip4/172.16.0.0/ipcidr/12" "/ip4/192.0.0.0/ipcidr/24" "/ip4/192.0.2.0/ipcidr/24" "/ip4/192.168.0.0/ipcidr/16" "/ip4/198.18.0.0/ipcidr/15" "/ip4/198.51.100.0/ipcidr/24" "/ip4/203.0.113.0/ipcidr/24" "/ip4/240.0.0.0/ipcidr/4" "/ip6/100::/ipcidr/64" "/ip6/2001:2::/ipcidr/48" "/ip6/2001:db8::/ipcidr/32" "/ip6/fe80::/ipcidr/10" ] ++ optionals (!hasAttr "wireguard" this) [ "/ip4/10.0.0.0/ipcidr/8" "/ip6/fc00::/ipcidr/7" ]; in { Addresses = with config.services.ipfs; { # https://github.com/NixOS/nixpkgs/pull/165259 # I think this shit broke inheritance... Gotta test more and make # a PR I guess. API = apiAddress; Gateway = gatewayAddress; Swarm = swarmAddress; NoAnnounce = filterAddresses; }; Swarm.AddrFilters = filterAddresses; API.HTTPHeaders.Access-Control-Allow-Methods = ["GET" "POST" "PUT"]; }) (mkIf this.isHeadful { API.HTTPHeaders.Access-Control-Allow-Origin = ["*"]; }) (mkIf this.isHeadless { API.HTTPHeaders.Access-Control-Allow-Origin = ["https://${cfg.domain}" "https://api.${cfg.domain}"]; }) ]; }; networking.firewall = rec { allowedTCPPorts = [swarmDefaultPort]; allowedUDPPorts = allowedTCPPorts; }; } (mkIf this.isHeadless { nixfiles.modules.nginx = { enable = true; upstreams = { ipfs_gateway.servers."127.0.0.1:${toString cfg.gatewayPort}" = {}; ipfs_swarm.servers."127.0.0.1:${toString cfg.swarmPort}" = {}; ipfs_api.servers."127.0.0.1:${toString cfg.apiPort}" = {}; }; virtualHosts = { ${cfg.domain}.locations."/".proxyPass = "http://ipfs_gateway"; "swarm.${cfg.domain}" = { serverName = cfg.domain; listen = [ { addr = "0.0.0.0"; port = swarmDefaultPort; } { addr = "[::0]"; port = swarmDefaultPort; } ]; locations."/".proxyPass = "http://ipfs_swarm"; }; "api.${cfg.domain}" = { # TODO Redirect "/" to "/webui" but keep other endpoints. locations."/".proxyPass = "http://ipfs_api"; extraConfig = nginxInternalOnly; }; }; }; }) ]); }