blob: 1b2432401deff16fc609bef894bb71d1db2c8a62 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
{ config, pkgs, ... }:
with pkgs.lib;
let
cfg = config.services.vsftpd;
inherit (pkgs) vsftpd;
yesNoOption = p : name :
"${name}=${if p then "YES" else "NO"}";
in
{
###### interface
options = {
services.vsftpd = {
enable = mkOption {
default = false;
description = "Whether to enable the vsftpd FTP server.";
};
anonymousUser = mkOption {
default = false;
description = "Whether to enable the anonymous FTP user.";
};
anonymousUserHome = mkOption {
default = "/home/ftp";
description = "Path to anonymous user data.";
};
localUsers = mkOption {
default = false;
description = "Whether to enable FTP for local users.";
};
writeEnable = mkOption {
default = false;
description = "Whether any write activity is permitted to users.";
};
anonymousUploadEnable = mkOption {
default = false;
description = "Whether any uploads are permitted to anonymous users.";
};
anonymousMkdirEnable = mkOption {
default = false;
description = "Whether mkdir is permitted to anonymous users.";
};
chrootlocalUser = mkOption {
default = false;
description = "Whether local users are confined to their home directory.";
};
userlistEnable = mkOption {
default = false;
description = "Whether users are included.";
};
userlistDeny = mkOption {
default = false;
description = "Whether users are excluded.";
};
};
};
###### implementation
config = mkIf cfg.enable {
users.extraUsers =
[ { name = "vsftpd";
uid = config.ids.uids.vsftpd;
description = "VSFTPD user";
home = "/homeless-shelter";
}
] ++ pkgs.lib.optional cfg.anonymousUser
{ name = "ftp";
uid = config.ids.uids.ftp;
group = "ftp";
description = "Anonymous FTP user";
home = cfg.anonymousUserHome;
};
users.extraGroups = singleton
{ name = "ftp";
gid = config.ids.gids.ftp;
};
jobs.vsftpd =
{ description = "vsftpd server";
startOn = "started network-interfaces";
stopOn = "stopping network-interfaces";
preStart =
''
# !!! Why isn't this generated in the normal way?
cat > /etc/vsftpd.conf <<EOF
${yesNoOption cfg.anonymousUser "anonymous_enable"}
${yesNoOption cfg.localUsers "local_enable"}
${yesNoOption cfg.writeEnable "write_enable"}
${yesNoOption cfg.anonymousUploadEnable "anon_upload_enable"}
${yesNoOption cfg.anonymousMkdirEnable "anon_mkdir_write_enable"}
${yesNoOption cfg.chrootlocalUser "chroot_local_user"}
${yesNoOption cfg.userlistEnable "userlist_enable"}
${yesNoOption cfg.userlistDeny "userlist_deny"}
background=NO
listen=YES
nopriv_user=vsftpd
secure_chroot_dir=/var/empty
EOF
${if cfg.anonymousUser then ''
mkdir -p -m 555 ${cfg.anonymousUserHome}
chown -R ftp:ftp ${cfg.anonymousUserHome}
'' else ""}
'';
exec = "${vsftpd}/sbin/vsftpd /etc/vsftpd.conf";
};
};
}
|