aboutsummaryrefslogtreecommitdiff
path: root/documentation/content/en/books/handbook/security/_index.adoc
blob: 9f7d1566beddb1fa94d6b03e2c8b88e2fdb00de6 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
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
---
title: Chapter 16. Security
part: Part III. System Administration
prev: books/handbook/boot
next: books/handbook/jails
description: Hundreds of standard practices have been authored about how to secure systems and networks, and as a user of FreeBSD, understanding how to protect against attacks and intruders is a must
tags: ["security", "TCP Wrappers", "Kerberos", "OpenSSL", "OpenSSH", "ACL", "NFSv4 ACLs", "advisories", "sudo", "doas", "capsicum", "monitoring"]
showBookMenu: true
weight: 20
path: "/books/handbook/security/"
---

[[security]]
= Security
:doctype: book
:toc: macro
:toclevels: 1
:icons: font
:sectnums:
:sectnumlevels: 6
:sectnumoffset: 16
:partnums:
:source-highlighter: rouge
:experimental:
:images-path: books/handbook/security/

ifdef::env-beastie[]
ifdef::backend-html5[]
:imagesdir: ../../../../images/{images-path}
endif::[]
ifndef::book[]
include::shared/authors.adoc[]
include::shared/mirrors.adoc[]
include::shared/releases.adoc[]
include::shared/attributes/attributes-{{% lang %}}.adoc[]
include::shared/{{% lang %}}/teams.adoc[]
include::shared/{{% lang %}}/mailing-lists.adoc[]
include::shared/{{% lang %}}/urls.adoc[]
toc::[]
endif::[]
ifdef::backend-pdf,backend-epub3[]
include::../../../../../shared/asciidoctor.adoc[]
endif::[]
endif::[]

ifndef::env-beastie[]
toc::[]
include::../../../../../shared/asciidoctor.adoc[]
endif::[]

[[security-synopsis]]
== Synopsis

Hundreds of standard practices have been authored about how to secure systems and networks, and as a user of FreeBSD, understanding how to protect against attacks and intruders is a must.

In this chapter, several fundamentals and techniques will be discussed.
The FreeBSD system comes with multiple layers of security, and many more third party utilities may be added to enhance security.

This chapter covers:

* Basic FreeBSD system security concepts.
* The various crypt mechanisms available in FreeBSD.
* How to configure TCP Wrappers for use with man:inetd[8].
* How to set up Kerberos on FreeBSD.
* How to configure and use OpenSSH on FreeBSD.
* How to use OpenSSL on FreeBSD.
* How to use file system ACLs.
* How to use pkg to audit third party software packages installed from the Ports Collection.
* How to utilize FreeBSD security advisories.
* What Process Accounting is and how to enable it on FreeBSD.
* How to control user resources using login classes or the resource limits database.
* What is Capsicum and a basic example.

Certain topics due to their complexity are found in dedicated chapters such as crossref:firewalls[firewalls,Firewalls], crossref:mac[mac,Mandatory Access Control] and articles like extref:{vpn-ipsec}[VPN over IPsec].

[[security-intro]]
== Introduction

Security is everyone's responsibility.
A weak entry point in any system could allow intruders to gain access to critical information and cause havoc on an entire network.
One of the core principles of information security is the CIA triad, which stands for the Confidentiality, Integrity, and Availability of information systems.

The CIA triad is a bedrock concept of computer security as customers and users expect their data to be protected.
For example, a customer expects that their credit card information is securely stored (confidentiality), that their orders are not changed behind the scenes (integrity), and that they have access to their order information at all times (availability).

To provide CIA, security professionals apply a defense in depth strategy.
The idea of defense in depth is to add several layers of security to prevent one single layer failing and the entire security system collapsing.
For example, a system administrator cannot simply turn on a firewall and consider the network or system secure.
One must also audit accounts, check the integrity of binaries, and ensure malicious tools are not installed.
To implement an effective security strategy, one must understand threats and how to defend against them.

What is a threat as it pertains to computer security? Threats are not limited to remote attackers who attempt to access a system without permission from a remote location.
Threats also include employees, malicious software, unauthorized network devices, natural disasters, security vulnerabilities, and even competing corporations.

Systems and networks can be accessed without permission, sometimes by accident, or by remote attackers, and in some cases, via corporate espionage or former employees.
As a user, it is important to prepare for and admit when a mistake has led to a security breach and report possible issues to the security team.
As an administrator, it is important to know of the threats and be prepared to mitigate them.

When applying security to systems, it is recommended to start by securing the basic accounts and system configuration, and then to secure the network layer so that it adheres to the system policy and the organization's security procedures.
Many organizations already have a security policy that covers the configuration of technology devices.
The policy should include the security configuration of workstations, desktops, mobile devices, phones, production servers, and development servers.
In many cases, standard operating procedures (SOPs) already exist.
When in doubt, ask the security team.

[[sec-accounts]]
== Securing Accounts

Maintaining secure accounts in FreeBSD is crucial for data confidentiality, system integrity, and privilege separation, as it prevents unauthorized access, malware, and data breaches while ensuring compliance and protecting an organization's reputation.

[[security-accounts]]
=== Preventing Logins

In securing a system, a good starting point is an audit of accounts.
Disable any accounts that do not need login access.

[TIP]
====
Ensure that `root` has a strong password and that this password is not shared.
====

To deny login access to accounts, two methods exist.

The first is to lock the account, this example shows how to lock the `imani` account:

[source,shell]
....
# pw lock imani
....

The second method is to prevent login access by changing the shell to [.filename]#/usr/sbin/nologin#.
The man:nologin[8] shell prevents the system from assigning a shell to the user when they attempt to login.

Only the superuser can change the shell for other users:

[source,shell]
....
# chsh -s /usr/sbin/nologin imani
....

[[security-passwords]]
=== Password Hashes

Passwords are a necessary evil of technology.
When they must be used, they should be complex and a powerful hash mechanism should be used to encrypt the version that is stored in the password database.
FreeBSD supports several algorithms, including SHA256, SHA512 and Blowfish hash algorithms in its `crypt()` library, see man:crypt[3] for details.

The default of SHA512 should not be changed to a less secure hashing algorithm, but can be changed to the more secure Blowfish algorithm.

[NOTE]
====
Blowfish is not part of AES and is not considered compliant with any Federal Information Processing Standards (FIPS).
Its use may not be permitted in some environments.
====

To determine which hash algorithm is used to encrypt a user's password, the superuser can view the hash for the user in the FreeBSD password database.
Each hash starts with a symbol which indicates the type of hash mechanism used to encrypt the password.

If DES is used, there is no beginning symbol.
For MD5, the symbol is `$`.
For SHA256 and SHA512, the symbol is `$6$`.
For Blowfish, the symbol is `$2a$`.
In this example, the password for `imani` is hashed using the default SHA512 algorithm as the hash starts with `$6$`.
Note that the encrypted hash, not the password itself, is stored in the password database:

[source,shell]
....
# grep imani /etc/master.passwd
....

The output should be similar to the following:

[.programlisting]
....
imani:$6$pzIjSvCAn.PBYQBA$PXpSeWPx3g5kscj3IMiM7tUEUSPmGexxta.8Lt9TGSi2lNQqYGKszsBPuGME0:1001:1001::0:0:imani:/usr/home/imani:/bin/sh
....

The hash mechanism is set in the user's login class.

The following command can be run to check which hash mechanism is currently being used:

[source,shell]
....
# grep user /etc/master.passwd
....

The output should be similar to the following:

[.programlisting]
....
:passwd_format=sha512:\
....

For example, to change the algorithm to Blowfish, modify that line to look like this:

[.programlisting]
....
:passwd_format=blf:\
....

Then, man:cap_mkdb[1] must be executed to upgrade the login.conf database:

[source,shell]
....
# cap_mkdb /etc/login.conf
....

Note that this change will not affect any existing password hashes.
This means that all passwords should be re-hashed by asking users to run `passwd` in order to change their password.

[[security-pwpolicy]]
=== Password Policy Enforcement

Enforcing a strong password policy for local accounts is a fundamental aspect of system security.
In FreeBSD, password length, password strength, and password complexity can be implemented using built-in Pluggable Authentication Modules (PAM).

This section demonstrates how to configure the minimum and maximum password length and the enforcement of mixed characters using the man:pam_passwdqc[8] module.
This module is enforced when a user changes their password.

To configure this module, become the superuser and uncomment the line containing `pam_passwdqc.so` in [.filename]#/etc/pam.d/passwd#.

Then, edit that line to match the password policy:

[.programlisting]
....
password        requisite       pam_passwdqc.so         min=disabled,disabled,disabled,12,10 similar=deny retry=3 enforce=users
....

The explanation of the parameters can be found in man:pam_passwdqc[8].

Once this file is saved, a user changing their password will see a message similar to the following:

[source,shell]
....
% passwd
....

The output should be similar to the following:

[.programlisting]
....
Changing local password for user
Old Password:

You can now choose the new password.
A valid password should be a mix of upper and lower case letters,
digits and other characters.  You can use a 12 character long
password with characters from at least 3 of these 4 classes, or
a 10 character long password containing characters from all the
classes.  Characters that form a common pattern are discarded by
the check.
Alternatively, if no one else can see your terminal now, you can
pick this as your password: "trait-useful&knob".
Enter new password:
....

If a password that does not match the policy is entered, it will be rejected with a warning and the user will have an opportunity to try again, up to the configured number of retries.

If your organization's policy requires passwords to expire, FreeBSD supports the `passwordtime` in the user's login class in [.filename]#/etc/login.conf#

The `default` login class contains an example:

[.programlisting]
....
#       :passwordtime=90d:\
....

So, to set an expiry of 90 days for this login class, remove the comment symbol (#), save the edit, and execute the following command:

[source,shell]
....
# cap_mkdb /etc/login.conf
....

To set the expiration on individual users, pass an expiration date or the number of days to expiry and a username to `pw`:

[source,shell]
....
# pw usermod -p 30-apr-2025 -n user
....

As seen here, an expiration date is set in the form of day, month, and year.
For more information, see man:pw[8].

[[security-sudo]]
=== Shared Administration with sudo

System administrators often need the ability to grant enhanced permissions to users so they may perform privileged tasks.
The idea that team members are provided access to a FreeBSD system to perform their specific tasks opens up unique challenges to every administrator.
These team members only need a subset of access beyond normal end user levels; however, they almost always tell management they are unable to perform their tasks without superuser access.
Thankfully, there is no reason to provide such access to end users because tools exist to manage this exact requirement.

[TIP]
====
Even administrators should limit their privileges when not needed.
====

Up to this point, the security chapter has covered permitting access to authorized users and attempting to prevent unauthorized access.
Another problem arises once authorized users have access to the system resources.
In many cases, some users may need access to application startup scripts, or a team of administrators need to maintain the system.
Traditionally, the standard users and groups, file permissions, and even the man:su[1] command would manage this access.
And as applications required more access, as more users needed to use system resources, a better solution was required.
The most used application is currently Sudo.

Sudo allows administrators to configure more rigid access to system commands and provide for some advanced logging features.
As a tool, it is available from the Ports Collection as package:security/sudo[] or by use of the man:pkg[8] utility.

Execute the following command to install it:

[source,shell]
....
# pkg install sudo
....

After the installation is complete, the installed `visudo` will open the configuration file with a text editor.
Using `visudo` is highly recommended as it comes with a built in syntax checker to verify there are no errors before the file is saved.

The configuration file is made up of several small sections which allow for extensive configuration.
In the following example, web application maintainer, user1, needs to start, stop, and restart the web application known as _webservice_.
To grant this user permission to perform these tasks, add this line to the end of [.filename]#/usr/local/etc/sudoers#:

[.programlisting]
....
user1   ALL=(ALL)       /usr/sbin/service webservice *
....

The user may now start _webservice_ using this command:

[source,shell]
....
% sudo /usr/sbin/service webservice start
....

While this configuration allows a single user access to the webservice service;
however, in most organizations, there is an entire web team in charge of managing the service.
A single line can also give access to an entire group.
These steps will create a web group, add a user to this group, and allow all members of the group to manage the service:

[source,shell]
....
# pw groupadd -g 6001 -n webteam
....

Using the same man:pw[8] command, the user is added to the webteam group:

[source,shell]
....
# pw groupmod -m user1 -n webteam
....

Finally, this line in [.filename]#/usr/local/etc/sudoers# allows any member of the webteam group to manage _webservice_:

[.programlisting]
....
%webteam   ALL=(ALL)       /usr/sbin/service webservice *
....

Unlike man:su[1], man:sudo[8] only requires the end user password.
This avoids sharing passwords, which is a poor practice.

Users permitted to run applications with man:sudo[8] only enter their own passwords.
This is more secure and gives better control than man:su[1],
where the `root` password is entered and the user acquires all `root` permissions.

[TIP]
====
Most organizations are moving or have moved toward a two factor authentication model.
In these cases, the user may not have a password to enter.

man:sudo[8] can be configured to permit two factor authentication model by using the `NOPASSWD` variable.
Adding it to the configuration above will allow all members of the _webteam_ group to manage the service without the password requirement:

[.programlisting]
....
%webteam   ALL=(ALL)       NOPASSWD: /usr/sbin/service webservice *
....
====

[[security-doas]]
=== Shared Administration with Doas

man:doas[1] is a command-line utility ported from OpenBSD.
It serves as an alternative to the widely used man:sudo[8] command in Unix-like systems.

With doas, users can execute commands with elevated privileges, typically as the root user, while maintaining a simplified and security-conscious approach.
Unlike man:sudo[8], doas emphasizes simplicity and minimalism, focusing on streamlined privilege delegation without an overwhelming array of configuration options.

Execute the following command to install it:

[source,shell]
....
# pkg install doas
....

After the installation [.filename]#/usr/local/etc/doas.conf# must be configured to grant access for users for specific commands, or roles.

The simplest entry could be the following, which grants the user `local_user` with `root` permissions without asking for its password when executing the doas command.

[.programlisting]
....
permit nopass local_user as root
....

After the installation and configuration of the `doas` utility, a command can now be executed with enhanced privileges, for example:

[source,shell]
....
$ doas vi /etc/rc.conf
....

For more configuration examples, please read man:doas.conf[5].

[[security-ids]]
== Intrusion Detection System (IDS)

Verification of system files and binaries is important because it provides the system administration and security teams information about system changes.
A software application that monitors the system for changes is called an Intrusion Detection System (IDS).

FreeBSD provides native support for a basic IDS system called man:mtree[8].
While the nightly security emails will notify an administrator of changes, the information is stored locally and there is a chance that a malicious user could modify this information in order to hide their changes to the system.
As such, it is recommended to create a separate set of binary signatures and store them on a read-only, root-owned directory or, preferably, on a removable USB disk or remote server.

It is also recommended to run `freebsd-update IDS` after each update.

[[security-ids-generate-spec-file]]
=== Generating the Specification File

The built-in man:mtree[8] utility can be used to generate a specification of the contents of a directory.
A seed, or a numeric constant, is used to generate the specification and is required to check that the specification has not changed.
This makes it possible to determine if a file or binary has been modified.
Since the seed value is unknown by an attacker, faking or checking the checksum values of files will be difficult to impossible.

[TIP]
====
It is recommended to create specifications for the directories which contain binaries and configuration files, as well as any directories containing sensitive data.
Typically, specifications are created for [.filename]#/bin#, [.filename]#/sbin#, [.filename]#/usr/bin#, [.filename]#/usr/sbin#, [.filename]#/usr/local/bin#, [.filename]#/etc#, and [.filename]#/usr/local/etc#.
====

The following example generates a set of `sha512` hashes, one for each system binary in [.filename]#/bin#, and saves those values to a hidden file in user's home directory, [.filename]#/home/user/.bin_chksum_mtree#:

[source,shell]
....
# mtree -s 123456789 -c -K cksum,sha512 -p /bin > /home/user/.bin_chksum_mtree
....

The output should be similar to the following:

[.programlisting]
....
mtree: /bin checksum: 3427012225
....

[WARNING]
====
The `123456789` value represents the seed, and should be chosen randomly.
This value should be remembered, *but not shared*.

It is important to keep the seed value and the checksum output hidden from malicious users.
====

[[security-ids-spec-file-structure]]
=== The Specification File Structure

The mtree format is a textual format that describes a collection of filesystem objects.
Such files are typically used to create or verify directory hierarchies.

An mtree file consists of a series of lines, each providing information about a single filesystem object. Leading whitespace is always ignored.

The specification file created above will be used to explain the format and content:

[.programlisting]
....
#          user: root <.>
#       machine: machinename <.>
#          tree: /bin <.>
#          date: Thu Aug  24 21:58:37 2023 <.>

# .
/set type=file uid=0 gid=0 mode=0555 nlink=1 flags=uarch <.>
.               type=dir mode=0755 nlink=2 time=1681388848.239523000 <.>
    \133        nlink=2 size=12520 time=1685991378.688509000 \
                cksum=520880818 \
                sha512=5c1374ce0e2ba1b3bc5a41b23f4bbdc1ec89ae82fa01237f376a5eeef41822e68f1d8f75ec46b7bceb65396c122a9d837d692740fdebdcc376a05275adbd3471
    cat         size=14600 time=1685991378.694601000 cksum=3672531848 \ <.>
                sha512=b30b96d155fdc4795432b523989a6581d71cdf69ba5f0ccb45d9b9e354b55a665899b16aee21982fffe20c4680d11da4e3ed9611232a775c69f926e5385d53a2
    chflags     size=8920 time=1685991378.700385000 cksum=1629328991 \
                sha512=289a088cbbcbeb436dd9c1f74521a89b66643976abda696b99b9cc1fbfe8b76107c5b54d4a6a9b65332386ada73fc1bbb10e43c4e3065fa2161e7be269eaf86a
    chio        size=20720 time=1685991378.706095000 cksum=1948751604 \
                sha512=46f58277ff16c3495ea51e74129c73617f31351e250315c2b878a88708c2b8a7bb060e2dc8ff92f606450dbc7dd2816da4853e465ec61ee411723e8bf52709ee
    chmod       size=9616 time=1685991378.712546000 cksum=4244658911 \
                sha512=1769313ce08cba84ecdc2b9c07ef86d2b70a4206420dd71343867be7ab59659956f6f5a458c64e2531a1c736277a8e419c633a31a8d3c7ccc43e99dd4d71d630
....

<.> User who created the specification.
<.> Machine's hostname.
<.> Directory path.
<.> The Date and time when the specification was created.
<.> `/set` special commands, defines some settings obtained from the files analyzed.
<.> Refers to the parsed directory and indicates things like what type it is, its mode, the number of hard links, and the time in UNIX format since it was modified.
<.> Refers to the file and shows the size, time and a list of hashes to verify the integrity.

[[security-ids-verify-specification-file]]
=== Verify the Specification file

To verify that the binary signatures have not changed, compare the current contents of the directory to the previously generated specification, and save the results to a file.

This command requires the seed that was used to generate the original specification:

[source,shell]
....
# mtree -s 123456789 -p /bin < /home/user/.bin_chksum_mtree >> /home/user/.bin_chksum_output
....

This should produce the same checksum for [.filename]#/bin# that was produced when the specification was created.
If no changes have occurred to the binaries in this directory, the [.filename]#/home/user/.bin_chksum_output# output file will be empty.

To simulate a change, change the date on [.filename]#/bin/cat# using man:touch[1] and run the verification command again:

[source,shell]
....
# touch /bin/cat
....

Run the verification command again:

[source,shell]
....
# mtree -s 123456789 -p /bin < /home/user/.bin_chksum_mtree >> /home/user/.bin_chksum_output
....

And then check the content of the output file:

[source,shell]
....
# cat /root/.bin_chksum_output
....

The output should be similar to the following:

[.programlisting]
....
cat:    modification time (Fri Aug 25 13:30:17 2023, Fri Aug 25 13:34:20 2023)
....

[WARNING]
====
This is just an example of what would be displayed when executing the command,
to show the changes that would occur in the metadata.
====

[[security-secure-levels]]
== Secure levels

securelevel is a security mechanism implemented in the kernel.
When the securelevel is positive, the kernel restricts certain tasks; not even the superuser (root) is allowed to do them.

The securelevel mechanism limits the ability to:

* Unset certain file flags, such as `schg` (the system immutable flag).
* Write to kernel memory via [.filename]#/dev/mem# and [.filename]#/dev/kmem#.
* Load kernel modules.
* Alter firewall rules.

[[security-secure-levels-definitions]]
=== Secure Levels Definitions

The kernel runs with five different security levels.
Any super-user process can raise the level, but no process can lower it.

The security definitions are:

-1::
*Permanently insecure mode* - always run the system in insecure mode.
This is the default initial value.

0::
*Insecure mode* - immutable and append-only flags may be turned off.
All devices may be read or written subject to their permissions.

1::
*Secure mode* - the system immutable and system append-only flags may not be turned off;
disks for mounted file systems, [.filename]#/dev/mem# and [.filename]#/dev/kmem# may not be opened for writing;
[.filename]#/dev/io# (if your platform has it) may not be opened at all; kernel modules (see man:kld[4]) may not be loaded or unloaded.
The kernel debugger may not be entered using the debug.kdb.enter sysctl.
A panic or trap cannot be forced using the debug.kdb.panic, debug.kdb.panic_str and other sysctl's.

2::
*Highly secure mode* - same as secure mode, plus disks may not be opened for writing (except by man:mount[2]) whether mounted or not.
This level precludes tampering with file systems by unmounting them, but also inhibits running man:newfs[8] while the system is multiuser.

3::
*Network secure mode* - same as highly secure mode, plus IP packet filter rules (see man:ipfw[8], man:ipfirewall[4] and man:pfctl[8]) cannot be changed and man:dummynet[4] or man:pf[4] configuration cannot be adjusted.

[TIP]
====
In summary, the key difference between `Permanently Insecure Mode` and `Insecure Mode` in FreeBSD secure levels is the degree of security they provide.
`Permanently Insecure Mode` completely lifts all security restrictions, while `Insecure Mode` relaxes some restrictions but still maintains a level of control and security.
====

[[security-modify-secure-levels]]
=== Modify Secure Levels

In order to change the securelevel of the system it is necessary to activate `kern_securelevel_enable` by executing the following command:

[source,shell]
....
# sysrc kern_securelevel_enable="YES"
....

And set the value of `kern_securelevel` to the desired security level:

[source,shell]
....
# sysrc kern_securelevel=2
....

To check the status of the securelevel on a running system execute the following command:

[source,shell]
....
# sysctl -n kern.securelevel
....

The output contains the current value of the securelevel.
If it is greater than 0, at least some of the securelevel's protections are enabled.

[[security-file-flags]]
== File flags

File flags allow users to attach additional metadata or attributes to files and directories beyond basic permissions and ownership.
These flags provide a way to control various behaviors and properties of files without needing to resort to creating special directories or using extended attributes.

File flags can be used to achieve different goals, such as preventing file deletion, making files append-only, synchronizing file updates, and more.
Some commonly used file flags in FreeBSD include the "immutable" flag, which prevents modification or deletion of a file, and the "append-only" flag, which allows only data to be added to the end of a file but not modified or removed.

These flags can be managed using the man:chflags[1] command in FreeBSD, providing administrators and users with greater control over the behavior and characteristics of their files and directories.
It is important to note that file flags are typically managed by root or users with appropriate privileges, as they can influence how files are accessed and manipulated.
Some flags are available for the use of the file's owner, as described in man:chflags[1].

[[security-work-file-flag]]
=== Work with File Flags

In this example, a file named [.filename]#~/important.txt# in user's home directory want to be protected against deletions.

Execute the following command to set the `schg` file flag:

[source,shell]
....
# chflags schg ~/important.txt
....

When any user, including the `root` user, tries to delete the file, the system will display the message:

[.programlisting]
....
rm: important.txt: Operation not permitted
....

To delete the file, it will be necessary to delete the file flags of that file by executing the following command:

[source,shell]
....
# chflags noschg ~/important.txt
....

A list of supported file flags and their functionality can be found in man:chflags[1].

[[openssh]]
== OpenSSH

OpenSSH is a set of network connectivity tools used to provide secure access to remote machines.
Additionally, TCP/IP connections can be tunneled or forwarded securely through SSH connections.
OpenSSH encrypts all traffic to eliminate eavesdropping, connection hijacking, and other network-level attacks.

OpenSSH is maintained by the OpenBSD project and is installed by default in FreeBSD.

When data is sent over the network in an unencrypted form, network sniffers anywhere in between the client and server can steal user/password information or data transferred during the session.
OpenSSH offers a variety of authentication and encryption methods to prevent this from happening.

More information about OpenSSH is available in the link:https://www.openssh.com/[web page].

This section provides an overview of the built-in client utilities to securely access other systems and securely transfer files from a FreeBSD system.
It then describes how to configure a SSH server on a FreeBSD system.

[TIP]
====
As stated, this chapter will cover the base system version of OpenSSH.
A version of OpenSSH is also available in the package:security/openssh-portable[], which provides additional configuration options and is updated more regularly.
====

=== Using the SSH Client Utilities

To log into a SSH server, use man:ssh[1] and specify a username that exists on that server and the IP address or hostname of the server.
If this is the first time a connection has been made to the specified server, the user will be prompted to first verify the server's fingerprint:

[source,shell]
....
# ssh user@example.com
....

The output should be similar to the following:

[.programlisting]
....
The authenticity of host 'example.com (10.0.0.1)' can't be established.
ECDSA key fingerprint is 25:cc:73:b5:b3:96:75:3d:56:19:49:d2:5c:1f:91:3b.
Are you sure you want to continue connecting (yes/no)? yes
Permanently added 'example.com' (ECDSA) to the list of known hosts.
Password for user@example.com: user_password
....

SSH utilizes a key fingerprint system to verify the authenticity of the server when the client connects.
When the user accepts the key's fingerprint by typing `yes` when connecting for the first time, a copy of the key is saved to [.filename]#~/.ssh/known_hosts# in the user's home directory.
Future attempts to login are verified against the saved key and man:ssh[1] will display an alert if the server's key does not match the saved key.
If this occurs, the user should first verify why the key has changed before continuing with the connection.

[NOTE]
====
How to perform this check is outside the scope of this chapter.
====

Use man:scp[1] to securely copy a file to or from a remote machine.

This example copies `COPYRIGHT` on the remote system to a file of the same name in the current directory of the local system:

[source,shell]
....
# scp user@example.com:/COPYRIGHT COPYRIGHT
....

The output should be similar to the following:

[.programlisting]
....
Password for user@example.com: *******
COPYRIGHT            100% |*****************************|  4735
....

Since the fingerprint was already verified for this host, the server's key is automatically checked before prompting for the user's password.

The arguments passed to man:scp[1] are similar to man:cp[1].
The file or files to copy is the first argument and the destination to copy to is the second.
Since the file is fetched over the network, one or more of the file arguments takes the form `user@host:<path_to_remote_file>`.
Be aware when copying directories recursively that man:scp[1] uses `-r`, whereas man:cp[1] uses `-R`.

To open an interactive session for copying files, use man:sftp[1].

Refer to man:sftp[1] for a list of available commands while in an man:sftp[1] session.

[[security-ssh-keygen]]
=== Key-based Authentication

Instead of using passwords, a client can be configured to connect to the remote machine using keys.
For security reasons, this is the preferred method.

man:ssh-keygen[1] can be used to generate the authentication keys.
To generate a public and private key pair, specify the type of key and follow the prompts.
It is recommended to protect the keys with a memorable, but hard to guess passphrase.

[source,shell]
....
% ssh-keygen -t rsa -b 4096
....

The output should be similar to the following:

[.programlisting]
....
Generating public/private rsa key pair.
Enter file in which to save the key (/home/user/.ssh/id_rsa):
Created directory '/home/user/.ssh/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/user/.ssh/id_rsa.
Your public key has been saved in /home/user/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:54Xm9Uvtv6H4NOo6yjP/YCfODryvUU7yWHzMqeXwhq8 user@host.example.com
The key's randomart image is:
+---[RSA 2048]----+
|                 |
|                 |
|                 |
|        . o..    |
|       .S*+*o    |
|      . O=Oo . . |
|       = Oo= oo..|
|      .oB.* +.oo.|
|       =OE**.o..=|
+----[SHA256]-----+
....

The private key is stored in [.filename]#~/.ssh/id_rsa# and the public key is stored in [.filename]#~/.ssh/id_rsa.pub#.
The _public_ key must be copied to [.filename]#~/.ssh/authorized_keys# on the remote machine for key-based authentication to work.

[WARNING]
====
Utilizing a passphrase for OpenSSH keys is a key security practice, providing an extra layer of protection against unauthorized access and enhancing overall cybersecurity.

In case of loss or theft, this adds another layer of security.
====

[[security-ssh-tunneling]]
=== SSH Tunneling

OpenSSH has the ability to create a tunnel to encapsulate another protocol in an encrypted session.

The following command tells man:ssh[1] to create a tunnel:

[source,shell]
....
% ssh -D 8080 user@example.com
....

This example uses the following options:

-D::
Specifies a local "dynamic" application-level port forwarding.

user@foo.example.com::
The login name to use on the specified remote SSH server.

An SSH tunnel works by creating a listen socket on `localhost` on the specified `localport`.

This method can be used to wrap any number of insecure TCP protocols such as SMTP, POP3, and FTP.

=== Enabling the SSH Server

In addition to providing built-in SSH client utilities, a FreeBSD system can be configured as an SSH server, accepting connections from other SSH clients.

[TIP]
====
As stated, this chapter will cover the base system version of OpenSSH.
Please *not* confuse with package:security/openssh-portable[], the version of OpenSSH that ships with the FreeBSD ports.
====

In order to have the SSH Server enabled across reboots execute the following command:

[source,shell]
....
# sysrc sshd_enable="YES"
....

Then execute the following command to enable the service:

[source,shell]
....
# service sshd start
....

The first time sshd starts on a FreeBSD system, the system's host keys will be automatically created and the fingerprint will be displayed on the console.
Provide users with the fingerprint so that they can verify it the first time they connect to the server.

Refer to man:sshd[8] for the list of available options when starting sshd and a complete discussion about authentication, the login process, and the various configuration files.

At this point, the sshd should be available to all users with a username and password on the system.

[[config-publickey-auth]]
=== Configuring publickey auth method

Configuring OpenSSH to use public key authentication enhances security by leveraging asymmetric cryptography for authentication.
This method eliminates password-related risks, such as weak passwords or interception during transmission, while thwarting various password-based attacks.
However, it's vital to ensure the private keys are well-protected to prevent unauthorized access.

The first step will be to configure man:sshd[8] to use the required authentication method.

Edit [.filename]#/etc/ssh/sshd_config# and uncomment the following configuration:

[.programlisting]
....
PubkeyAuthentication yes
....

Once the configuration is done, the users will have to send the system administrator their *public key* and these keys will be added in [.filename]#.ssh/authorized_keys#.
The process for generating the keys is described in <<Key-based Authentication>>.

Then restart the server executing the following command:

[source,shell]
....
# service sshd reload
....

It is strongly recommended to follow the security improvements indicated in <<security-sshd-security-options>>.

[[security-sshd-security-options]]
=== SSH Server Security Options

While sshd is the most widely used remote administration facility for FreeBSD, brute force and drive by attacks are common to any system exposed to public networks.

Several additional parameters are available to prevent the success of these attacks and will be described in this section.
All configurations will be done in [.filename]#/etc/ssh/sshd_config#

[TIP]
====
Do not confuse [.filename]#/etc/ssh/sshd_config# with [.filename]#/etc/ssh/ssh_config# (note the extra `d` in the first filename).
The first file configures the server and the second file configures the client.
Refer to man:ssh_config[5] for a listing of the available client settings.
====

By default, authentication can be done with both pubkey and password.
To allow *only* pubkey authentication, *which is strongly recommended*, change the variable:

[.programlisting]
....
PasswordAuthentication no
....

It is a good idea to limit which users can log into the SSH server and from where using the `AllowUsers` keyword in the OpenSSH server configuration file.
For example, to only allow `user` to log in from `192.168.1.32`, add this line to [.filename]#/etc/ssh/sshd_config#:

[.programlisting]
....
AllowUsers user@192.168.1.32
....

To allow `user` to log in from anywhere, list that user without specifying an IP address:

[.programlisting]
....
AllowUsers user
....

Multiple users should be listed on the same line, like so:

[.programlisting]
....
AllowUsers root@192.168.1.32 user
....

After making all the changes, and before restarting the service, it is recommended to verify that the configuration made is correct by executing the following command:

[source,shell]
....
# sshd -t
....

If the configuration file is correct, no output will be shown.
In case the configuration file is incorrect, it will show something like this:

[.programlisting]
....
/etc/ssh/sshd_config: line 3: Bad configuration option: sdadasdasdasads
/etc/ssh/sshd_config: terminating, 1 bad configuration options
....

After making the changes and checking that the configuration file is correct, tell sshd to reload its configuration file by running:

[source,shell]
....
# service sshd reload
....

[[openssl]]
== OpenSSL

OpenSSL is a cryptography toolkit implementing the Secure Sockets Layer (SSL) and Transport Layer Security (TLS) network protocols and many cryptography routines.

The openssl program is a command line tool for using the various cryptography functions of OpenSSL's crypto library from the shell.
It can be used for

* Creation and management of private keys, public keys and parameters
* Public key cryptographic operations
* Creation of X.509 certificates, CSRs and CRLs
* Calculation of Message Digests
* Encryption and Decryption with Ciphers
* SSL/TLS Client and Server Tests
* Handling of S/MIME signed or encrypted mail
* Time Stamp requests, generation and verification
* Benchmarking the crypto routines

For more information about OpenSSL, read the free https://www.feistyduck.com/books/openssl-cookbook/[OpenSSL Cookbook].

[[generating-certificates]]
=== Generating Certificates

OpenSSL supports the generation of certificates both to be validated by a link:https://en.wikipedia.org/wiki/Certificate_authority[CA] and for own use.

Run the command man:openssl[1] to generate a valid certificate for a link:https://en.wikipedia.org/wiki/Certificate_authority[CA] with the following arguments.
This command will create two files in the current directory.
The certificate request, [.filename]#req.pem#, can be sent to a link:https://en.wikipedia.org/wiki/Certificate_authority[CA] which,
will validate the entered credentials, sign the request, and return the signed certificate.
The second file, [.filename]#cert.key#, is the private key for the certificate and should be stored in a secure location.
If this falls in the hands of others, it can be used to impersonate the user or the server.

Execute the following command to generate the certificate:

[source,shell]
....
# openssl req -new -nodes -out req.pem -keyout cert.key -sha3-512 -newkey rsa:4096
....

The output should be similar to the following:

[.programlisting]
....
Generating a RSA private key
..................................................................................................................................+++++
......................................+++++
writing new private key to 'cert.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:ES
State or Province Name (full name) [Some-State]:Valencian Community
Locality Name (eg, city) []:Valencia
Organization Name (eg, company) [Internet Widgits Pty Ltd]:My Company
Organizational Unit Name (eg, section) []:Systems Administrator
Common Name (e.g. server FQDN or YOUR name) []:localhost.example.org
Email Address []:user@FreeBSD.org

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:123456789
An optional company name []:Another name
....

Alternately, if a signature from a link:https://en.wikipedia.org/wiki/Certificate_authority[CA] is not required, a self-signed certificate can be created.
This will create two new files in the current directory: a private key file [.filename]#cert.key#, and the certificate itself, [.filename]#cert.crt#.
These should be placed in a directory, preferably under [.filename]#/etc/ssl/#, which is readable only by `root`.
Permissions of `0700` are appropriate for these files and can be set using `chmod`.

Execute the following command to generate the certificate:

[source,shell]
....
# openssl req -new -x509 -days 365 -sha3-512 -keyout /etc/ssl/private/cert.key -out /etc/ssl/certs/cert.crt
....

The output should be similar to the following:

[.programlisting]
....
Generating a RSA private key
........................................+++++
...........+++++
writing new private key to '/etc/ssl/private/cert.key'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:ES
State or Province Name (full name) [Some-State]:Valencian Community
Locality Name (eg, city) []:Valencia
Organization Name (eg, company) [Internet Widgits Pty Ltd]:My Company
Organizational Unit Name (eg, section) []:Systems Administrator
Common Name (e.g. server FQDN or YOUR name) []:localhost.example.org
Email Address []:user@FreeBSD.org
....

[[fips-provider]]
=== Configuring the FIPS Provider

With the import of OpenSSL 3 into the base system (on FreeBSD 14 and later), its new concept of provider modules was introduced in the system.
Besides the default provider module built-in to the library, the _legacy_ module implements the now optional deprecated cryptography algorithms, while the _fips_ module restricts the OpenSSL implementation to the cryptography algorithms present in the link:https://en.wikipedia.org/wiki/Federal_Information_Processing_Standards[FIPS] set of standards.
This part of OpenSSL receives link:https://www.openssl.org/docs/fips.html[particular care], including a link:https://www.openssl.org/news/fips-cve.html[list of relevant security issues], and is subject to the link:https://github.com/openssl/openssl/blob/master/README-FIPS.md[FIPS 140 validation process] on a regular basis.
The link:https://www.openssl.org/source/[list of FIPS validated versions] is also available.
This allows users to ensure FIPS compliance in their use of OpenSSL.

Importantly, the man:fips_module[7] is protected by an additional security measure, preventing its use without passing an integrity check.
This check can be setup by the local system administrator, allowing every user of OpenSSL 3 to load this module.
When not configured correctly, the FIPS module is expected to fail as follows:

[source,shell]
....
# echo test | openssl aes-128-cbc -a -provider fips -pbkdf2
....

The output should be similar to the following:

[.programlisting]
....
aes-128-cbc: unable to load provider fips
Hint: use -provider-path option or OPENSSL_MODULES environment variable.
00206124D94D0000:error:1C8000D5:Provider routines:SELF_TEST_post:missing config data:crypto/openssl/providers/fips/self_test.c:275:
00206124D94D0000:error:1C8000E0:Provider routines:ossl_set_error_state:fips module entering error state:crypto/openssl/providers/fips/self_test.c:373:
00206124D94D0000:error:1C8000D8:Provider routines:OSSL_provider_init_int:self test post failure:crypto/openssl/providers/fips/fipsprov.c:707:
00206124D94D0000:error:078C0105:common libcrypto routines:provider_init:init fail:crypto/openssl/crypto/provider_core.c:932:name=fips
....

The check can be configured through the creation of a file in [.filename]#/etc/ssl/fipsmodule.cnf#, which will then be referenced in OpenSSL's main configuration file [.filename]#/etc/ssl/openssl.cnf#.
OpenSSL provides the man:openssl-fipsinstall[1] utility to help with this process, which can be used as follows:

[source,shell]
....
# openssl fipsinstall -module /usr/lib/ossl-modules/fips.so -out /etc/ssl/fipsmodule.cnf
....

The output should be similar to the following:

[.programlisting]
....
INSTALL PASSED
....

The [.filename]#/etc/ssl/openssl.cnf# should then be modified, in order to:

* Include the [.filename]#/etc/ssl/fipsmodule.cnf# file generated above,
* Expose the FIPS module for possible use,
* And explicitly activate the default module.

[.programlisting]
....
[...]
# For FIPS
# Optionally include a file that is generated by the OpenSSL fipsinstall
# application. This file contains configuration data required by the OpenSSL
# fips provider. It contains a named section e.g. [fips_sect] which is
# referenced from the [provider_sect] below.
# Refer to the OpenSSL security policy for more information.
.include /etc/ssl/fipsmodule.cnf

[...]

# List of providers to load
[provider_sect]
default = default_sect
# The fips section name should match the section name inside the
# included fipsmodule.cnf.
fips = fips_sect

# If no providers are activated explicitly, the default one is activated implicitly.
# See man 7 OSSL_PROVIDER-default for more details.
#
# If you add a section explicitly activating any other provider(s), you most
# probably need to explicitly activate the default provider, otherwise it
# becomes unavailable in openssl.  As a consequence applications depending on
# OpenSSL may not work correctly which could lead to significant system
# problems including inability to remotely access the system.
[default_sect]
activate = 1
....

With this done, it should be possible to confirm that the FIPS module is effectively available and working:

[source,shell]
....
# echo test | openssl aes-128-cbc -a -provider fips -pbkdf2
....

The output should be similar to the following:

[.programlisting]
....
enter AES-128-CBC encryption password:
Verifying - enter AES-128-CBC encryption password:
U2FsdGVkX18idooW6e3LqWeeiKP76kufcOUClh57j8U=
....

This procedure has to be repeated every time the FIPS module is modified, e.g., after performing system updates, or after applying security fixes affecting OpenSSL in the base system.

[[kerberos5]]
== Kerberos

Kerberos is a network authentication protocol which was originally created by the Massachusetts Institute of Technology (MIT) as a way to securely provide authentication across a potentially hostile network.
The Kerberos protocol uses strong cryptography so that both a client and server can prove their identity without sending any unencrypted secrets over the network.
Kerberos can be described as an identity-verifying proxy system and as a trusted third-party authentication system.
After a user authenticates with Kerberos, their communications can be encrypted to assure privacy and data integrity.

The only function of Kerberos is to provide the secure authentication of users and servers on the network.
It does not provide authorization or auditing functions.
It is recommended that Kerberos be used with other security methods which provide authorization and audit services.

The current version of the protocol is version 5, described in RFC 4120.
Several free implementations of this protocol are available, covering a wide range of operating systems.
MIT continues to develop their Kerberos package.
It is commonly used in the US as a cryptography product, and has historically been subject to US export regulations.
In FreeBSD, MITKerberos is available as the package:security/krb5[] package or port.
The Heimdal Kerberos implementation was explicitly developed outside of the US to avoid export regulations.
The Heimdal Kerberos distribution is included in the base FreeBSD installation, and another distribution with more configurable options is available as package:security/heimdal[] in the Ports Collection.

In Kerberos users and services are identified as "principals" which are contained within an administrative grouping, called a "realm".
A typical user principal would be of the form `_user_@_REALM_` (realms are traditionally uppercase).

This section provides a guide on how to set up Kerberos using the Heimdal distribution included in FreeBSD.

For purposes of demonstrating a Kerberos installation, the name spaces will be as follows:

* The DNS domain (zone) will be `example.org`.
* The Kerberos realm will be `EXAMPLE.ORG`.

[NOTE]
====
Use real domain names when setting up Kerberos, even if it will run internally.
This avoids DNS problems and assures inter-operation with other Kerberos realms.
====

=== Setting up a Heimdal KDC

The Key Distribution Center (KDC) is the centralized authentication service that Kerberos provides, the "trusted third party" of the system.
It is the computer that issues Kerberos tickets, which are used for clients to authenticate to servers.
As the KDC is considered trusted by all other computers in the Kerberos realm, it has heightened security concerns.
Direct access to the KDC should be limited.

While running a KDC requires few computing resources, a dedicated machine acting only as a KDC is recommended for security reasons.

To begin, install the package:security/heimdal[] package as follows:

[source,shell]
....
# pkg install heimdal
....

Next, update [.filename]#/etc/rc.conf# using `sysrc` as follows:

[source,shell]
....
# sysrc kdc_enable=yes
# sysrc kadmind_enable=yes
....

Next, edit [.filename]#/etc/krb5.conf# as follows:

[.programlisting]
....
[libdefaults]
    default_realm = EXAMPLE.ORG
[realms]
    EXAMPLE.ORG = {
	kdc = kerberos.example.org
	admin_server = kerberos.example.org
    }
[domain_realm]
    .example.org = EXAMPLE.ORG
....

In this example, the KDC will use the fully-qualified hostname `kerberos.example.org`.
The hostname of the KDC must be resolvable in the DNS.

Kerberos can also use the DNS to locate KDCs, instead of a `[realms]` section in [.filename]#/etc/krb5.conf#.
For large organizations that have their own DNS servers, the above example could be trimmed to:

[.programlisting]
....
[libdefaults]
      default_realm = EXAMPLE.ORG
[domain_realm]
    .example.org = EXAMPLE.ORG
....

With the following lines being included in the `example.org` zone file:

[.programlisting]
....
_kerberos._udp      IN  SRV     01 00 88 kerberos.example.org.
_kerberos._tcp      IN  SRV     01 00 88 kerberos.example.org.
_kpasswd._udp       IN  SRV     01 00 464 kerberos.example.org.
_kerberos-adm._tcp  IN  SRV     01 00 749 kerberos.example.org.
_kerberos           IN  TXT     EXAMPLE.ORG
....

[NOTE]
====
In order for clients to be able to find the Kerberos services, they _must_ have either a fully configured [.filename]#/etc/krb5.conf# or a minimally configured [.filename]#/etc/krb5.conf# _and_ a properly configured DNS server.
====

Next, create the Kerberos database which contains the keys of all principals (users and hosts) encrypted with a master password.
It is not required to remember this password as it will be stored in [.filename]#/var/heimdal/m-key#;
it would be reasonable to use a 45-character random password for this purpose.
To create the master key, run `kstash` and enter a password:

[source,shell]
....
# kstash
....

The output should be similar to the following:

[.programlisting]
....
Master key: xxxxxxxxxxxxxxxxxxxxxxx
Verifying password - Master key: xxxxxxxxxxxxxxxxxxxxxxx
....

Once the master key has been created, the database should be initialized.
The Kerberos administrative tool man:kadmin[8] can be used on the KDC in a mode that operates directly on the database, without using the man:kadmind[8] network service, as `kadmin -l`.
This resolves the chicken-and-egg problem of trying to connect to the database before it is created.
At the `kadmin` prompt, use `init` to create the realm's initial database:

[source,shell]
....
# kadmin -l
kadmin> init EXAMPLE.ORG
Realm max ticket life [unlimited]:
....

Lastly, while still in `kadmin`, create the first principal using `add`.
Stick to the default options for the principal for now, as these can be changed later with `modify`.
Type `?` at the prompt to see the available options.

[source,shell]
....
kadmin> add tillman
....

The output should be similar to the following:

[.programlisting]
....
Max ticket life [unlimited]:
Max renewable life [unlimited]:
Principal expiration time [never]:
Password expiration time [never]:
Attributes []:
Password: xxxxxxxx
Verifying password - Password: xxxxxxxx
....

Next, start the KDC services by running:

[source,shell]
....
# service kdc start
# service kadmind start
....

While there will not be any kerberized daemons running at this point, it is possible to confirm that the KDC is functioning by obtaining a ticket for the principal that was just created:

[source,shell]
....
% kinit tillman
....

The output should be similar to the following:

[.programlisting]
....
tillman@EXAMPLE.ORG's Password:
....

Confirm that a ticket was successfully obtained using `klist`:

[source,shell]
....
% klist
....

The output should be similar to the following:

[.programlisting]
....
Credentials cache: FILE:/tmp/krb5cc_1001
	Principal: tillman@EXAMPLE.ORG

  Issued                Expires               Principal
Aug 27 15:37:58 2013  Aug 28 01:37:58 2013  krbtgt/EXAMPLE.ORG@EXAMPLE.ORG
....

The temporary ticket can be destroyed when the test is finished:

[source,shell]
....
% kdestroy
....

=== Configuring a Server to Use Kerberos

The first step in configuring a server to use Kerberos authentication is to ensure that it has the correct configuration in [.filename]#/etc/krb5.conf#.
The version from the KDC can be used as-is, or it can be regenerated on the new system.

Next, create [.filename]#/etc/krb5.keytab# on the server.
This is the main part of "Kerberizing" a service - it corresponds to generating a secret shared between the service and the KDC.
The secret is a cryptographic key, stored in a "keytab".
The keytab contains the server's host key, which allows it and the KDC to verify each others' identity.
It must be transmitted to the server in a secure fashion, as the security of the server can be broken if the key is made public.
Typically, the [.filename]#keytab# is generated on an administrator's trusted machine using `kadmin`, then securely transferred to the server, e.g.,
with man:scp[1]; it can also be created directly on the server if that is consistent with the desired security policy.
It is very important that the keytab is transmitted to the server in a secure fashion: if the key is known by some other party, that party can impersonate any user to the server! Using `kadmin` on the server directly is convenient, because the entry for the host principal in the KDC database is also created using `kadmin`.

Of course, `kadmin` is a kerberized service; a Kerberos ticket is needed to authenticate to the network service, but to ensure that the user running `kadmin` is actually present (and their session has not been hijacked), `kadmin` will prompt for the password to get a fresh ticket.
The principal authenticating to the kadmin service must be permitted to use the `kadmin` interface, as specified in [.filename]#/var/heimdal/kadmind.acl#. See the section titled "Remote administration" in `info heimdal` for details on designing access control lists.
Instead of enabling remote `kadmin` access, the administrator could securely connect to the KDC via the local console or man:ssh[1], and perform administration locally using `kadmin -l`.

After installing [.filename]#/etc/krb5.conf#, use `add --random-key` in `kadmin`.
This adds the server's host principal to the database, but does not extract a copy of the host principal key to a keytab.
To generate the keytab, use `ext` to extract the server's host principal key to its own keytab:

[source,shell]
....
# kadmin
....

The output should be similar to the following:

[.programlisting]
....
kadmin> add --random-key host/myserver.example.org
Max ticket life [unlimited]:
Max renewable life [unlimited]:
Principal expiration time [never]:
Password expiration time [never]:
Attributes []:
kadmin> ext_keytab host/myserver.example.org
kadmin> exit
....

Note that `ext_keytab` stores the extracted key in [.filename]#/etc/krb5.keytab# by default.
This is good when being run on the server being kerberized, but the `--keytab _path/to/file_` argument should be used when the keytab is being extracted elsewhere:

[source,shell]
....
# kadmin
....

The output should be similar to the following:

[.programlisting]
....
kadmin> ext_keytab --keytab=/tmp/example.keytab host/myserver.example.org
kadmin> exit
....

The keytab can then be securely copied to the server using man:scp[1] or a removable media.
Be sure to specify a non-default keytab name to avoid inserting unneeded keys into the system's keytab.

At this point, the server can read encrypted messages from the KDC using its shared key, stored in [.filename]#krb5.keytab#.
It is now ready for the Kerberos-using services to be enabled.
One of the most common such services is man:sshd[8], which supports Kerberos via the GSS-API.
In [.filename]#/etc/ssh/sshd_config#, add the line:

[.programlisting]
....
GSSAPIAuthentication yes
....

After making this change, man:sshd[8] must be restarted for the new configuration to take effect: `service sshd restart`.

=== Configuring a Client to Use Kerberos

As it was for the server, the client requires configuration in [.filename]#/etc/krb5.conf#.
Copy the file in place (securely) or re-enter it as needed.

Test the client by using `kinit`, `klist`, and `kdestroy` from the client to obtain, show, and then delete a ticket for an existing principal.
Kerberos applications should also be able to connect to Kerberos enabled servers.
If that does not work but obtaining a ticket does, the problem is likely with the server and not with the client or the KDC.
In the case of kerberized man:ssh[1], GSS-API is disabled by default, so test using `ssh -o GSSAPIAuthentication=yes _hostname_`.

When testing a Kerberized application, try using a packet sniffer such as `tcpdump` to confirm that no sensitive information is sent in the clear.

Various Kerberos client applications are available.
With the advent of a bridge so that applications using SASL for authentication can use GSS-API mechanisms as well, large classes of client applications can use Kerberos for authentication, from Jabber clients to IMAP clients.

Users within a realm typically have their Kerberos principal mapped to a local user account.
Occasionally, one needs to grant access to a local user account to someone who does not have a matching Kerberos principal.
For example, `tillman@EXAMPLE.ORG` may need access to the local user account `webdevelopers`.
Other principals may also need access to that local account.

The [.filename]#.k5login# and [.filename]#.k5users# files, placed in a user's home directory, can be used to solve this problem.
For example, if the following [.filename]#.k5login# is placed in the home directory of `webdevelopers`, both principals listed will have access to that account without requiring a shared password:

[.programlisting]
....
tillman@example.org
jdoe@example.org
....

Refer to man:ksu[1] for more information about [.filename]#.k5users#.

=== MIT Differences

The major difference between the MIT and Heimdal implementations is that `kadmin` has a different, but equivalent, set of commands and uses a different protocol.
If the KDC is MIT, the Heimdal version of `kadmin` cannot be used to administer the KDC remotely, and vice versa.

Client applications may also use slightly different command line options to accomplish the same tasks.
Following the instructions at http://web.mit.edu/Kerberos/www/[http://web.mit.edu/Kerberos/www/] is recommended.
Be careful of path issues: the MIT port installs into [.filename]#/usr/local/# by default, and the FreeBSD system applications run instead of the MIT versions if `PATH` lists the system directories first.

When using MIT Kerberos as a KDC on FreeBSD, execute the following commands to add the required configurations to [.filename]#/etc/rc.conf#:

[source,shell]
....
# sysrc kdc_program="/usr/local/sbin/kdc"
# sysrc kadmind_program="/usr/local/sbin/kadmind"
# sysrc kdc_flags=""
# sysrc kdc_enable="YES"
# sysrc kadmind_enable="YES"
....

=== Kerberos Tips, Tricks, and Troubleshooting

When configuring and troubleshooting Kerberos, keep the following points in mind:

* When using either Heimdal or MITKerberos from ports, ensure that the `PATH` lists the port's versions of the client applications before the system versions.
* If all the computers in the realm do not have synchronized time settings, authentication may fail. crossref:network-servers[network-ntp,“Clock Synchronization with NTP”] describes how to synchronize clocks using NTP.
* If the hostname is changed, the `host/` principal must be changed and the keytab updated. This also applies to special keytab entries like the `HTTP/` principal used for Apache's package:www/mod_auth_kerb[].
* All hosts in the realm must be both forward and reverse resolvable in DNS or, at a minimum, exist in [.filename]#/etc/hosts#. CNAMEs will work, but the A and PTR records must be correct and in place. The error message for unresolvable hosts is not intuitive: `Kerberos5 refuses authentication because Read req failed: Key table entry not found`.
* Some operating systems that act as clients to the KDC do not set the permissions for `ksu` to be setuid `root`. This means that `ksu` does not work. This is a permissions problem, not a KDC error.
* With MITKerberos, to allow a principal to have a ticket life longer than the default lifetime of ten hours, use `modify_principal` at the man:kadmin[8] prompt to change the `maxlife` of both the principal in question and the `krbtgt` principal. The principal can then use `kinit -l` to request a ticket with a longer lifetime.
* When running a packet sniffer on the KDC to aid in troubleshooting while running `kinit` from a workstation, the Ticket Granting Ticket (TGT) is sent immediately, even before the password is typed. This is because the Kerberos server freely transmits a TGT to any unauthorized request. However, every TGT is encrypted in a key derived from the user's password. When a user types their password, it is not sent to the KDC, it is instead used to decrypt the TGT that `kinit` already obtained. If the decryption process results in a valid ticket with a valid time stamp, the user has valid Kerberos credentials. These credentials include a session key for establishing secure communications with the Kerberos server in the future, as well as the actual TGT, which is encrypted with the Kerberos server's own key. This second layer of encryption allows the Kerberos server to verify the authenticity of each TGT.
* Host principals can have a longer ticket lifetime. If the user principal has a lifetime of a week but the host being connected to has a lifetime of nine hours, the user cache will have an expired host principal and the ticket cache will not work as expected.
* When setting up [.filename]#krb5.dict# to prevent specific bad passwords from being used as described in man:kadmind[8], remember that it only applies to principals that have a password policy assigned to them. The format used in [.filename]#krb5.dict# is one string per line. Creating a symbolic link to [.filename]#/usr/share/dict/words# might be useful.

=== Mitigating Kerberos Limitations

Since Kerberos is an all or nothing approach, every service enabled on the network must either be modified to work with Kerberos or be otherwise secured against network attacks.
This is to prevent user credentials from being stolen and re-used.
An example is when Kerberos is enabled on all remote shells but the non-Kerberized POP3 mail server sends passwords in plain text.

The KDC is a single point of failure.
By design, the KDC must be as secure as its master password database.
The KDC should have absolutely no other services running on it and should be physically secure.
The danger is high because Kerberos stores all passwords encrypted with the same master key which is stored as a file on the KDC.

A compromised master key is not quite as bad as one might fear.
The master key is only used to encrypt the Kerberos database and as a seed for the random number generator.
As long as access to the KDC is secure, an attacker cannot do much with the master key.

If the KDC is unavailable, network services are unusable as authentication cannot be performed.
This can be alleviated with a single master KDC and one or more slaves, and with careful implementation of secondary or fall-back authentication using PAM.

Kerberos allows users, hosts and services to authenticate between themselves.
It does not have a mechanism to authenticate the KDC to the users, hosts, or services.
This means that a trojaned `kinit` could record all user names and passwords.
File system integrity checking tools like package:security/tripwire[] can alleviate this.

=== Resources and Further Information

* http://www.faqs.org/faqs/Kerberos-faq/general/preamble.html[The Kerberos FAQ]
* http://web.mit.edu/Kerberos/www/dialogue.html[Designing an Authentication System: a Dialog in Four Scenes]
* https://www.ietf.org/rfc/rfc4120.txt[RFC 4120, The Kerberos Network Authentication Service (V5)]
* http://web.mit.edu/Kerberos/www/[MIT Kerberos home page]
* https://github.com/heimdal/heimdal/wiki[Heimdal Kerberos project wiki page]

[[tcpwrappers]]
== TCP Wrappers

TCP Wrappers is a host-based network access control system.
By intercepting incoming network requests before they reach the actual network service,
TCP Wrappers assess whether the source IP address is permitted or denied access based on predefined rules in configuration files.

However, while TCP Wrappers provide basic access control, they should not be considered a substitute for more robust security measures.
For comprehensive protection, it's recommended to use advanced technologies like firewalls, along with proper user authentication practices and intrusion detection systems.

[[tcpwrappers-initial-configuration]]
=== Initial Configuration

TCP Wrappers are enabled by default in man:inetd[8].
So the first step will be to enable man:inetd[8] executing the following commands:

[source,shell]
....
# sysrc inetd_enable="YES"
# service inetd start
....

Then, properly configure [.filename]#/etc/hosts.allow#.

[WARNING]
====
Unlike other implementations of TCP Wrappers, the use of [.filename]#hosts.deny# is deprecated in FreeBSD.
All configuration options should be placed in [.filename]#/etc/hosts.allow#.
====

In the simplest configuration, daemon connection policies are set to either permit or block, depending on the options in [.filename]#/etc/hosts.allow#.
The default configuration in FreeBSD is to allow all connections to the daemons started with inetd.

Basic configuration usually takes the form of `daemon : address : action`, where `daemon` is the daemon which inetd started, `address` is a valid hostname, IP address, or an IPv6 address enclosed in brackets ([ ]), and `action` is either `allow` or `deny`.
TCP Wrappers uses a first rule match semantic, meaning that the configuration file is scanned from the beginning for a matching rule.
When a match is found, the rule is applied and the search process stops.

For example, to allow POP3 connections via the package:mail/qpopper[] daemon, the following lines should be appended to [.filename]#/etc/hosts.allow#:

[.programlisting]
....
# This line is required for POP3 connections:
qpopper : ALL : allow
....

Whenever this file is edited, restart inetd:

[source,shell]
....
# service inetd restart
....

[[tcpwrappers-advanced-config]]
=== Advanced Configuration

TCP Wrappers provides advanced options to allow more control over the way connections are handled.
In some cases, it may be appropriate to return a comment to certain hosts or daemon connections.
In other cases, a log entry should be recorded or an email sent to the administrator.
Other situations may require the use of a service for local connections only.
This is all possible through the use of configuration options known as wildcards, expansion characters, and external command execution.
To learn more about wildcards and their associated functionality, refer to man:hosts_access[5].

[[fs-acl]]
== Access Control Lists

Access Control Lists (ACLs) extend traditional UNIX(R) file permissions by allowing fine-grained access control for users and groups on a per-file or per-directory basis.
Each ACL entry defines a user or group and the associated permissions, such as read, write, and execute.
FreeBSD provides commands like man:getfacl[1] and man:setfacl[1] to manage ACLs.

ACLs are useful in scenarios requiring more specific access control than standard permissions, commonly used in multi-user environments or shared hosting.
However, complexity may be unavoidable, but careful planning is required to ensure that the desired security properties are being provided

[NOTE]
====
FreeBSD supports the implementation of NFSv4 ACLs in both UFS and OpenZFS.
Please note that some arguments to the man:setfacl[1] command only work with POSIX ACLs and others in NFSv4 ACLs.
====

[[acl-enabling-support-ufs]]
=== Enabling ACL Support in UFS

ACLs are enabled by the mount-time administrative flag, `acls`, which may be added to [.filename]#/etc/fstab#.

Therefore it will be necessary to access [.filename]#/etc/fstab# and in the options section add the `acls` flag as follows:

[.programlisting]
....
# Device        Mountpoint        FStype    Options     Dump      Pass#
/dev/ada0s1a    /                 ufs       rw,acls     1         1
....

[[security-acl-info]]
=== Get ACLs information

It is possible to check the ACLs of a file or a directory using man:getfacl[1].

For example, to view the ACL settings on [.filename]#~/test# file execute the following command:

[source,shell]
....
% getfacl test
....

The output should be similar to the following in case of using NFSv4 ACLs:

[.programlisting]
....
# file: test
# owner: freebsduser
# group: freebsduser
            owner@:rw-p--aARWcCos:-------:allow
            group@:r-----a-R-c--s:-------:allow
         everyone@:r-----a-R-c--s:-------:allow
....

And the output should be similar to the following in case of using POSIX.1e ACLs:

[.programlisting]
....
# file: test
# owner: freebsduser
# group: freebsduser
user::rw-
group::r--
other::r--
....

[[security-working-acls]]
=== Working with ACLs

man:setfacl[1] can be used to add, modify or remove ACLs from a file or directory.

As noted above, some arguments to man:setfacl[1] do not work with NFSv4 ACLs, and vice versa.
This section covers how to execute the commands for POSIX ACLs and for NFSv4 ACLs and shows examples of both.

For example, to set the mandatory elements of the POSIX.1e default ACL:

[source,shell]
....
% setfacl -d -m u::rwx,g::rx,o::rx,mask::rwx directory
....

This other example sets read, write, and execute permissions for the file owner's POSIX.1e ACL entry and read and write permissions for group mail on file:

[source,shell]
....
% setfacl -m u::rwx,g:mail:rw file
....

To do the same as in the previous example but in NFSv4 ACL:

[source,shell]
....
% setfacl -m owner@:rwxp::allow,g:mail:rwp::allow file
....

To remove all ACL entries except for the three required from file in POSIX.1e ACL:

[source,shell]
....
% setfacl -bn file
....

To remove all ACL entries in NFSv4 ACL:

[source,shell]
....
% setfacl -b file
....

Refer to man:getfacl[1] and man:setfacl[1] for more information about the options available for these commands.

[[capsicum]]
== Capsicum

Capsicum is a lightweight OS capability and sandbox framework implementing a hybrid capability system model.
Capabilities are unforgeable tokens of authority that can be delegated and must be presented to perform an action.
Capsicum makes file descriptors into capabilities.

Capsicum can be used for application and library compartmentalisation,
the decomposition of larger bodies of software into isolated (sandboxed) components in order to implement security policies and limit the impact of software vulnerabilities.

[[security-accounting]]
== Process Accounting

Process accounting is a security method in which an administrator may keep track of system resources used and their allocation among users, provide for system monitoring, and minimally track a user's commands.

Process accounting has both positive and negative points.
One of the positives is that an intrusion may be narrowed down to the point of entry.
A negative is the amount of logs generated by process accounting, and the disk space they may require.
This section walks an administrator through the basics of process accounting.

[NOTE]
====
If more fine-grained accounting is needed, refer to crossref:audit[audit,Security Event Auditing].
====

=== Enabling and Utilizing Process Accounting

Before using process accounting, it must be enabled using the following commands:

[source,shell]
....
# sysrc accounting_enable=yes
# service accounting start
....

The accounting information is stored in files located in [.filename]#/var/account#, which is automatically created, if necessary, the first time the accounting service starts.
These files contain sensitive information, including all the commands issued by all users.
Write access to the files is limited to `root`, and read access is limited to `root` and members of the `wheel` group.
To also prevent members of `wheel` from reading the files, change the mode of the [.filename]#/var/account# directory to allow access only by `root`.

Once enabled, accounting will begin to track information such as CPU statistics and executed commands.
All accounting logs are in a non-human readable format which can be viewed using man:sa[8].
If issued without any options, man:sa[8] prints information relating to the number of per-user calls, the total elapsed time in minutes, total CPU and user time in minutes, and the average number of I/O operations.
Refer to man:sa[8] for the list of available options which control the output.

To display the commands issued by users, use `lastcomm`.

For example, this command prints out all usage of `ls` by `trhodes` on the `ttyp1` terminal:

[source,shell]
....
# lastcomm ls trhodes ttyp1
....

Many other useful options exist and are explained in man:lastcomm[1], man:acct[5], and man:sa[8].

[[security-resourcelimits]]
== Resource Limits

In FreeBSD, resource limits refer to the mechanisms that control and manage the allocation of various system resources to processes and users.
These limits are designed to prevent a single process or user from consuming an excessive amount of resources, which could lead to performance degradation or system instability.
Resource limits help ensure fair resource distribution among all active processes and users on the system.

FreeBSD provides several methods for an administrator to limit the amount of system resources an individual may use.

The traditional method defines login classes by editing [.filename]#/etc/login.conf#.
While this method is still supported, any changes require a multi-step process of editing this file, rebuilding the resource database, making necessary changes to [.filename]#/etc/master.passwd#, and rebuilding the password database.
This can become time consuming, depending upon the number of users to configure.

man:rctl[8] can be used to provide a more fine-grained method for controlling resource limits.
This command supports more than user limits as it can also be used to set resource constraints on processes and jails.

This section demonstrates both methods for controlling resources, beginning with the traditional method.

[[security-resource-limits-types]]
=== Types of Resources

FreeBSD provides limits for various types of resources, including:

.Resource types
[options="header", cols="1,1"]
|===
| Type | Description

| CPU Time
| Limits the amount of CPU time a process can consume

| Memory
| Controls the amount of physical memory a process can use

| Open Files
| Limits the number of files a process can have open simultaneously

| Processes
| Controls the number of processes a user or a process can create

| File Size
| Limits the maximum size of files that a process can create

| Core Dumps
| Controls whether processes are allowed to generate core dump files

| Network Resources
| Limits the amount of network resources (e.g., sockets) a process can use

|===

For a full listing of types see man:login.conf[5] and man:rctl[8].

[[users-limiting]]
=== Configuring Login Classes

In the traditional method, login classes and the resource limits to apply to a login class are defined in [.filename]#/etc/login.conf#.
Each user account can be assigned to a login class, where `default` is the default login class.
Each login class has a set of login capabilities associated with it.
A login capability is a `_name_=_value_` pair, where _name_ is a well-known identifier and _value_ is an arbitrary string which is processed accordingly depending on the _name_.

The first step to configure a resource limit will be to open [.filename]#/etc/login.conf# by executing the following command:

[source,shell]
....
# ee /etc/login.conf
....

Then locate the section for the user class to be modified.
In this example, let's assume the user class is named `limited`, create it in case it does not exist.

[.programlisting]
....
limited:\ <.>
        :maxproc=50:\ <.>
        :tc=default: <.>
....

<.> Name of the user class.
<.> Sets the maximum number of processes (maxproc) to 50 for users in the `limited` class.
<.> Indicates that this user class inherits the default settings from the "default" class.

After modifying the [.filename]#/etc/login.conf# file, run man:cap_mkdb[1] to generate the database that FreeBSD uses to apply these settings:

[source,shell]
....
# cap_mkdb /etc/login.conf
....

man:chpass[1] can be used to change the class to the desired user by executing the following command:

[source,shell]
....
# chpass username
....

This will open a text editor, add the new `limited` class there as follows:

[.programlisting]
....
#Changing user information for username.
Login: username
Password: $6$2H.419USdGaiJeqK$6kgcTnDadasdasd3YnlNZsOni5AMymibkAfRCPirc7ZFjjv
DVsKyXx26daabdfqSdasdsmL/ZMUpdHiO0
Uid [#]: 1001
Gid [# or name]: 1001
Change [month day year]:
Expire [month day year]:
Class: limited
Home directory: /home/username
Shell: /bin/sh
Full Name: User &
Office Location:
Office Phone:
Home Phone:
Other information:
....

Now, the user assigned to the `limited` class will have a maximum process limit of 50.
Remember that this is just one example of setting a resource limit using the [.filename]#/etc/login.conf# file.

Keep in mind that after making changes to the [.filename]#/etc/login.conf# file, the user needs to log out and log back in for the changes to take effect.
Additionally, always exercise caution when editing system configuration files, especially when using privileged access.

[[security-rctl]]
=== Enabling and Configuring Resource Limits

The man:rctl[8] system provides a more fine-grained way to set and manage resource limits for individual processes and users.
It allows you to dynamically assign resource limits to specific processes or users, regardless of their user class.

The first step to use man:rctl[8] will be to enable it adding the following line to [.filename]#/boot/loader.conf# and reboot the system:

[.programlisting]
....
kern.racct.enable=1
....

Then enable and start the man:rctl[8] service by executing the following commands:

[source,shell]
....
# sysrc rctl_enable="YES"
# service rctl start
....

Then man:rctl[8] may be used to set rules for the system.

Rule syntax (man:rctl.conf[5]) is controlled through the use of a subject, subject-id, resource, and action, as seen in this example rule:

[.programlisting]
....
subject:subject-id:resource:action=amount/per
....

For example to constrained the user to add no more than 10 processes execute the following command:

[source,shell]
....
# rctl -a user:username:maxproc:deny=10/user
....

To check the applied resource limits the man:rctl[8] command can be executed:

[source,shell]
....
# rctl
....

The output should be similar to the following:

[.programlisting]
....
user:username:maxproc:deny=10
....

Rules will persist across reboots if they have been added to [.filename]#/etc/rctl.conf#.
The format is a rule, without the preceding command. For example, the previous rule could be added as:

[.programlisting]
....
user:username:maxproc:deny=10
....

[[security-pkg]]
== Monitoring Third Party Security Issues

In recent years, the security world has made many improvements to how vulnerability assessment is handled.
The threat of system intrusion increases as third party utilities are installed and configured for virtually any operating system available today.

Vulnerability assessment is a key factor in security.
While FreeBSD releases advisories for the base system, doing so for every third party utility is beyond the FreeBSD Project's capability.
There is a way to mitigate third party vulnerabilities and warn administrators of known security issues.
A FreeBSD add on utility known as pkg includes options explicitly for this purpose.

pkg polls a database for security issues.
The database is updated and maintained by the FreeBSD Security Team and ports developers.

Installation provides man:periodic[8] configuration files for maintaining the pkg audit database, and provides a programmatic method of keeping it updated.

After installation, and to audit third party utilities as part of the Ports Collection at any time, an administrator may choose to update the database and view known vulnerabilities of installed packages by invoking:

[source,shell]
....
% pkg audit -F
....

The output should be similar to the following:

[.programlisting]
....
vulnxml file up-to-date
chromium-116.0.5845.96_1 is vulnerable:
  chromium -- multiple vulnerabilities
  CVE: CVE-2023-4431
  CVE: CVE-2023-4427
  CVE: CVE-2023-4428
  CVE: CVE-2023-4429
  CVE: CVE-2023-4430
  WWW: https://vuxml.FreeBSD.org/freebsd/5fa332b9-4269-11ee-8290-a8a1599412c6.html

samba413-4.13.17_5 is vulnerable:
  samba -- multiple vulnerabilities
  CVE: CVE-2023-3347
  CVE: CVE-2023-34966
  CVE: CVE-2023-34968
  CVE: CVE-2022-2127
  CVE: CVE-2023-34967
  WWW: https://vuxml.FreeBSD.org/freebsd/441e1e1a-27a5-11ee-a156-080027f5fec9.html

2 problem(s) in 2 installed package(s) found.
....

By pointing a web browser to the displayed URL, an administrator may obtain more information about the vulnerability.

This will include the versions affected, by FreeBSD port version, along with other web sites which may contain security advisories.

[[security-advisories]]
== FreeBSD Security Advisories

Like many producers of quality operating systems, the FreeBSD Project has a security team which is responsible for determining the End-of-Life (EoL) date for each FreeBSD release and to provide security updates for supported releases which have not yet reached their EoL.
More information about the FreeBSD security team and the supported releases is available on the link:https://www.FreeBSD.org/security[FreeBSD security page].

One task of the security team is to respond to reported security vulnerabilities in the FreeBSD operating system.
Once a vulnerability is confirmed, the security team verifies the steps necessary to fix the vulnerability and updates the source code with the fix.
It then publishes the details as a "Security Advisory".
Security advisories are published on the link:https://www.FreeBSD.org/security/advisories/[FreeBSD website] and mailed to the {freebsd-security-notifications}, {freebsd-security}, and {freebsd-announce}.

=== Format of a Security Advisory

Here is an example of a FreeBSD security advisory:

[.programlisting]
....
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

=============================================================================
FreeBSD-SA-23:07.bhyve                                      Security Advisory
                                                          The FreeBSD Project

Topic:          bhyve privileged guest escape via fwctl

Category:       core
Module:         bhyve
Announced:      2023-08-01
Credits:        Omri Ben Bassat and Vladimir Eli Tokarev from Microsoft
Affects:        FreeBSD 13.1 and 13.2
Corrected:      2023-08-01 19:48:53 UTC (stable/13, 13.2-STABLE)
                2023-08-01 19:50:47 UTC (releng/13.2, 13.2-RELEASE-p2)
                2023-08-01 19:48:26 UTC (releng/13.1, 13.1-RELEASE-p9)
CVE Name:       CVE-2023-3494

For general information regarding FreeBSD Security Advisories,
including descriptions of the fields above, security branches, and the
following sections, please visit <URL:https://security.FreeBSD.org/>.

I.   Background

bhyve(8)'s fwctl interface provides a mechanism through which guest
firmware can query the hypervisor for information about the virtual
machine.  The fwctl interface is available to guests when bhyve is run
with the "-l bootrom" option, used for example when booting guests in
UEFI mode.

bhyve is currently only supported on the amd64 platform.

II.  Problem Description

The fwctl driver implements a state machine which is executed when the
guest accesses certain x86 I/O ports.  The interface lets the guest copy
a string into a buffer resident in the bhyve process' memory.  A bug in
the state machine implementation can result in a buffer overflowing when
copying this string.

III. Impact

A malicious, privileged software running in a guest VM can exploit the
buffer overflow to achieve code execution on the host in the bhyve
userspace process, which typically runs as root.  Note that bhyve runs
in a Capsicum sandbox, so malicious code is constrained by the
capabilities available to the bhyve process.

IV.  Workaround

No workaround is available.  bhyve guests that are executed without the
"-l bootrom" option are unaffected.

V.   Solution

Upgrade your vulnerable system to a supported FreeBSD stable or
release / security branch (releng) dated after the correction date.

Perform one of the following:

1) To update your vulnerable system via a binary patch:

Systems running a RELEASE version of FreeBSD on the amd64, i386, or
(on FreeBSD 13 and later) arm64 platforms can be updated via the
freebsd-update(8) utility:

# freebsd-update fetch
# freebsd-update install

Restart all affected virtual machines.

2) To update your vulnerable system via a source code patch:

The following patches have been verified to apply to the applicable
FreeBSD release branches.

a) Download the relevant patch from the location below, and verify the
detached PGP signature using your PGP utility.

[FreeBSD 13.2]
# fetch https://security.FreeBSD.org/patches/SA-23:07/bhyve.13.2.patch
# fetch https://security.FreeBSD.org/patches/SA-23:07/bhyve.13.2.patch.asc
# gpg --verify bhyve.13.2.patch.asc

[FreeBSD 13.1]
# fetch https://security.FreeBSD.org/patches/SA-23:07/bhyve.13.1.patch
# fetch https://security.FreeBSD.org/patches/SA-23:07/bhyve.13.1.patch.asc
# gpg --verify bhyve.13.1.patch.asc

b) Apply the patch.  Execute the following commands as root:

# cd /usr/src
# patch < /path/to/patch

c) Recompile the operating system using buildworld and installworld as
described in <URL:https://www.FreeBSD.org/handbook/makeworld.html>.

Restart all affected virtual machines.

VI.  Correction details

This issue is corrected by the corresponding Git commit hash or Subversion
revision number in the following stable and release branches:

Branch/path                             Hash                     Revision
- -------------------------------------------------------------------------
stable/13/                              9fe302d78109    stable/13-n255918
releng/13.2/                            2bae613e0da3  releng/13.2-n254625
releng/13.1/                            87702e38a4b4  releng/13.1-n250190
- -------------------------------------------------------------------------

Run the following command to see which files were modified by a
particular commit:

# git show --stat <commit hash>

Or visit the following URL, replacing NNNNNN with the hash:

<URL:https://cgit.freebsd.org/src/commit/?id=NNNNNN>

To determine the commit count in a working tree (for comparison against
nNNNNNN in the table above), run:

# git rev-list --count --first-parent HEAD

VII. References

<URL:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-3494>

The latest revision of this advisory is available at
<URL:https://security.FreeBSD.org/advisories/FreeBSD-SA-23:07.bhyve.asc>
-----BEGIN PGP SIGNATURE-----

iQIzBAEBCgAdFiEEthUnfoEIffdcgYM7bljekB8AGu8FAmTJdsIACgkQbljekB8A
Gu8Q1Q/7BFw5Aa0cFxBzbdz+O5NAImj58MvKS6xw61bXcYr12jchyT6ENC7yiR+K
qCqbe5TssRbtZ1gg/94gSGEXccz5OcJGxW+qozhcdPUh2L2nzBPkMCrclrYJfTtM
cnmQKjg/wFZLUVr71GEM95ZFaktlZdXyXx9Z8eBzow5rXexpl1TTHQQ2kZZ41K4K
KFhup91dzGCIj02cqbl+1h5BrXJe3s/oNJt5JKIh/GBh5THQu9n6AywQYl18HtjV
fMb1qRTAS9WbiEP5QV2eEuOG86ucuhytqnEN5MnXJ2rLSjfb9izs9HzLo3ggy7yb
hN3tlbfIPjMEwYexieuoyP3rzKkLeYfLXqJU4zKCRnIbBIkMRy4mcFkfcYmI+MhF
NPh2R9kccemppKXeDhKJurH0vsetr8ti+AwOZ3pgO21+9w+mjE+EfaedIi+JWhip
hwqeFv03bAQHJdacNYGV47NsJ91CY4ZgWC3ZOzBZ2Y5SDtKFjyc0bf83WTfU9A/0
drC0z3xaJribah9e6k5d7lmZ7L6aHCbQ70+aayuAEZQLr/N1doB0smNi0IHdrtY0
JdIqmVX+d1ihVhJ05prC460AS/Kolqiaysun1igxR+ZnctE9Xdo1BlLEbYu2KjT4
LpWvSuhRMSQaYkJU72SodQc0FM5mqqNN42Vx+X4EutOfvQuRGlI=
=MlAY
-----END PGP SIGNATURE-----
....

Every security advisory uses the following format:

* Each security advisory is signed by the PGP key of the Security Officer. The public key for the Security Officer can be verified at crossref:pgpkeys[pgpkeys,OpenPGP Keys].
* The name of the security advisory always begins with `FreeBSD-SA-` (for FreeBSD Security Advisory), followed by the year in two digit format (`23:`), followed by the advisory number for that year (`07.`), followed by the name of the affected application or subsystem (`bhyve`).
* The `Topic` field summarizes the vulnerability.
* The `Category` refers to the affected part of the system which may be one of `core`, `contrib`, or `ports`. The `core` category means that the vulnerability affects a core component of the FreeBSD operating system. The `contrib` category means that the vulnerability affects software included with FreeBSD, such as BIND. The `ports` category indicates that the vulnerability affects software available through the Ports Collection.
* The `Module` field refers to the component location. In this example, the `bhyve` module is affected; therefore, this vulnerability affects an application installed with the operating system.
* The `Announced` field reflects the date the security advisory was published. This means that the security team has verified that the problem exists and that a patch has been committed to the FreeBSD source code repository.
* The `Credits` field gives credit to the individual or organization who noticed the vulnerability and reported it.
* The `Affects` field explains which releases of FreeBSD are affected by this vulnerability.
* The `Corrected` field indicates the date, time, time offset, and releases that were corrected. The section in parentheses shows each branch for which the fix has been merged, and the version number of the corresponding release from that branch. The release identifier itself includes the version number and, if appropriate, the patch level. The patch level is the letter `p` followed by a number, indicating the sequence number of the patch, allowing users to track which patches have already been applied to the system.
* The `CVE Name` field lists the advisory number, if one exists, in the public http://cve.mitre.org[cve.mitre.org] security vulnerabilities database.
* The `Background` field provides a description of the affected module.
* The `Problem Description` field explains the vulnerability. This can include information about the flawed code and how the utility could be maliciously used.
* The `Impact` field describes what type of impact the problem could have on a system.
* The `Workaround` field indicates if a workaround is available to system administrators who cannot immediately patch the system.
* The `Solution` field provides the instructions for patching the affected system. This is a step by step tested and verified method for getting a system patched and working securely.
* The `Correction Details` field displays each affected Subversion or Git branch with the revision number that contains the corrected code.
* The `References` field offers sources of additional information regarding the vulnerability.