aboutsummaryrefslogtreecommitdiff
path: root/modules/private/ftp.nix
blob: 8ae4e650bb41facba3047842f05c8a68382ffc32 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
{ lib, pkgs, config, ... }:
let
  package = pkgs.pure-ftpd.override { ldapFtpId = "immaeFtp"; };
in
{
  options = {
    services.pure-ftpd.enable = lib.mkOption {
      type = lib.types.bool;
      default = false;
      description = ''
        Whether to enable pure-ftpd.
      '';
    };
  };

  config = lib.mkIf config.services.pure-ftpd.enable {
    services.duplyBackup.profiles.ftp = {
      rootDir = "/var/lib/ftp";
    };
    security.acme.certs."ftp" = config.myServices.certificates.certConfig // {
      domain = "eldiron.immae.eu";
      postRun = ''
        systemctl restart pure-ftpd.service
      '';
      extraDomains = { "ftp.immae.eu" = null; };
    };

    networking = {
      firewall = {
        allowedTCPPorts = [ 21 ];
        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.pure-ftpd = ''
      install -m 0755 -o ftp -g ftp -d /var/lib/ftp
      '';

    secrets.keys = [{
      dest = "pure-ftpd-ldap";
      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.filter}

        LDAPAuthMethod      BIND

        # Pas de possibilite de donner l'Uid/Gid !
        # Compile dans pure-ftpd directement avec immaeFtpUid / immaeFtpGid
        LDAPHomeDir         immaeFtpDirectory
        '';
    }];

    services.filesWatcher.pure-ftpd = {
      restart = true;
      paths = [ "/var/secrets/pure-ftpd-ldap" ];
    };

    systemd.services.pure-ftpd = let
      configFile = pkgs.writeText "pure-ftpd.conf" ''
        PassivePortRange             40000 50000
        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               /var/secrets/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 {
      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";
    };
  };

}