--- /dev/null
+{ lib, pkgs, config, myconfig, ... }:
+{
+ options = {
+ services.pure-ftpd.enable = lib.mkOption {
+ type = lib.types.bool;
+ default = false;
+ description = ''
+ Whether to enable pure-ftpd.
+ '';
+ };
+ };
+
+ config = lib.mkIf config.services.pure-ftpd.enable {
+ security.acme.certs."ftp" = config.services.myCertificates.certConfig // {
+ domain = "eldiron.immae.eu";
+ };
+
+ nixpkgs.config.packageOverrides = oldpkgs: rec {
+ pure-ftpd = pkgs.callPackage ./pure-ftpd.nix {};
+ };
+
+ networking = {
+ firewall = {
+ allowedTCPPorts = [ 21 ];
+ allowedTCPPortRanges = [ { from = 40000; to = 50000; } ];
+ };
+ };
+
+ users.users = [
+ {
+ name = "ftp";
+ uid = config.ids.uids.ftp;
+ group = "ftp";
+ description = "Anonymous FTP user";
+ home = "/homeless-shelter";
+ }
+ ];
+
+ users.groups.ftp.gid = config.ids.gids.ftp;
+
+ system.activationScripts.pure-ftpd = ''
+ install -m 0755 -o ftp -g ftp -d /var/lib/ftp
+ '';
+
+ systemd.services.pure-ftpd = let
+ ldapConfigFile = pkgs.writeText "pure-ftpd-ldap.conf" ''
+ LDAPServer ${myconfig.env.ftp.ldap.host}
+ LDAPPort 389
+ LDAPUseTLS True
+ LDAPBaseDN ${myconfig.env.ftp.ldap.base}
+ LDAPBindDN ${myconfig.env.ftp.ldap.dn}
+ LDAPBindPW ${myconfig.env.ftp.ldap.password}
+ LDAPDefaultUID 500
+ LDAPForceDefaultUID False
+ LDAPDefaultGID 100
+ LDAPForceDefaultGID False
+ LDAPFilter ${myconfig.env.ftp.ldap.filter}
+
+ LDAPAuthMethod BIND
+
+ # Pas de possibilité de donner l'Uid/Gid !
+ # Compilé dans pure-ftpd directement avec immaeFtpUid / immaeFtpGid
+ LDAPHomeDir immaeFtpDirectory
+ '';
+ configFile = pkgs.writeText "pure-ftpd.conf" ''
+ PassivePortRange 40000 50000
+ ChrootEveryone yes
+ CreateHomeDir yes
+ BrokenClientsCompatibility yes
+ MaxClientsNumber 50
+ Daemonize yes
+ MaxClientsPerIP 8
+ VerboseLog no
+ DisplayDotFiles yes
+ AnonymousOnly no
+ NoAnonymous no
+ SyslogFacility ftp
+ DontResolve yes
+ MaxIdleTime 15
+ LDAPConfigFile ${ldapConfigFile}
+ LimitRecursion 10000 8
+ AnonymousCanCreateDirs no
+ MaxLoad 4
+ AntiWarez yes
+ Umask 133:022
+ # ftp
+ MinUID 8
+ AllowUserFXP no
+ AllowAnonymousFXP no
+ ProhibitDotFilesWrite no
+ ProhibitDotFilesRead no
+ AutoRename no
+ AnonymousCantUpload no
+ MaxDiskUsage 99
+ CustomerProof yes
+ TLS 1
+ CertFile /var/lib/acme/ftp/full.pem
+ '';
+ in {
+ description = "Pure-FTPd server";
+ wantedBy = [ "multi-user.target" ];
+ after = [ "network.target" ];
+
+ serviceConfig.ExecStart = "${pkgs.pure-ftpd}/bin/pure-ftpd ${configFile}";
+ serviceConfig.Type = "forking";
+ serviceConfig.PIDFile = "/run/pure-ftpd.pid";
+ };
+ };
+
+}
--- /dev/null
+{ stdenv, fetchurl, openssl, postgresql, openldap }:
+
+stdenv.mkDerivation rec {
+ name = "pure-ftpd-1.0.47";
+
+ src = fetchurl {
+ url = "https://download.pureftpd.org/pub/pure-ftpd/releases/${name}.tar.gz";
+ sha256 = "1b97ixva8m10vln8xrfwwwzi344bkgxqji26d0nrm1yzylbc6h27";
+ };
+
+ preConfigure = ''
+ sed -i -e "s#FTPuid#immaeFtpUid#" src/log_ldap.h
+ sed -i -e "s#FTPgid#immaeFtpGid#" src/log_ldap.h
+ '';
+ postConfigure = ''
+ sed -i 's/define MAX_DATA_SIZE (40/define MAX_DATA_SIZE (70/' src/ftpd.h
+ '';
+ buildInputs = [ openssl postgresql openldap ];
+
+ configureFlags = [ "--with-everything" "--with-tls" "--with-pgsql" "--with-ldap" ];
+
+ meta = with stdenv.lib; {
+ description = "A free, secure, production-quality and standard-conformant FTP server";
+ homepage = https://www.pureftpd.org;
+ license = licenses.isc; # with some parts covered by BSD3(?)
+ maintainers = [ maintainers.lethalman ];
+ platforms = platforms.linux;
+ };
+}