]> git.immae.eu Git - perso/Immae/Config/Nix.git/blame - modules/private/ftp.nix
Move notification systems to apprise
[perso/Immae/Config/Nix.git] / modules / private / 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 {
5400b9b6 33 security.acme.certs."ftp" = config.myServices.certificates.certConfig // {
439049e5 34 domain = "eldiron.immae.eu";
e34b3079
IB
35 # FIXME: make it global
36 extraLegoRunFlags = ["--preferred-chain" "ISRG Root X1"];
37 extraLegoRenewFlags = ["--preferred-chain" "ISRG Root X1"];
fcbdf67a 38 postRun = (lib.optionalString pure-ftpd-enabled ''
740f9843 39 systemctl restart pure-ftpd.service
fcbdf67a
IB
40 '') + (lib.optionalString proftpd-enabled ''
41 systemctl restart proftpd.service
42 '');
e34b3079 43 extraDomainNames = [ "ftp.immae.eu" ];
439049e5
IB
44 };
45
439049e5
IB
46 networking = {
47 firewall = {
fcbdf67a 48 allowedTCPPorts = [ 21 115 ];
439049e5
IB
49 allowedTCPPortRanges = [ { from = 40000; to = 50000; } ];
50 };
51 };
52
258dd18b
IB
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 };
439049e5
IB
60
61 users.groups.ftp.gid = config.ids.gids.ftp;
62
fcbdf67a 63 system.activationScripts.ftp = ''
439049e5 64 install -m 0755 -o ftp -g ftp -d /var/lib/ftp
fcbdf67a
IB
65 '' + (lib.optionalString proftpd-enabled ''
66 install -m 0755 -o nobody -g nogroup -d /var/lib/proftpd/authorized_keys
67 '');
439049e5 68
fcbdf67a 69 secrets.keys."pure-ftpd-ldap" = lib.mkIf pure-ftpd-enabled {
926a4007
IB
70 permissions = "0400";
71 user = "ftp";
72 group = "ftp";
73 text = ''
ab8f306d 74 LDAPServer ${config.myEnv.ftp.ldap.host}
439049e5
IB
75 LDAPPort 389
76 LDAPUseTLS True
ab8f306d
IB
77 LDAPBaseDN ${config.myEnv.ftp.ldap.base}
78 LDAPBindDN ${config.myEnv.ftp.ldap.dn}
79 LDAPBindPW ${config.myEnv.ftp.ldap.password}
439049e5
IB
80 LDAPDefaultUID 500
81 LDAPForceDefaultUID False
82 LDAPDefaultGID 100
83 LDAPForceDefaultGID False
fcbdf67a 84 LDAPFilter ${config.myEnv.ftp.ldap.pure-ftpd_filter}
439049e5
IB
85
86 LDAPAuthMethod BIND
87
926a4007
IB
88 # Pas de possibilite de donner l'Uid/Gid !
89 # Compile dans pure-ftpd directement avec immaeFtpUid / immaeFtpGid
439049e5
IB
90 LDAPHomeDir immaeFtpDirectory
91 '';
4c4652aa 92 };
fcbdf67a
IB
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 };
926a4007 115
fcbdf67a 116 services.filesWatcher.pure-ftpd = lib.mkIf pure-ftpd-enabled {
17f6eae9 117 restart = true;
da30ae4f 118 paths = [ config.secrets.fullPaths."pure-ftpd-ldap" ];
17f6eae9 119 };
fcbdf67a
IB
120 services.filesWatcher.proftpd = lib.mkIf proftpd-enabled {
121 restart = true;
122 paths = [ config.secrets.fullPaths."proftpd-ldap.conf" ];
123 };
17f6eae9 124
926a4007 125 systemd.services.pure-ftpd = let
439049e5
IB
126 configFile = pkgs.writeText "pure-ftpd.conf" ''
127 PassivePortRange 40000 50000
fcbdf67a 128 Bind 42
439049e5
IB
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
da30ae4f 142 LDAPConfigFile ${config.secrets.fullPaths."pure-ftpd-ldap"}
439049e5
IB
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
5400b9b6 159 CertFile ${config.security.acme.certs.ftp.directory}/full.pem
439049e5 160 '';
fcbdf67a 161 in lib.mkIf pure-ftpd-enabled {
439049e5
IB
162 description = "Pure-FTPd server";
163 wantedBy = [ "multi-user.target" ];
164 after = [ "network.target" ];
165
fe696f35 166 serviceConfig.ExecStart = "${package}/bin/pure-ftpd ${configFile}";
439049e5
IB
167 serviceConfig.Type = "forking";
168 serviceConfig.PIDFile = "/run/pure-ftpd.pid";
169 };
fcbdf67a
IB
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
87e1ff0f
IB
231
232 SFTPOptions IgnoreSFTPSetOwners
343e326e 233 AllowChrootSymlinks off
fcbdf67a
IB
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 ];
439049e5
IB
250 };
251
252}