File: after-install.sgml.svn-base

package info (click to toggle)
harden-doc 3.13.3
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 8,908 kB
  • ctags: 25
  • sloc: sh: 789; makefile: 174; xml: 105; perl: 86
file content (2816 lines) | stat: -rw-r--r-- 121,469 bytes parent folder | download | duplicates (2)
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
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
<!-- CVS revision of this document "$Revision: 1.68 $"  -->

<chapt>After installation

<p>Once the system is installed you can still do more to secure the system;
some of the steps described in this chapter can be taken. Of course
this really depends on your setup but for physical access prevention
you should read <ref id="bios-boot">,<ref id="lilo-passwd">,<ref
id="kernel-root-prompt">, <ref
id="restrict-console-login">, and <ref id="restrict-reboots">.

<p>Before connecting to any network, especially if it's a public one
you should, at the very least, execute a security update (see 
<ref id="security-update">). Optionally, you could take a snapshot of your
system (see <ref id="snapshot">).

<sect id="debian-sec-announce">Subscribe to the Debian Security Announce mailing list

<p>In order to receive information on available security updates you
should subscribe yourself to the debian-security-announce mailing list
in order to receive the Debian Security Advisories (DSAs). See <ref
id="debian-sec-team"> for more information on how the Debian security
team works. For information on how to subscribe to the Debian mailing
lists read <url id="http://lists.debian.org">.

<p>DSAs are signed with the Debian Security Team's signature which can
be retrieved from <url id="http://security.debian.org">.

<p>You should consider, also, subscribing to the <url
id="http://lists.debian.org/debian-security" name="debian-security
mailing list"> for general discussion on security issues in the Debian
operating system. You will be able to contact other fellow system
administrators in the list as well as Debian developers and upstream
developers of security tools who can answer your questions and offer
advice.

<p>FIXME: Add the key here too?

<sect id="security-update">Execute a security update

<p>As soon as new security bugs are detected in packages, Debian
maintainers and upstream authors generally patch them within days or
even hours. After the bug is fixed, a new package is provided on <url
name="http://security.debian.org" id="http://security.debian.org">.

<p>If you are installing a Debian release you must take into account
that since the release was made there might have been security updates
after it has been determined that a given package is vulnerable. Also,
there might have been minor releases (there have been four for the Debian
3.0 <em>sarge</em> release) which include these package updates. 

<p>You need to note down the date the removable media (if you are
using it) was made and check the security site in order to see if
there are security updates. If there are and you cannot download the
packages from the security site on another system (you are not
connected to the Internet yet? are you?) before connecting to the
network you could consider (if not protected by a firewall for
example) adding firewall rules so that your system could only connect
to security.debian.org and then run the update. A sample configuration
is shown in <ref id="fw-security-update">.

<p><em>Note:</em> Since Debian woody 3.0, after installation you are given the
opportunity to add security updates to the system. If you say 'yes' to this,
the installation system will take the appropriate steps to add the
source for security updates to your package sources and your system, if
you have an Internet connection, will download and install any security
updates that might have been produced after your media was created.
If you are upgrading a previous version of Debian, or you asked 
the installation system not to do this, you should take the steps 
described here.

<p>To manually update the system, put the following line in your
<file>sources.list</file> and you will get security updates
automatically, whenever you update your system.

<example>
  deb http://security.debian.org/ stable/updates main contrib non-free
</example>

<p><em>Note</em>: If you are using the <em>testing</em> branch use the security
testing mirror sources as described in <ref id="security-support-testing">.

<p>Once you've done this you can use multiple tools to upgrade your system.  If
you are running a desktop system you will have<footnote>In <em>etch</em> and
later releases</footnote> an application called <prgn>update-notifier</prgn>
that will make it easy to check if new updates are available, by selecting it
you can make a system upgrade from the desktop (using
<prgn>update-manager</prgn>). For more information see <ref
id="update-desktop">. In
desktop environments you can also use <package>synaptic</package> (GNOME),
<package>kpackage</package> or <package>adept</package> (KDE) for more advanced
interfaces. If you are running a text-only terminal you can use
<package>aptitude</package>, <package>apt</package> or
<package>dselect</package> (deprecated) to upgrade:

<list>
<item>If you want to use <package>aptitude</package>'s text interface
you just have to press <em>u</em> (update) followed by <em>g</em> (to upgrade).
Or just do the following from the command line (as root):
<example>
# aptitude update
# aptitude upgrade
</example>

<item>If you want to use <package>apt</package> do just like with aptitude but
substitute the <prgn>aptitude</prgn> lines above with <prgn>apt-get</prgn>.

<item>If you want to use <package>dselect</package> then first [U]pdate,
then [I]nstall and finally, [C]onfigure the installed/upgraded packages.
</list>

<p>If you like, you can add the deb-src lines to 
<file>/etc/apt/sources.list</file> as well. See 
<manref name="apt" section="8"> for further details.

<p>Note: You do <em>not</em> need to add the following line:

<example>
  deb http://security.debian.org/debian-non-US stable/non-US main contrib non-free
</example>
<p>this is because security.debian.org is hosted in a non-US location and 
doesn't have a separate non-US archive.

<sect1 id="lib-security-update">Security update of libraries

<p>Once you have executed a security update you might need to restart some
of the system services. If you do not do this, some services might still be vulnerable
after a security upgrade. The reason for this is that daemons that are running
before an upgrade might still be using the old libraries before the upgrade
<footnote>Even though the libraries have been removed from the filesystem the inodes
will not be cleared up until no program has an open file descriptor pointing
to them.</footnote>. In order to detect which daemons might need to be restarted
you can use the <prgn>checkrestart</prgn> program (available in the 
<package>debian-goodies</package> package) or use this one liner<footnote><p>Depending on your lsof version you might need to use $8 instead of $9</p></footnote> (as root):

<example>
# lsof | grep &lt;the_upgraded_library&gt; | awk '{print $1, $9}' | uniq | sort -k 1
</example>

<P>Some packages (like <package>libc6</package>) will do this check in the postinst
phase for a limited set of services specially since an upgrade of essential libraries
might break some applications (until restarted)<footnote>This happened, for example,
in the upgrade from libc6 2.2.x to 2.3.x due to NSS authentication issues, see
<url id="http://lists.debian.org/debian-glibc/2003/debian-glibc-200303/msg00276.html">.</footnote>.

<P>Bringing the system to run level 1 (single user) and then back to
run level 3 (multi user) should take care of the restart of most (if not all)
system services. But this is not an option if you are executing the security
upgrade from a remote connection (like ssh) since it will be severed.

<p>Excercise caution when dealing with security upgrades if you are doing them
over a remote connection like ssh. A suggested procedure for a security
upgrade that involves a service restart is to restart the SSH daemon and then, inmediately,
attempt a new ssh connection without breaking the previous one. If the connection
fails, revert the upgrade and investigate the issue. 

</sect1>
<sect1 id="kernel-security-update">Security update of the kernel

<P>First, make sure your kernel is being managed through the packaging
system. If you have installed using the installation system from Debian 3.0
or previous releases, your kernel is <em>not</em> integrated into the
packaging system and might be out of date. You can easily confirm this
by running:

<example>
$ dpkg -S `readlink -f /vmlinuz`
linux-image-2.6.18-4-686: /boot/vmlinuz-2.6.18-4-686
</example>

<p>If your kernel is not being managed you will see a message saying that
the package manager did not find the file associated to any package instead
of the message above, which says that the file associated to the current
running kernel is being provided by the
<package>linux-image-2.6.18-4-686</package>. So first, you will need
to manually install a kernel image package. The exact kernel image you need
to install depends on your architecture and your prefered kernel version.
Once this is done, you will be able to manage the security updates of the
kernel just like those of any other package. In any case, notice that
the kernel updates will <em>only</em> be done for kernel updates of
the same kernel version you are using, that is, <prgn>apt</prgn>
will not automatically upgrade your kernel from the 2.4 release to the
2.6 release (or from the 2.4.26 release to the 2.4.27 release<footnote>Unless
you have installed a kernel metapackage like 
<package>linux-image-2.6-686</package> which will always pull in the 
latest kernel minor revision for a kernel release and a given
architecture.</footnote>).

<p>The installation system of recent Debian releases will handle
the selected kernel as part of the package system.
You can review which kernels you have installed by running:

<example>
$ COLUMNS=150 dpkg -l 'linux-image*' | awk '$1 ~ /ii/ { print $0 }'
</example>

<p>To see if your kernel needs to be updated run:

<example>
$ kernfile=`readlink -f /vmlinuz`
$ kernel=`dpkg -S $kernfile | awk -F : '{print $1}'`
$ apt-cache policy $kernel
linux-image-2.6.18-4-686:
  Installed: 2.6.18.dfsg.1-12
  Candidate: 2.6.18.dfsg.1-12
  Version table:
 *** 2.6.18.dfsg.1-12 0
        100 /var/lib/dpkg/status
</example>


<P>If you are doing a security update which includes the kernel image
you <em>need</em> to reboot the system in order for the security update to be useful.
Otherwise, you will still be running the old (and vulnerable) kernel image.

<!-- FIXME: Do a script to check for the above, maybe using ps -p 1 -o etime | tail -1
and obtain the creation time of `readlink -f /vmlinuz`. -->

<p>If you need to do a system reboot (because of a kernel upgrade) you should
make sure that the kernel will boot up correctly and network connectivity will be 
restored, specially if the security upgrade is done over a remote connection like ssh.
For the former you can configure your boot loader to reboot to the original kernel in
the event of a failure (for more detailed information  read
<url id="http://www.debian-administration.org/?article=70" name="Remotely rebooting Debian GNU/Linux machines">). For the latter you have to introduce a network
connectivity test script that will check if the kernel has started up the network
subsystem properly and reboot the system if it did not<footnote>A sample
script called
<url id="http://www.debian-administration.org/articles/70/testnet" name="testnet">
is available in the <url id="http://www.debian-administration.org/?article=70" 
name="Remotely rebooting Debian GNU/Linux machines"> article. A more elaborate 
network connectivity testing script is available in the 
<url id="http://www.debian-administration.org/?article=128" 
name="Testing network connectivity"> article.</footnote>. This  should prevent
nasty surprises like updating the kernel and then realizing, after a reboot, that
it did not detect or configure the network hardware properly and you need
to travel a long distance to bring the system up again. Of course, having the
system serial console <footnote>Setting up a serial console
is beyond the scope of this document, for more information read the 
<url id="http://www.tldp.org/HOWTO/Serial-HOWTO.html" name="Serial HOWTO">
and the <url id="http://www.tldp.org/HOWTO/Remote-Serial-Console-HOWTO/index.html"
name="Remote Serial Console HOWTO">.</footnote> in the system connected to a 
console or terminal server should also help debug reboot issues remotely.
</p>

</sect1>

<sect id="bios-boot">Change the BIOS (again)

<p>Remember <ref id="bios-passwd">? Well, then you should now, once
you do not need to boot from removable media, to change the default
BIOS setup so that it <em>only</em> boots from the hard drive. Make
sure you will not lose the BIOS password, otherwise, in the event of a
hard disk failure you will not be able to return to the BIOS and
change the setup so you can recover it using, for example, a CD-ROM.

<p>Another less secure but more convenient way is to change the
setup to have the system boot up from the hard disk and, if it fails,
try removable media. By the way, this is often done because
most people don't use the BIOS password that often; it's easily forgotten.

<sect id="lilo-passwd">Set a LILO or GRUB password
<p>
Anybody can easily get a root-shell and change your passwords by
entering <tt>&lt;name-of-your-bootimage&gt; init=/bin/sh</tt> at the boot
prompt. After changing the passwords and rebooting the system, the
person has unlimited root-access and can do anything he/she wants to the
system.  After this procedure you will not have root access to your
system, as you do not know the root password.
<p>
To make sure that this cannot happen, you should set a password for
the boot loader. You can choose between a global password or a
password for a certain image.
<p>
For LILO you need to edit the config file <file>/etc/lilo.conf</file> and add
a <tt>password</tt> and <tt>restricted</tt> line as in the example below.

<example>
  image=/boot/2.2.14-vmlinuz
     label=Linux
     read-only
     password=hackme
     restricted
</example>

<p>Then, make sure that the configuration file is not world readable
to prevent local users from reading the password.
When done, rerun lilo.  Omitting the <tt>restricted</tt> line causes lilo to
always prompt for a password, regardless of whether LILO was passed
parameters. The default permissions for <file>/etc/lilo.conf</file>
grant read and write permissions to root, and enable read-only access
for <file>lilo.conf</file>'s group, root.

<p>
If you use GRUB instead of LILO, edit <file>/boot/grub/menu.lst</file>
and add the following two lines at the top (substituting, of course
<tt>hackme</tt> with the desired password). This prevents users from editing
the boot items. <tt>timeout 3</tt> specifies a 3 second delay before 
<prgn>grub</prgn> boots the default item.

<example>
  timeout 3
  password hackme
</example>

<p>To further harden the integrity of the password, you may store the password
in an encrypted form. The utility <prgn>grub-md5-crypt</prgn> generates a 
hashed password which is compatible with GRUB's encrypted password algorithm 
(MD5).
To specify in <prgn>grub</prgn> that an MD5 format password will be used, use 
the following directive:
<example>
  timeout 3
  password --md5 $1$bw0ez$tljnxxKLfMzmnDVaQWgjP0
</example>

The --md5 parameter was added to instruct <prgn>grub</prgn> to perform the MD5 
authentication process. The provided password is the MD5 encrypted version of 
hackme. Using the MD5 password method is preferable to choosing its clear-text 
counterpart. More information about <prgn>grub</prgn> passwords may be found 
in the <package>grub-doc</package> package.

<sect id="kernel-initramfs-prompt">Disable root prompt on the initramfs

<p>Note: This applies to the default kernels provided for releases after Debian
3.1

<p>Linux 2.6 kernels provide a way to access a root shell while booting which
will be presented during loading the initramfs on error. This is helpful to
permit the administrator to enter a rescue shell with root permissions.  This
shell can be used to manually load modules when autodetection fails.  This
behavior is the default for <prgn>initramfs-tools</prgn> generated initramfs.
The following message will appear:
<example>
  "ALERT!  /dev/sda1 does not exist.  Dropping to a shell!
</example>

<p>In order to remove this behavior you need to set the following boot
argument:<em>panic=0</em>. Either add it to the kopt section of
<file>/boot/grub/menu.lst</file> and issue <prgn>update-grub</prgn> or to the
append section of <file>/etc/lilo.conf</file>.

<sect id="kernel-root-prompt">Remove root prompt on the kernel

<p>Note: This does not apply to the kernels provided for Debian 3.1 as the
timeout for the kernel delay has been changed to 0.

<p>Linux 2.4 kernels provide a way to access a root shell while booting which 
will be presented just after loading the cramfs file system. A message will 
appear to permit the administrator to enter an executable shell with root 
permissions, this shell can be used to manually load modules when 
autodetection fails. This behavior is the default for <prgn>initrd</prgn>'s 
<file>linuxrc</file>. The following message will appear:
<example>
  Press ENTER to obtain a shell (waits 5 seconds)
</example>

<p>In order to remove this behavior you need to change 
<file>/etc/mkinitrd/mkinitrd.conf</file> and set:
<example>
  # DELAY  The  number  of seconds the linuxrc script should wait to
  # allow the user to interrupt it before the system is brought up
  DELAY=0
</example>
<p>Then regenerate your ramdisk image. You can do this for example with:
<example>
  # cd /boot
  # mkinitrd -o initrd.img-2.4.18-k7 /lib/modules/2.4.18-k7
</example>
<p>or (preferred):
<example>
  # dpkg-reconfigure -plow kernel-image-2.4.x-yz
</example>


<sect id="restrict-console-login">Restricting console login access 

<p>Some security policies might force administrators to log in to
the system through the console with their user/password and then
become superuser (with <prgn>su</prgn> or <prgn>sudo</prgn>). This
policy is implemented in Debian by editing the
<file>/etc/login.defs</file> file or <file>/etc/securetty</file> when
using PAM. In:

<list>

<item><file>login.defs</file>, editing the CONSOLE variable which
defines a file or list of terminals on which root logins are allowed

<item><file>securetty</file><footnote>
The <file>/etc/securetty</file> is a configuration file that belongs
to the <package>login</package> package.
</footnote>
by adding/removing the terminals to which
root access will be allowed. If you wish to allow only local console access
then you need <em>console</em>, <em>ttyX</em><footnote>
Or <em>ttyvX</em> in GNU/FreeBSD, and <em>ttyE0</em> in GNU/KNetBSD.
</footnote>
and <em>vc/X</em> (if using <em>devfs</em> devices), you might want to add
also <em>ttySX</em><footnote>
Or <em>comX</em> in GNU/Hurd, <em>cuaaX</em> in GNU/FreeBSD, 
and <em>ttyXX</em> in GNU/KNetBSD.
</footnote>
if you are using
a serial console for local access (where X is an integer, you might want
to have multiple instances<footnote>
The default configuration in <em>woody</em> includes 12
local tty and vc consoles, as well as the <em>console</em> device but
does not allow remote logins. In <em>sarge</em> the default 
configuration provides 64 consoles for tty and vc consoles.
You can safely remove this if you are not using that many consoles.
</footnote>
depending on the number of virtual consoles
you have enabled in <file>/etc/inittab</file><footnote>
Look for the <em>getty</em> calls.</footnote>). For more
information on terminal devices read the
<url id="http://tldp.org/HOWTO/Text-Terminal-HOWTO-6.html" name="Text-Terminal-HOWTO">.

</list>

<p>When using PAM, other changes to the login process, which might
include restrictions to users and groups at given times, can be
configured in <file>/etc/pam.d/login</file>. An interesting feature
that can be disabled is the possibility to login with null (blank)
passwords. This feature can be limited by removing <em>nullok</em>
from the line:

<example>
  auth       required   pam_unix.so nullok
</example>

<sect id="restrict-reboots">Restricting system reboots through the console

<p>If your system has a keyboard attached to it anyone (yes
<em>anyone</em>) can reboot the system through it without login to the
system. This might, or might not, adhere to your security policy. If
you want to restrict this, you must check the
<file>/etc/inittab</file> so that the line that includes
<tt>ctrlaltdel</tt> calls <prgn>shutdown</prgn> with the <tt>-a</tt>
switch (remember to run <tt>init q</tt> after making any changes to
this file). The default in Debian includes this switch:

<example>
  ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now
</example>

<p>Now, in order to allow <em>some</em> users to shutdown the system,
as the manpage <manref section="8" name="shutdown"> describes, you must
create the file <file>/etc/shutdown.allow</file> and include there the
name of users which can boot the system. When the <em>three finger
salute</em> (a.k.a. <em>ctrl+alt+del</em>) is given the program will
check if any of the users listed in the file are logged in. If none of
them is, <prgn>shutdown</prgn> will <em>not</em> reboot the system.
 
</sect>

<sect>Mounting partitions the right way
<p>
When mounting an <tt>ext2</tt> or <tt>ext3</tt> file system, there are several
additional options you can apply to the mount call or to
<file>/etc/fstab</file>. For instance, this is my fstab entry for the
<file>/tmp</file> partition:

<example>
  /dev/hda7    /tmp    ext2    defaults,nosuid,noexec,nodev    0    2
</example>

<p>
You see the difference in the options sections. The option
<tt>nosuid</tt> ignores the setuid and setgid bits completely, while
<tt>noexec</tt> forbids execution of any program on that mount point,
and <tt>nodev</tt> ignores device files. This sounds great, but it:

<list>
<item>only applies to <tt>ext2</tt> or <tt>ext3</tt> file systems
<item>can be circumvented easily
</list>

<p>The <tt>noexec</tt> option prevents binaries from being executed
directly, but was easily circumvented in earlier versions of the kernel:

<example>
  alex@joker:/tmp# mount | grep tmp
  /dev/hda7 on /tmp type ext2 (rw,noexec,nosuid,nodev)
  alex@joker:/tmp# ./date
  bash: ./date: Permission denied
  alex@joker:/tmp# /lib/ld-linux.so.2 ./date
  Sun Dec  3 17:49:23 CET 2000
</example>

<p>Newer versions of the kernel do however handle the <tt>noexec</tt> flag
properly:

<example>
  angrist:/tmp# mount | grep /tmp
  /dev/hda3 on /tmp type ext3 (rw,noexec,nosuid,nodev)
  angrist:/tmp# ./date
  bash: ./tmp: Permission denied 
  angrist:/tmp# /lib/ld-linux.so.2 ./date 
  ./date: error while loading shared libraries: ./date: failed to map segment 
  from shared object: Operation not permitted
</example>

<p>However, many script kiddies have exploits which try to create and execute 
files in <file>/tmp</file>. If they do not have a clue, they will fall into
this pit. In other words, a user cannot be tricked into executing a trojanized 
binary in <file>/tmp</file> e.g. when he incidentally adds <file>/tmp</file> 
into his PATH.

<p>Also be forewarned, some script might depend on <file>/tmp</file> being
executable. Most notably, Debconf has (had?) some issues regarding
this, for more information see Bug <url
id="http://bugs.debian.org/116448" name="116448">.

<p>
The following is a more thorough example. A note, though: 
<file>/var</file> could be set noexec, but some software 
<footnote>Some of this includes the package manager <package>dpkg</package>
since the installation (post,pre) and removal (post,pre) scripts are
at <file>/var/lib/dpkg/</file> and Smartlist</footnote>
keeps its programs under in <file>/var</file>. 
The same applies to the nosuid option.

<example>
/dev/sda6   /usr          ext3    defaults,ro,nodev       0       2
/dev/sda12  /usr/share    ext3    defaults,ro,nodev,nosuid        0       2
/dev/sda7   /var          ext3    defaults,nodev,usrquota,grpquota 0      2
/dev/sda8   /tmp          ext3    defaults,nodev,nosuid,noexec,usrquota,grpquota    0       2
/dev/sda9   /var/tmp      ext3    defaults,nodev,nosuid,noexec,usrquota,grpquota    0       2
/dev/sda10  /var/log      ext3    defaults,nodev,nosuid,noexec    0       2
/dev/sda11  /var/account  ext3    defaults,nodev,nosuid,noexec    0       2
/dev/sda13  /home         ext3    rw,nosuid,nodev,exec,auto,nouser,async,usrquota,grpquota                0       2
/dev/fd0    /mnt/fd0      ext3    defaults,users,nodev,nosuid,noexec      0       0
/dev/fd0    /mnt/floppy   vfat    defaults,users,nodev,nosuid,noexec      0       0
/dev/hda    /mnt/cdrom    iso9660 ro,users,nodev,nosuid,noexec            0       0
</example>

<sect1>Setting <file>/tmp</file> noexec
<p>Be careful if setting <file>/tmp</file> noexec when you want to install new 
software, since some programs might use it for installation. 
<package>apt</package> is one such program (see 
<url id="http://bugs.debian.org/116448">) if not configured properly
<tt>APT::ExtractTemplates::TempDir</tt> (see 
<manref name="apt-extracttemplates" section="1">). 
You can set this variable in <file>/etc/apt/apt.conf</file> to another 
directory with exec privileges other than <file>/tmp</file>.

<!-- This is a duplicate of the example a few paragraphs up. So why repeat it?
(thomas)
<p>Regarding noexec, please be aware that it might not offer you that much 
security. 
Consider this:
<example>
  $ cp /bin/date /tmp
  $ /tmp/date
  (does not execute due to noexec)
  $/lib/ld-linux.so.2 /tmp/date
  (works since date is not executed directly)
</example>
-->

<sect1>Setting /usr read-only
<p>If you set <file>/usr</file> read-only you will not be able to install new 
packages on your Debian GNU/Linux system. You will have to first remount it 
read-write, install the packages and then remount it read-only. 
<package>apt</package> can be configured to 
run commands before and after installing packages, so you might want to 
configure it properly.

<p>To do this modify <file>/etc/apt/apt.conf</file> and add:
<example>
  DPkg
  {
      Pre-Invoke  { "mount /usr -o remount,rw" };
      Post-Invoke { "mount /usr -o remount,ro" };
  };
</example>

<p>Note that the Post-Invoke may fail with a "/usr busy" error message.
This happens mainly when you are using files during the update that
got updated.  You can find these programs by running
<example>
# lsof +L1
</example>

<p>Stop or restart these programs and run the Post-Invoke manually.
<em>Beware!</em>  This means you'll likely need to restart your X
session (if you're running one) every time you do a major upgrade of
your system.  You might want to reconsider whether a read-only
<file>/usr</file> is suitable for your system. See also this <url
id="http://lists.debian.org/debian-devel/2001/11/threads.html#00212"
name="discussion on debian-devel about read-only /usr">.

<sect>Providing secure user access

<sect1 id="auth-pam">User authentication: PAM

<p>PAM (Pluggable Authentication Modules) allows system administrators
to choose how applications authenticate users. Note that PAM can do
nothing unless an application is compiled with support for PAM. Most
of the applications that are shipped with Debian have this support
built in (Debian did not have PAM support before 2.2). The
current default configuration for any PAM-enabled service is to
emulate UNIX authentication (read
<file>/usr/share/doc/libpam0g/Debian-PAM-MiniPolicy.gz</file> for more
information on how PAM services <em>should</em> work in Debian).

<p>Each application with PAM support provides a configuration file
in <file>/etc/pam.d/</file> which can be used to modify its behavior:

<list>
<item>what backend is used for authentication.
<item>what backend is used for sessions.
<item>how do password checks behave.
</list>

<p>
The following description is far from complete, for more information
you might want to read the <url
id="http://www.kernel.org/pub/linux/libs/pam/Linux-PAM-html/pam.html"
name="The Linux-PAM System Administrator's Guide"> (at the <url
id="http://www.kernel.org/pub/linux/libs/pam/" name="primary PAM
distribution site">). This document is also provided in the
<package>libpam-doc</package> Debian package.

<p>PAM offers you the possibility to go through several authentication steps at
once, without the user's knowledge. You could authenticate against a Berkeley
database and against the normal <file>passwd</file> file,
and the user only logs in if he authenticates correct in both.
You can restrict a lot with PAM, just as you can open your system
doors very wide. So be careful. A typical configuration line has a control
field as its second element. 
<!-- Second in mine (old Debian v2.0 though), check this! (FIXME) (era) -->
Generally it should be set to <tt>requisite</tt>, which
returns a login failure if one module fails.
<!-- Lots of fields in mine are "required", please elaborate? (FIXME) (era) -->

<p>The first thing I like to do, is to add MD5 support to PAM 
applications, since this helps protect against dictionary cracks (passwords 
can be longer if using MD5). The following two lines should be added to all 
files in <file>/etc/pam.d/</file> that grant access to the machine, like 
<tt>login</tt> and <tt>ssh</tt>.

<example>
  # Be sure to install libpam-cracklib first or you will not be able to log in
  password   required     pam_cracklib.so retry=3 minlen=12 difok=3
  password   required     pam_unix.so use_authtok nullok md5
</example>


<p>So, what does this incantation do? The first line loads the
cracklib PAM module, which provides password strength-checking,
prompts for a new password with a minimum length of 12 characters, a
difference of at least 3 characters from the old password, and allows
3 retries. Cracklib depends on a wordlist package (such as
<package>wenglish</package>, <package>wspanish</package>, 
<package>wbritish</package>, ...), so make sure you install one that is
appropriate for your language or cracklib might not be useful to you at all.
<footnote>
This dependency is not fixed, however, in the Debian 3.0 package. Please
see <url id="http://bugs.debian.org/112965" name="Bug #112965">.
</footnote>
The second line introduces the standard authentication
module with MD5 passwords and allows a zero length password. The
<tt>use_authtok</tt> directive is necessary to hand over the password from the
previous module. 

<p>To make sure that the user root can only log into the system from
local terminals, the following line should be enabled in
<file>/etc/pam.d/login</file>:

<example>
  auth     requisite  pam_securetty.so
</example>

<p>Then you should modify the list of terminals on which direct root login
is allowed in <file>/etc/securetty</file>. Alternatively, you could enable
the <tt>pam_access</tt> module and modify
<file>/etc/security/access.conf</file> which allows for a more general and
fine-tuned access control, but (unfortunately) lacks decent log
messages (logging within PAM is not standardized and is particularly
unrewarding problem to deal with). We'll return to <file>access.conf</file>
a little later.

<p>
Last but not the
least, the following line should be enabled in <file>/etc/pam.d/login</file>
to set up user resource limits.

<example>
  session  required   pam_limits.so
</example>

<p>This restricts the system resources that users are allowed (see
below in <ref id="user-limits">).  For example, you could restrict the
number of concurrent logins (of a given group of users, or
system-wide), number of processes, memory size etc.

<p>Now edit <file>/etc/pam.d/passwd</file> and change the first line. You
should add the option "md5" to use MD5 passwords, change the minimum
length of password from 4 to 6 (or more) and set a maximum length, if
you desire. The resulting line will look something like:

<example>
  password   required   pam_unix.so nullok obscure min=6 max=11 md5
</example>

<p>If you want to protect su, so that only some people can use it to
become root on your system, you need to add a new group "wheel" to your
system (that is the cleanest way, since no file has such a group
permission yet). Add root and the other users that should be able to
<prgn>su</prgn> to the root user to this group.  Then add the following line to
<file>/etc/pam.d/su</file>:

<example>
  auth        requisite   pam_wheel.so group=wheel debug
</example>

<p>This makes sure that only people from the group "wheel" can use
<prgn>su</prgn> to become root. Other users will not be able to become
root. In fact they will get a denied message if they try to become
root.

<p>If you want only certain users to authenticate at a PAM service,
this is quite easy to achieve by using files where the users who are
allowed to login (or not) are stored. Imagine you only want to allow
user 'ref' to log in via <prgn>ssh</prgn>. So you put him into
<file>/etc/sshusers-allowed</file> and write the following into
<file>/etc/pam.d/ssh</file>:

<example>
  auth        required    pam_listfile.so item=user sense=allow file=/etc/sshusers-allowed onerr=fail
</example>

<p>Since there have been a number of so called insecure tempfile 
vulnerabilities, thttpd is one example (see 
<url id="http://www.debian.org/security/2005/dsa-883" name="DSA-883-1">),
the <package>libpam-tmpdir</package> is a good package to install.
All you have to do is add the following to 
<file>/etc/pam.d/common-session</file>:

<example>
 session    optional     pam_tmpdir.so
</example>

There has also been a discussion about adding this by default in etch. See
<url id="http://lists.debian.org/debian-devel/2005/11/msg00297.html"> for 
more information.

<p>Last, but not least, create <file>/etc/pam.d/other</file> and enter
the following lines:

<example>
  auth     required       pam_securetty.so
  auth     required       pam_unix_auth.so
  auth     required       pam_warn.so
  auth     required       pam_deny.so
  account  required       pam_unix_acct.so
  account  required       pam_warn.so
  account  required       pam_deny.so
  password required       pam_unix_passwd.so
  password required       pam_warn.so
  password required       pam_deny.so
  session  required       pam_unix_session.so
  session  required       pam_warn.so
  session  required       pam_deny.so
</example>

<p>These lines will provide a good default configuration for all
applications that support PAM (access is denied by default).


<sect1 id="user-limits">Limiting resource usage: the <file>limits.conf</file> file

<p>You should really take a serious look into this file. Here you can
define user resource limits. In old releases this configuration file
was <file>/etc/limits.conf</file>, but in newer releases (with PAM)
the <file>/etc/security/limits.conf</file> configuration file should
be used instead.

<p>If you do not restrict resource usage, <em>any</em> user with a
valid shell in your system (or even an intruder who compromised the
system through a service or a daemon going awry) can use up as much
CPU, memory, stack, etc. as the system can provide. This <em>resource
exhaustion</em> problem can be fixed by the use of PAM. 

<p>There is a way to add resource limits to some shells (for example,
<prgn>bash</prgn> has <prgn>ulimit</prgn>, see <manref section="1"
name="bash">), but since not all of them provide the same limits and
since the user can change shells (see <manref section="1"
name="chsh">) it is better to place the limits on the PAM modules as
they will apply regardless of the shell used and will also apply to
PAM modules that are not shell-oriented.

<p>Resource limits are imposed by the kernel, but they need to be
configured through the <file>limits.conf</file> and the PAM configuration
of the different services need to load the appropriate PAM. You can
check which services are enforcing limits by running:

<example>
$ find /etc/pam.d/ \! -name "*.dpkg*" | xargs -- grep limits |grep -v ":#"
</example>

<P>Commonly, <file>login</file>, <file>ssh</file> and the graphic
session managers (<file>gdm</file>, <file>kdm</file> or
<file>xdm</file>) should enforce user limits but you might want to do
this in other PAM configuration files, such as <file>cron</file>, to
prevent system daemons from taking over all system resources.

<p>The specific limits settings you might want to enforce depend on
your system's resources, that's one of the main reasons why no limits
are enforced in the default installation.</p>

<p>For example, the configuration example below enforces a 100 process
limit for all users (to prevent <em>fork bombs</em>) as well as a
limit of 10MB of memory per process and a limit of 10 simultaneous
logins. Users in the <tt>adm</tt> group have higher limits and
can produce core files if they want to (there is only a <em>soft</em>
limit).

<p>
<example>
*              soft    core            0
*              hard    core            0
*              hard    rss             1000
*              hard    memlock         1000
*              hard    nproc           100
*              -       maxlogins       1
*              hard    data            102400
*              hard    fsize           2048
@adm           hard    core            100000
@adm           hard    rss             100000
@adm           soft    nproc           2000
@adm           hard    nproc           3000
@adm           hard    fsize           100000
@adm           -       maxlogins       10
</example>

<p>These would be the limits a default user (including system daemons)
would have:

<example>
$ ulimit -a
core file size        (blocks, -c) 0
data seg size         (kbytes, -d) 102400
file size             (blocks, -f) 2048
max locked memory     (kbytes, -l) 10000
max memory size       (kbytes, -m) 10000
open files                    (-n) 1024
pipe size          (512 bytes, -p) 8
stack size            (kbytes, -s) 8192
cpu time             (seconds, -t) unlimited
max user processes            (-u) 100
virtual memory        (kbytes, -v) unlimited
</example>

<p>And these are the limits for an administrative user:

<example>
$ ulimit -a
core file size        (blocks, -c) 0
data seg size         (kbytes, -d) 102400
file size             (blocks, -f) 100000
max locked memory     (kbytes, -l) 100000
max memory size       (kbytes, -m) 100000
open files                    (-n) 1024
pipe size          (512 bytes, -p) 8
stack size            (kbytes, -s) 8192
cpu time             (seconds, -t) unlimited
max user processes            (-u) 2000
virtual memory        (kbytes, -v) unlimited
</example>


<p>For more information read:
<list>

<item><url
id="http://www.kernel.org/pub/linux/libs/pam/Linux-PAM-html/pam-6.html"
name="PAM reference guide for available modules">

<item><url
id="http://www.samag.com/documents/s=1161/sam0009a/0009a.htm"
name="PAM configuration article">.

<item> <url
id="http://seifried.org/security/os/linux/20020324-securing-linux-step-by-step.html"
name="Seifried's Securing Linux Step by Step"> on the <em>Limiting
users overview</em> section.

<item><url id="http://seifried.org/lasg/users/" name="LASG"> in the 
<em>Limiting and monitoring users</em> section.

</list>

<sect1>User login actions: edit <file>/etc/login.defs</file>
<p>
The next step is to edit the basic configuration and action upon user login.
Note that this file is not part of the PAM configuration, it's a configuration
file honored by <tt>login</tt> and <tt>su</tt> programs,
so it doesn't make sense tuning it for cases where neither of the two
programs are at least indirectly called (the <prgn>getty</prgn> program
which sits on the consoles and offers the initial login prompt 
<em>does</em> invoke <prgn>login</prgn>).

<example>
  FAIL_DELAY          10
</example>

<p>This variable should be set to a higher value to make it harder to
use the terminal to log in using brute force. If a wrong password is
typed in, the possible attacker (or normal user!) has to wait for 10
seconds to get a new login prompt, which is quite time consuming when
you test passwords. Pay attention to the fact that this setting is useless if
using program other than <prgn>getty</prgn>, such as <prgn>mingetty</prgn> 
for example.

<example>
  FAILLOG_ENAB        yes
</example>

If you enable this variable, failed logins will be logged. It is important to
keep track of them to catch someone who tries a brute force attack.

<example>
  LOG_UNKFAIL_ENAB    no
</example>

<p>If you set this variable to 'yes' it will record unknown usernames if the
login failed.  It is best if you use 'no' (the default) since, otherwise,
user passwords might be inadvertenly logged here (if a user mistypes
and they enter their password as the username). If you set it to 'yes', make
sure the logs have the proper permissions (640 for example, with an appropriate
group setting such as
adm).

<example>
  SYSLOG_SU_ENAB      yes
</example>

<p>This one enables logging of <prgn>su</prgn> attempts to <file>syslog</file>.
Quite important on serious machines but note that this can create privacy
issues as well.

<example>
  SYSLOG_SG_ENAB      yes
</example>

<p>The same as <var>SYSLOG_SU_ENAB</var> but applies to the <prgn>sg</prgn> 
program.

<example>
  MD5_CRYPT_ENAB      yes
</example>

<p>As stated above, MD5 sum passwords greatly reduce the problem of
dictionary attacks, since you can use longer passwords.
If you are using slink, read the docs about MD5 before enabling this
option.  Otherwise this is set in PAM.

<example>
  PASS_MAX_LEN        50
</example>

<p>If MD5 passwords are activated in your PAM configuration, then this
variable should be set to the same value as used there.


<sect1>Restricting ftp: editing <file>/etc/ftpusers</file>
<p>
The <file>/etc/ftpusers</file> file contains a list of users who are
not allowed to log into the host using ftp. Only use this file if you
really want to allow ftp (which is not recommended in general, because
it uses clear-text passwords). If your daemon supports PAM, you can
also use that to allow and deny users for certain services.

<p>FIXME (BUG): Is it a bug that the default <file>ftpusers</file> in Debian 
does <em>not</em> include all the administrative users (in 
<package>base-passwd</package>).

<p>
A convenient way to add all system accounts to the <file>/etc/ftpusers</file>
is to run

<example>
$ awk -F : '{if ($3<1000) print $1}' /etc/passwd > /etc/ftpusers
</example>

<sect1>Using su

<p>
If you really need users to become the super user on your system, e.g. for 
installing packages or adding users, you can use the command <prgn>su</prgn> 
to change your identity. You should try to avoid any login as user root and 
instead use <prgn>su</prgn>.  Actually, the best solution is to remove 
<prgn>su</prgn> and switch to the <prgn>sudo</prgn> mechanism which has
a broader logic and more features than 
<prgn>su</prgn>. However, <prgn>su</prgn> is more common as it is used on many 
other Unices.


<sect1>Using sudo

<p>
<prgn>sudo</prgn> allows the user to execute defined commands under
another user's identity, even as root. If the user is added to
<file>/etc/sudoers</file> and authenticates himself correctly, he is
able to run commands which have been defined in
<file>/etc/sudoers</file>. Violations, such as incorrect passwords or
trying to run a program you don't have permission for, are logged and
mailed to root.

<sect1>Disallow remote administrative access
<p>You should also modify <file>/etc/security/access.conf</file> to
disallow remote logins to administrative accounts. This way users
need to invoke <prgn>su</prgn> (or <prgn>sudo</prgn>)
to use any administrative powers and the appropriate audit trace
will always be generated.

<p>You need to add the following line to
<file>/etc/security/access.conf</file>, the default Debian
configuration file has a sample line commented out:
<example>
   -:wheel:ALL EXCEPT LOCAL
</example>

<p>Remember to enable the <tt>pam_access</tt> module for every
service (or default configuration) in <file>/etc/pam.d/</file> if you
want your changes to <file>/etc/security/access.conf</file> honored.


<sect1 id="user-restrict">Restricting users's access

<p>Sometimes you might think you need to have users created in your
local system in order to provide a given service (pop3 mail service or
ftp). Before doing so, first remember that the PAM implementation in
Debian GNU/Linux allows you to validate users with a wide variety of
external directory services (radius, ldap, etc.) provided by the
libpam packages.

<p>If users need to be created and the system can be accessed remotely
take into account that users will be able to log in to the system. You
can fix this by giving users a null (<file>/dev/null</file>) shell (it
would need to be listed in <file>/etc/shells</file>). If you want to
allow users to access the system but limit their movements, you can
use the <file>/bin/rbash</file>, equivalent to adding the <tt>-r</tt>
option in <prgn>bash</prgn> (<em>RESTRICTED SHELL</em> see <manref name="bash"
section="1">). Please note that even with restricted shell, a user
that access an interactive program (that might allow execution of a
subshell) could be able to bypass the limits of the shell.

<p>Debian currently provides in the unstable release (and might be included in 
the next stable releases) the <file>pam_chroot</file> module (in the <package>
libpam-chroot</package>). An alternative to it is to <prgn>chroot</prgn> the 
service that provides remote logging (<prgn>ssh</prgn>, <prgn>telnet</prgn>).
<footnote><package>libpam-chroot</package> has not been yet thoroughly
tested, it does work for <prgn>login</prgn> but it might not be easy to set up 
the environment for other programs</footnote>

<p>If you wish to restrict <em>when</em> users can access the system you will
have to customize <file>/etc/security/access.conf</file> for your
needs.

<p>Information on how to <prgn>chroot</prgn> users accessing the
system through the <prgn>ssh</prgn> service is described in <ref
id="chroot-ssh-env">.

<sect1>User auditing

<p>If you are really paranoid you might want to add a system-wide
configuration to audit what the users are doing in your system.
This sections presents some tips using diverse utilities you can use.

<sect2>Input and output audit with script

<P>You can use the <prgn>script</prgn> command to audit both what the
users run and what are the results of those commands.
You cannot setup <prgn>script</prgn> as a shell 
(even if you add it to <file>/etc/shells</file>). But you can have the
shell initialization file run the following:

<example>
umask 077
exec script -q -a "/var/log/sessions/$USER"
</example>

<p>Of course, if you do this system wide it means that the shell would
not continue reading personal initialization files (since the shell
gets overwritten by <prgn>script</prgn>). An alternative is to do this
in the user's initialization files (but then the user could remove this,
see the comments about this below)
</p>

<p>You also need to setup the
files in the audit directory (in the example <file>/var/log/sessions/</file>)
so that users can write to it but cannot remove the file. This could be
done, for example, by creating the user session files in advance and
setting them with the <em>append-only</em> flag using <prgn>chattr</prgn>.
</p>

<p>A useful alternative for sysadmins, which includes date information
would be:

<example>
umask 077
exec script -q -a "/var/log/sessions/$USER-`date +%Y%m%d`"
</example>

<sect2>Using the shell history file

<p>If you want to review what does the user type in the shell (but not
what the result of that is) you can setup a system-wide
<file>/etc/profile</file> that configures the
environment so that all commands are saved into a history file.
The system-wide configuration needs to be setup in such a way that users 
cannot remove audit capabilities from their shell. This is somewhat
shell specific so make sure that all users are using a shell that
supports this.</p>

<p>For example, for bash, the <file>/etc/profile</file> 
could be set as follows
<footnote>
Setting HISTSIZE to a very large number can cause issues under some
shells since the history is kept in memory for every user session. You
might be safer if you set this to a high-enough value and backup
user's history files (if you need all of the user's history for 
some reason)
</footnote>
:

<example>
  HISTFILE=~/.bash_history
  HISTSIZE=10000
  HISTFILESIZE=999999
  # Don't let the users enter commands that are ignored
  # in the history file
  HISTIGNORE=""
  HISTCONTROL=""
  readonly HISTFILE
  readonly HISTSIZE
  readonly HISTFILESIZE
  readonly HISTIGNORE
  readonly HISTCONTROL
  export HISTFILE HISTSIZE HISTFILESIZE HISTIGNORE HISTCONTROL
</example>

<p>For this to work, the user can only append information to
<file>.bash_history</file> file. You need <em>also</em> to set the 
<em>append-only</em> option using <prgn>chattr</prgn> program 
for <file>.bash_history</file> for all users.
<footnote>
Without the append-only flag users would be able to empty the 
contents of the history file running <tt> > .bash_history</tt>
</footnote>.

<p>Note that you could introduce the configuration above in 
the user's <file>.profile</file>. But
then you would need to setup permissions properly in such a way that
prevents the user from modifying this file. This includes: having the user's
home directories <em>not</em> belong to the user (since he would
be able to remove the file otherwise) but at the same time enable them
to read the <file>.profile</file> configuration file and write on the
<file>.bash_history</file>. It would be good to set
the <em>immutable</em> flag (also using <prgn>chattr</prgn>)
for <file>.profile</file> too if you do it this way.

<sect2>Complete user audit with accounting utilities

<p>The previous example is a simple way to configure user auditing
but might be not useful for complex systems or for those in which users 
do not run shells at all (or exclusively). If this is your case,
you need to look at <package>acct</package>, the accounting
utilities. These utilities will log all the commands run by users or processes
in the system, at the expense of disk space.

<p>When activating accounting, all the information on processes and
users is kept under <file>/var/account/</file>, more specifically in
the <file>pacct</file>. The accounting package includes some tools
(<prgn>sa</prgn>, <prgn>ac</prgn> and <prgn>lastcomm</prgn>) to analyse
this data.

<sect2>Other user auditing methods
<p>If you are completely paranoid and want to audit every user's command, you 
could take <prgn>bash</prgn> source code, edit it and have it send all that 
the user typed into another file. Or have <package>ttysnoop</package> 
constantly monitor any new ttys
<footnote>Ttys are spawned for local logins and remote logins through ssh and telnet</footnote>
and dump the output into a file. Other useful 
program is <package>snoopy</package> 
(see also  <url id="http://sourceforge.net/projects/snoopylogger/" name="the project page">)
which is a user-transparent program that 
hooks in as a library providing a wrapper around <var>execve()</var> 
calls, any command executed is logged to <prgn>syslogd</prgn> using the 
<tt>authpriv</tt> facility (usually stored at <file>/var/log/auth.log</file>).

<sect1>Reviewing user profiles

<p>If you want to <em>see</em> what users are actually doing when they 
logon to the system you can use the <file>wtmp</file> database that
includes all login information. This file can be processed with
several utilities, amongst them <prgn>sac</prgn> which can output a
profile on each user showing in which timeframe they usually log on to
the system.

<p>In case you have accounting activated, you can also use the tools
provided by it in order to determine when the users access the
system and what do they execute. 

<sect1>Setting users umasks

<p>Depending on your user policy you might want to change how
information is shared between users, that is, what the default
permissions of new files created by users are. 

<p>Debian's default <tt>umask</tt> setting is <em>022</em> this means
that files (and directories) can be read and accessed by the user's
group and by any other users in the system. This definition is set
in the standard configuration file <file>/etc/profile</file> which 
is used by all shells.

<p>If Debian's default value is too permissive for your system you will have to
change the umask setting for all the shells. More restrictive umask settings
include 027 (no access is allowed to new files for the <em>other</em> group,
i.e. to other users in the system) or 077 (no access is allowed to new files
to the members the user's group). Debian (by default<footnote><p>As defined in 
<file>/etc/adduser.conf</file> (USERGROUPS=yes). You can change this behaviour if
you set this value to no, although it is not recommended</p></footnote>)
creates one group per user so that only the user is included in its group.
Consequently 027 and 077 are equivalent as the user's group contains only the
user himself.

<p>This change is set by defining a proper <tt>umask</tt> setting for all
users. You can change this by introducing an <prgn>umask</prgn> call
in the shell configuration files: <file>/etc/profile</file> (source by
all Bourne-compatible shells), <file>/etc/csh.cshrc</file>,
<file>/etc/csh.login</file>, <file>/etc/zshrc</file> and probably some
others (depending on the shells you have installed on your system). You
can also change the <var>UMASK</var> setting in <file>/etc/login.defs</file>,
Of all of these the last one that gets loaded by the shell takes precedence.
The order is: the default system configuration for the user's shell (i.e.
<file>/etc/profile</file> and other system-wide configuration files) and then
the user's shell (his <file>~/.profile</file>, <file>~/.bash_profile</file>,
etc...).  Some shells, however, can be executed with a <em>nologin</em> value
which might skip sourcing some of those files. See your shell's manpage
for additional information.

<p>For connections that make use of <prgn>login</prgn> the UMASK definition in
<file>/etc/login.defs</file> is used before any of the others. However, that
value does not apply to user executed programs  that do not use
<prgn>login</prgn> such as those run through <prgn>su</prgn>, <prgn>cron</prgn>
or <prgn>ssh</prgn>.

<p>Don't forget to review and maybe modify the dotfiles under
<file>/etc/skel/</file> since these will be new user's defaults when created
with the <prgn>adduser</prgn> command. Debian default dotfiles do not include
any <prgn>umask</prgn> call but if there is any in the dotfiles newly created
users might a different value.

<p>Note, however that users can modify their own <tt>umask</tt> setting if they
want to, making it more permissive or more restricted, by changing their
own dotfiles.

<p>The <package>libpam-umask</package> package adjusts the users' default
<tt>umask</tt> using PAM.  Add the following, after installing the package, to 
<file>/etc/pam.d/common-session</file>:

<example>
session    optional     pam_umask.so umask=077
</example>

<p>Finally, you should consider changing root's default 022 umask (as defined
in <file>/root/.bashrc</file>) to a more strict umask. That will prevent the
system administrator from inadvertenly dropping sensitive files when working as
root to world-readable directories (such as <file>/tmp</file>) and having
them available for your average user.

<sect1>Limiting what users can see/access

<P>FIXME: Content needed. Describe the consequences of changing packages 
permissions when upgrading (an admin this paranoid should <prgn>chroot</prgn> 
his users BTW) if not using <prgn>dpkg-statoverride</prgn>.

<p>If you need to grant users access to the system with a shell think
about it very carefully. A user can, by default unless in a severely
restricted environment (like a <tt>chroot</tt> jail), retrieve
quite a lot of information from your system including:

<list>

<item>some configuration files in <file>/etc</file>. However, Debian's default
permissions for some sensitive files (which might, for example,
contain passwords), will prevent access to critical information. To
see which files are only accessible by the root user
for example <tt>find /etc -type f -a -perm 600 -a -uid 0</tt> as
superuser.

<item>your installed packages, either by looking at the package
database, at the <file>/usr/share/doc</file> directory or by guessing
by looking at the binaries and libraries installed in your system.

<item>some log files at <file>/var/log</file>. Note also that some
log files are only accessible to root and the <tt>adm</tt> group (try
<tt>find /var/log -type f -a -perm 640</tt>) and some are even only
available to the root user (try <tt>find /var/log -type f -a -perm
600 -a -uid 0</tt>).

</list>


<p>What can a user see in your system? Probably quite a lot of things,
try this (take a deep breath):
<example>
  find / -type f -a -perm +006 2>/dev/null  
  find / -type d -a -perm +007 2>/dev/null  
</example>

<p>The output is the list of files that a user can <em>see</em> and
the directories to which he has access.

<sect2 id="limit-user-perm">Limiting access to other user's information

<p>If you still grant shell access to users you might want to limit
what information they can view from other users. Users with shell
access have a tendency to create quite a number of files under their
$HOMEs: mailboxes, personal documents, configuration of X/GNOME/KDE
applications... 

<p>In Debian each user is created with one associated group, and
no two users belong to the same group. This is the default behavior:
when an user account is created, a group
of the same name is created too, and the user is assigned to it.
This avoids the concept of a common <em>users</em>
group which might make it more difficult for users to hide information
from other users.

<p>However, users' <var>$HOME</var> directories are created with 0755 
permissions (group-readable and world-readable). The group permissions is not 
an issue since only the user belongs to the group, however the world 
permissions might (or might not) be an issue depending on your local policy.

<p>You can change this behavior so that user creation provides different 
<var>$HOME</var> permissions. To change the behavior for <em>new</em> users 
when they get created, change <em>DIR_MODE</em> in the configuration file 
<file>/etc/adduser.conf</file> to 0750 (no world-readable access).

<p>Users can still share information, but not directly in their 
<var>$HOME</var> directories unless they change its permissions.

<p>Note that disabling world-readable home directories will prevent
users from creating their personal web pages in the <file>~/public_html</file> 
directory, since the web server will not be able to read one component in
the path - namely their <var>$HOME</var> directory.
If you want to permit
users to publish HTML pages in their <file>~/public_html</file>,
then change <em>DIR_MODE</em> to 0751. This will allow the web server
to access the final <file>public_html</file> directory (which itself should
have a mode of 0755) and provide the content published by users.
Of course, we are only talking about a default configuration here; users
can generally tune modes of their own files completely to their liking,
or you could keep content intended for the web in a separate location 
which is not a subdirectory of user's <var>$HOME</var> directory.

<sect1 id="user-pwgen">Generating user passwords

<p>There are many cases when an administrator needs to create many
user accounts and provide passwords for all of them. Of course, the
administrator could easily just set the password to be the same as the
user's account name, but that would not be very sensitive
security-wise. A better approach is to use a password generating
program. Debian provides <package>makepasswd</package>,
<package>apg</package> and <package>pwgen</package> packages which
provide programs (the name is the same as the package) that can be
used for this purpose. <prgn>Makepasswd</prgn> will generate true
random passwords with an emphasis on security over pronounceability
while <prgn>pwgen</prgn> will try to make meaningless but
pronounceable passwords (of course this might depend on your mother
language). <prgn>Apg</prgn> has algorithms to provide for both (there
is a client/server version for this program but it is not included in
the Debian package).

<p><prgn>Passwd</prgn> does not allow non-interactive assignation of
passwords (since it uses direct tty access). If you want to change
passwords when creating a large number of users you can create them
using <prgn>adduser</prgn> with the <tt>--disabled-login</tt> option
and then use <prgn>usermod</prgn> or <prgn>chpasswd</prgn>
<footnote>
<prgn>Chpasswd</prgn> cannot handle MD5 password generation so it needs to be 
given the password in encrypted form before using it, with the <tt>-e</tt>
option.
</footnote>
(both from the <package>passwd</package> package so you already have them
installed). If you want to use a file with all the information to make
users as a batch process you might be better off using
<prgn>newusers</prgn>.

<sect1>Checking user passwords

<p>User passwords can sometimes become the <em>weakest link</em> in the 
security of a given system. This is due to some users choosing weak passwords 
for their accounts (and the more of them that have access to it the greater 
the chances of this happening). Even if you established checks with the 
cracklib PAM module and password limits as described in <ref id="auth-pam"> 
users will still be able to use weak passwords. Since user access might 
include remote shell access (over <prgn>ssh</prgn>, hopefully) it's important 
to make password guessing as hard as possible for the remote attackers, 
especially if they were somehow able to collect important information such
as usernames or even the <file>passwd</file> and <file>shadow</file> files
themselves.

<p>A system administrator must, given a big number of users, check if
the passwords they have are consistent with the local security
policy. How to check? Try to crack them as an attacker would if he had
access to the hashed passwords (the <file>/etc/shadow</file> file). 

<p>An administrator can use <package>john</package> or <package>crack</package>
(both are brute force password crackers) together with an appropriate wordlist 
to check users' passwords and take appropriate action when a weak
password is detected.
You can search for Debian GNU packages that contain word lists using 
<prgn>apt-cache search wordlist</prgn>, or visit the classic Internet
wordlist sites such as 
<url id="ftp://ftp.ox.ac.uk/pub/wordlists"> or
<url id="ftp://ftp.cerias.purdue.edu/pub/dict">.

<sect1 id="idle-logoff">Logging off idle users

<p>Idle users are usually a security problem, a user might be idle
maybe because he's out to lunch or because a remote connection
hung and was not re-established. For whatever the reason, idle users
might lead to a compromise:

<list>
<item>because the user's console might be unlocked and can be
accessed by an intruder.  

<item>because an attacker might be able to re-attach himself to a
closed network connection and send commands to the remote shell (this
is fairly easy if the remote shell is not encrypted as in the case of
<prgn>telnet</prgn>).
</list>

<p>Some remote systems have even been compromised
through an idle (and detached) <prgn>screen</prgn>.

<p>Automatic disconnection of idle users is usually a part of the local 
security policy that must be enforced. There are several ways to do this:

<list>
<item>If <prgn>bash</prgn> is the user shell, a system administrator 
can set a default <tt>TMOUT</tt> value (see <manref section="1" name="bash">) 
which will make the shell automatically log off remote idle users. Note that it 
must be set with the <tt>-o</tt> option or users will be able to 
change (or unset) it.

<item>Install <package>timeoutd</package> and configure
<file>/etc/timeouts</file> according to your local security
policy. The daemon will watch for idle users and time out their shells
accordingly.
<!-- FIXME : Does 'screen' prevent timeoutd from detecting idle time like
I think it does, or it was due to my tricks with ttysnoop. -->

<item>Install <package>autolog</package> and configure it to remove idle users.

</list>

<p>The <prgn>timeoutd</prgn> or <prgn>autolog</prgn> daemons are the
preferred method since, after all, users can change their default shell
or can, after running their default shell, switch to another
(uncontrolled) shell.


<sect id="tcpwrappers">Using tcpwrappers 

<p>TCP wrappers were developed when there were no real packet filters
available and access control was needed. Nevertheless, they're still very 
interesting and useful.
The TCP wrappers allow you to
allow or deny a service for a host or a domain and define a default
allow or deny rule (all performed on the application level).
If you want more information take a look at
<manref name="hosts_access" section="5">.

<p>Many services installed in Debian are either:

<list>
<item>launched through the tcpwrapper service (<file>tcpd</file>)
<item>compiled with libwrapper support built-in.
</list>

<p>On the one hand, for services configured in
<file>/etc/inetd.conf</file> (this includes <prgn>telnet</prgn>, 
<prgn>ftp</prgn>, <prgn>netbios</prgn>, <prgn>swat</prgn>
and <prgn>finger</prgn>) you will see that the configuration file executes
<prgn>/usr/sbin/tcpd</prgn> first. On the other hand, even if a
service is not launched by the <prgn>inetd</prgn> superdaemon,
support for the tcp wrappers rules can be compiled
into it. Services compiled with tcp wrappers in Debian include
<prgn>ssh</prgn>, <prgn>portmap</prgn>, <prgn>in.talk</prgn>,
<prgn>rpc.statd</prgn>, <prgn>rpc.mountd</prgn>, <prgn>gdm</prgn>,
<prgn>oaf</prgn> (the GNOME
activator daemon), <prgn>nessus</prgn> and many others. 

<p>To see which packages use tcpwrappers
<footnote>
<p>On older Debian releases you might need to do this:
<example>
  $ apt-cache showpkg libwrap0 | egrep '^[[:space:]]' | sort -u | \
        sed 's/,libwrap0$//;s/^[[:space:]]\+//'
</example>
</footnote>
try:

<example>
  $ apt-cache rdepends libwrap0
</example>


<p>Take this into account when running <prgn>tcpdchk</prgn>
(a very useful TCP wrappers config file rule and syntax checker).
When you add stand-alone services (that are directly linked with the wrapper
library) into the <file>hosts.deny</file> and <file>hosts.allow</file> files,
<prgn>tcpdchk</prgn> will warn you that it is not able to find
the mentioned services since it only looks for them in
<file>/etc/inetd.conf</file> (the manpage is not totally accurate here).

<p>Now, here comes a small trick, and probably the smallest intrusion 
detection system available. In general, you should have a decent firewall 
policy as a first line, and tcp wrappers as the second line of defense. One 
little trick is to set up a <var>SPAWN</var> <footnote>be sure to use 
uppercase here since <em>spawn</em> will not work</footnote> command in 
<file>/etc/hosts.deny</file> that sends mail to root whenever a denied service
triggers wrappers:

<example>
  ALL: ALL: SPAWN ( \
    echo -e "\n\
    TCP Wrappers\: Connection refused\n\
    By\: $(uname -n)\n\
    Process\: %d (pid %p)\n\
    User\: %u\n\
    Host\: %c\n\
    Date\: $(date)\n\
  " | /usr/bin/mail -s "Connection to %d blocked" root) &
</example>

<p><em>Beware</em>: The above printed example is open to a DoS attack by
making many connections in a short period of time. Many emails mean
a lot of file I/O by sending only a few packets.

<!--
# Could this example be more interesting? 
# It also relates to the next section (jfs)
#
# era: cf hosts_access(5) manual page,
# and why are you not using logger(1) here? (FIXME?)
#
#&lt;example&gt;
#ALL: ALL: SPAWN ( \
#  /usr/local/sbin/send_syslog %u %c %d )
#&lt;example&gt;

#  With send_syslog as:
##!/usr/bin/perl -w
#
#use Sys::Syslog qw(:DEFAULT setlogsock);
#
#$user=shift(@ARGV) || 'unknown';
#$host=shift(@ARGV) || 'unknown';
#$service=shift(@ARGV) || 'unknown';
#setlogsock('unix');
#openlog("alert",'', 'user');
#syslog('warning', 'Connection from %s at %s to %s blocked.', ($user, $host, $service) );
#closelog();
#
#exit 0;
-->

<sect id="log-alerts">The importance of logs and alerts

<p>It is easy to see that the treatment of logs and alerts is an
important issue in a secure system. Suppose a system is perfectly
configured and 99% secure. If the 1% attack occurs, and there are no
security measures in place to, first, detect this and, second, raise
alarms, the system is not secure at all.

<p>Debian GNU/Linux provides some tools to perform log analysis, most notably 
<package>swatch</package>, <footnote>there's a very good article on it written 
by <url id="http://www.spitzner.net/swatch.html" name="Lance Spitzner">
</footnote> <package>logcheck</package> or <package>log-analysis</package> 
(all will need some customisation to remove unnecessary things from the 
report). It might also be useful, if the system is nearby, to have the system 
logs printed on a virtual console. This is useful since you can (from a 
distance) see if the system is behaving properly. Debian's 
<file>/etc/syslog.conf</file> comes with a commented default configuration; to 
enable it uncomment the lines and restart <prgn>syslogd</prgn>
(<tt>/etc/init.d/syslogd restart</tt>):

<example>
  daemon,mail.*;\
        news.=crit;news.=err;news.=notice;\
        *.=debug;*.=info;\
        *.=notice;*.=warn       /dev/tty8
</example>


<p>
To colorize the logs, you could take a look at
<package>colorize</package>, <package>ccze</package> or
<package>glark</package>. There is a lot to log analysis that
cannot be fully covered here, so a good information resource would be
<url name="Log Analysis" id="http://www.loganalysis.org/"> website.
In any case, even automated tools are no match for the best
analysis tool: your brain. 

<!-- FIXME: Check information on SHARP, the 'syslog heuristic analysis
and response program'. The paper is at
id="http://www.csis.gvsu.edu/sharp/". Is it free software? packaged?

URL doesn't exist any more, but its archive on archive.org:
http://web.archive.org/web/20020816100838/http://www.csis.gvsu.edu/sharp/
http://web.archive.org/web/20020816100838/http://www.csis.gvsu.edu/sharp/sharp.ps

No download location is available.
-->

<sect1 id="custom-logcheck">Using and customizing <prgn>logcheck</prgn>

<p>The <prgn>logcheck</prgn> package in Debian is divided into the
three packages <package>logcheck</package> (the main program),
<package>logcheck-database</package> (a database of regular
expressions for the program) and <package>logtail</package> (prints
loglines that have not yet been read). The Debian default (in
<file>/etc/cron.d/logcheck</file>) is that <prgn>logcheck</prgn> is run
every hour and after reboots.

<p>This tool can be quite useful if properly customized to alert the
administrator of unusual system events. <prgn>Logcheck</prgn>
can be fully customized so that it sends mails based on events found
in the logs and worthy of attention. The default
installation includes profiles for ignored events and policy
violations for three different setups (workstation, server and
paranoid). The Debian package includes a configuration file
<file>/etc/logcheck/logcheck.conf</file>, sourced by the program, that
defines which user the checks are sent to. It also provides a way for
packages that provide services to implement new policies in the
directories: <file>/etc/logcheck/cracking.d/_packagename_</file>,
<file>/etc/logcheck/violations.d/_packagename_</file>,
<file>/etc/logcheck/violations.ignore.d/_packagename_</file>,
<file>/etc/logcheck/ignore.d.paranoid/_packagename_</file>,
<file>/etc/logcheck/ignore.d.server/_packagename_</file>, and
<file>/etc/logcheck/ignore.d.workstation/_packagename_</file>. However,
not many packages currently do so. If you have a policy that can be
useful for other users, please send it as a bug report for the
appropriate package (as a <em>wishlist</em> bug). For more information read
<file>/usr/share/doc/logcheck/README.Debian</file>.

<p>The best way to configure <prgn>logcheck</prgn> is to edit its
main configuration file <file>/etc/logcheck/logcheck.conf</file>
after installation. Change the default user (root) to whom reports 
should be mailed. You should set the reportlevel in there, too.
<package>logcheck-database</package> has three report levels of 
increasing verbosity: workstation, server, paranoid.
"server" being the default level, paranoid is only recommended
for high-security machines running as few services as possible
and workstation for relatively sheltered, non-critical machines.
If you wish to add new log files just add them to
<file>/etc/logcheck/logcheck.logfiles</file>. It is tuned for default
syslog install.

<p>Once this is done you might want to check the mails that are sent, for the 
first few days/weeks/months. If you find you are sent messages you do not wish 
to receive, just add the regular expressions (see
<manref name="regex" section="7"> and <manref name="egrep" section="1">) that
correspond to these messages to the
<file>/etc/logcheck/ignore.d.<var>reportlevel</var>/local</file>.
Try to match the whole logline. Details on howto write rules are explained in
<file>/usr/share/doc/logcheck-database/README.logcheck-database.gz</file>.
It's an ongoing tuning process; once the messages that are sent are always
relevant you can consider the tuning finished.  Note that if
<prgn>logcheck</prgn> does not find anything relevant in your system
it will not mail you even if it does run (so you might get a mail only
once a week, if you are lucky).


<sect1>Configuring where alerts are sent

<p>Debian comes with a standard <tt>syslog</tt> configuration (in 
<file>/etc/syslog.conf</file>) that logs messages to the appropriate files 
depending on the system facility.  You should be familiar with this; have a 
look at the <file>syslog.conf</file> file and the documentation if not. If you 
intend to maintain a secure system you should be aware of where log messages 
are sent so they do not go unnoticed.

<p>For example, sending messages to the console also is an interesting
setup useful for many production-level systems. But for many such
systems it is also important to add a new machine that will serve as
loghost (i.e. it receives logs from all other systems).

<p>Root's mail should be considered also, many security controls (like
<package>snort</package>) send alerts to root's mailbox. This 
mailbox usually points to
the first user created in the system (check <file>/etc/aliases</file>).
Take care to send root's mail to some place where it will be read (either
locally or remotely).

<p>There are other role accounts and aliases on your system.  On a
small system, it's probably simplest to make sure that all such
aliases point to the root account, and that mail to root is forwarded
to the system administrator's personal mailbox.

<p>FIXME: It would be interesting to tell how a Debian system can
send/receive SNMP traps related to security problems (jfs). Check:
<package>snmptrapfmt</package>, <package>snmp</package> and
<package>snmpd</package>.


<sect1>Using a loghost

<p>A loghost is a host which collects syslog data remotely over the
network. If one of your machines is cracked, the intruder is not able
to cover his tracks, unless he hacks the loghost as well.  So, the
loghost should be especially secure.  Making a machine a loghost is
simple. Just start the <prgn>syslogd</prgn> with <tt>syslogd -r</tt> 
and a new loghost is born. In order to do this permanently in Debian, edit
<file>/etc/default/syslogd</file> and change the line

<!-- FIXME: The following could also be interesting -->
<!-- How to hide the logging server on the network i.e. by not giving -->
<!-- it an IP address and adding a static ARP entry on the hosts using -->
<!-- the remote syslog server (only if on the same hub); if the remote -->
<!-- syslog server would be on a separate network, the default gateway -->
<!-- should be configured accordingly. -->

<example>
SYSLOGD=""
</example>
to 
<example>
SYSLOGD="-r"
</example>

Next, configure the other machines to send data to the loghost. Add
an entry like the following to <file>/etc/syslog.conf</file>:

<example>
  facility.level            @your_loghost
</example>

See the documentation for what to use in place of <em>facility</em>
and <em>level</em> (they should not be entered verbatim like this).
If you want to log everything remotely, just write:

<example>
  *.*                       @your_loghost
</example>

into your <file>syslog.conf</file>. Logging remotely as well as locally 
is the best solution (the attacker might presume to have covered 
his tracks after deleting the local log files). See the <manref name="syslog"
section="3">, <manref name="syslogd" section="8"> and <manref
name="syslog.conf" section="5"> manpages for additional information.


<sect1>Log file permissions

<p>It is not only important to decide how alerts are used, but also
who has read/modify access to the log files (if not
using a remote loghost).  Security alerts which the attacker can
change or disable are not worth much in the event of an intrusion.
Also, you have to take into account that log files might reveal
quite a lot of information about your system to an intruder 
if he has access to them.

<!--  It should be explained why after installation this is not
 already done, jfs -->

<p>Some log file permissions are not perfect after the installation (but of 
course this really depends on your local security policy). First 
<file>/var/log/lastlog</file> and <file>/var/log/faillog</file> do not need to 
be readable by normal users. In the <file>lastlog</file> file you can see who 
logged in recently, and in the <file>faillog</file> you see a summary of failed
logins. The author recommends <prgn>chmod 660</prgn> for both. Take a brief 
look at your log files and decide very carefully which log files to make 
readable/writable for a user with a UID other than 0 and a group other than 
'adm' or 'root'. You can easily check this in your system with:

<example>
  #  find /var/log -type f -exec ls -l {} \; | cut -c 17-35 |sort -u
  (see to what users do files in /var/log belong)
  #  find /var/log -type f -exec ls -l {} \; | cut -c 26-34 |sort -u
  (see to what groups do files in /var/log belong)
  # find /var/log -perm +004
  (files which are readable by any user)
  #  find /var/log \! -group root \! -group adm -exec ls -ld {} \;
  (files which belong to groups not root or adm)
</example>

<p>To customize how log files are created you will probably have to
customize the program that generates them. If the log file gets
rotated, however, you can customize the behavior of creation and rotation.

<!-- This is no longer true, check apache's logrotate
<p>
I want to emphasize that the apache log file permissions are really
screwed due to the fact that the apache user owns the apache log
files. If a user gets a shell with a back door in apache, they can
easily remove the log files.
-->

<sect id="kernel-patches">Adding kernel patches

<p>Debian GNU/Linux provides some of the patches for the Linux kernel
that enhance its security. These include:

<list>

<item>
<url id="http://www.lids.org" name="Linux Intrusion Detection">
provided in the <package>kernel-patch-2.4-lids</package> package.
This kernel patch makes the
process of hardening your Linux system easier by allowing you to
restrict, hide and protect processes, even from root. It implements
mandatory access control capabilities.


<item><url id="http://trustees.sourceforge.net/" name="Linux Trustees">,
provided in package <package>trustees</package>. This patch
adds a decent advanced permissions management system to your Linux kernel.
Special objects (called trustees) are bound to every file or directory, and
are stored in kernel memory, which allows fast lookup of all permissions.

<item>NSA Enhanced Linux (in package <package>selinux</package>). Backports
of the SElinux-enabled packages are available at
<url id="http://selinux.alioth.debian.org/">.
More
information available at
<url id="http://wiki.debian.org/SELinux" name="SElinux in Debian Wiki page">,
at 
<url id="http://www.golden-gryphon.com/software/security/selinux.xhtml" 
name="Manoj Srivastava's"> and
<url id="http://www.coker.com.au/selinux/" name="Russell Cookers's"> SElinux
websites.

<item>The <url id="http://people.redhat.com/mingo/exec-shield/"
name="exec-shield patch"> provided in the
<package>kernel-patch-exec-shield</package> package. This patch provides
protection against some buffer overflows (stack smashing attacks).

<item>The <url id="http://www.grsecurity.net/" name="Grsecurity patch">,
provided by the <package>kernel-patch-2.4-grsecurity</package> and
<package>kernel-patch-grsecurity2</package> packages
<footnote>
Notice that this patch conflicts with patches already included
in Debian's 2.4 kernel source package. You will need to
use the stock vanilla kernel. You can do this with the following steps:
<example>
# apt-get install kernel-source-2.4.22 kernel-patch-debian-2.4.22
# tar xjf /usr/src/kernel-source-2.4.22.tar.bz2
# cd kernel-source-2.4.22
# /usr/src/kernel-patches/all/2.4.22/unpatch/debian
</example>
<p>For more
information see <url id="http://bugs.debian.org/194225"
name="#194225">, <url id="http://bugs.debian.org/199519"
name="#199519">, <url id="http://bugs.debian.org/206458"
name="#206458">, <url id="http://bugs.debian.org/203759"
name="#203759">, <url id="http://bugs.debian.org/204424"
name="#204424">, <url id="http://bugs.debian.org/210762"
name="#210762">, <url id="http://bugs.debian.org/211213"
name="#211213">, and the <url
id="http://lists.debian.org/debian-devel/2003/debian-devel-200309/msg01133.html"
name="discussion at debian-devel">
</footnote>
implements Mandatory Access
Control through RBAC, provides buffer overflow protection through PaX, 
ACLs, network randomness (to make OS fingerprinting more difficult) and <url
id="http://www.grsecurity.net/features.php" name="many more
features">.

<item>The <package>kernel-patch-adamantix</package> provides the patches
developed for <url id="http://www.adamantix.org/" name="Adamantix">,
a Debian-based distribution. This kernel patch for the 2.4.x kernel
releases introduces some security features such as a non-executable stack
through the use of 
<url id="http://pageexec.virtualave.net/" name="PaX"> and mandatory
access control based on <url id="http://www.rsbac.org/" name="RSBAC" >.
Other features include: 
<url name="the Random PID patch" id="http://www.vanheusden.com/Linux/sp/">,
AES encrypted loop device, MPPE support and an IPSEC v2.6 backport.


<item><package>cryptoloop-source</package>. This patches allows you to
use the functions of the kernel crypto API 
to create encrypted filesystems using the loopback device.

<item>IPSEC kernel support (in package
<package>linux-patch-openswan</package>). If you want to use the
IPsec protocol with Linux, you need this patch. You can create VPNs
with this quite easily, even to Windows machines, as IPsec is a common
standard. IPsec capabilities have been added to the 2.5 development
kernel, so this feature will be present by default in the future Linux
Kernel 2.6. Homepage: <url id="http://www.openswan.org">. 

<em>FIXME</em>: The latest 2.4 kernels provided in Debian include a backport of
the IPSEC code from 2.5. Comment on this.

</list>

<p>The following security kernel patches are only available for old
kernel versions in woody and are deprecated:

<list>
<item><url id="http://acl.bestbits.at/" name="POSIX Access Control Lists">
(ACLs) for Linux provided in the package 
<package>kernel-patch-acl</package>. This kernel patch adds access
control lists, an advanced method for restricting access to files. It
allows you to control fine-grain access to files and directory. 

<item>The <url name="Openwall" id="http://www.openwall.com/linux/">
linux kernel patch by Solar Designer, provided in the 
<package>kernel-patch-2.2.18-openwall</package> package.
This is a useful set of kernel restrictions, like restricted
links, FIFOs in <file>/tmp</file>, a restricted <file>/proc</file>
file system, special file descriptor handling, non-executable user
stack area and other features. Note: This package applies to the 2.2
release, no packages are available for the 2.4 release patches provided
by Solar.

<item><package>kernel-patch-int</package>. This patch also adds
cryptographic capabilities to the Linux kernel, and was useful with
Debian releases up to Potato. It doesn't work with Woody, and if you
are using Sarge or a newer version, you should use a more recent
kernel which includes these features already.

</list>

<!-- FIXME: Make the entries coherent: should the package names be links to the
relevant package pages? -->

<p>However, some patches have not been provided in Debian yet. If you
feel that some of these should be included please ask for it at the
<url name="Work Needing and Prospective Packages"
id="http://www.debian.org/devel/wnpp/">.

<sect>Protecting against buffer overflows

<p><em>Buffer overflow</em> is the name of a common attack to software
<footnote>So common, in fact, that they have been the basis of 20% of the
reported security vulnerabilities every year, as determined by 
<url id="http://icat.nist.gov/icat.cfm?function=statistics"
name="statistics from ICAT's vulnerability database"></footnote>
which makes use of insufficient boundary checking (a 
programming error, most commonly in the C language) in order to execute
machine code through
program inputs. These attacks, against server software which listen
to connections remotely and against local software which grant higher
privileges to users (<tt>setuid</tt> or <tt>setgid</tt>) can result in the 
compromise of any given system.

<p>There are mainly four methods to protect against buffer overflows:

<list>

<item>patch the kernel to prevent stack execution. You can use either:
Exec-shield, OpenWall or PaX (included in the Grsecurity and Adamantix
patches).

<item>fix the source code by using tools to find fragments of it that
might introduce this vulnerability.

<item>recompile the source code to introduce proper checks that
prevent overflows, using the <url
id="http://www.research.ibm.com/trl/projects/security/ssp/" name="Stack
Smashing Protector (SSP)"> patch for GCC (which is used by <url
id="http://www.adamantix.org" name="Adamantix">)

</list>

<p>Debian GNU/Linux, as of the 3.0 release, provides software to
introduce all of these methods except for the protection on source
code compilation (but this has been requested in <url
id="http://bugs.debian.org/213994" name="Bug #213994">).

<p>Notice that even if Debian provided a compiler which featured
stack/buffer overflow protection all packages would need to be
recompiled in order to introduce this feature. This is, in fact, what
the Adamantix distribution does (among other features). The effect of this 
new feature on the stability of software is yet to be determined
(some programs or some processor architectures might break due to it).

<p>In any case, be aware that even these workarounds might not
prevent buffer overflows since there are ways to circumvent these, as
described in phrack's magazine <url name="issue 58"
id="http://packetstorm.linuxsecurity.com/mag/phrack/phrack58.tar.gz">
or in CORE's Advisory
<url id="http://online.securityfocus.com/archive/1/269246"
name="Multiple vulnerabilities in stack smashing protection technologies">.

<p>If you want to test out your buffer overflow protection once you
have implemented it (regardless of the method) you might want
to install the <package>paxtest</package> and run the tests it provides.

<sect1>Kernel patch protection for buffer overflows

<p>Kernel patches related to buffer overflows include the Openwall
patch provides protection against buffer overflows in 2.2 linux
kernels. For 2.4 or newer kernels, you need to use the Exec-shield
implementation, or the PaX implementation (provided in the 
grsecurity patch, <package>kernel-patch-2.4-grsecurity</package>,
and in the Adamantix patch, <package>kernel-patch-adamantix</package>).
For more information on using these patches read the the section <ref
id="kernel-patches">.

<sect1>Testing programs for overflows

<p>The use of tools to detect buffer overflows requires, in any case,
of programming experience in order to fix (and recompile) the
code. Debian provides, for example: <package>bfbtester</package> (a
buffer overflow tester that brute-forces binaries through command line
and environment overflows)<!-- FIXME: Where is it? and <package>njamd</package>-->. Other packages
of interest would also be <package>rats</package>, <package>pscan</package>,
<package>flawfinder</package> and <package>splint</package>.


<sect>Secure file transfers 

<p>During normal system administration one usually needs to transfer
files in and out from the installed system. Copying files in a secure
manner from a host to another can be achieved by using the
<package>ssh</package> server package. Another possibility is the use
of <package>ftpd-ssl</package>, a ftp server which uses the <em>Secure
Socket Layer</em> to encrypt the transmissions.

<p>Any of these methods need special clients. Debian does
provide client software, such as <prgn>scp</prgn> from the 
<package>ssh</package> package, which works like <prgn>rcp</prgn> but is
encrypted completely, so the <em>bad guys</em> cannot even find out WHAT you
copy. There is also a <package>ftp-ssl</package> package for
the equivalent server. You can find clients for these software even
for other operating systems (non-UNIX), <prgn>putty</prgn> and
<prgn>winscp</prgn> provide secure copy implementations for any
version of Microsoft's operating system.

<p>Note that using <prgn>scp</prgn> provides access to the users to
all the file system unless <prgn>chroot</prgn>'ed as described in <ref
id="ssh-chroot">. FTP access can be <prgn>chroot</prgn>'ed, probably easier
depending on you chosen daemon, as described in <ref
id="ftp-secure">. If you are worried about users browsing your local
files and want to have encrypted communication you can either use an
ftp daemon with SSL support or combine clear-text ftp and a VPN setup
(see <ref id="vpn">).

<sect>File system limits and control

<sect1>Using quotas

<p>
Having a good quota policy is important, as it keeps users from
filling up the hard disk(s).
<p>
You can use two different quota systems: user quota and group
quota. As you probably figured out, user quota limits the amount of
space a user can take up, group quota does the equivalent for
groups. Keep this in mind when you're working out quota sizes.

<p>There are a few important points to think about in setting up a
quota system:

<list>
<item>Keep the quotas small enough, so users do not eat up your disk
space.

<item>Keep the quotas big enough, so users do not complain or their mail quota
keeps them from accepting mail over a longer period.

<item>Use quotas on all user-writable areas, on <file>/home</file> as well 
as on <file>/tmp</file>.
</list>

<p>Every partition or directory to which users have full write access should
be quota enabled. Calculate and assign a workable quota size for those 
partitions and directories which combines usability and security.

<p>So, now you want to use quotas. First of all you need to check
whether you enabled quota support in your kernel. If not, you will
need to recompile it. After this, control whether the package 
<package>quota</package> is installed. If not you will need this one as well.

<!-- FIXME: How to check for quota support? What to tweak when recompiling? -->

<p>
Enabling quota for the respective file systems is as easy as modifying
the <tt>defaults</tt> setting to <tt>defaults,usrquota</tt> in your
<file>/etc/fstab</file> file. If you need group quota, substitute
<tt>usrquota</tt> to <tt>grpquota</tt>.  You can also use them both.
Then create empty quota.user and quota.group files in the roots of the
file systems you want to use quotas on (e.g.  <tt>touch
/home/quota.user /home/quota.group</tt> for a <file>/home</file> file system).

<p>
Restart <prgn>quota</prgn> by doing <tt>/etc/init.d/quota stop;/etc/init.d/quota
start</tt>. Now quota should be running, and quota sizes can be set.

<p>
Editing quotas for a specific user can be done by
<tt>edquota -u &lt;user&gt;</tt>. Group quotas can be modified with
<tt>edquota -g
&lt;group&gt;</tt>. Then set the soft and hard quota and/or inode quotas 
as needed.

<p>
For more information about quotas, read the quota man page, and the quota
mini-howto (<file>/usr/share/doc/HOWTO/en-html/mini/Quota.html</file>).
You may also want to look at <file>pam_limits.so</file>.

<sect1 id="ext2attr">The ext2 filesystem specific attributes (chattr/lsattr) 
<!-- section last edited by Frdric Schtz <schutz@mathgen.ch> -->

<p>
In addition to the usual Unix permissions, the ext2 and ext3
filesystems offer a set of specific attributes that give you more
control over the files on your system. Unlike the basic permissions,
these attributes are not displayed by the usual <prgn>ls -l</prgn>
command or changed using <prgn>chmod</prgn>, and you need two other
utilities, <prgn>lsattr</prgn> and <prgn>chattr</prgn> (in package
<package>e2fsprogs</package>) to manage them. Note that this means
that these attributes will usually not be saved when you backup
your system, so if you change any of them, it may be worth
saving the successive <prgn>chattr</prgn> commands in a script so that
you can set them again later if you have to restore a backup.

<p>
Among all available attributes, the two that are most important for
increasing security are referenced by the letters 'i' and 'a', and
they can only be set (or removed) by the superuser:

<list>
<item>The 'i' attribute ('immutable'): a file with this attribute can
neither be modified nor deleted or renamed and no link can be created
to it, even by the superuser.

<item>The 'a' attribute ('append'): this attribute has the same effect
that the immutable attribute, except that you can still open the file
in append mode. This means that you can still add more content to it
but it is impossible to modify previous content. This attribute is
especially useful for the log files stored in <file>/var/log/</file>,
though you should consider that they get moved sometimes due to the
log rotation scripts.
</list>

<p>
These attributes can also be set for directories, in which case
everyone is denied the right to modify the contents of a directory
list (e.g. rename or remove a file, ...). When applied to a directory,
the append attribute only allows file creation.

<p>
It is easy to see how the 'a' attribute improves security, by giving
to programs that are not running as the superuser the ability to add
data to a file without modifying its previous content. On the other
hand, the 'i' attribute seems less interesting: after all, the
superuser can already use the basic Unix permissions to restrict
access to a file, and an intruder that would get access to the
superuser account could always use the <prgn>chattr</prgn> program to
remove the attribute. Such an intruder may first be confused when he
sees that he is not able to remove a file, but you should not assume
that he is blind - after all, he got into your system! Some manuals
(including a previous version of this document) suggest to simply
remove the <prgn>chattr</prgn> and <prgn>lsattr</prgn> programs from
the system to increase security, but this kind of strategy, also known
as "security by obscurity", is to be absolutely avoided, since it
provides a false sense of security.

<p>
A secure way to solve this problem is to use the capabilities of the Linux
kernel, as described in <ref id="proactive">. The capability of
interest here is called <tt>CAP_LINUX_IMMUTABLE</tt>: if you remove it
from the capabilities bounding set (using for example the command
<tt>lcap CAP_LINUX_IMMUTABLE</tt>) it won't be possible to change any
'a' or 'i' attribute on your system anymore, even by the superuser ! A
complete strategy could be as follows:

<enumlist>
  <item> Set the attributes 'a' and 'i' on any file you want;
  <item> Add the command <tt>lcap CAP_LINUX_IMMUTABLE</tt> (as well as
         <tt>lcap CAP_SYS_MODULE</tt>, as suggested in <ref id="proactive">)
         to one of the startup scripts;
<!-- Is there anything interesting in :
http://lists.debian.org/debian-security/2001/debian-security-200107/msg00024.html -->
  <item> Set the 'i' attribute on this script and other startup files, as
         well as on the <prgn>lcap</prgn> binary itself;
  <item> Execute the above command manually (or reboot your system to
         make sure everything works as planned).
</enumlist>

<p>
Now that the capability has been removed from the system, an intruder
cannot change any attribute on the protected files, and thus cannot
change or remove the files. If he forces the machine to reboot (which
is the only way to restore the capabilities bounding set), it will
easily be detected, and the capability will be removed again as soon
as the system restarts anyway. The only way to change a protected file
would be to boot the system in single-user mode or using another
bootdisk, two operations that require physical access to the machine !

<!-- Add a note about the fact that it is not widely used -->

<sect1 id="check-integ">Checking file system integrity

<p>Are you sure <file>/bin/login</file> on your hard drive is still the binary 
you installed there some months ago? What if it is a hacked version, which
stores the entered password in a hidden file or mails it in clear-text version 
all over the Internet?

<p>
The only method to have some kind of protection is to check your files
every hour/day/month (I prefer daily) by comparing the actual and the
old md5sum of this file. Two files cannot have the same md5sum (the
MD5 digest is 128 bits, so the chance that two different files will
have the same md5sum is roughly one in 3.4e3803), so you're on the
safe site here, unless someone has also hacked the algorithm that
creates md5sums on that machine. This is, well, extremely difficult
and very unlikely. You really should consider this auditing of your
binaries as very important, since it is an easy way to recognize
changes at your binaries.

<p>Common tools used for this are 
<package>sxid</package>, <package>aide</package> (Advanced Intrusion Detection 
Environment), <package>tripwire</package>, 
<package>integrit</package> and <package>samhain</package>.
Installing <prgn>debsums</prgn> will also help you to check the file system
integrity, by comparing the md5sums of every file against the md5sums
used in the Debian package archive. But beware: those files can easily
be changed by an attacker and not all packages provide md5sums listings for 
the binaries they provided. For more information please read
<ref id="periodic-integrity"> and <ref id="snapshot">.

<p>You might want to use <prgn>locate</prgn> to
index the whole filesystem, if so, consider the implications of that.
The Debian <package>findutils</package> package contains
<prgn>locate</prgn> which runs as user 
nobody, and so it only indexes files which are visible to everybody.
However, if you change it's behaviour you will make all file locations
visible to all users. If you want to index all the filesystem
(not the bits that the user nobody can see) you can replace 
<prgn>locate</prgn> with the package <package>slocate</package>. 
slocate is labeled as a security enhanced version of GNU locate, but
it actually provides additional file-locating functionality.
When using <prgn>slocate</prgn>, the user only sees the files he really
has access to and you can exclude any files or directories on the
system. The <package>slocate</package> package runs its update process with
higher privledges than locate, and indexes every file.  Users are
then able to quickly search for every file which they are
able to see.  <prgn>slocate</prgn> doesn't let them see new files;
it filters the output based on your UID. 

<p>You might want to use <package>bsign</package> or <package>elfsign</package>.
<package>elfsign</package> provides an utility to add a digital signature to
an ELF binary and a second utility to verify that signature. The current
implementation uses PKI to sign the checksum of the binary. The benefits of
doing this are that it enables one to determine if a binary has been
modified and who created it. <package>bsign</package> uses GPG,
<package>elfsign</package> uses PKI (X.509) certificates (OpenSSL).

<sect1>Setting up setuid check

<p>
The Debian <package>checksecurity</package> package
provides a <prgn>cron</prgn> job that runs daily in
<file>/etc/cron.daily/checksecurity</file>
<footnote>In previous releases, checksecurity was integrated into
cron and the file was <file>/etc/cron.daily/standard</file></footnote>.
This <prgn>cron</prgn> job will run the
<prgn>/usr/sbin/checksecurity</prgn> script that will store
information of this changes.

<p>The default behavior does not send this information to the superuser
but, instead keeps daily copies of the changes in
<file>/var/log/setuid.changes</file>. You should set the
MAILTO variable (in <file>/etc/checksecurity.conf</file>) to 'root' to
have this information mailed to him. See <manref
name="checksecurity" section="8"> for more configuration info.

<sect id="network-secure">Securing network access

<p>FIXME: More (Debian-specific) content needed.

<sect1 id="kernel-conf">Configuring kernel network features

<p>Many features of the kernel can be modified while running by
echoing something into the <file>/proc</file> file system or by using
<prgn>sysctl</prgn>. By entering <tt>/sbin/sysctl -A</tt> you can see
what you can configure and what the options are, and it can be
modified running <tt>/sbin/sysctl -w variable=value</tt> (see <manref
section="8" name="sysctl">). Only in rare cases do you need to edit
something here, but you can increase security that way as well. For
example:

<!-- FIXME: Should the prefix on all of these be /proc/sys/? era -->

<example>
net/ipv4/icmp_echo_ignore_broadcasts = 1
</example>

<p>This is a <em>Windows emulator</em> because it acts like Windows on
broadcast ping if this option is set to 1. That is, ICMP echo requests
sent to the broadcast address will be ignored. Otherwise, it does
nothing.

<p>If you want to prevent you system from answering ICMP echo requests,
just enable this configuration option:

<example>
net/ipv4/icmp_echo_ignore_all = 1
</example>

<p>To log packets with impossible addresses (due to wrong routes) on your
network use:

<example>
/proc/sys/net/ipv4/conf/all/log_martians = 1
</example>

<p>For more information on what things can be done with
<file>/proc/sys/net/ipv4/*</file> read
<file>/usr/src/linux/Documentation/filesystems/proc.txt</file>. All
the options are described thoroughly under
<file>/usr/src/linux/Documentation/networking/ip-sysctl.txt</file>
<footnote>In Debian the <package>kernel-source-<var>version</var></package> packages
copy the sources to <file>/usr/src/kernel-source-<var>version</var>.tar.bz2</file>,
just substitute <var>version</var> to whatever kernel version sources you
have installed</footnote>.

<sect1 id="tcp-syncookies">Configuring syncookies


<p>This option is a double-edged sword. On the one hand it protects
your system against syn packet flooding; on the other hand it violates
defined standards (RFCs).

<!-- What does this mean? (jfs)
This option is quite dumb as it floods the
other side like it floods you, so the other side is also busy. 
-->

<example>
net/ipv4/tcp_syncookies = 1
</example>

<p>If you want to change this option each time the kernel is
working you need to change it in <tt>/etc/network/options</tt> by
setting <tt>syncookies=yes</tt>. This will take effect when ever
<tt>/etc/init.d/networking</tt> is run (which is typically done at boot time)
while the following will have a one-time effect until the reboot:

<example>
echo 1 > /proc/sys/net/ipv4/tcp_syncookies 
</example>

<p>This option will only be available if the kernel is compiled with
the <tt>CONFIG_SYNCOOKIES</tt>. All Debian kernels are compiled with
this option builtin but you can verify it running:

<example>
$ sysctl -A |grep syncookies
net/ipv4/tcp_syncookies = 1
</example>

<p>For more information  on TCP syncookies read
<url id="http://cr.yp.to/syncookies.html">.

<sect1 id="net-harden">Securing the network on boot-time

<p>When setting configuration options for the kernel networking you
need configure it so that it's loaded every time the system is
restarted. The following example enables many of the previous options
as well as other useful options.

<p>There are actually two ways to configure your network at boot
time. You can configure <file>/etc/sysctl.conf</file> (see: <manref
section="5" name="sysctl.conf">) or introduce a script that is called
when the interface is enabled. The first option will be applied to all
interfaces, whileas the second option allows you to configure this on
a per-interface basis.

<p>An example of a <file>/etc/sysctl.conf</file> configuration
that will secure some network options at the kernel level is shown below. Notice the comment in it, <file>/etc/network/options</file> might override some values if they contradict those in this file when the <file>/etc/init.d/networking</file> is run (which is later than <file>procps</file> on the startup sequence).

<example>
#
# /etc/sysctl.conf - Configuration file for setting system variables
# See sysctl.conf (5) for information. Also see the files under
# Documentation/sysctl/, Documentation/filesystems/proc.txt, and
# Documentation/networking/ip-sysctl.txt in the kernel sources 
# (/usr/src/kernel-$version if you have a kernel-package installed)
# for more information of the values that can be defined here.

#
# Be warned that /etc/init.d/procps is executed to set the following
# variables.  However, after that, /etc/init.d/networking sets some
# network options with builtin values.  These values may be overridden
# using /etc/network/options.
#
#kernel.domainname = example.com

# Additional settings - adapted from the script contributed
# by Dariusz Puchala (see below)
# Ignore ICMP broadcasts
net/ipv4/icmp_echo_ignore_broadcasts = 1
#
# Ignore bogus ICMP errors
net/ipv4/icmp_ignore_bogus_error_responses = 1
# 
# Do not accept ICMP redirects (prevent MITM attacks)
net/ipv4/conf/all/accept_redirects = 0
# _or_
# Accept ICMP redirects only for gateways listed in our default
# gateway list (enabled by default)
# net/ipv4/conf/all/secure_redirects = 1
#
# Do not send ICMP redirects (we are not a router)
net/ipv4/conf/all/send_redirects = 0
#
# Do not forward IP packets (we are not a router)
# Note: Make sure that /etc/network/options has 'ip_forward=no'
net/ipv4/conf/all/forwarding = 0
#
# Enable TCP Syn Cookies
# Note: Make sure that /etc/network/options has 'syncookies=yes'
net/ipv4/tcp_syncookies = 1
#
# Log Martian Packets
net/ipv4/conf/all/log_martians = 1
#
# Turn on Source Address Verification in all interfaces to
# prevent some spoofing attacks
# Note: Make sure that /etc/network/options has 'spoofprotect=yes'
net/ipv4/conf/all/rp_filter = 1
#
# Do not accept IP source route packets (we are not a router)
net/ipv4/conf/all/accept_source_route = 0
</example>

<p>To use the script you need to first create the script, for
example, in <file>/etc/network/interface-secure</file> (the name is
given as an example) and call it from
<file>/etc/network/interfaces</file> like this:

<example>
auto eth0
iface eth0 inet static
        address xxx.xxx.xxx.xxx
        netmask 255.255.255.xxx
        broadcast xxx.xxx.xxx.xxx
        gateway xxx.xxx.xxx.xxx
        pre-up /etc/network/interface-secure
</example>

<p>In this example, before the interface eth0 is enabled the script
will be called to secure all network interfaces as shown below.

<example>
#!/bin/sh -e
# Script-name: /etc/network/interface-secure
#
# Modifies some default behavior in order to secure against 
# some TCP/IP spoofing & attacks for all interfaces.
#
# Contributed by Dariusz Puchalak.
#
echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts 
                                           # Broadcast echo protection enabled.
echo 0 > /proc/sys/net/ipv4/conf/all/forwarding
                                           # IP forwarding disabled.
echo 1 > /proc/sys/net/ipv4/tcp_syncookies # TCP syn cookies protection enabled.
echo 1 >/proc/sys/net/ipv4/conf/all/log_martians # Log strange packets.
# (this includes spoofed packets, source routed packets, redirect packets)
# but be careful with this on heavy loaded web servers.
echo 1 > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses 
                                           # Bad error message protection enabled.

# IP spoofing protection.
echo 1 > /proc/sys/net/ipv4/conf/all/rp_filter

# Disable ICMP redirect acceptance.
echo 0 > /proc/sys/net/ipv4/conf/all/accept_redirects
echo 0 > /proc/sys/net/ipv4/conf/all/send_redirects

# Disable source routed packets.
echo 0 > /proc/sys/net/ipv4/conf/all/accept_source_route

exit 0
</example>

<p>Notice that you can actually have per-interface scripts that will
enable different network options for different interfaces (if you have
more than one), just change the pre-up line to:

<example>
pre-up /etc/network/interface-secure $IFACE
</example>

<p>And use a script which will only apply changes to a specific
interface, not to all of the interfaces available. Notice that some
networking options can only be enabled globally, however. A sample
script is this one:

<example>
#!/bin/sh -e
# Script-name: /etc/network/interface-secure
#
# Modifies some default behavior in order to secure against 
# some TCP/IP spoofing & attacks for a given interface.
#
# Contributed by Dariusz Puchalak.
#

IFACE=$1
if [ -z "$IFACE" ] ; then
   echo "$0: Must give an interface name as argument!"
   echo "Usage: $0 &lt;interface&gt;"
   exit 1
fi

if [ ! -e /proc/sys/net/ipv4/conf/$IFACE/ ]; then
   echo "$0: Interface $IFACE does not exit (cannot find /proc/sys/net/ipv4/conf/)"
   exit 1
fi

echo 0 > /proc/sys/net/ipv4/conf/$IFACE/forwarding  # IP forwarding disabled.
echo 1 >/proc/sys/net/ipv4/conf/$IFACE/log_martians # Log strange packets.
# (this includes spoofed packets, source routed packets, redirect packets)
# but be careful with this on heavy loaded web servers.

# IP spoofing protection.
echo 1 > /proc/sys/net/ipv4/conf/$IFACE/rp_filter

# Disable ICMP redirect acceptance.
echo 0 > /proc/sys/net/ipv4/conf/$IFACE/accept_redirects
echo 0 > /proc/sys/net/ipv4/conf/$IFACE/send_redirects

# Disable source routed packets.
echo 0 > /proc/sys/net/ipv4/conf/$IFACE/accept_source_route

exit 0
</example>


<p>An alternative solution is to create an <tt>init.d</tt> script and
have it run on bootup (using <prgn>update-rc.d</prgn> to create the
appropriate <tt>rc.d</tt> links).

<sect1 id="kernel-fw">Configuring firewall features 

<p>In order to have firewall capabilities, either to protect the local
system or others <em>behind</em> it, the kernel needs to be compiled
with firewall capabilities. The standard Debian 2.2 kernel (Linux 2.2)
provides the packet filter <prgn>ipchains</prgn> firewall, Debian 3.0
standard kernel (Linux 2.4) provides the <em>stateful</em> packet
filter <prgn>iptables</prgn> (netfilter) firewall.

<p>In any case, it is pretty easy to use a kernel different from the
one provided by Debian. You can find pre-compiled kernels as packages
you can easily install in the Debian system. You can also download the
kernel sources using the <package>kernel-source-<var>X</var></package> and build
custom kernel packages using <prgn>make-kpkg</prgn> from the
<package>kernel-package</package> package.

<p>Setting up firewalls in Debian is discussed more thoroughly in <ref
id="firewall-setup">.


<sect1 id="limit-bindaddr">Disabling weak-end hosts issues

<!-- FIXME I read this and I dont get what's the point? -->

<p>Systems with more than one interface on different networks
can have services configured so that they will bind only to 
a given IP address. This usually prevents access to services when requested
through any other address. However, this does not mean (although
it is a common misconception) that the service is
bound to a given <em>hardware</em> address (interface card).
<footnote>
To reproduce this (example provided by Felix von Leitner on the
Bugtraq mailing list):
<example>
   host a (eth0 connected to eth0 of host b):
     ifconfig eth0 10.0.0.1
     ifconfig eth1 23.0.0.1
     tcpserver -RHl localhost 23.0.0.1 8000 echo fnord

   host b:
     ifconfig eth0 10.0.0.2
     route add 23.0.0.1 gw 10.0.0.1
     telnet 23.0.0.1 8000
</example>
<p>It seems, however, not to work with services bound to
127.0.0.1, you might need to write the tests using raw sockets.</p>
</footnote>

<p>This is not an ARP issue and it's not an RFC violation (it's 
called <em>weak end host</em> in 
<url id="ftp://ftp.isi.edu/in-notes/rfc1122.txt" name="RFC1122">, 
section 3.3.4.2). 
Remember, IP addresses have nothing to do with physical interfaces.

<p>On 2.2 (and previous) kernels this can be fixed with:
<example>
# echo 1 > /proc/sys/net/ipv4/conf/all/hidden
# echo 1 > /proc/sys/net/ipv4/conf/eth0/hidden
# echo 1 > /proc/sys/net/ipv4/conf/eth1/hidden
.....
</example>
<p>On later kernels this can be fixed either with:
<list>
<item>iptables rules.
<item>properly configured routing.
<footnote>
The fact that this behavior can be changed through routing
was described by Matthew G. Marsh in the Bugtraq thread:
<example>
eth0 = 1.1.1.1/24
eth1 = 2.2.2.2/24

ip rule add from 1.1.1.1/32 dev lo table 1 prio 15000
ip rule add from 2.2.2.2/32 dev lo table 2 prio 16000

ip route add default dev eth0 table 1
ip route add default dev eth1 table 2
</example>
</footnote>
<item>kernel patching.
<footnote>
There are some patches available for this behavior as
described in Bugtraq's thread at
<url id="http://www.linuxvirtualserver.org/~julian/#hidden">
and <url id="http://www.fefe.de/linux-eth-forwarding.diff">.
</footnote>
</list>
<p>Along this text there will be many occasions in which it
is shown how to configure some services (sshd server, apache, printer
service...) in order to have them listening on any given
address, the reader should take into account that, without 
the fixes given here, the fix would not prevent accesses from 
within the same (local) network.
<footnote>
An attacker might have many problems pulling the access through
after configuring the IP-address binding if he is not on the same
broadcast domain (same network) as the attacked host. If the attack
goes through a router it might be quite difficult for the answers
to return somewhere.
</footnote>

<p>FIXME: Comments on Bugtraq indicate there is a Linux
specific method to bind to a given interface.

<p>FIXME: Submit a bug against netbase so that the routing fix
is standard behavior in Debian?

<sect1>Protecting against ARP attacks

<p>When you don't trust the other boxes on your LAN (which should
always be the case, because it's the safest attitude) you should
protect yourself from the various existing ARP attacks.

<p>As you know the ARP protocol is used to link IP addresses to MAC
addresses (see <url name="RFC826"
id="ftp://ftp.isi.edu/in-notes/rfc826.txt"> for all the
details). Every time you send a packet to an IP address an ARP
resolution is done (first by looking into the local ARP cache then if
the IP isn't present in the cache by broadcasting an ARP query) to
find the target's hardware address.  All the ARP attacks aim to fool
your box into thinking that box B's IP address is associated to the
intruder's box's MAC address; Then every packet that you want to send
to the IP associated to box B will be send to the intruder's box...

<p>
Those attacks (ARP cache poisoning, ARP spoofing...) allow the attacker
to sniff the traffic even on switched networks, to easily hijack
connections, to disconnect any host from the network... ARP attacks
are powerful and simple to implement, and several tools exists, such as
<prgn>arpspoof</prgn> from the <package>dsniff</package> package or
<url name="arpoison" id="http://arpoison.sourceforge.net/">.

<p>However, there is always a solution:

<list>

<item>Use a static ARP cache. You can set up "static" entries in your
ARP cache with:

<example>
  arp -s host_name hdwr_addr 
</example> 

<p>By setting static entries for each important host in your network
you ensure that nobody will create/modify a (fake) entry for these
hosts (static entries don't expire and can't be modified) and spoofed
ARP replies will be ignored.


<item>Detect suspicious ARP traffic. You can use
<package>arpwatch</package>, <package>karpski</package> or more
general IDS that can also detect suspicious ARP traffic
(<package>snort</package>, <url name="prelude"
id="http://www.prelude-ids.org">...).

<item>Implement IP traffic filtering validating the MAC address.
</list>


<sect id="snapshot">Taking a snapshot of the system

<p>Before putting the system into production system you could take a
snapshot of the whole system. This snapshot could be used in the event
of a compromise (see <ref id="after-compromise">). You should remake
this upgrade whenever the system is upgraded, especially if you upgrade
to a new Debian release.

<p>For this you can use a writable removable-media that can be set up
read-only, this could be a floppy disk (read protected after use), a
CD on a CD-ROM unit (you could use a rewritable CD-ROM so you could
even keep backups of md5sums in different dates), or a USB disk or MMC
card (if your system can access those and they can be write protected).

<p>The following script creates such a snapshot:

<example>
#!/bin/bash
/bin/mount /dev/fd0 /mnt/floppy
if [ ! -f /usr/bin/md5sum ] ; then
	echo "Cannot find md5sum. Aborting."
	exit 1
fi
/bin/cp /usr/bin/md5sum /mnt/floppy
echo "Calculating md5 database"
>/mnt/floppy/md5checksums.txt
for dir in /bin/ /sbin/ /usr/bin/ /usr/sbin/ /lib/ /usr/lib/
do
   find $dir -type f | xargs /usr/bin/md5sum >>/mnt/floppy/md5checksums-lib.txt
done
echo "post installation md5 database calculated"
if [ ! -f /usr/bin/sha1sum ] ; then
	echo "Cannot find sha1sum"
else
	/bin/cp /usr/bin/sha1sum /mnt/floppy
	echo "Calculating SHA-1 database"
	>/mnt/floppy/sha1checksums.txt
	for dir in /bin/ /sbin/ /usr/bin/ /usr/sbin/ /lib/ /usr/lib/
	do
	   find $dir -type f | xargs /usr/bin/sha1sum >>/mnt/floppy/sha1checksums-lib.txt
	done
	echo "post installation sha1 database calculated"
fi
/bin/umount /dev/fd0
exit 0
</example>

<p>Note that the md5sum binary (and sha1sum, if available) is placed on the 
floppy drive so it can
be used later on to check the binaries of the system (just in case it
gets trojaned). However, if you want to make sure that you are running
a legitimate binary, you might want to either compile a static copy
of the md5sum binary and use that one (to prevent a trojaned libc library
from interfering with the binary) or to use the snapshot of md5sums only from 
a clean environment such as a rescue CD-ROM or a Live-CD (to prevent
a trojaned kernel from interfering). I cannot stress this enough:
if you are on a compromised system you cannot trust its output, see
<ref id="after-compromise">.

<p>The snapshot does not include the files under
<file>/var/lib/dpkg/info</file> which includes the MD5 hashes of
installed packages (in files ending with <file>.md5sums</file>). You
could copy this information along too, however you should notice:

<list>
<item>the md5sums files include the md5sum of all files 
provided by the Debian packages, not just system binaries.
As a consequence, that database is bigger (5 Mb versus
600 Kb in a Debian GNU/Linux system with a graphical system and around
2.5 Gb of software installed) and will not fit in small removable
media (like a single floppy disk, but would probably fit in a removable
USB memory).

<item>not all Debian packages provide md5sums for the files installed
since it is not (currently) mandated policy. Notice, however,
that you can generate the md5sums for all packages using 
<package>debsums</package> after you've finished the system installation:
<example>
# debsums --generate=missing,keep
</example>

</list>

<p>Once the snapshot is done you should make sure to set the medium
read-only. You can then store it for backup or place it in the drive
and use it to drive a <prgn>cron</prgn> check nightly comparing the original
md5sums against those on the snapshot.

<p>If you do not want to setup a manual check you can always use
any of the integrity systems available that will do this and more,
for more information please read <ref id="periodic-integrity">.

<sect>Other recommendations

<!-- TODO: Remove this? -->

<sect1>Do not use software depending on svgalib

<p>
SVGAlib is very nice for console lovers like me, but in the past it
has been proven several times that it is very insecure. Exploits
against <prgn>zgv</prgn> were released, and it was simple to become
root. Try to prevent using SVGAlib programs wherever possible.  

<!-- FIXME: Move this to policy section if there ever is one? -->