]> git.immae.eu Git - perso/Immae/Config/Nix.git/blob - modules/private/ftp.nix
Migrate to proftpd
[perso/Immae/Config/Nix.git] / modules / private / ftp.nix
1 { lib, pkgs, config, ... }:
2 let
3 package = pkgs.pure-ftpd.override { ldapFtpId = "immaeFtp"; };
4 pure-ftpd-enabled = config.myServices.ftp.pure-ftpd.enable;
5 proftpd-enabled = config.myServices.ftp.proftpd.enable;
6 in
7 {
8 options = {
9 myServices.ftp.enable = lib.mkOption {
10 type = lib.types.bool;
11 default = false;
12 description = ''
13 Whether to enable ftp.
14 '';
15 };
16 myServices.ftp.pure-ftpd.enable = lib.mkOption {
17 type = lib.types.bool;
18 default = false;
19 description = ''
20 Whether to enable pure-ftpd.
21 '';
22 };
23 myServices.ftp.proftpd.enable = lib.mkOption {
24 type = lib.types.bool;
25 default = true;
26 description = ''
27 Whether to enable proftpd.
28 '';
29 };
30 };
31
32 config = lib.mkIf config.myServices.ftp.enable {
33 services.duplyBackup.profiles.ftp = {
34 rootDir = "/var/lib/ftp";
35 remotes = [ "eriomem" "ovh" ];
36 };
37 security.acme.certs."ftp" = config.myServices.certificates.certConfig // {
38 domain = "eldiron.immae.eu";
39 postRun = (lib.optionalString pure-ftpd-enabled ''
40 systemctl restart pure-ftpd.service
41 '') + (lib.optionalString proftpd-enabled ''
42 systemctl restart proftpd.service
43 '');
44 extraDomains = { "ftp.immae.eu" = null; };
45 };
46
47 networking = {
48 firewall = {
49 allowedTCPPorts = [ 21 115 ];
50 allowedTCPPortRanges = [ { from = 40000; to = 50000; } ];
51 };
52 };
53
54 users.users.ftp = {
55 uid = config.ids.uids.ftp; # 8
56 group = "ftp";
57 description = "Anonymous FTP user";
58 home = "/homeless-shelter";
59 extraGroups = [ "keys" ];
60 };
61
62 users.groups.ftp.gid = config.ids.gids.ftp;
63
64 system.activationScripts.ftp = ''
65 install -m 0755 -o ftp -g ftp -d /var/lib/ftp
66 '' + (lib.optionalString proftpd-enabled ''
67 install -m 0755 -o nobody -g nogroup -d /var/lib/proftpd/authorized_keys
68 '');
69
70 secrets.keys."pure-ftpd-ldap" = lib.mkIf pure-ftpd-enabled {
71 permissions = "0400";
72 user = "ftp";
73 group = "ftp";
74 text = ''
75 LDAPServer ${config.myEnv.ftp.ldap.host}
76 LDAPPort 389
77 LDAPUseTLS True
78 LDAPBaseDN ${config.myEnv.ftp.ldap.base}
79 LDAPBindDN ${config.myEnv.ftp.ldap.dn}
80 LDAPBindPW ${config.myEnv.ftp.ldap.password}
81 LDAPDefaultUID 500
82 LDAPForceDefaultUID False
83 LDAPDefaultGID 100
84 LDAPForceDefaultGID False
85 LDAPFilter ${config.myEnv.ftp.ldap.pure-ftpd_filter}
86
87 LDAPAuthMethod BIND
88
89 # Pas de possibilite de donner l'Uid/Gid !
90 # Compile dans pure-ftpd directement avec immaeFtpUid / immaeFtpGid
91 LDAPHomeDir immaeFtpDirectory
92 '';
93 };
94 secrets.keys."proftpd-ldap.conf" = lib.mkIf proftpd-enabled {
95 permissions = "0400";
96 user = "ftp";
97 group = "ftp";
98 text = ''
99 LDAPServer ldaps://${config.myEnv.ftp.ldap.host}:636/??sub
100 LDAPUseTLS on
101 LDAPAuthBinds on
102 LDAPBindDN "${config.myEnv.ftp.ldap.dn}" "${config.myEnv.ftp.ldap.password}"
103 LDAPSearchScope subtree
104 LDAPAuthBinds on
105 LDAPDefaultGID 100
106 LDAPDefaultUID 500
107 LDAPForceDefaultUID off
108 LDAPForceDefaultGID off
109 LDAPAttr gidNumber immaeFtpGid
110 LDAPAttr uidNumber immaeFtpUid
111 LDAPAttr homeDirectory immaeFtpDirectory
112 LDAPUsers "${config.myEnv.ftp.ldap.base}" "${config.myEnv.ftp.ldap.proftpd_filter}"
113 LDAPGroups "${config.myEnv.ftp.ldap.base}"
114 '';
115 };
116
117 services.filesWatcher.pure-ftpd = lib.mkIf pure-ftpd-enabled {
118 restart = true;
119 paths = [ config.secrets.fullPaths."pure-ftpd-ldap" ];
120 };
121 services.filesWatcher.proftpd = lib.mkIf proftpd-enabled {
122 restart = true;
123 paths = [ config.secrets.fullPaths."proftpd-ldap.conf" ];
124 };
125
126 systemd.services.pure-ftpd = let
127 configFile = pkgs.writeText "pure-ftpd.conf" ''
128 PassivePortRange 40000 50000
129 Bind 42
130 ChrootEveryone yes
131 CreateHomeDir yes
132 BrokenClientsCompatibility yes
133 MaxClientsNumber 50
134 Daemonize yes
135 MaxClientsPerIP 8
136 VerboseLog no
137 DisplayDotFiles yes
138 AnonymousOnly no
139 NoAnonymous no
140 SyslogFacility ftp
141 DontResolve yes
142 MaxIdleTime 15
143 LDAPConfigFile ${config.secrets.fullPaths."pure-ftpd-ldap"}
144 LimitRecursion 10000 8
145 AnonymousCanCreateDirs no
146 MaxLoad 4
147 AntiWarez yes
148 Umask 133:022
149 # ftp
150 MinUID 8
151 AllowUserFXP no
152 AllowAnonymousFXP no
153 ProhibitDotFilesWrite no
154 ProhibitDotFilesRead no
155 AutoRename no
156 AnonymousCantUpload no
157 MaxDiskUsage 99
158 CustomerProof yes
159 TLS 1
160 CertFile ${config.security.acme.certs.ftp.directory}/full.pem
161 '';
162 in lib.mkIf pure-ftpd-enabled {
163 description = "Pure-FTPd server";
164 wantedBy = [ "multi-user.target" ];
165 after = [ "network.target" ];
166
167 serviceConfig.ExecStart = "${package}/bin/pure-ftpd ${configFile}";
168 serviceConfig.Type = "forking";
169 serviceConfig.PIDFile = "/run/pure-ftpd.pid";
170 };
171
172 systemd.services.proftpd = let
173 configFile = pkgs.writeText "proftpd.conf" ''
174 ServerName "ProFTPD"
175 ServerType standalone
176 DefaultServer on
177
178 Port 21
179 UseIPv6 on
180 Umask 022
181 MaxInstances 30
182 MaxClients 50
183 MaxClientsPerHost 8
184
185 # Set the user and group under which the server will run.
186 User ftp
187 Group ftp
188
189 CreateHome on
190 DefaultRoot ~
191
192 AllowOverwrite on
193
194 TLSEngine on
195 TLSRequired off
196 TLSProtocol TLSv1.1 TLSv1.2 TLSv1.3
197
198 TLSCertificateChainFile ${config.security.acme.certs.ftp.directory}/fullchain.pem
199 TLSECCertificateFile ${config.security.acme.certs.ftp.directory}/cert.pem
200 TLSECCertificateKeyFile ${config.security.acme.certs.ftp.directory}/key.pem
201 TLSRenegotiate none
202 PidFile /run/proftpd/proftpd.pid
203
204 ScoreboardFile /run/proftpd/proftpd.scoreboard
205
206 PassivePorts 40000 50000
207 #DebugLevel 10
208 Include ${config.secrets.fullPaths."proftpd-ldap.conf"}
209
210 RequireValidShell off
211
212 # Bar use of SITE CHMOD by default
213 <Limit SITE_CHMOD>
214 DenyAll
215 </Limit>
216
217 <VirtualHost 0.0.0.0>
218 Umask 022
219 Port 115
220 SFTPEngine on
221 CreateHome on
222 DefaultRoot ~
223
224 AllowOverwrite on
225
226 SFTPHostKey /etc/ssh/ssh_host_ed25519_key
227 SFTPHostKey /etc/ssh/ssh_host_rsa_key
228 Include ${config.secrets.fullPaths."proftpd-ldap.conf"}
229 RequireValidShell off
230 SFTPAuthorizedUserKeys file:/var/lib/proftpd/authorized_keys/%u
231 SFTPAuthMethods password publickey
232 </VirtualHost>
233 '';
234 in lib.mkIf proftpd-enabled {
235 description = "ProFTPD server";
236 wantedBy = [ "multi-user.target" ];
237 after = [ "network.target" ];
238
239 serviceConfig.ExecStart = "${pkgs.proftpd}/bin/proftpd -c ${configFile}";
240 serviceConfig.Type = "forking";
241 serviceConfig.PIDFile = "/run/proftpd/proftpd.pid";
242 serviceConfig.RuntimeDirectory = "proftpd";
243 };
244
245 services.cron.systemCronJobs = lib.mkIf proftpd-enabled [
246 "*/2 * * * * nobody ${./ftp_sync.sh}"
247 ];
248 };
249
250 }