diff --git a/hosts/koi/configuration.nix b/hosts/koi/configuration.nix index 5cfcc9a..cacff3a 100755 --- a/hosts/koi/configuration.nix +++ b/hosts/koi/configuration.nix @@ -21,8 +21,8 @@ ./services/landing ./containers/torrent.nix - ./containers/puffer.nix ./containers/vaultwarden.nix + ./containers/sftpgo ./containers/verdaccio ./containers/sharkey ./containers/pds diff --git a/hosts/koi/containers/puffer.nix b/hosts/koi/containers/puffer.nix deleted file mode 100644 index b66db14..0000000 --- a/hosts/koi/containers/puffer.nix +++ /dev/null @@ -1,210 +0,0 @@ -{ abs, lib, config, pkgs, ... }@inputs: - -let - containers = import (abs "lib/containers.nix") inputs; - avahi = import (abs "lib/avahi.nix") inputs; - systemd = import (abs "lib/systemd.nix") inputs; - sftpgo = import (abs "services/sftpgo.nix") inputs; - secrets = import (abs "lib/secrets.nix"); - - sftpKey = secrets.mount config "sftpgo-ed25519"; - - sambaConfig = { - imports = [ - (systemd.mkOneshot { - name = "smb-guest-setup"; - # for whatever reason smbd refuses to write unless we set the password - script = "${pkgs.samba}/bin/smbpasswd -a smb-guest -n"; - }) - ]; - - services.samba = { - enable = true; - openFirewall = true; - - securityType = "user"; - extraConfig = '' - workgroup = WORKGROUP - server string = puffer - netbios name = puffer - security = user - hosts allow = 10.0.0.0/8 - hosts deny = 0.0.0.0/0 - guest account = smb-guest - map to guest = bad user - inherit permissions = yes - - # Performance - socket options = TCP_NODELAY IPTOS_LOWDELAY SO_RCVBUF=131072 SO_SNDBUF=131072 - read raw = yes - write raw = yes - server signing = no - strict locking = no - min receivefile size = 16384 - use sendfile = Yes - aio read size = 16384 - aio write size = 16384 - - # Fruit global config - fruit:aapl = yes - fruit:nfs_aces = no - fruit:copyfile = no - fruit:model = MacSamba - ''; - - shares = - let - publicShare = { - browseable = "yes"; - "read only" = "no"; - "guest ok" = "yes"; - "create mask" = "2775"; - "directory mask" = "2775"; - "force user" = "smb-guest"; - "force group" = "puffer"; - }; - in - { - Downloads = { - path = "/mnt/puffer/Downloads"; - browseable = "yes"; - "read only" = "yes"; - "guest ok" = "yes"; - }; - - Public = publicShare // { - path = "/mnt/puffer/Public"; - }; - - # its ok for this to be local-public, since Time Machine - # backups are to be encrypted anyway - # (and also im too lazy to set up users here) - Backups = publicShare // { - path = "/mnt/puffer/Backups"; - # whatever this means - "vfs objects" = "catia fruit streams_xattr"; - "fruit:time machine" = "yes"; - "fruit:time machine max size" = "100G"; - }; - }; - }; - }; - - avahiConfig = avahi.setup { - name = "puffer"; - services = [ - { type = "_smb._tcp"; port = 445; } - # cancer stuff for macs to see this disk as a time machine-compatible disk - [ - { type = "_adisk._tcp"; port = 9; } - { txt-record = "sys=waMa=0,adVF=0x100"; } - { txt-record = "dk0=adVN=Puffer TimeMachine,adVF=0x82"; } - ] - { type = "_device-info._tcp"; port = 0; txt-record = "model=TimeCapsule8,119"; } - ]; - }; - - sftpgoConfig = sftpgo.setup { - package = pkgs.callPackage (abs "packages/sftpgo.nix") { - tags = [ "nogcs" "nos3" "noazblob" "nobolt" "nomysql" "nopgsql" "nometrics" "bundle" ]; - }; - - config = { - sftpd = { - bindings = [ - { port = 22; } - ]; - host_keys = [ "id_ed25519" ]; - }; - }; - keys.ed25519 = sftpKey.path; - - users.guest = { - # bcrypt-hashed 0 - password = "$2a$10$IcGdNtx10ycmPRD6lA4c0uNfRXTEchFRzCZEDkngTjzForn6pd0Wa"; - }; - - folders.Public.path = "/mnt/puffer/Public"; - folders.Downloads.path = "/mnt/puffer/Downloads"; - - usersFolders = [ - { username = "guest"; folder = "Public"; } - { username = "guest"; folder = "Downloads"; } - ]; - }; - - container = containers.mkNixosContainer { - name = "puffer"; - ip = "10.42.0.5"; - private = false; - - config = { ... }: { - imports = [ - sambaConfig - avahiConfig - sftpgoConfig - ]; - - environment.systemPackages = with pkgs; [ - uxplay - ]; - - users.groups.puffer = { }; - users.users.smb-guest = { - isNormalUser = true; - description = "Guest account for Samba"; - extraGroups = [ "puffer" ]; - createHome = false; - shell = pkgs.shadow; - }; - - systemd.tmpfiles.rules = [ - "d /mnt/puffer/Public 0755 smb-guest puffer - -" - "d /mnt/puffer/Backups 0755 smb-guest puffer - -" - ]; - - networking.firewall.allowedTCPPorts = [ 22 7000 7001 7002 ]; - networking.firewall.allowedUDPPorts = [ 22 7000 7001 7002 ]; - }; - - mounts = { - "/mnt/puffer" = { - hostPath = "/mnt/puffer"; - isReadOnly = false; - }; - } // (sftpKey.mounts); - }; -in -{ - imports = [ - (secrets.declare [ "sftpgo-ed25519" ]) - container - ]; - - services.nginx.virtualHosts."puffer.stupid.fish" = { - forceSSL = true; - useACMEHost = "stupid.fish"; - - locations."/public/" = { - extraConfig = '' - alias /mnt/puffer/Public/; - autoindex on; - ''; - }; - - locations."/downloads/" = { - extraConfig = '' - alias /mnt/puffer/Downloads/; - autoindex on; - ''; - }; - - locations."= /" = { - extraConfig = '' - add_header 'Content-Type' 'text/html; charset=utf-8'; - return 200 '

🐡 puffer

public
downloads'; - ''; - }; - }; -} - diff --git a/hosts/koi/containers/sftpgo/default.nix b/hosts/koi/containers/sftpgo/default.nix new file mode 100644 index 0000000..412de55 --- /dev/null +++ b/hosts/koi/containers/sftpgo/default.nix @@ -0,0 +1,68 @@ +{ pkgs, abs, config, ... }@inputs: + +let + secrets = import (abs "lib/secrets.nix"); + + UID = 1112; +in { + imports = [ + (secrets.declare [{ + name = "sftpgo-env"; + owner = "sftpgo"; + }]) + ./samba.nix + ]; + + users.users.sftpgo = { + isNormalUser = true; + uid = UID; + }; + + virtualisation.oci-containers.containers.sftpgo = { + image = "drakkan/sftpgo:v2.6.2"; + volumes = [ + "/srv/sftpgo/data:/srv/sftpgo" + "/srv/sftpgo/config:/var/lib/sftpgo" + "/mnt/puffer:/mnt/puffer" + ]; + user = builtins.toString UID; + environment = { + SFTPGO_SFTPD__BINDINGS__0__PORT = "22"; + SFTPGO_WEBDAVD__BINDINGS__0__PORT = "80"; + SFTPGO_WEBDAVD__BINDINGS__0__PROXY_ALLOWED = "172.17.0.1"; + SFTPGO_WEBDAVD__BINDINGS__0__CLIENT_IP_PROXY_HEADER = "X-Forwarded-For"; + SFTPGO_WEBDAVD__BINDINGS__0__PREFIX = "/dav/"; + SFTPGO_HTTPD__BINDINGS__0__PORT = "8080"; + SFTPGO_HTTPD__BINDINGS__0__ENABLED_LOGIN_METHODS = "3"; + SFTPGO_HTTPD__BINDINGS__0__SECURITY__ENABLED = "true"; + SFTPGO_HTTPD__BINDINGS__0__SECURITY__ALLOWED_HOSTS = "puffer.stupid.fish"; + SFTPGO_HTTPD__BINDINGS__0__BRANDING__NAME = "puffer"; + SFTPGO_HTTPD__BINDINGS__0__BRANDING__SHORT_NAME = "puffer"; + SFTPGO_HTTPD__BINDINGS__0__OIDC__REDIRECT_BASE_URL = "https://puffer.stupid.fish/"; + SFTPGO_HTTPD__BINDINGS__0__OIDC__USERNAME_FIELD = "preferred_username"; + SFTPGO_HTTPD__BINDINGS__0__OIDC__IMPLICIT_ROLES = "true"; + }; + environmentFiles = [ + (secrets.file config "sftpgo-env") + ]; + }; + + systemd.tmpfiles.rules = [ + "d /srv/sftpgo/data 0700 ${builtins.toString UID} ${builtins.toString UID} -" + "d /srv/sftpgo/config 0700 ${builtins.toString UID} ${builtins.toString UID} -" + ]; + + services.nginx.virtualHosts."puffer.stupid.fish" = { + forceSSL = true; + useACMEHost = "stupid.fish"; + + locations."/" = { + proxyPass = "http://sftpgo.docker:8080$request_uri"; + proxyWebsockets = true; + }; + + locations."/dav/" = { + proxyPass = "http://sftpgo.docker:80$request_uri"; + }; + }; +} \ No newline at end of file diff --git a/hosts/koi/containers/sftpgo/samba.nix b/hosts/koi/containers/sftpgo/samba.nix new file mode 100644 index 0000000..615243c --- /dev/null +++ b/hosts/koi/containers/sftpgo/samba.nix @@ -0,0 +1,116 @@ +{ abs, lib, config, pkgs, ... }@inputs: + +let + containers = import (abs "lib/containers.nix") inputs; +in +{ + imports = [ + (containers.mkNixosContainer { + name = "puffer"; + ip = "10.42.0.5"; + private = false; + + config = { ... }: { + users.users.smb-guest.isNormalUser = true; + + services.avahi = { + enable = true; + nssmdns4 = true; + openFirewall = true; + publish = { + enable = true; + userServices = true; + }; + + extraServiceFiles.puffer = '' + + + + puffer + + 445 + _smb._tcp + + + 9 + _adisk._tcp + sys=waMa=0,adVF=0x100 + dk0=adVN=Puffer TimeMachine,adVF=0x82 + + + 0 + _device-info._tcp + model=TimeCapsule8,119 + + + ''; + }; + + services.samba = { + enable = true; + openFirewall = true; + + securityType = "user"; + extraConfig = '' + workgroup = WORKGROUP + server string = puffer + netbios name = puffer + security = user + guest account = smb-guest + map to guest = bad user + hosts allow = 10.0.0.0/8 + hosts deny = 0.0.0.0/0 + inherit permissions = yes + + # Performance + socket options = TCP_NODELAY IPTOS_LOWDELAY SO_RCVBUF=131072 SO_SNDBUF=131072 + read raw = yes + write raw = yes + server signing = no + strict locking = no + min receivefile size = 16384 + use sendfile = Yes + aio read size = 16384 + aio write size = 16384 + + # Fruit global config + fruit:aapl = yes + fruit:nfs_aces = no + fruit:copyfile = no + fruit:model = MacSamba + ''; + + shares = + let + common = { + browseable = "yes"; + "read only" = "yes"; + "guest ok" = "yes"; + }; + in + { + Downloads = common // { + path = "/mnt/puffer/Downloads"; + }; + + Public = common // { + path = "/mnt/puffer/Public"; + }; + }; + }; + }; + + mounts = { + "/mnt/puffer/Downloads" = { + hostPath = "/mnt/puffer/Downloads"; + isReadOnly = true; + }; + "/mnt/puffer/Public" = { + hostPath = "/mnt/puffer/Public"; + isReadOnly = true; + }; + }; + }) + ]; + +} diff --git a/hosts/koi/services/coredns.nix b/hosts/koi/services/coredns.nix index fbc57f3..9dcf6c5 100644 --- a/hosts/koi/services/coredns.nix +++ b/hosts/koi/services/coredns.nix @@ -11,6 +11,7 @@ let 10.42.0.2 very.stupid.fish 10.42.0.8 bnuuy.stupid.fish 10.42.0.2 puffer.stupid.fish + 10.42.0.2 puffer-webdav.stupid.fish ''; package = coredns.override { diff --git a/lib/avahi.nix b/lib/avahi.nix deleted file mode 100644 index 092de88..0000000 --- a/lib/avahi.nix +++ /dev/null @@ -1,47 +0,0 @@ -{ ... }@inputs: - -let - xml = import ./xml.nix; -in -rec { - mkConfig = config: - let - configs = if builtins.isList config then config else [ config ]; - data = map - (cfg: { - service-group = - [{ name = cfg.name; }] ++ - map (service: { inherit service; }) cfg.services ++ - [ cfg.extra or { } ]; - }) - configs; - in - '' - - - ${xml.generateXMLInner { obj = data; }} - ''; - - setup = services: - let - servicesList = if builtins.isList services then services else [ services ]; - in - { - services.avahi = { - enable = true; - nssmdns4 = true; - openFirewall = true; - publish = { - enable = true; - userServices = true; - }; - - extraServiceFiles = (builtins.listToAttrs (map - (service: { - name = service.name; - value = mkConfig service; - }) - servicesList)); - }; - }; -} diff --git a/secrets/sftpgo-ed25519.age b/secrets/sftpgo-ed25519.age deleted file mode 100644 index baca874..0000000 --- a/secrets/sftpgo-ed25519.age +++ /dev/null @@ -1,5 +0,0 @@ -age-encryption.org/v1 --> ssh-ed25519 sj88Xw 2YLa2A0IPI5OYU1pACLEZmIXse0w3rwthY/0IhUfITE -W3fHzNoxCouKZXeEZpfZTAfIAKIF07rCDvvnNHgF23Y ---- dIuhxlxaabb+kOpULhF3wcj6CaDpjnLCdog9dTnsWyo -%0E~G Z^UFRjiw/֑CM~vAd>[hA ʿV>D>[m?yCZ^yTP