]> git.immae.eu Git - perso/Immae/Config/Nix.git/blame - systems/eldiron/ftp.nix
Migrate to borg backup
[perso/Immae/Config/Nix.git] / systems / eldiron / ftp.nix
CommitLineData
ab8f306d 1{ lib, pkgs, config, ... }:
fe696f35
IB
2let
3 package = pkgs.pure-ftpd.override { ldapFtpId = "immaeFtp"; };
fcbdf67a
IB
4 pure-ftpd-enabled = config.myServices.ftp.pure-ftpd.enable;
5 proftpd-enabled = config.myServices.ftp.proftpd.enable;
fe696f35 6in
439049e5
IB
7{
8 options = {
fcbdf67a
IB
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 {
439049e5
IB
17 type = lib.types.bool;
18 default = false;
19 description = ''
20 Whether to enable pure-ftpd.
21 '';
22 };
fcbdf67a
IB
23 myServices.ftp.proftpd.enable = lib.mkOption {
24 type = lib.types.bool;
25 default = true;
26 description = ''
27 Whether to enable proftpd.
28 '';
29 };
439049e5
IB
30 };
31
fcbdf67a 32 config = lib.mkIf config.myServices.ftp.enable {
1c90c0dd
IB
33 services.borgBackup.profiles.global.ignoredPaths = [
34 "ftp/test_ftp"
35 "proftpd/authorized_keys"
36 ];
1a64deeb
IB
37 myServices.dns.zones."immae.eu".subdomains.ftp =
38 with config.myServices.dns.helpers; ips servers.eldiron.ips.main;
39
40 myServices.chatonsProperties.services.espace-de-stockage = {
41 file.datetime = "2022-08-22T01:00:00";
42 service = {
43 name = "Espace de stockage";
44 description = "Compte FTP/SFTP";
45 logo = if pure-ftpd-enabled
46 then "https://www.pureftpd.org/project/pure-ftpd/images/favicon.png"
47 else if proftpd-enabled
48 then "http://proftpd.org/proftpd.png"
49 else "";
50 website = "ftp.immae.eu";
51 status.level = "OK";
52 status.description = "OK";
53 registration."" = ["MEMBER" "CLIENT"];
54 registration.load = "OPEN";
55 install.type = "PACKAGE";
56 };
57 software = if pure-ftpd-enabled then {
58 name = "Pure-ftpd";
59 website = "https://www.pureftpd.org/project/pure-ftpd/";
60 license.url = "https://github.com/jedisct1/pure-ftpd/blob/master/COPYING";
61 license.name = "MIT Licence";
62 version = package.version;
63 source.url = "https://github.com/jedisct1/pure-ftpd/";
64 modules = "openssh";
65 } else if proftpd-enabled then {
66 name = "ProFTPD";
67 website = "http://proftpd.org/";
68 license.url = "https://github.com/proftpd/proftpd/blob/master/COPYING";
69 license.name = "GNU General Public License v2.0";
70 version = pkgs.proftpd.version;
71 source.url = "https://github.com/proftpd/proftpd/";
72 modules = "openssh";
73 } else {};
74 };
75 #myServices.chatonsProperties.services.ftp = {
76 # file.datetime = "2022-08-22T01:00:00";
77 # service = {
78 # name = "Comptes FTP";
79 # description = "Compte FTP/SFTP";
80 # logo = if pure-ftpd-enabled
81 # then "https://www.pureftpd.org/project/pure-ftpd/images/favicon.png"
82 # else if proftpd-enabled
83 # then "http://proftpd.org/proftpd.png"
84 # else "";
85 # website = "ftp.immae.eu";
86 # status.level = "OK";
87 # status.description = "OK";
88 # registration."" = ["MEMBER" "CLIENT"];
89 # registration.load = "OPEN";
90 # install.type = "PACKAGE";
91 # };
92 # software = if pure-ftpd-enabled then {
93 # name = "Pure-ftpd";
94 # website = "https://www.pureftpd.org/project/pure-ftpd/";
95 # license.url = "https://github.com/jedisct1/pure-ftpd/blob/master/COPYING";
96 # license.name = "MIT Licence";
97 # version = package.version;
98 # source.url = "https://github.com/jedisct1/pure-ftpd/";
99 # } else if proftpd-enabled then {
100 # name = "ProFTPD";
101 # website = "http://proftpd.org/";
102 # license.url = "https://github.com/proftpd/proftpd/blob/master/COPYING";
103 # license.name = "GNU General Public License v2.0";
104 # version = pkgs.proftpd.version;
105 # source.url = "https://github.com/proftpd/proftpd/";
106 # } else {};
107 #};
108 security.acme.certs."ftp" = {
439049e5 109 domain = "eldiron.immae.eu";
1a64deeb
IB
110 # FIXME: make it global
111 extraLegoRunFlags = ["--preferred-chain" "ISRG Root X1"];
112 extraLegoRenewFlags = ["--preferred-chain" "ISRG Root X1"];
fcbdf67a 113 postRun = (lib.optionalString pure-ftpd-enabled ''
740f9843 114 systemctl restart pure-ftpd.service
fcbdf67a
IB
115 '') + (lib.optionalString proftpd-enabled ''
116 systemctl restart proftpd.service
117 '');
1a64deeb 118 extraDomainNames = [ "ftp.immae.eu" ];
439049e5
IB
119 };
120
439049e5
IB
121 networking = {
122 firewall = {
fcbdf67a 123 allowedTCPPorts = [ 21 115 ];
439049e5
IB
124 allowedTCPPortRanges = [ { from = 40000; to = 50000; } ];
125 };
126 };
127
258dd18b
IB
128 users.users.ftp = {
129 uid = config.ids.uids.ftp; # 8
130 group = "ftp";
131 description = "Anonymous FTP user";
132 home = "/homeless-shelter";
133 extraGroups = [ "keys" ];
134 };
439049e5
IB
135
136 users.groups.ftp.gid = config.ids.gids.ftp;
137
fcbdf67a 138 system.activationScripts.ftp = ''
439049e5 139 install -m 0755 -o ftp -g ftp -d /var/lib/ftp
fcbdf67a
IB
140 '' + (lib.optionalString proftpd-enabled ''
141 install -m 0755 -o nobody -g nogroup -d /var/lib/proftpd/authorized_keys
142 '');
439049e5 143
fcbdf67a 144 secrets.keys."pure-ftpd-ldap" = lib.mkIf pure-ftpd-enabled {
926a4007
IB
145 permissions = "0400";
146 user = "ftp";
147 group = "ftp";
148 text = ''
ab8f306d 149 LDAPServer ${config.myEnv.ftp.ldap.host}
439049e5
IB
150 LDAPPort 389
151 LDAPUseTLS True
ab8f306d
IB
152 LDAPBaseDN ${config.myEnv.ftp.ldap.base}
153 LDAPBindDN ${config.myEnv.ftp.ldap.dn}
154 LDAPBindPW ${config.myEnv.ftp.ldap.password}
439049e5
IB
155 LDAPDefaultUID 500
156 LDAPForceDefaultUID False
157 LDAPDefaultGID 100
158 LDAPForceDefaultGID False
fcbdf67a 159 LDAPFilter ${config.myEnv.ftp.ldap.pure-ftpd_filter}
439049e5
IB
160
161 LDAPAuthMethod BIND
162
926a4007
IB
163 # Pas de possibilite de donner l'Uid/Gid !
164 # Compile dans pure-ftpd directement avec immaeFtpUid / immaeFtpGid
439049e5
IB
165 LDAPHomeDir immaeFtpDirectory
166 '';
4c4652aa 167 };
fcbdf67a
IB
168 secrets.keys."proftpd-ldap.conf" = lib.mkIf proftpd-enabled {
169 permissions = "0400";
170 user = "ftp";
171 group = "ftp";
172 text = ''
173 LDAPServer ldaps://${config.myEnv.ftp.ldap.host}:636/??sub
174 LDAPUseTLS on
175 LDAPAuthBinds on
176 LDAPBindDN "${config.myEnv.ftp.ldap.dn}" "${config.myEnv.ftp.ldap.password}"
177 LDAPSearchScope subtree
178 LDAPAuthBinds on
179 LDAPDefaultGID 100
180 LDAPDefaultUID 500
181 LDAPForceDefaultUID off
182 LDAPForceDefaultGID off
183 LDAPAttr gidNumber immaeFtpGid
184 LDAPAttr uidNumber immaeFtpUid
185 LDAPAttr homeDirectory immaeFtpDirectory
186 LDAPUsers "${config.myEnv.ftp.ldap.base}" "${config.myEnv.ftp.ldap.proftpd_filter}"
187 LDAPGroups "${config.myEnv.ftp.ldap.base}"
188 '';
189 };
926a4007 190
fcbdf67a 191 services.filesWatcher.pure-ftpd = lib.mkIf pure-ftpd-enabled {
17f6eae9 192 restart = true;
da30ae4f 193 paths = [ config.secrets.fullPaths."pure-ftpd-ldap" ];
17f6eae9 194 };
fcbdf67a
IB
195 services.filesWatcher.proftpd = lib.mkIf proftpd-enabled {
196 restart = true;
197 paths = [ config.secrets.fullPaths."proftpd-ldap.conf" ];
198 };
17f6eae9 199
926a4007 200 systemd.services.pure-ftpd = let
439049e5
IB
201 configFile = pkgs.writeText "pure-ftpd.conf" ''
202 PassivePortRange 40000 50000
fcbdf67a 203 Bind 42
439049e5
IB
204 ChrootEveryone yes
205 CreateHomeDir yes
206 BrokenClientsCompatibility yes
207 MaxClientsNumber 50
208 Daemonize yes
209 MaxClientsPerIP 8
210 VerboseLog no
211 DisplayDotFiles yes
212 AnonymousOnly no
213 NoAnonymous no
214 SyslogFacility ftp
215 DontResolve yes
216 MaxIdleTime 15
da30ae4f 217 LDAPConfigFile ${config.secrets.fullPaths."pure-ftpd-ldap"}
439049e5
IB
218 LimitRecursion 10000 8
219 AnonymousCanCreateDirs no
220 MaxLoad 4
221 AntiWarez yes
222 Umask 133:022
223 # ftp
224 MinUID 8
225 AllowUserFXP no
226 AllowAnonymousFXP no
227 ProhibitDotFilesWrite no
228 ProhibitDotFilesRead no
229 AutoRename no
230 AnonymousCantUpload no
231 MaxDiskUsage 99
232 CustomerProof yes
233 TLS 1
5400b9b6 234 CertFile ${config.security.acme.certs.ftp.directory}/full.pem
439049e5 235 '';
fcbdf67a 236 in lib.mkIf pure-ftpd-enabled {
439049e5
IB
237 description = "Pure-FTPd server";
238 wantedBy = [ "multi-user.target" ];
239 after = [ "network.target" ];
240
fe696f35 241 serviceConfig.ExecStart = "${package}/bin/pure-ftpd ${configFile}";
439049e5
IB
242 serviceConfig.Type = "forking";
243 serviceConfig.PIDFile = "/run/pure-ftpd.pid";
244 };
fcbdf67a
IB
245
246 systemd.services.proftpd = let
247 configFile = pkgs.writeText "proftpd.conf" ''
248 ServerName "ProFTPD"
249 ServerType standalone
250 DefaultServer on
251
252 Port 21
253 UseIPv6 on
254 Umask 022
255 MaxInstances 30
256 MaxClients 50
257 MaxClientsPerHost 8
258
259 # Set the user and group under which the server will run.
260 User ftp
261 Group ftp
262
263 CreateHome on
264 DefaultRoot ~
265
266 AllowOverwrite on
267
268 TLSEngine on
269 TLSRequired off
270 TLSProtocol TLSv1.1 TLSv1.2 TLSv1.3
271
272 TLSCertificateChainFile ${config.security.acme.certs.ftp.directory}/fullchain.pem
273 TLSECCertificateFile ${config.security.acme.certs.ftp.directory}/cert.pem
274 TLSECCertificateKeyFile ${config.security.acme.certs.ftp.directory}/key.pem
275 TLSRenegotiate none
276 PidFile /run/proftpd/proftpd.pid
277
278 ScoreboardFile /run/proftpd/proftpd.scoreboard
279
280 PassivePorts 40000 50000
281 #DebugLevel 10
282 Include ${config.secrets.fullPaths."proftpd-ldap.conf"}
283
284 RequireValidShell off
285
286 # Bar use of SITE CHMOD by default
287 <Limit SITE_CHMOD>
288 DenyAll
289 </Limit>
290
291 <VirtualHost 0.0.0.0>
292 Umask 022
293 Port 115
294 SFTPEngine on
295 CreateHome on
296 DefaultRoot ~
297
298 AllowOverwrite on
299
300 SFTPHostKey /etc/ssh/ssh_host_ed25519_key
301 SFTPHostKey /etc/ssh/ssh_host_rsa_key
302 Include ${config.secrets.fullPaths."proftpd-ldap.conf"}
303 RequireValidShell off
304 SFTPAuthorizedUserKeys file:/var/lib/proftpd/authorized_keys/%u
305 SFTPAuthMethods password publickey
87e1ff0f
IB
306
307 SFTPOptions IgnoreSFTPSetOwners
1a64deeb 308 AllowChrootSymlinks off
fcbdf67a
IB
309 </VirtualHost>
310 '';
311 in lib.mkIf proftpd-enabled {
312 description = "ProFTPD server";
313 wantedBy = [ "multi-user.target" ];
314 after = [ "network.target" ];
315
316 serviceConfig.ExecStart = "${pkgs.proftpd}/bin/proftpd -c ${configFile}";
317 serviceConfig.Type = "forking";
318 serviceConfig.PIDFile = "/run/proftpd/proftpd.pid";
319 serviceConfig.RuntimeDirectory = "proftpd";
320 };
321
322 services.cron.systemCronJobs = lib.mkIf proftpd-enabled [
323 "*/2 * * * * nobody ${./ftp_sync.sh}"
324 ];
1a64deeb
IB
325
326 myServices.monitoring.fromMasterActivatedPlugins = [ "ftp" ];
327 myServices.monitoring.fromMasterObjects.service = [
328 {
329 service_description = "ftp has access to database for authentication";
330 host_name = config.hostEnv.fqdn;
331 use = "external-service";
332 check_command = "check_ftp_database";
333
334 servicegroups = "webstatus-remote-services";
335 _webstatus_name = "FTP";
336 _webstatus_url = "ftp.immae.eu";
337 }
338
339 ];
340
439049e5
IB
341 };
342
343}