about summary refs log tree commit diff
path: root/modules/nixos/ipfs.nix
diff options
context:
space:
mode:
authorAzat Bahawi <azat@bahawi.net>2022-12-17 16:39:09 +0300
committerAzat Bahawi <azat@bahawi.net>2022-12-17 16:39:09 +0300
commit8f137c28230623259a964484adcf31fe00756594 (patch)
tree82bce6a13fda125087cf6d9dc80aa91d9230d6c4 /modules/nixos/ipfs.nix
parent2022-11-20 (diff)
2022-12-17
Diffstat (limited to 'modules/nixos/ipfs.nix')
-rw-r--r--modules/nixos/ipfs.nix167
1 files changed, 167 insertions, 0 deletions
diff --git a/modules/nixos/ipfs.nix b/modules/nixos/ipfs.nix
new file mode 100644
index 0000000..0ec64e5
--- /dev/null
+++ b/modules/nixos/ipfs.nix
@@ -0,0 +1,167 @@
+{
+  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;
+          };
+        };
+      };
+    })
+  ]);
+}

Consider giving Nix/NixOS a try! <3