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