From 3b958ba3567e75196db892ee76f0ae3023eff26e Mon Sep 17 00:00:00 2001 From: Colin Date: Mon, 19 Jun 2023 03:49:42 +0000 Subject: [PATCH] sftp: allow read-only anonymous FTP --- hosts/by-name/servo/services/default.nix | 2 +- hosts/by-name/servo/services/ftp.nix | 32 --------- hosts/by-name/servo/services/ftp/default.nix | 70 +++++++++++++++++++ .../services/ftp/sftpgo_external_auth_hook | 55 +++++++++++++++ 4 files changed, 126 insertions(+), 33 deletions(-) delete mode 100644 hosts/by-name/servo/services/ftp.nix create mode 100644 hosts/by-name/servo/services/ftp/default.nix create mode 100755 hosts/by-name/servo/services/ftp/sftpgo_external_auth_hook diff --git a/hosts/by-name/servo/services/default.nix b/hosts/by-name/servo/services/default.nix index 7bdafb5c..57d1483f 100644 --- a/hosts/by-name/servo/services/default.nix +++ b/hosts/by-name/servo/services/default.nix @@ -7,7 +7,7 @@ ./email ./ejabberd.nix ./freshrss.nix - ./ftp.nix + ./ftp ./gitea.nix ./goaccess.nix ./ipfs.nix diff --git a/hosts/by-name/servo/services/ftp.nix b/hosts/by-name/servo/services/ftp.nix deleted file mode 100644 index 1cd0c667..00000000 --- a/hosts/by-name/servo/services/ftp.nix +++ /dev/null @@ -1,32 +0,0 @@ -# docs: -# - -# - config options: -# - config defaults: -# -# sftpgo is a FTP server that also supports WebDAV, SFTP, and web clients. - -{ ... }: -{ - sane.ports.ports."21" = { - protocol = [ "tcp" ]; - visibleTo.lan = true; - description = "colin-FTP server"; - }; - - services.sftpgo = { - enable = false; - # enable = true; - settings.ftpd.bindings = [{ - address = "10.0.10.5"; - port = 21; - - banner = '' - Welcome, friends, to Colin's read-only FTP server! Also available via NFS on the same host. - Please let me know if anything's broken or not as it should be. Otherwise, browse and DL freely :) - ''; - hash_support = true; - - debug = true; - }]; - }; -} diff --git a/hosts/by-name/servo/services/ftp/default.nix b/hosts/by-name/servo/services/ftp/default.nix new file mode 100644 index 00000000..c7d83a7e --- /dev/null +++ b/hosts/by-name/servo/services/ftp/default.nix @@ -0,0 +1,70 @@ +# docs: +# - +# - config options: +# - config defaults: +# - nixos options: +# +# sftpgo is a FTP server that also supports WebDAV, SFTP, and web clients. + + +{ lib, pkgs, sane-lib, ... }: +let + authProgram = pkgs.static-nix-shell.mkBash { + pname = "sftpgo_external_auth_hook"; + src = ./.; + }; +in +{ + # Client initiates a FTP "control connection" on port 21. + # - this handles the client -> server commands, and the server -> client status, but not the actual data + # - file data, directory listings, etc need to be transferred on an ephemeral "data port". + # - 50000-50100 is a common port range for this. + sane.ports.ports = { + "21" = { + protocol = [ "tcp" ]; + visibleTo.lan = true; + description = "colin-FTP server"; + }; + } // (sane-lib.mapToAttrs + (port: { + name = builtins.toString port; + value = { + protocol = [ "tcp" ]; + visibleTo.lan = true; + description = "colin-FTP server data port range"; + }; + }) + (lib.range 50000 50100) + ); + + services.sftpgo = { + enable = true; + settings = { + ftpd = { + bindings = [{ + address = "10.0.10.5"; + port = 21; + debug = true; + }]; + + # active mode is susceptible to "bounce attacks", without much benefit over passive mode + disable_active_mode = true; + hash_support = true; + passive_port_range = { + start = 50000; + end = 50100; + }; + + banner = '' + Welcome, friends, to Colin's read-only FTP server! Also available via NFS on the same host. + Please let me know if anything's broken or not as it should be. Otherwise, browse and DL freely :) + ''; + + }; + data_provider = { + driver = "memory"; + external_auth_hook = "${authProgram}/bin/sftpgo_external_auth_hook"; + }; + }; + }; +} diff --git a/hosts/by-name/servo/services/ftp/sftpgo_external_auth_hook b/hosts/by-name/servo/services/ftp/sftpgo_external_auth_hook new file mode 100755 index 00000000..04492b02 --- /dev/null +++ b/hosts/by-name/servo/services/ftp/sftpgo_external_auth_hook @@ -0,0 +1,55 @@ +#!/usr/bin/env nix-shell +#!nix-shell -i bash +# vim: set filetype=bash : +# +# available environment variables: +# - SFTPGO_AUTHD_USERNAME +# - SFTPGO_AUTHD_USER +# - SFTPGO_AUTHD_IP +# - SFTPGO_AUTHD_PROTOCOL = { "DAV", "FTP", "HTTP", "SSH" } +# - SFTPGO_AUTHD_PASSWORD +# - SFTPGO_AUTHD_PUBLIC_KEY +# - SFTPGO_AUTHD_KEYBOARD_INTERACTIVE +# - SFTPGO_AUTHD_TLS_CERT +# +# user permissions: +# - see +# - "*" = grant all permissions +# - read-only perms: +# - "list" = list files and directories +# - "download" +# - rw perms: +# - "upload" +# - "overwrite" = allow uploads to replace existing files +# - "delete" = delete files and directories +# - "delete_files" +# - "delete_dirs" +# - "rename" = rename files and directories +# - "rename_files" +# - "rename_dirs" +# - "create_dirs" +# - "create_symlinks" +# - "chmod" +# - "chown" +# - "chtimes" = change atime/mtime (access and modification times) +# +# home_dir: +# - it seems (empirically) that a user can't cd above their home directory. +# though i don't have a reference for that in the docs. +# TODO: don't reuse /var/nfs/export here. formalize this some other way. + + +if [ "$SFTPGO_AUTHD_USERNAME" = "anonymous" ]; then + echo '{' + echo ' "status":1,' + echo ' "username":"anonymous","expiration_date":0,' + echo ' "home_dir":"/var/nfs/export","uid":65534,"gid":65534,"max_sessions":0,"quota_size":0,"quota_files":100000,' + echo ' "permissions":{' + echo ' "/":["list", "download"]' + echo ' },' + echo ' "upload_bandwidth":0,"download_bandwidth":0,' + echo ' "filters":{"allowed_ip":[],"denied_ip":[]},"public_keys":[]' + echo '}' +else + echo '{"username":""}' +fi