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