-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathREADME
262 lines (192 loc) · 7.16 KB
/
README
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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
mod_prison : is an Apache httpd module that attempt to put httpd
children in a very restrictive context :
- chroot with no need of shared libs
- network restrictions
- system calls restrictions
- CPU stickiness and limitation
- Memory usage limit
Unlike mod_unixd restrictions (ChrootDir, RLimit), mod_prison create
a global restricted context and attach each child in it.
Currently mod_prison is a FreeBSD only stuff using jail, rctl and
cpuset.
DEPENDENCIES
- FreeBSD version that supports libjail (> 7.2).
check ldconfig -r | grep jail
- rctl compiled into the kernel
options RACCT
options RCTL
- Apache httpd-2.4 compiled with dso support (2.2 may work
but is untested).
INSTALL
Simply uses the Makefile : make && make install
You can specify apxs path when building :
make APXS=/usr/local/httpd/bin/apxs
By default PARANOID is set. You can remove it by editing the Makefile
USAGE
1) PrisonDir : the directory we will be jailed on
DocumentRoot must be relative to this path so you must use httpd -T
to start Apache. If PARANOID is set at compile time, PrisonDir must
be owned by root and not be world or group writable.
Eg:
PrisonDir /usr/local/www
DocumentRoot /sites
2) PrisonIP : A single ipv4 or ipv6 string representation (default none).
Apache still bind everything specified in Listen. PrisonIP is just used for
script stuff like database connections, dns lookup...
If PARANOID is set you can't use INADDR_ANY (0.0.0.0).
Eg:
PrisonIP 192.168.0.1
PrisonIP ::1
3) PrisonSecurity : None|ALL|IPC
NONE : security settings are inherit from the system.
ALL : restrict system calls
The idea is to restrict systems operations even if the attacker gains root
privileges.
- disallow SysV IPC.
- disallow row devices access (/dev/io, /dev/mem, /dev/kmem, newfs).
- disallow loding modules into the kernel.
- reduce the possibility to have information about mount-points.
- disallow row sockets
- disallow changing IP filter rules
- disallow chflags
- disallow mount and quota management
- limit socket creation to IPv4, IPv6 and unix
IPC : like ALL but SysV IPC are allowed.
The default is NONE (ALL if PARANOID is set).
4) PrisonCPU : the CPU in which children will be execute.
- a single cpu. Eg:
PrisonCPU 1
- a list of cpu. Eg:
PrisonCPU 1,2,6
- a cpu range. Eg
PrisonCPU 8-10 # means 8,9 and 10
5) PrisonMemory : total of memory usable within the jail.
Args are : report deny
Eg:
PrisonMemory 900M 1G
This means that when the total of all children memory usage will be of
900MB an event will be reported (via devd on FreeBSD). When this total
is 1GB further usage will be denied.
Warning : usage is not allocation (look at the difference between SIZE
and RES in a top command). This rule apply to the effective memory use.
Allocation should be larger.
Zero means infinite. Eg:
PrisonMemory 512k 0 # Report at 512k. Never deny.
On FreeBSD vm.overcommit has to be set to 1, otherwise the processes will
be pushed in swap by deny.
6) PrisonOptions : various options.
Currently OneSite and OneListen are implemented. OneSite deny VirtualHosts
in configuration. OneListen deny multiple listen statements.
It's useful if you want your users to access quite whole config but not to change
Listen statement or add some vhosts.
SeverName plop.rmdir.fr
Listen 127.0.0.1:8080
#mpm config ...
DocumentRoot /html
PrisonPath /home/user/
PrisonOptions OneSite OneListen
# A listen or virtualhost in this file
# will makes configtest to fail
Include /home/user/conf/apache.conf
EXAMPLES
# httpd.conf
PrisonDir /usr/local/www/plop
DocumentRoot /htdocs
ServerName plop.rmdir.fr
Listen *:8088
PrisonIP ::1
PrisonCPU 1
PrisonSecurity IPC
PrisonMemory 200M 256M
# Starting apache
$ sudo httpd -k start -T
# We now have a jail
$ sudo jls jid name host.hostname ip4.addr ip6.addr path
65 plop_rmdir_fr plop.rmdir.fr - ::1 /usr/local/www/plop
# We now have our processes jailed
$ pgrep -j 65
61100
61086
61085
61084
61083
61082
# Listening on port 8088
$ sockstat -j 65
USER COMMAND PID FD PROTO LOCAL ADDRESS FOREIGN ADDRESS
joris httpd 61100 3 tcp4 6 *:8088 *:*
joris httpd 61100 4 tcp4 *:* *:*
joris httpd 61086 3 tcp4 6 *:8088 *:*
joris httpd 61086 4 tcp4 *:* *:*
joris httpd 61085 3 tcp4 6 *:8088 *:*
joris httpd 61085 4 tcp4 *:* *:*
joris httpd 61084 3 tcp4 6 *:8088 *:*
joris httpd 61084 4 tcp4 *:* *:*
joris httpd 61083 3 tcp4 6 *:8088 *:*
joris httpd 61083 4 tcp4 *:* *:*
joris httpd 61082 3 tcp4 6 *:8088 *:*
joris httpd 61082 4 tcp4 *:* *:*
# Our cpuset
$ cpuset -g -j 65
jail 65 mask: 1
# Our rctl rules
# rctl -l process:61100
$ sudo rctl -l process:61100
jail:plop_rmdir_fr:memoryuse:deny=104857600
jail:plop_rmdir_fr:memoryuse:devctl=52428800
# Our sysctls set
$ curl -i http://www.rmdir.fr:8088/sysctl.cgi
HTTP/1.1 200 OK
Date: Wed, 10 Oct 2012 16:24:38 GMT
Server: Apache/2.4.3 (Unix)
Transfer-Encoding: chunked
Content-Type: text/plain
security.jail.jailed: 1
security.jail.set_hostname_allowed: 0
security.jail.socket_unixiproute_only: 1
security.jail.sysvipc_allowed: 1
security.jail.allow_raw_sockets: 0
security.jail.chflags_allowed: 0
security.jail.mount_allowed: 0
security.jail.mount_devfs_allowed: 0
security.jail.mount_nullfs_allowed: 0
security.jail.mount_procfs_allowed: 0
security.jail.mount_zfs_allowed: 0
security.jail.enforce_statfs: 2
kern.securelevel: 3
# We only see the root mountpoint of the jail
$ mount | grep plop
tank/plop on /usr/local/www/plop (zfs, local, nfsv4acls)
tmpfs on /usr/local/www/plop/tmp (tmpfs, local)
$ curl http://www.rmdir.fr:8088/mount.cgi
tank/plop on / (zfs, local, nfsv4acls)
SYSTEM DATABASES
With a basic NSS configuration, name resolution will work if there is a
route between PrisonIP and the resolver (take a particular care when
setting loopback IPs). /etc/hosts will no work. No resolv.conf is needed
inside the prison. As other system databases lookup, it will fail even
if the relevant file is accessible within the prison.
$ curl http://www.rmdir.fr:8088/id.cgi
uid=1001 gid=1001 groups=1001
$ sudo mkdir /usr/local /usr/local/www/plop/etc
$ sudo cp /etc/passwd /usr/local/www/plop/etc/
$ curl http://www.rmdir.fr:8088/id.cgi
uid=1001 gid=1001 groups=1001
NETWORK
Child process will access incomming requests and apache IPC.
They also will access what is routable through PrisonIP.
BUGS AND STATUS
This is work in progress.
- What about ChrootDirectory.
IMPLEMENTATION NOTE
The main problem in implementation is that jail is a kernel context which
has to be persistent before there is any process in it but not persistent
if you want it to die at the same time as httpd.
Currently everything is set in post_config
- create or update the jail
- fork a process that waits a few time before setting it non persistent.
It sounds like a hack, but I really hesitate to make things much more complicate
with some IPC. The current implementation has around no overhead and is really
simple to understand.
SEE ALSO
mod-jail : http://code.google.com/p/mod-jail/