1 |
swift 12/10/01 20:22:35 |
2 |
|
3 |
Added: ima-guide.xml |
4 |
Log: |
5 |
Initial draft for IMA guide |
6 |
|
7 |
Revision Changes Path |
8 |
1.1 xml/htdocs/proj/en/hardened/integrity/docs/ima-guide.xml |
9 |
|
10 |
file : http://sources.gentoo.org/viewvc.cgi/gentoo/xml/htdocs/proj/en/hardened/integrity/docs/ima-guide.xml?rev=1.1&view=markup |
11 |
plain: http://sources.gentoo.org/viewvc.cgi/gentoo/xml/htdocs/proj/en/hardened/integrity/docs/ima-guide.xml?rev=1.1&content-type=text/plain |
12 |
|
13 |
Index: ima-guide.xml |
14 |
=================================================================== |
15 |
<?xml version='1.0' encoding='UTF-8'?> |
16 |
<!DOCTYPE guide SYSTEM "/dtd/guide.dtd"> |
17 |
<!-- $Header: /var/cvsroot/gentoo/xml/htdocs/proj/en/hardened/integrity/docs/ima-guide.xml,v 1.1 2012/10/01 20:22:35 swift Exp $ --> |
18 |
|
19 |
<guide lang="en"> |
20 |
<title>Using Integrity Measurement Architecture in Gentoo</title> |
21 |
|
22 |
<author title="Author"> |
23 |
<mail link="swift"/> |
24 |
</author> |
25 |
|
26 |
<abstract> |
27 |
The Linux IMA subsystem is responsible for calculating the hashes |
28 |
of files and programs before they are loaded, and supports reporting |
29 |
on the hashes and validate if they adhere to a predefined list. In this |
30 |
guide, we introduce this technology and how it can be enabled in Gentoo |
31 |
Linux. |
32 |
</abstract> |
33 |
|
34 |
<!-- The content of this document is licensed under the CC-BY-SA license --> |
35 |
<!-- See http://creativecommons.org/licenses/by-sa/3.0 --> |
36 |
<license version="3.0" /> |
37 |
|
38 |
<version>1</version> |
39 |
<date>2012-10-01</date> |
40 |
|
41 |
<chapter> |
42 |
<title>Purpose of IMA</title> |
43 |
<section> |
44 |
<title>Introduction</title> |
45 |
<body> |
46 |
|
47 |
<p> |
48 |
The Linux IMA subsystem introduces hooks within the Linux kernel to |
49 |
support measuring the integrity of files that are loaded (including |
50 |
application code) before it is executed or mmap()ed to memory. The |
51 |
measured value (hash) is then registered in a log that can be consulted |
52 |
by administrators. |
53 |
</p> |
54 |
|
55 |
<p> |
56 |
To support proven integrity of the files, the IMA subsystem can interact |
57 |
with the TPM chip within the system to protect the registered hashes from |
58 |
tampering by a rogue administrator or application. |
59 |
The IMA subsystem, as already supported by the Linux kernel, supports |
60 |
<e>reporting</e> on the hashes of files and commands ran by privileged |
61 |
accounts (and more if you create your own measurement policies). |
62 |
</p> |
63 |
|
64 |
<p> |
65 |
With a pending patch, called the <e>IMA appraisal patch</e>, |
66 |
the IMA subsystem can even register the measured |
67 |
value as an extended attribute, and after subsequent measurement(s) |
68 |
validate this extended attribute against the measured value and refuse |
69 |
to load the file (or execute the application) if the hash does not match. |
70 |
In that case, the IMA subsystem allows files and applications to be loaded |
71 |
if the hashes match (and will save the updated hash if the file is modified) |
72 |
but refuse to load it if it doesn't. This provides some protection against |
73 |
offline tampering of the files. |
74 |
</p> |
75 |
|
76 |
<p> |
77 |
Protection of the extended attribute itself is handled by EVM, which is |
78 |
discussed in a separate document. |
79 |
</p> |
80 |
|
81 |
</body> |
82 |
</section> |
83 |
<section> |
84 |
<title>Trusted Computing Base</title> |
85 |
<body> |
86 |
|
87 |
<p> |
88 |
The Trusted Computing Base defines a set of rules that a properly, |
89 |
integrity-protected system should adhere to. The Linux IMA subsystem supports |
90 |
this set of rules through the <e>ima_tcb</e> policy. This policy roughly states |
91 |
that all files read by root (applications, but also regular files, libraries, |
92 |
...) need to be measured and registered against the security log, as well as |
93 |
application binaries when ran (or mmap()ed for execution) by any user. |
94 |
</p> |
95 |
|
96 |
</body> |
97 |
</section> |
98 |
</chapter> |
99 |
|
100 |
<chapter> |
101 |
<title>Setting up IMA</title> |
102 |
<section> |
103 |
<title>Kernel configuration</title> |
104 |
<body> |
105 |
|
106 |
<p> |
107 |
First of all, enable the IMA subsystem in the Linux kernel configuration. |
108 |
IMA is supported in the main tree since 2.6.30, and it is expected that |
109 |
the IMA appraisal patch (needed when you want the system to stop if it |
110 |
detects an off-line modified file) will hit the main tree with Linux |
111 |
3.7. |
112 |
</p> |
113 |
|
114 |
<pre caption="Linux kernel configuration for IMA"> |
115 |
CONFIG_INTEGRITY=y |
116 |
CONFIG_IMA=y |
117 |
CONFIG_IMA_MEASURE_PCR_IDX=10 |
118 |
CONFIG_IMA_AUDIT=y |
119 |
CONFIG_IMA_LSM_RULES=y |
120 |
|
121 |
<comment># Only if the IMA appraisal patch is available:</comment> |
122 |
CONFIG_INTEGRITY_SIGNATURE=y |
123 |
CONFIG_IMA_APPRAISE=y |
124 |
</pre> |
125 |
|
126 |
</body> |
127 |
</section> |
128 |
<section> |
129 |
<title>Bootloader configuration</title> |
130 |
<body> |
131 |
|
132 |
<p> |
133 |
Next, configure the bootloader to enable the TCB policy: |
134 |
</p> |
135 |
|
136 |
<pre caption="Bootloader configuration to enable IMA TCB policy"> |
137 |
kernel /boot/vmlinuz root=/dev/vda1 <i>ima_tcb</i> |
138 |
|
139 |
<comment># Only if IMA appraisal patch is enabled:</comment> |
140 |
kernel /boot/vmlinuz root=/dev/vda1 <i>ima_tcb ima_appraise=enforce ima_appraise_tcb</i> |
141 |
</pre> |
142 |
|
143 |
<p> |
144 |
However, at the first boot, you will need to set <c>ima_appraise=fix</c> |
145 |
instead. Otherwise, your system will surely refuse to boot as no preregistered |
146 |
values are available. |
147 |
</p> |
148 |
|
149 |
</body> |
150 |
</section> |
151 |
<section> |
152 |
<title>Enable security file system</title> |
153 |
<body> |
154 |
|
155 |
<p> |
156 |
Finally, have the security file system mounted (if this is not already the |
157 |
case): |
158 |
</p> |
159 |
|
160 |
<pre caption="Mounting the security file system"> |
161 |
~# <i>mount | grep securityfs</i> |
162 |
securityfs on /sys/kernel/security type securityfs (rw,nosuid,nodev,noexec,relatime) |
163 |
</pre> |
164 |
|
165 |
</body> |
166 |
</section> |
167 |
<section> |
168 |
<title>Enable i_version mount option</title> |
169 |
<body> |
170 |
|
171 |
<p> |
172 |
Mount all file systems with the <e>i_version</e> support (which, sadly, means |
173 |
you need to mount it with <c>iversion</c> mount option - without the |
174 |
underscore). This is needed for IMA to detect changes on files, allowing it to |
175 |
remeasure the hash of the file. |
176 |
</p> |
177 |
|
178 |
<pre caption="Enabling i_version on all mounts"> |
179 |
<comment># Example for a single partition, in /etc/fstab:</comment> |
180 |
/dev/vda1 / ext4 noatime<i>,iversion</i> 1 2 |
181 |
</pre> |
182 |
|
183 |
</body> |
184 |
</section> |
185 |
</chapter> |
186 |
|
187 |
<chapter> |
188 |
<title>Using the IMA subsystem</title> |
189 |
<section> |
190 |
<title>Reading the integrity log</title> |
191 |
<body> |
192 |
|
193 |
<p> |
194 |
To read the integrity log as registered by the IMA subsystem, look at the |
195 |
<path>/sys/kernel/security/ima/ascii_runtime_measurements</path> file: |
196 |
</p> |
197 |
|
198 |
<pre caption="Reading the ascii_runtime_measurements file"> |
199 |
~# <i>head /sys/kernel/security/ima/ascii_runtime_measurements</i> |
200 |
10 0000000000000000000000000000000000000000 ima 0000000000000000000000000000000000000000 boot_aggregate |
201 |
10 dc99efa590c706a43792618dde88c590a6942ec7 ima fe932380326d7c51d17bac45f5d1c9f576d19f6c /sbin/init |
202 |
10 fcaa7505fae70096cb9b6a8ec06ec6400b756aa2 ima 0ddd922ae7f5a6dcf788438db1fe47e9a0641e6d ld-2.15.so |
203 |
10 501975777299919e49aac14c262d6388eae38e79 ima 8d848950517879e0dd77dc9602cad294b454b05a ld.so.cache |
204 |
10 195830b88844db79ff994c57022e94da416c486c ima 28c4c3a750f5679b9092b2bb2f98c5f745e422f7 libselinux.so.1 |
205 |
10 770cd9400624a5678da388545df1297e182ccd10 ima 03db374e3cedeaf987db096a034bccb5c5bcf3d0 libc-2.15.so |
206 |
10 82d48ec5fc4344a18a9d17ec1bf1bd8511f99fe6 ima e801e50a5f3ce7acc6e39b1133bce04120c46c35 libpcre.so.1.0.1 |
207 |
10 81ee4b0bbf4f5b464135e3e3d79b2777bceaa236 ima 869231d2fe1afe45ab284adc0efe5a237509bc7f libdl-2.15.so |
208 |
10 67f5923749dfa266721ee0d6ad038102297c1170 ima e5f8003967fd31f295a115e1d682dd0169b34592 config |
209 |
10 24894f13a9def8dd2f18838f04fde4becc184fc3 ima 032663452ea268aa1528bd466dda3738bb59a8f2 libsepol.so.1 |
210 |
|
211 |
# <i>tail /sys/kernel/security/ima/ascii_runtime_measurements</i> |
212 |
10 d326b31af052ccb96366e4eceaf34f72450dad4b ima def5be24075b501b43ad864bd7141e9db1c55611 /bin/getfattr |
213 |
10 3059f6b0f617256e42617c9e09ad13f6a1eb8f24 ima 7bb939b0ef153dce06098fd5460e31e6052af2a8 libattr.so.1.1.0 |
214 |
10 8c4a121f6e06255e5a8cf3cb94f526412273d661 ima 66abbade137338df340767b0f54a5da6b132e4c6 /usr/bin/touch |
215 |
10 a8cf6c5215be6e6a2de12f50f09b8dbb12af04c8 ima f0cf26d5095d4b19134d8aaf71763bc8f53cd6a9 /usr/bin/zgrep |
216 |
10 60fd90cb2d9581feb241a165f2f83e03abe46c24 ima 8c72350a7d0774c25f8b36b49327d874dec19ea5 test.te |
217 |
10 e359faf89a81e105d3d470d6a513b3ee201376de ima 6b4aa6f895bcdd34ace49879f9a25c1c12197317 /usr/bin/tail |
218 |
10 4a91a89db743704b7afe599528156823b48f192b ima 34228b5c748b13b6d51168c88b0ddf10467a5979 mtab |
219 |
10 5c4c4ffec7487c7fb07a9946238efc3c2957075e ima 41ec2f49dd9c025bcf2810f17bf69de80d45bec1 user_u |
220 |
10 0000000000000000000000000000000000000000 ima 0000000000000000000000000000000000000000 utmp |
221 |
10 6582662a747e7bcf051a6b83367c69c854d5d414 ima 38ccbf9330666831e0b4d9dafa2d5364a3449e1d /usr/bin/du |
222 |
</pre> |
223 |
|
224 |
<p> |
225 |
What you see here are: |
226 |
</p> |
227 |
|
228 |
<ul> |
229 |
<li> |
230 |
The PCR (Process Control Register) in which the values are registered. This |
231 |
only makes sense if you have a TPM chip in use. |
232 |
</li> |
233 |
<li> |
234 |
The hash of the hash of the file + filename (padded with null characters to |
235 |
the length of 255 bytes) |
236 |
</li> |
237 |
<li> |
238 |
The subsystem that registered the integrity value (ima in our case) |
239 |
</li> |
240 |
<li> |
241 |
The hash of the file content |
242 |
</li> |
243 |
</ul> |
244 |
|
245 |
<p> |
246 |
Unless you have asked for a different hashing algorithm, the default one will be |
247 |
used which is the SHA-1 hashing algorithm. |
248 |
</p> |
249 |
|
250 |
</body> |
251 |
</section> |
252 |
<section> |
253 |
<title>Registering the file hashes for the system</title> |
254 |
<body> |
255 |
|
256 |
<note> |
257 |
This is only applicable when IMA appraisal patch is enabled. |
258 |
</note> |
259 |
|
260 |
<p> |
261 |
First boot with the <c>ima_appraise=fix</c> boot option. This will allow the |
262 |
system to boot up even when no (or wrong) hashes are registered. |
263 |
</p> |
264 |
|
265 |
<p> |
266 |
Next, have all files on the file system checked and their value stored as an |
267 |
extended attribute. This is done by reading all files that the default appraisal |
268 |
policy will check and take action on (which is all root-owned files). |
269 |
</p> |
270 |
|
271 |
<pre caption="Registering all files"> |
272 |
~# <i>find / \( -fstype rootfs -o ext4 -type f \) -uid 0 -exec head -n 1 '{}' > /dev/null \;</i> |
273 |
</pre> |
274 |
|
275 |
<p> |
276 |
When done, you should be able to see the registered hash value as an extended |
277 |
attribute: |
278 |
</p> |
279 |
|
280 |
<pre caption="Viewing the extended attributes of a file"> |
281 |
~# <i>getfattr -m . -d /boot/grub/grub.conf</i> |
282 |
# file: grub.conf |
283 |
security.selinux="root:object_r:boot_t" |
284 |
security.ima="76a0d787be14d84dfe3cf3930ac3da38bb389464" |
285 |
</pre> |
286 |
|
287 |
<p> |
288 |
Finally, reboot with <c>ima_appraise=enforce</c>. The system should now run with |
289 |
appraisal enabled, causing the system to validate the hash against the stored |
290 |
value before using it. If it doesn't match, then the file is not loaded. If it |
291 |
does match, and afterwards the file is modified, then the new hash is stored as |
292 |
extended attribute. |
293 |
</p> |
294 |
|
295 |
<p> |
296 |
You can check if this works by booting with <c>ima_appraise=off</c> and changing |
297 |
the contents of a root-owned file (or the value of the extended attribute) and |
298 |
reboot with <c>ima_appraise=enforce</c>. |
299 |
</p> |
300 |
|
301 |
</body> |
302 |
</section> |
303 |
<section> |
304 |
<title>Using immutable files</title> |
305 |
<body> |
306 |
|
307 |
<p> |
308 |
The IMA appraisal code also supports immutable files. In this case, an RSA-key |
309 |
based signature is taken of the file and stored in the extended attribute. The |
310 |
private key is used to sign the files, whereas the public key is used to verify |
311 |
the signature. This provides additional protection against tampering as the |
312 |
private key does not need to be available on the system while its running (only |
313 |
during the initial marking). |
314 |
</p> |
315 |
|
316 |
<p> |
317 |
To sign such immutable files (like kernel modules and application code), you |
318 |
need to use the <c>evmctl</c> command provided by the |
319 |
<path>sys-admin/ima-evm-utils</path> package: |
320 |
</p> |
321 |
|
322 |
<pre caption="Signing files to mark them as immutable"> |
323 |
~# <i>find /lib/modules -name "*.ko" -type f -uid 0 -exec \ |
324 |
evmctl sign --imasig '{}' /path/to/rsa_private.pem \;</i> |
325 |
</pre> |
326 |
|
327 |
<p> |
328 |
This private key can be generated first using <c>openssl</c>: |
329 |
</p> |
330 |
|
331 |
<pre caption="Generating a public/private key pair"> |
332 |
<comment># Unencrypted private key (non-protected):</comment> |
333 |
~# <i>openssl genrsa -out rsa_private.pem 1024</i> |
334 |
|
335 |
<comment># Or encrypted private key (password-protected):</comment> |
336 |
~# <i>openssl genrsa -des3 -out rsa_private.pem 1024</i> |
337 |
|
338 |
<comment># Public key:</comment> |
339 |
~# <i>openssl rsa -pubout -in rsa_private.pem -out rsa_public.pem</i> |
340 |
</pre> |
341 |
|
342 |
<p> |
343 |
To allow the IMA subsystem to validate the signature, you will need to load the |
344 |
public key onto the IMA keyring. You will need to do this every time the system |
345 |
boots, so it makes sense to do so within an initramfs (early in the boot |
346 |
process): |
347 |
</p> |
348 |
|
349 |
<pre caption="Loading the public key in the IMA keyring"> |
350 |
~# <i>ima_id=`keyctl newring _ima @u`</i> |
351 |
~# <i>evmctl import /path/to/rsa_public.pem $ima_id</i> |
352 |
</pre> |
353 |
|
354 |
</body> |
355 |
</section> |
356 |
</chapter> |
357 |
|
358 |
<chapter> |
359 |
<title>Working with a TPM</title> |
360 |
<section> |
361 |
<title>Introduction</title> |
362 |
<body> |
363 |
|
364 |
<p> |
365 |
When your system supports TPM, the measured hash values can be registered |
366 |
against the TPM to provide protection against tampering. In that case, the list |
367 |
provided by <path>ascii_runtime_measurements</path> can be validated against the |
368 |
TPM chip. This is done by <e>extending</e> a register inside the TPM chip with |
369 |
the measured value. |
370 |
</p> |
371 |
|
372 |
<p> |
373 |
When a register is extended, its value (which is a hash) is appended with the |
374 |
value that it is extended with. Then, this new code is hashed again and stored |
375 |
in the register. Because of this operation, the entire measured list can be |
376 |
replayed by a third party and the final result validated against the value in |
377 |
the TPM chip. If it matches, then the list surely comes from this system, and |
378 |
hasn't been tampered by a rogue administrator or application. |
379 |
</p> |
380 |
|
381 |
</body> |
382 |
</section> |
383 |
<section> |
384 |
<title>Taking ownership</title> |
385 |
<body> |
386 |
|
387 |
<p> |
388 |
Before you can use the TPM on your device, you need to take ownership. This will |
389 |
allow you to set a specific password (to manage the TPM) and is needed for the |
390 |
TPM to generate specific keys it'll use later. |
391 |
</p> |
392 |
|
393 |
<p> |
394 |
To take ownership, first install the <path>app-crypt/tpm-tools</path> package. |
395 |
Then start the <e>tcsd</e> service and execute <c>tpm_takeownership -u -z</c>. |
396 |
</p> |
397 |
|
398 |
<pre caption="Taking ownership of the TPM"> |
399 |
~# <i>emerge app-crypt/tpm-tools</i> |
400 |
~# <i>rc-service tcsd start</i> |
401 |
~# <i>tpm_takeownership -u -z</i> |
402 |
</pre> |
403 |
|
404 |
</body> |
405 |
</section> |
406 |
<section> |
407 |
<title>Validating the measured list</title> |
408 |
<body> |
409 |
|
410 |
<p> |
411 |
$$$TODO |
412 |
</p> |
413 |
|
414 |
</body> |
415 |
</section> |
416 |
</chapter> |
417 |
|
418 |
</guide> |