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