aboutsummaryrefslogblamecommitdiff
path: root/modules/private/ftp.nix
blob: cae25c1dc5fdc2828efa59701213e15ffcba4f3f (plain) (tree)
1
2
3
4
5
6
7
8
                           

                                                                

                                                             
  

             







                                                    





                                    






                                                  

    
                                                  
                                                                              
                                  
                                                        
                                           


                                                  
                                                

      

                  
                                     



                                                                 






                                         


                                               
                                     
                                                   


                                                                              
 
                                                                



                           
                                                         

                                


                                                             



                                 
                                                                     


                                

                                                                           

                                             
      





















                                                                                                     
 
                                                                  
                     
                                                            
      



                                                               
 
                                    

                                                     
                                       












                                        
                                                                                 















                                            
                                                                                         
           
                                   



                                         
                                                                         


                                                   




























































                                                                                         

                                                           















                                                                               


    
{ 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}"
    ];
  };

}