X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=modules%2Fprivate%2Fftp.nix;h=d6742e22c289fd5089c7ebd207911d810586e403;hb=bbea22c02b6c059a6be1064391f06737ee244ba6;hp=233031a05ed335534dca26303e82927da2602b18;hpb=546864bc7d2d452803baafcb5d30438924e1d223;p=perso%2FImmae%2FConfig%2FNix.git diff --git a/modules/private/ftp.nix b/modules/private/ftp.nix index 233031a..d6742e2 100644 --- a/modules/private/ftp.nix +++ b/modules/private/ftp.nix @@ -1,34 +1,119 @@ { lib, pkgs, config, ... }: let package = pkgs.pure-ftpd.override { ldapFtpId = "immaeFtp"; }; + pure-ftpd-enabled = config.myServices.ftp.pure-ftpd.enable; + proftpd-enabled = config.myServices.ftp.proftpd.enable; in { options = { - services.pure-ftpd.enable = lib.mkOption { + myServices.ftp.enable = lib.mkOption { + type = lib.types.bool; + default = false; + description = '' + Whether to enable ftp. + ''; + }; + myServices.ftp.pure-ftpd.enable = lib.mkOption { type = lib.types.bool; default = false; description = '' Whether to enable pure-ftpd. ''; }; + myServices.ftp.proftpd.enable = lib.mkOption { + type = lib.types.bool; + default = true; + description = '' + Whether to enable proftpd. + ''; + }; }; - config = lib.mkIf config.services.pure-ftpd.enable { - services.duplyBackup.profiles.ftp = { - rootDir = "/var/lib/ftp"; - remotes = [ "eriomem" "ovh" ]; + config = lib.mkIf config.myServices.ftp.enable { + myServices.chatonsProperties.services.espace-de-stockage = { + file.datetime = "2022-08-22T01:00:00"; + service = { + name = "Espace de stockage"; + description = "Compte FTP/SFTP"; + logo = if pure-ftpd-enabled + then "https://www.pureftpd.org/project/pure-ftpd/images/favicon.png" + else if proftpd-enabled + then "http://proftpd.org/proftpd.png" + else ""; + website = "ftp.immae.eu"; + status.level = "OK"; + status.description = "OK"; + registration."" = ["MEMBER" "CLIENT"]; + registration.load = "OPEN"; + install.type = "PACKAGE"; + }; + software = if pure-ftpd-enabled then { + name = "Pure-ftpd"; + website = "https://www.pureftpd.org/project/pure-ftpd/"; + license.url = "https://github.com/jedisct1/pure-ftpd/blob/master/COPYING"; + license.name = "MIT Licence"; + version = package.version; + source.url = "https://github.com/jedisct1/pure-ftpd/"; + modules = "openssh"; + } else if proftpd-enabled then { + name = "ProFTPD"; + website = "http://proftpd.org/"; + license.url = "https://github.com/proftpd/proftpd/blob/master/COPYING"; + license.name = "GNU General Public License v2.0"; + version = pkgs.proftpd.version; + source.url = "https://github.com/proftpd/proftpd/"; + modules = "openssh"; + } else {}; }; + #myServices.chatonsProperties.services.ftp = { + # file.datetime = "2022-08-22T01:00:00"; + # service = { + # name = "Comptes FTP"; + # description = "Compte FTP/SFTP"; + # logo = if pure-ftpd-enabled + # then "https://www.pureftpd.org/project/pure-ftpd/images/favicon.png" + # else if proftpd-enabled + # then "http://proftpd.org/proftpd.png" + # else ""; + # website = "ftp.immae.eu"; + # status.level = "OK"; + # status.description = "OK"; + # registration."" = ["MEMBER" "CLIENT"]; + # registration.load = "OPEN"; + # install.type = "PACKAGE"; + # }; + # software = if pure-ftpd-enabled then { + # name = "Pure-ftpd"; + # website = "https://www.pureftpd.org/project/pure-ftpd/"; + # license.url = "https://github.com/jedisct1/pure-ftpd/blob/master/COPYING"; + # license.name = "MIT Licence"; + # version = package.version; + # source.url = "https://github.com/jedisct1/pure-ftpd/"; + # } else if proftpd-enabled then { + # name = "ProFTPD"; + # website = "http://proftpd.org/"; + # license.url = "https://github.com/proftpd/proftpd/blob/master/COPYING"; + # license.name = "GNU General Public License v2.0"; + # version = pkgs.proftpd.version; + # source.url = "https://github.com/proftpd/proftpd/"; + # } else {}; + #}; security.acme.certs."ftp" = config.myServices.certificates.certConfig // { domain = "eldiron.immae.eu"; - postRun = '' + # FIXME: make it global + extraLegoRunFlags = ["--preferred-chain" "ISRG Root X1"]; + extraLegoRenewFlags = ["--preferred-chain" "ISRG Root X1"]; + postRun = (lib.optionalString pure-ftpd-enabled '' systemctl restart pure-ftpd.service - ''; - extraDomains = { "ftp.immae.eu" = null; }; + '') + (lib.optionalString proftpd-enabled '' + systemctl restart proftpd.service + ''); + extraDomainNames = [ "ftp.immae.eu" ]; }; networking = { firewall = { - allowedTCPPorts = [ 21 ]; + allowedTCPPorts = [ 21 115 ]; allowedTCPPortRanges = [ { from = 40000; to = 50000; } ]; }; }; @@ -43,12 +128,13 @@ in users.groups.ftp.gid = config.ids.gids.ftp; - system.activationScripts.pure-ftpd = '' + system.activationScripts.ftp = '' install -m 0755 -o ftp -g ftp -d /var/lib/ftp - ''; + '' + (lib.optionalString proftpd-enabled '' + install -m 0755 -o nobody -g nogroup -d /var/lib/proftpd/authorized_keys + ''); - secrets.keys = [{ - dest = "pure-ftpd-ldap"; + secrets.keys."pure-ftpd-ldap" = lib.mkIf pure-ftpd-enabled { permissions = "0400"; user = "ftp"; group = "ftp"; @@ -63,7 +149,7 @@ in LDAPForceDefaultUID False LDAPDefaultGID 100 LDAPForceDefaultGID False - LDAPFilter ${config.myEnv.ftp.ldap.filter} + LDAPFilter ${config.myEnv.ftp.ldap.pure-ftpd_filter} LDAPAuthMethod BIND @@ -71,16 +157,43 @@ in # Compile dans pure-ftpd directement avec immaeFtpUid / immaeFtpGid LDAPHomeDir immaeFtpDirectory ''; - }]; + }; + secrets.keys."proftpd-ldap.conf" = lib.mkIf proftpd-enabled { + permissions = "0400"; + user = "ftp"; + group = "ftp"; + text = '' + LDAPServer ldaps://${config.myEnv.ftp.ldap.host}:636/??sub + LDAPUseTLS on + LDAPAuthBinds on + LDAPBindDN "${config.myEnv.ftp.ldap.dn}" "${config.myEnv.ftp.ldap.password}" + LDAPSearchScope subtree + LDAPAuthBinds on + LDAPDefaultGID 100 + LDAPDefaultUID 500 + LDAPForceDefaultUID off + LDAPForceDefaultGID off + LDAPAttr gidNumber immaeFtpGid + LDAPAttr uidNumber immaeFtpUid + LDAPAttr homeDirectory immaeFtpDirectory + LDAPUsers "${config.myEnv.ftp.ldap.base}" "${config.myEnv.ftp.ldap.proftpd_filter}" + LDAPGroups "${config.myEnv.ftp.ldap.base}" + ''; + }; - services.filesWatcher.pure-ftpd = { + services.filesWatcher.pure-ftpd = lib.mkIf pure-ftpd-enabled { + restart = true; + paths = [ config.secrets.fullPaths."pure-ftpd-ldap" ]; + }; + services.filesWatcher.proftpd = lib.mkIf proftpd-enabled { restart = true; - paths = [ "/var/secrets/pure-ftpd-ldap" ]; + paths = [ config.secrets.fullPaths."proftpd-ldap.conf" ]; }; systemd.services.pure-ftpd = let configFile = pkgs.writeText "pure-ftpd.conf" '' PassivePortRange 40000 50000 + Bind 42 ChrootEveryone yes CreateHomeDir yes BrokenClientsCompatibility yes @@ -94,7 +207,7 @@ in SyslogFacility ftp DontResolve yes MaxIdleTime 15 - LDAPConfigFile /var/secrets/pure-ftpd-ldap + LDAPConfigFile ${config.secrets.fullPaths."pure-ftpd-ldap"} LimitRecursion 10000 8 AnonymousCanCreateDirs no MaxLoad 4 @@ -113,7 +226,7 @@ in TLS 1 CertFile ${config.security.acme.certs.ftp.directory}/full.pem ''; - in { + in lib.mkIf pure-ftpd-enabled { description = "Pure-FTPd server"; wantedBy = [ "multi-user.target" ]; after = [ "network.target" ]; @@ -122,6 +235,86 @@ in serviceConfig.Type = "forking"; serviceConfig.PIDFile = "/run/pure-ftpd.pid"; }; + + systemd.services.proftpd = let + configFile = pkgs.writeText "proftpd.conf" '' + ServerName "ProFTPD" + ServerType standalone + DefaultServer on + + Port 21 + UseIPv6 on + Umask 022 + MaxInstances 30 + MaxClients 50 + MaxClientsPerHost 8 + + # Set the user and group under which the server will run. + User ftp + Group ftp + + CreateHome on + DefaultRoot ~ + + AllowOverwrite on + + TLSEngine on + TLSRequired off + TLSProtocol TLSv1.1 TLSv1.2 TLSv1.3 + + TLSCertificateChainFile ${config.security.acme.certs.ftp.directory}/fullchain.pem + TLSECCertificateFile ${config.security.acme.certs.ftp.directory}/cert.pem + TLSECCertificateKeyFile ${config.security.acme.certs.ftp.directory}/key.pem + TLSRenegotiate none + PidFile /run/proftpd/proftpd.pid + + ScoreboardFile /run/proftpd/proftpd.scoreboard + + PassivePorts 40000 50000 + #DebugLevel 10 + Include ${config.secrets.fullPaths."proftpd-ldap.conf"} + + RequireValidShell off + + # Bar use of SITE CHMOD by default + + DenyAll + + + + Umask 022 + Port 115 + SFTPEngine on + CreateHome on + DefaultRoot ~ + + AllowOverwrite on + + SFTPHostKey /etc/ssh/ssh_host_ed25519_key + SFTPHostKey /etc/ssh/ssh_host_rsa_key + Include ${config.secrets.fullPaths."proftpd-ldap.conf"} + RequireValidShell off + SFTPAuthorizedUserKeys file:/var/lib/proftpd/authorized_keys/%u + SFTPAuthMethods password publickey + + SFTPOptions IgnoreSFTPSetOwners + AllowChrootSymlinks off + + ''; + in lib.mkIf proftpd-enabled { + description = "ProFTPD server"; + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + + serviceConfig.ExecStart = "${pkgs.proftpd}/bin/proftpd -c ${configFile}"; + serviceConfig.Type = "forking"; + serviceConfig.PIDFile = "/run/proftpd/proftpd.pid"; + serviceConfig.RuntimeDirectory = "proftpd"; + }; + + services.cron.systemCronJobs = lib.mkIf proftpd-enabled [ + "*/2 * * * * nobody ${./ftp_sync.sh}" + ]; }; }