+++ /dev/null
-{ 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 = {
- 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.myServices.ftp.enable {
- security.acme.certs."ftp" = config.myServices.certificates.certConfig // {
- domain = "eldiron.immae.eu";
- postRun = (lib.optionalString pure-ftpd-enabled ''
- systemctl restart pure-ftpd.service
- '') + (lib.optionalString proftpd-enabled ''
- systemctl restart proftpd.service
- '');
- extraDomains = { "ftp.immae.eu" = null; };
- };
-
- networking = {
- firewall = {
- allowedTCPPorts = [ 21 115 ];
- allowedTCPPortRanges = [ { from = 40000; to = 50000; } ];
- };
- };
-
- users.users.ftp = {
- uid = config.ids.uids.ftp; # 8
- group = "ftp";
- description = "Anonymous FTP user";
- home = "/homeless-shelter";
- extraGroups = [ "keys" ];
- };
-
- users.groups.ftp.gid = config.ids.gids.ftp;
-
- 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."pure-ftpd-ldap" = lib.mkIf pure-ftpd-enabled {
- permissions = "0400";
- user = "ftp";
- group = "ftp";
- text = ''
- LDAPServer ${config.myEnv.ftp.ldap.host}
- LDAPPort 389
- LDAPUseTLS True
- LDAPBaseDN ${config.myEnv.ftp.ldap.base}
- LDAPBindDN ${config.myEnv.ftp.ldap.dn}
- LDAPBindPW ${config.myEnv.ftp.ldap.password}
- LDAPDefaultUID 500
- LDAPForceDefaultUID False
- LDAPDefaultGID 100
- LDAPForceDefaultGID False
- LDAPFilter ${config.myEnv.ftp.ldap.pure-ftpd_filter}
-
- LDAPAuthMethod BIND
-
- # Pas de possibilite de donner l'Uid/Gid !
- # 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 = lib.mkIf pure-ftpd-enabled {
- restart = true;
- paths = [ config.secrets.fullPaths."pure-ftpd-ldap" ];
- };
- services.filesWatcher.proftpd = lib.mkIf proftpd-enabled {
- restart = true;
- 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
- MaxClientsNumber 50
- Daemonize yes
- MaxClientsPerIP 8
- VerboseLog no
- DisplayDotFiles yes
- AnonymousOnly no
- NoAnonymous no
- SyslogFacility ftp
- DontResolve yes
- MaxIdleTime 15
- LDAPConfigFile ${config.secrets.fullPaths."pure-ftpd-ldap"}
- LimitRecursion 10000 8
- AnonymousCanCreateDirs no
- MaxLoad 4
- AntiWarez yes
- Umask 133:022
- # ftp
- MinUID 8
- AllowUserFXP no
- AllowAnonymousFXP no
- ProhibitDotFilesWrite no
- ProhibitDotFilesRead no
- AutoRename no
- AnonymousCantUpload no
- MaxDiskUsage 99
- CustomerProof yes
- TLS 1
- CertFile ${config.security.acme.certs.ftp.directory}/full.pem
- '';
- in lib.mkIf pure-ftpd-enabled {
- description = "Pure-FTPd server";
- wantedBy = [ "multi-user.target" ];
- after = [ "network.target" ];
-
- serviceConfig.ExecStart = "${package}/bin/pure-ftpd ${configFile}";
- 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
- <Limit SITE_CHMOD>
- DenyAll
- </Limit>
-
- <VirtualHost 0.0.0.0>
- 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
- </VirtualHost>
- '';
- 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}"
- ];
- };
-
-}