diff options
Diffstat (limited to 'modules/private/ftp.nix')
-rw-r--r-- | modules/private/ftp.nix | 146 |
1 files changed, 135 insertions, 11 deletions
diff --git a/modules/private/ftp.nix b/modules/private/ftp.nix index 1428198..111d6bc 100644 --- a/modules/private/ftp.nix +++ b/modules/private/ftp.nix | |||
@@ -1,34 +1,52 @@ | |||
1 | { lib, pkgs, config, ... }: | 1 | { lib, pkgs, config, ... }: |
2 | let | 2 | let |
3 | package = pkgs.pure-ftpd.override { ldapFtpId = "immaeFtp"; }; | 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; | ||
4 | in | 6 | in |
5 | { | 7 | { |
6 | options = { | 8 | options = { |
7 | services.pure-ftpd.enable = lib.mkOption { | 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 { | ||
8 | type = lib.types.bool; | 17 | type = lib.types.bool; |
9 | default = false; | 18 | default = false; |
10 | description = '' | 19 | description = '' |
11 | Whether to enable pure-ftpd. | 20 | Whether to enable pure-ftpd. |
12 | ''; | 21 | ''; |
13 | }; | 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 | }; | ||
14 | }; | 30 | }; |
15 | 31 | ||
16 | config = lib.mkIf config.services.pure-ftpd.enable { | 32 | config = lib.mkIf config.myServices.ftp.enable { |
17 | services.duplyBackup.profiles.ftp = { | 33 | services.duplyBackup.profiles.ftp = { |
18 | rootDir = "/var/lib/ftp"; | 34 | rootDir = "/var/lib/ftp"; |
19 | remotes = [ "eriomem" "ovh" ]; | 35 | remotes = [ "eriomem" "ovh" ]; |
20 | }; | 36 | }; |
21 | security.acme.certs."ftp" = config.myServices.certificates.certConfig // { | 37 | security.acme.certs."ftp" = config.myServices.certificates.certConfig // { |
22 | domain = "eldiron.immae.eu"; | 38 | domain = "eldiron.immae.eu"; |
23 | postRun = '' | 39 | postRun = (lib.optionalString pure-ftpd-enabled '' |
24 | systemctl restart pure-ftpd.service | 40 | systemctl restart pure-ftpd.service |
25 | ''; | 41 | '') + (lib.optionalString proftpd-enabled '' |
42 | systemctl restart proftpd.service | ||
43 | ''); | ||
26 | extraDomains = { "ftp.immae.eu" = null; }; | 44 | extraDomains = { "ftp.immae.eu" = null; }; |
27 | }; | 45 | }; |
28 | 46 | ||
29 | networking = { | 47 | networking = { |
30 | firewall = { | 48 | firewall = { |
31 | allowedTCPPorts = [ 21 ]; | 49 | allowedTCPPorts = [ 21 115 ]; |
32 | allowedTCPPortRanges = [ { from = 40000; to = 50000; } ]; | 50 | allowedTCPPortRanges = [ { from = 40000; to = 50000; } ]; |
33 | }; | 51 | }; |
34 | }; | 52 | }; |
@@ -43,11 +61,13 @@ in | |||
43 | 61 | ||
44 | users.groups.ftp.gid = config.ids.gids.ftp; | 62 | users.groups.ftp.gid = config.ids.gids.ftp; |
45 | 63 | ||
46 | system.activationScripts.pure-ftpd = '' | 64 | system.activationScripts.ftp = '' |
47 | install -m 0755 -o ftp -g ftp -d /var/lib/ftp | 65 | install -m 0755 -o ftp -g ftp -d /var/lib/ftp |
48 | ''; | 66 | '' + (lib.optionalString proftpd-enabled '' |
67 | install -m 0755 -o nobody -g nogroup -d /var/lib/proftpd/authorized_keys | ||
68 | ''); | ||
49 | 69 | ||
50 | secrets.keys."pure-ftpd-ldap" = { | 70 | secrets.keys."pure-ftpd-ldap" = lib.mkIf pure-ftpd-enabled { |
51 | permissions = "0400"; | 71 | permissions = "0400"; |
52 | user = "ftp"; | 72 | user = "ftp"; |
53 | group = "ftp"; | 73 | group = "ftp"; |
@@ -62,7 +82,7 @@ in | |||
62 | LDAPForceDefaultUID False | 82 | LDAPForceDefaultUID False |
63 | LDAPDefaultGID 100 | 83 | LDAPDefaultGID 100 |
64 | LDAPForceDefaultGID False | 84 | LDAPForceDefaultGID False |
65 | LDAPFilter ${config.myEnv.ftp.ldap.filter} | 85 | LDAPFilter ${config.myEnv.ftp.ldap.pure-ftpd_filter} |
66 | 86 | ||
67 | LDAPAuthMethod BIND | 87 | LDAPAuthMethod BIND |
68 | 88 | ||
@@ -71,15 +91,42 @@ in | |||
71 | LDAPHomeDir immaeFtpDirectory | 91 | LDAPHomeDir immaeFtpDirectory |
72 | ''; | 92 | ''; |
73 | }; | 93 | }; |
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 | }; | ||
74 | 116 | ||
75 | services.filesWatcher.pure-ftpd = { | 117 | services.filesWatcher.pure-ftpd = lib.mkIf pure-ftpd-enabled { |
76 | restart = true; | 118 | restart = true; |
77 | paths = [ config.secrets.fullPaths."pure-ftpd-ldap" ]; | 119 | paths = [ config.secrets.fullPaths."pure-ftpd-ldap" ]; |
78 | }; | 120 | }; |
121 | services.filesWatcher.proftpd = lib.mkIf proftpd-enabled { | ||
122 | restart = true; | ||
123 | paths = [ config.secrets.fullPaths."proftpd-ldap.conf" ]; | ||
124 | }; | ||
79 | 125 | ||
80 | systemd.services.pure-ftpd = let | 126 | systemd.services.pure-ftpd = let |
81 | configFile = pkgs.writeText "pure-ftpd.conf" '' | 127 | configFile = pkgs.writeText "pure-ftpd.conf" '' |
82 | PassivePortRange 40000 50000 | 128 | PassivePortRange 40000 50000 |
129 | Bind 42 | ||
83 | ChrootEveryone yes | 130 | ChrootEveryone yes |
84 | CreateHomeDir yes | 131 | CreateHomeDir yes |
85 | BrokenClientsCompatibility yes | 132 | BrokenClientsCompatibility yes |
@@ -112,7 +159,7 @@ in | |||
112 | TLS 1 | 159 | TLS 1 |
113 | CertFile ${config.security.acme.certs.ftp.directory}/full.pem | 160 | CertFile ${config.security.acme.certs.ftp.directory}/full.pem |
114 | ''; | 161 | ''; |
115 | in { | 162 | in lib.mkIf pure-ftpd-enabled { |
116 | description = "Pure-FTPd server"; | 163 | description = "Pure-FTPd server"; |
117 | wantedBy = [ "multi-user.target" ]; | 164 | wantedBy = [ "multi-user.target" ]; |
118 | after = [ "network.target" ]; | 165 | after = [ "network.target" ]; |
@@ -121,6 +168,83 @@ in | |||
121 | serviceConfig.Type = "forking"; | 168 | serviceConfig.Type = "forking"; |
122 | serviceConfig.PIDFile = "/run/pure-ftpd.pid"; | 169 | serviceConfig.PIDFile = "/run/pure-ftpd.pid"; |
123 | }; | 170 | }; |
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 | ]; | ||
124 | }; | 248 | }; |
125 | 249 | ||
126 | } | 250 | } |