Index: head/en_US.ISO8859-1/books/handbook/security/chapter.xml =================================================================== --- head/en_US.ISO8859-1/books/handbook/security/chapter.xml (revision 43277) +++ head/en_US.ISO8859-1/books/handbook/security/chapter.xml (revision 43278) @@ -1,3736 +1,3736 @@ Security MatthewDillonMuch of this chapter has been taken from the security(7) manual page by security Synopsis This chapter provides a basic introduction to system security concepts, some general good rules of thumb, and some advanced topics under &os;. Many of the topics covered here can be applied to system and Internet security in general. Securing a system is imperative to protect data, intellectual property, time, and much more from the hands of hackers and the like. &os; provides an array of utilities and mechanisms to protect the integrity and security of the system and network. After reading this chapter, you will know: Basic &os; system security concepts. The various crypt mechanisms available in &os;. How to set up one-time password authentication. How to configure TCP Wrappers for use with &man.inetd.8;. How to set up Kerberos on &os;. How to configure IPsec and create a VPN. How to configure and use OpenSSH on &os;. How to use filesystem ACLs. How to use portaudit to audit third party software packages installed from the Ports Collection. How to utilize &os; security advisories. What Process Accounting is and how to enable it on &os;. Understand the resource limits database and how to utilize it to control user resources. Before reading this chapter, you should: Understand basic &os; and Internet concepts. Additional security topics are covered elsewhere in this Handbook. For example, Mandatory Access Control is discussed in and Internet firewalls are discussed in . Introduction Security is a function that begins and ends with the system administrator. While &os; provides some inherent security, the job of configuring and maintaining additional security mechanisms is probably one of the single largest undertakings of the sysadmin. System security also pertains to dealing with various forms of attack, including attacks that attempt to crash, or otherwise make a system unusable, but do not attempt to compromise the root account. Security concerns can be split up into several categories: Denial of service attacks. User account compromises. Root compromise through accessible services. Root compromise via user accounts. Backdoor creation. DoS attacks Denial of Service (DoS) security DoS attacks Denial of Service (DoS) Denial of Service (DoS) A Denial of Service DoS attack is an action that deprives the machine of needed resources. Typically, DoS attacks are brute-force mechanisms that attempt to crash or otherwise make a machine unusable by overwhelming its services or network stack. Attacks on servers can often be fixed by properly specifying options to limit the load the servers incur on the system under adverse conditions. Brute-force network attacks are harder to deal with. This type of attack may not be able to take the machine down, but it can saturate the Internet connection. security account compromises A user account compromise is more common than a DoS attack. Many sysadmins still run unencrypted services, meaning that users logging into the system from a remote location are vulnerable to having their password sniffed. The attentive sysadmin analyzes the remote access logs looking for suspicious source addresses and suspicious logins. In a well secured and maintained system, access to a user account does not necessarily give the attacker access to root. Without root access, the attacker cannot generally hide his tracks and may, at best, be able to do nothing more than mess with the user's files or crash the machine. User account compromises are common because users tend not to take the precautions that sysadmins take. security backdoors There are potentially many ways to break root: the attacker may know the root password, the attacker may exploit a bug in a service which runs as root, or the attacker may know of a bug in a SUID-root program. An attacker may utilize a program known as a backdoor to search for vulnerable systems, take advantage of unpatched exploits to access a system, and hide traces of illegal activity. Security remedies should always be implemented with a multi-layered onion peel approach and can be categorized as follows: Secure root and staff accounts. Secure root–run servers and SUID/SGID binaries. Secure user accounts. Secure the password file. Secure the kernel core, raw devices, and filesystems. Quick detection of inappropriate changes made to the system. Paranoia. The next section covers these items in greater depth. Securing &os; security securing &os; This section describes methods for securing a &os; system against the attacks that were mentioned in the previous section. Securing the <systemitem class="username">root</systemitem> Account &man.su.1; Most systems have a password assigned to the root account. Assume that this password is always at risk of being compromised. This does not mean that the password should be disabled as the password is almost always necessary for console access to the machine. However, it should not be possible to use this password outside of the console or possibly even with &man.su.1;. For example, setting the entries in /etc/ttys to insecure prevents root logins to the specified terminals. In &os;, root logins using &man.ssh.1; are disabled by default as PermitRootLogin is set to no in /etc/ssh/sshd_config. Consider every access method as services such as FTP often fall through the cracks. Direct root logins should only be allowed via the system console. wheel Since a sysadmin needs access to root, additional password verification should be configured. One method is to add appropriate user accounts to wheel in /etc/group. Members of wheel are allowed to &man.su.1; to root. Only those users who actually need to have root access should be placed in wheel. When using Kerberos for authentication, create a .k5login in the home directory of root to allow &man.ksu.1; to be used without having to place anyone in wheel. To lock an account completely, use &man.pw.8;: &prompt.root; pw lock staff This will prevent the specified user from logging in using any mechanism, including &man.ssh.1;. Another method of blocking access to accounts would be to replace the encrypted password with a single * character. This character would never match the encrypted password and thus blocks user access. For example, the entry for the following account: foobar:R9DT/Fa1/LV9U:1000:1000::0:0:Foo Bar:/home/foobar:/usr/local/bin/tcsh could be changed to this using &man.vipw.8;: foobar:*:1000:1000::0:0:Foo Bar:/home/foobar:/usr/local/bin/tcsh This prevents foobar from logging in using conventional methods. This method for access restriction is flawed on sites using Kerberos or in situations where the user has set up keys with &man.ssh.1;. These security mechanisms assume that users are logging in from a more restrictive server to a less restrictive server. For example, if the server is running network services, the workstation should not be running any. In order for a workstation to be reasonably secure, run zero or as few services as possible and run a password-protected screensaver. Of course, given physical access to any system, an attacker can break any sort of security. Fortunately, many break-ins occur remotely, over a network, from people who do not have physical access to the system. Using Kerberos provides the ability to disable or change the password for a user in one place, and have it immediately affect all the machines on which the user has an account. If an account is compromised, the ability to instantly change the associated password on all machines should not be underrated. Additional restrictions can be imposed with Kerberos: a Kerberos ticket can be configured to timeout and the Kerberos system can require that the user choose a new password after a configurable period of time. Securing Root-run Servers and SUID/SGID Binaries sandboxes &man.sshd.8; The prudent sysadmin only enables required services and is aware that third party servers are often the most bug-prone. Never run a server that has not been checked out carefully. Think twice before running any service as root as many daemons can be run as a separate service account or can be started in a sandbox. Do not activate insecure services such as &man.telnetd.8; or &man.rlogind.8;. Another potential security hole is SUID-root and SGID binaries. Most of these binaries, such as &man.rlogin.1;, reside in /bin, /sbin, /usr/bin, or /usr/sbin. While nothing is 100% safe, the system-default SUID and SGID binaries can be considered reasonably safe. It is recommended to restrict SUID binaries to a special group that only staff can access, and to delete any unused SUID binaries. SGID binaries can be almost as dangerous. If an intruder can break an SGID-kmem binary, the intruder might be able to read /dev/kmem and thus read the encrypted password file, potentially compromising user accounts. Alternatively, an intruder who breaks group kmem can monitor keystrokes sent through ptys, including ptys used by users who login through secure methods. An intruder that breaks the tty group can write to almost any user's tty. If a user is running a terminal program or emulator with a keyboard-simulation feature, the intruder can potentially generate a data stream that causes the user's terminal to echo a command, which is then run as that user. Securing User Accounts User accounts are usually the most difficult to secure. Be vigilant in the monitoring of user accounts. Use of &man.ssh.1; and Kerberos for user accounts requires extra administration and technical support, but provides a good solution compared to an encrypted password file. Securing the Password File The only sure fire way is to star out as many passwords as possible and use &man.ssh.1; or Kerberos for access to those accounts. Even though the encrypted password file (/etc/spwd.db) can only be read by root, it may be possible for an intruder to obtain read access to that file even if the attacker cannot obtain root-write access. Security scripts should be used to check for and report changes to the password file as described in the Checking file integrity section. Securing the Kernel Core, Raw Devices, and Filesystems Most modern kernels have a packet sniffing device driver built in. Under &os; it is called bpf. This device is needed for DHCP, but can be removed in the custom kernel configuration file of systems that do not provide or use DHCP. &man.sysctl.8; Even if bpf is disabled, /dev/mem and /dev/kmem are still problematic. An intruder can still write to raw disk devices. An enterprising intruder can use &man.kldload.8; to install his own bpf, or another sniffing device, on a running kernel. To avoid these problems, run the kernel at a higher security level, at least security level 1. The security level of the kernel can be set in a variety of ways. The simplest way of raising the security level of a running kernel is to set kern.securelevel: &prompt.root; sysctl kern.securelevel=1 By default, the &os; kernel boots with a security level of -1. This is called insecure mode because immutable file flags may be turned off and all devices may be read from or written to. The security level will remain at -1 unless it is altered, either by the administrator or by &man.init.8;, because of a setting in the startup scripts. The security level may be raised during system startup by setting kern_securelevel_enable to YES in /etc/rc.conf, and the value of kern_securelevel to the desired security level. Once the security level is set to 1 or a higher value, the append-only and immutable files are honored, they cannot be turned off, and access to raw devices is denied. Higher levels restrict even more operations. For a full description of the effect of various security levels, refer to &man.security.7; and &man.init.8;. Bumping the security level to 1 or higher may cause a few problems to &xorg;, as access to /dev/io will be blocked, or to the installation of &os; built from source as installworld needs to temporarily reset the append-only and immutable flags of some files. In the case of &xorg;, it may be possible to work around this by starting &man.xdm.1; early in the boot process, when the security level is still low enough. Workarounds may not be possible for all secure levels or for all the potential restrictions they enforce. A bit of forward planning is a good idea. Understanding the restrictions imposed by each security level is important as they severely diminish the ease of system use. It will also make choosing a default setting much simpler and prevent any surprises. If the kernel's security level is raised to 1 or a higher value, it may be useful to set the schg flag on critical startup binaries, directories, script files, and everything that gets run up to the point where the security level is set. A less strict compromise is to run the system at a higher security level but skip setting the schg flag. Another possibility is to mount / and /usr read-only. It should be noted that being too draconian about what is permitted may prevent detection of an intrusion. Checking File Integrity One can only protect the core system configuration and control files so much before the convenience factor rears its ugly head. For example, using &man.chflags.1; to set the schg bit on most of the files in / and /usr is probably counterproductive, because while it may protect the files, it also closes an intrusion detection window. Security measures are useless or, worse, present a false sense of security, if potential intrusions cannot be detected. Half the job of security is to slow down, not stop, an attacker, in order to catch him in the act. The best way to detect an intrusion is to look for modified, missing, or unexpected files. The best way to look for modified files is from another, often centralized, limited-access system. Writing security scripts on the extra-security limited-access system makes them mostly invisible to potential attackers. In order to take maximum advantage, the limited-access box needs significant access to the other machines, usually either through a read-only NFS export or by setting up &man.ssh.1; key-pairs. Except for its network traffic, NFS is the least visible method, allowing the administrator to monitor the filesystems on each client box virtually undetected. If a limited-access server is connected to the client boxes through a switch, the NFS method is often the better choice. If a limited-access server is connected to the client boxes through several layers of routing, the NFS method may be too insecure and &man.ssh.1; may be the better choice. Once a limited-access box has been given at least read access to the client systems it is supposed to monitor, create the monitoring scripts. Given an NFS mount, write scripts out of simple system utilities such as &man.find.1; and &man.md5.1;. It is best to physically &man.md5.1; the client system's files at least once a day, and to test control files such as those found in /etc and /usr/local/etc even more often. When mismatches are found, relative to the base md5 information the limited-access machine knows is valid, it should alert the sysadmin. A good security script will also check for inappropriate SUID binaries and for new or deleted files on system partitions such as / and /usr. When using &man.ssh.1; rather than NFS, writing the security script is more difficult. For example, &man.scp.1; is needed to send the scripts to the client box in order to run them. The &man.ssh.1; client on the client box may already be compromised. Using &man.ssh.1; may be necessary when running over insecure links, but it is harder to deal with. A good security script will also check for changes to hidden configuration files, such as .rhosts and .ssh/authorized_keys, as these files might fall outside the purview of the MD5 check. For a large amount of user disk space, it may take too long to run through every file on those partitions. In this case, consider setting mount flags to disallow SUID binaries by using nosuid with &man.mount.8;. Scan these partitions at least once a week, since the objective is to detect a break-in attempt, whether or not the attempt succeeds. Process accounting (see &man.accton.8;) is a relatively low-overhead feature of &os; which might help as a post-break-in evaluation mechanism. It is especially useful in tracking down how an intruder broke into a system, assuming the file is still intact after the break-in has occurred. Finally, security scripts should process the log files, and the logs themselves should be generated in as secure a manner as possible and sent to a remote syslog server. An intruder will try to cover his tracks, and log files are critical to the sysadmin trying to track down the time and method of the initial break-in. One way to keep a permanent record of the log files is to run the system console to a serial port and collect the information to a secure machine monitoring the consoles. Paranoia A little paranoia never hurts. As a rule, a sysadmin can add any number of security features which do not affect convenience and can add security features that do affect convenience with some added thought. More importantly, a security administrator should mix it up a bit. If recommendations, such as those mentioned in this section, are applied verbatim, those methodologies are given to the prospective attacker who also has access to this document. Denial of Service Attacks Denial of Service (DoS) A DoS attack is typically a packet attack. While there is not much one can do about spoofed packet attacks that saturate a network, one can generally limit the damage by ensuring that the attack cannot take down servers by: Limiting server forks. Limiting springboard attacks such as ICMP response attacks and ping broadcasts. Overloading the kernel route cache. A common DoS attack scenario is to force a forking server to spawn so many child processes that the host system eventually runs out of memory and file descriptors, and then grinds to a halt. There are several options to &man.inetd.8; to limit this sort of attack. It should be noted that while it is possible to prevent a machine from going down, it is not generally possible to prevent a service from being disrupted by the attack. Read &man.inetd.8; carefully and pay specific attention to , , and . Spoofed IP attacks will circumvent to &man.inetd.8;, so typically a combination of options must be used. Some standalone servers have self-fork-limitation parameters. Sendmail provides , which tends to work better than trying to use Sendmail's load limiting options due to the load lag. Specify a MaxDaemonChildren when starting Sendmail which is high enough to handle the expected load, but not so high that the computer cannot handle that number of Sendmail instances. It is prudent to run Sendmail in queued mode using and to run the daemon (sendmail -bd) separate from the queue-runs (sendmail -q15m). For real-time delivery, run the queue at a much lower interval, such as , but be sure to specify a reasonable MaxDaemonChildren to prevent cascade failures. &man.syslogd.8; can be attacked directly and it is strongly recommended to use whenever possible, and otherwise. Be careful with connect-back services such as reverse-identd, which can be attacked directly. The reverse-ident feature of TCP Wrappers is not recommended for this reason. It is recommended to protect internal services from external access by firewalling them at the border routers. This is to prevent saturation attacks from outside the LAN, not so much to protect internal services from network-based root compromise. Always configure an exclusive firewall which denies everything by default except for traffic which is explicitly allowed. The range of port numbers used for dynamic binding in &os; is controlled by several net.inet.ip.portrange &man.sysctl.8; variables. Another common DoS attack, called a springboard attack, causes the server to generate responses which overloads the server, the local network, or some other machine. The most common attack of this nature is the ICMP ping broadcast attack. The attacker spoofs ping packets sent to the LAN's broadcast address with the source IP address set to the machine to attack. If the border routers are not configured to drop ping packets sent to broadcast addresses, the LAN generates sufficient responses to the spoofed source address to saturate the victim, especially when the attack is against several dozen broadcast addresses over several dozen different networks at once. A second common springboard attack constructs packets that generate ICMP error responses which can saturate a server's incoming network and cause the server to saturate its outgoing network with ICMP responses. This type of attack can crash the server by running it out of memory, especially if the server cannot drain the ICMP responses it generates fast enough. Use the &man.sysctl.8; variable net.inet.icmp.icmplim to limit these attacks. The last major class of springboard attacks is related to certain internal &man.inetd.8; services such as the UDP echo service. An attacker spoofs a UDP packet with a source address of server A's echo port and a destination address of server B's echo port, where server A and B on the same LAN. The two servers bounce this one packet back and forth between each other. The attacker can overload both servers and the LAN by injecting a few packets in this manner. Similar problems exist with the chargen port. These inetd-internal test services should remain disabled. Spoofed packet attacks may be used to overload the kernel route cache. Refer to the net.inet.ip.rtexpire, rtminexpire, and rtmaxcache &man.sysctl.8; parameters. A spoofed packet attack that uses a random source IP will cause the kernel to generate a temporary cached route in the route table, viewable with netstat -rna | fgrep W3. These routes typically timeout in 1600 seconds or so. If the kernel detects that the cached route table has gotten too big, it will dynamically reduce the rtexpire but will never decrease it to less than rtminexpire. This creates two problems: The kernel does not react quickly enough when a lightly loaded server is suddenly attacked. The rtminexpire is not low enough for the kernel to survive a sustained attack. If the servers are connected to the Internet via a T3 or better, it may be prudent to manually override both rtexpire and rtminexpire via &man.sysctl.8;. Never set either parameter to zero as this could crash the machine. Setting both parameters to 2 seconds should be sufficient to protect the route table from attack. Access Issues with Kerberos and &man.ssh.1; &man.ssh.1; There are a few issues with both Kerberos and &man.ssh.1; that need to be addressed if they are used. Kerberos is an excellent authentication protocol, but there are bugs in the kerberized versions of &man.telnet.1; and &man.rlogin.1; that make them unsuitable for dealing with binary streams. By default, Kerberos does not encrypt a session unless is used whereas &man.ssh.1; encrypts everything. While &man.ssh.1; works well, it forwards encryption keys by default. This introduces a security risk to a user who uses &man.ssh.1; to access an insecure machine from a secure workstation. The keys themselves are not exposed, but &man.ssh.1; installs a forwarding port for the duration of the login. If an attacker has broken root on the insecure machine, he can utilize that port to gain access to any other machine that those keys unlock. It is recommended that &man.ssh.1; is used in combination with Kerberos whenever possible for staff logins and &man.ssh.1; can be compiled with Kerberos support. This reduces reliance on potentially exposed SSH keys while protecting passwords via Kerberos. Keys should only be used for automated tasks from secure machines as this is something that Kerberos is unsuited to. It is recommended to either turn off key-forwarding in the SSH configuration, or to make use of from=IP/DOMAIN in authorized_keys to make the key only usable to entities logging in from specific machines. DES, Blowfish, MD5, SHA256, SHA512, and Crypt BillSwingleParts rewritten and updated by security crypt crypt Blowfish DES MD5 SHA256 SHA512 Every user on a &unix; system has a password associated with their account. In order to keep these passwords secret, they are encrypted with a one-way hash, as they can be easily encrypted but not decrypted. The operating system itself does not know the password. It only knows the encrypted form of the password. The only way to get the plain-text password is by a brute force search of the space of possible passwords. Originally, the only secure way to encrypt passwords in &unix; was based on the Data Encryption Standard (DES). Since the source code for DES could not be exported outside the US, &os; had to find a way to both comply with US law and retain compatibility with other &unix; variants that used DES. The solution was MD5 which is believed to be more secure than DES. Recognizing the Crypt Mechanism Currently the library supports DES, MD5, Blowfish, SHA256, and SHA512 hash functions. To identify which encryption method &os; is set up to use, examine the encrypted passwords in /etc/master.passwd. Passwords encrypted with the MD5 hash are longer than those encrypted with the DES hash and begin with the characters $1$. Passwords starting with $2a$ are encrypted with the Blowfish hash function. DES password strings do not have any particular identifying characteristics, but they are shorter than MD5 passwords, and are coded in a 64-character alphabet which does not include the $ character, so a relatively short string which does not begin with a dollar sign is very likely a DES password. Both SHA256 and SHA512 begin with the characters $6$. The password format used for new passwords is controlled by the passwd_format login capability in /etc/login.conf, which takes values of des, md5, blf, sha256 or sha512. Refer to &man.login.conf.5; for more information about login capabilities. One-time Passwords one-time passwords security one-time passwords By default, &os; includes support for One-time Passwords In Everything (OPIE), which uses the MD5 hash by default. There are three different types of passwords. The first is the usual &unix; style or Kerberos password. The second is the one-time password which is generated by &man.opiekey.1; and accepted by &man.opiepasswd.1; and the login prompt. The final type of password is the secret password used by &man.opiekey.1;, and sometimes &man.opiepasswd.1;, to generate one-time passwords. The secret password has nothing to do with the &unix; password. They can be the same, but this is not recommended. OPIE secret passwords are not limited to 8 characters like old &unix; passwordsUnder &os; the standard login password may be up to 128 characters in length.. Passwords of six or seven word long phrases are fairly common. For the most part, the OPIE system operates completely independently of the &unix; password system. Besides the password, there are two other pieces of data that are important to OPIE. One is the seed or key, consisting of two letters and five digits. The other is the iteration count, a number between 1 and 100. OPIE creates the one-time password by concatenating the seed and the secret password, applying the MD5 hash as many times as specified by the iteration count, and turning the result into six short English words. These six English words are the one-time password. The authentication system (primarily PAM) keeps track of the last one-time password used, and the user is authenticated if the hash of the user-provided password is equal to the previous password. Because a one-way hash is used, it is impossible to generate future one-time passwords if a successfully used password is captured. The iteration count is decremented after each successful login to keep the user and the login program in sync. When the iteration count gets down to 1, OPIE must be reinitialized. There are a few programs involved in this process. &man.opiekey.1; accepts an iteration count, a seed, and a secret password, and generates a one-time password or a consecutive list of one-time passwords. In addition to initializing OPIE, &man.opiepasswd.1; is used to change passwords, iteration counts, or seeds. It takes either a secret passphrase, or an iteration count, seed, and a one-time password. The relevant credential files in /etc/opiekeys are examined by &man.opieinfo.1; which prints out the invoking user's current iteration count and seed. There are four different sorts of operations. The first is to use &man.opiepasswd.1; over a secure connection to set up one-time-passwords for the first time, or to change the password or seed. The second operation is to use &man.opiepasswd.1; over an insecure connection, in conjunction with &man.opiekey.1; over a secure connection, to do the same. The third is to use &man.opiekey.1; to log in over an insecure connection. The fourth is to use &man.opiekey.1; to generate a number of keys which can be written down or printed out to carry to insecure locations in order to make a connection to anywhere. Secure Connection Initialization To initialize OPIE for the first time, execute &man.opiepasswd.1;: &prompt.user; opiepasswd -c [grimreaper] ~ $ opiepasswd -f -c Adding unfurl: Only use this method from the console; NEVER from remote. If you are using telnet, xterm, or a dial-in, type ^C now or exit with no password. Then run opiepasswd without the -c parameter. Using MD5 to compute responses. Enter new secret pass phrase: Again new secret pass phrase: ID unfurl OTP key is 499 to4268 MOS MALL GOAT ARM AVID COED At the Enter new secret pass phrase: or Enter secret password: prompt, enter a password or phrase. This is not the login password as this password is used to generate the one-time login keys. The ID line gives the parameters of the instance: the login name, iteration count, and seed. When logging in, the system will remember these parameters and display them, meaning that they do not have to be memorized. The last line gives the particular one-time password which corresponds to those parameters and the secret password. At the next login, this one-time password is the one to use. Insecure Connection Initialization To initialize or change the secret password over an insecure connection, a secure connection is needed to some place where &man.opiekey.1; can be run. This might be a shell prompt on a trusted machine. An iteration count is needed, where 100 is probably a good value, and the seed can either be specified or the randomly-generated one used. On the insecure connection, the machine being initialized, use &man.opiepasswd.1;: &prompt.user; opiepasswd Updating unfurl: You need the response from an OTP generator. Old secret pass phrase: otp-md5 498 to4268 ext Response: GAME GAG WELT OUT DOWN CHAT New secret pass phrase: otp-md5 499 to4269 Response: LINE PAP MILK NELL BUOY TROY ID mark OTP key is 499 gr4269 LINE PAP MILK NELL BUOY TROY To accept the default seed, press Return. Before entering an access password, move over to the secure connection and give it the same parameters: &prompt.user; opiekey 498 to4268 Using the MD5 algorithm to compute response. Reminder: Do not use opiekey from telnet or dial-in sessions. Enter secret pass phrase: GAME GAG WELT OUT DOWN CHAT Switch back over to the insecure connection, and copy the generated one-time password over to the relevant program. Generating a Single One-time Password After initializing OPIE and logging in, a prompt like this will be displayed: &prompt.user; telnet example.com Trying 10.0.0.1... Connected to example.com Escape character is '^]'. FreeBSD/i386 (example.com) (ttypa) login: <username> otp-md5 498 gr4269 ext Password: The OPIE prompts provides a useful feature. If Return is pressed at the password prompt, the prompt will turn echo on and display what is typed. This can be useful when attempting to type in a password by hand from a printout. MS-DOS Windows MacOS At this point, generate the one-time password to answer this login prompt. This must be done on a trusted system where it is safe to run &man.opiekey.1;. There are versions of this command for &windows;, &macos; and &os;. This command needs the iteration count and the seed as command line options. Use cut-and-paste from the login prompt on the machine being logged in to. On the trusted system: &prompt.user; opiekey 498 to4268 Using the MD5 algorithm to compute response. Reminder: Do not use opiekey from telnet or dial-in sessions. Enter secret pass phrase: GAME GAG WELT OUT DOWN CHAT Once the one-time password is generated, continue to log in. Generating Multiple One-time Passwords Sometimes there is no access to a trusted machine or secure connection. In this case, it is possible to use &man.opiekey.1; to generate a number of one-time passwords beforehand. For example: &prompt.user; opiekey -n 5 30 zz99999 Using the MD5 algorithm to compute response. Reminder: Do not use opiekey from telnet or dial-in sessions. Enter secret pass phrase: <secret password> 26: JOAN BORE FOSS DES NAY QUIT 27: LATE BIAS SLAY FOLK MUCH TRIG 28: SALT TIN ANTI LOON NEAL USE 29: RIO ODIN GO BYE FURY TIC 30: GREW JIVE SAN GIRD BOIL PHI The requests five keys in sequence, and specifies what the last iteration number should be. Note that these are printed out in reverse order of use. The really paranoid might want to write the results down by hand; otherwise, print the list. Each line shows both the iteration count and the one-time password. Scratch off the passwords as they are used. Restricting Use of &unix; Passwords OPIE can restrict the use of &unix; passwords based on the IP address of a login session. The relevant file is /etc/opieaccess, which is present by default. Refer to &man.opieaccess.5; for more information on this file and which security considerations to be aware of when using it. Here is a sample opieaccess: permit 192.168.0.0 255.255.0.0 This line allows users whose IP source address (which is vulnerable to spoofing) matches the specified value and mask, to use &unix; passwords at any time. If no rules in opieaccess are matched, the default is to deny non-OPIE logins. TCP Wrappers TomRhodesWritten by TCP Wrappers TCP Wrappers extends the abilities of to provide support for every server daemon under its control. It can be configured to provide logging support, return messages to connections, and permit a daemon to only accept internal connections. While some of these features can be provided by implementing a firewall, TCP Wrappers adds an extra layer of protection and goes beyond the amount of control a firewall can provide. TCP Wrappers should not be considered a replacement for a properly configured firewall. TCP Wrappers should be used in conjunction with a firewall and other security enhancements. Initial Configuration To enable TCP Wrappers in &os;, ensure the &man.inetd.8; server is started from /etc/rc.conf with . Then, properly configure /etc/hosts.allow. Unlike other implementations of TCP Wrappers, the use of hosts.deny has been deprecated. All configuration options should be placed in /etc/hosts.allow. In the simplest configuration, daemon connection policies are set to either be permitted or blocked depending on the options in /etc/hosts.allow. The default configuration in &os; is to allow a connection to every daemon started with &man.inetd.8;. Basic configuration usually takes the form of daemon : address : action, where daemon is the daemon which &man.inetd.8; 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 in ascending order 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 mail/qpopper daemon, the following lines should be appended to hosts.allow: # This line is required for POP3 connections: qpopper : ALL : allow After adding this line, &man.inetd.8; needs to be restarted: &prompt.root; service inetd restart 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. External Commands Suppose that a situation occurs where a connection should be denied yet a reason should be sent to the individual who attempted to establish that connection. That action is possible with . When a connection attempt is made, executes a shell command or script. An example exists in hosts.allow: # The rest of the daemons are protected. ALL : ALL \ : severity auth.info \ : twist /bin/echo "You are not welcome to use %d from %h." In this example, the message You are not allowed to use daemon from hostname. will be returned for any daemon not previously configured in the access file. This is useful for sending a reply back to the connection initiator right after the established connection is dropped. Any message returned must be wrapped in quote (") characters. It may be possible to launch a denial of service attack on the server if an attacker, or group of attackers, could flood these daemons with connection requests. Another possibility is to use . Like , implicitly denies the connection and may be used to run external shell commands or scripts. Unlike , will not send a reply back to the individual who established the connection. For example, consider the following configuration line: # We do not allow connections from example.com: ALL : .example.com \ : spawn (/bin/echo %a from %h attempted to access %d >> \ /var/log/connections.log) \ : deny This will deny all connection attempts from *.example.com and log the hostname, IP address, and the daemon to which access was attempted to /var/log/connections.log. This example uses the substitution characters %a and %h. Refer to &man.hosts.access.5; for the complete list. Wildcard Options The ALL option may be used to match every instance of a daemon, domain, or an IP address. Another wildcard is PARANOID which may be used to match any host which provides an IP address that may be forged. For example, PARANOID may be used to define an action to be taken whenever a connection is made from an IP address that differs from its hostname. In this example, all connection requests to &man.sendmail.8; which have an IP address that varies from its hostname will be denied: # Block possibly spoofed requests to sendmail: sendmail : PARANOID : deny Using the PARANOID wildcard may severely cripple servers if the client or server has a broken DNS setup. Administrator discretion is advised. To learn more about wildcards and their associated functionality, refer to &man.hosts.access.5;. Before any of the specific configuration lines above will work, the first configuration line should be commented out in hosts.allow. <application>Kerberos5</application> TillmanHodgsonContributed by MarkMurrayBased on a contribution by Kerberos is a network add-on system/protocol that allows users to authenticate themselves through the services of a secure server. Kerberos can be described as an identity-verifying proxy system. It can also be described 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 on the network. It does not provide authorization functions (what users are allowed to do) or auditing functions (what those users did). It is recommended that Kerberos be used with other security methods which provide authorization and audit services. This section provides a guide on how to set up Kerberos as distributed for &os;. Refer to the relevant manual pages for more complete descriptions. For purposes of demonstrating a Kerberos installation, the various name spaces will be as follows: The DNS domain (zone) will be example.org. The Kerberos realm will be EXAMPLE.ORG. 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. History Kerberos5 history Kerberos was created by MIT as a solution to network security problems. The Kerberos protocol uses strong cryptography so that a client can prove its identity to a server (and vice versa) across an insecure network connection. Kerberos is both the name of a network authentication protocol and an adjective to describe programs that implement it, such as Kerberos telnet. The current version of the protocol is version 5, described in RFC 1510. Several free implementations of this protocol are available, covering a wide range of operating systems. The Massachusetts Institute of Technology (MIT), where Kerberos was originally developed, continues to develop their Kerberos package. It is commonly used in the US as a cryptography product, and has historically been affected by US export regulations. The MIT Kerberos is available as the security/krb5 package or port. Heimdal Kerberos is another version 5 implementation, and was explicitly developed outside of the US to avoid export regulations. The Heimdal Kerberos distribution is available as a the security/heimdal package or port, and a minimal installation is included in the base &os; install. These instructions assume the use of the Heimdal distribution included in &os;. Setting up a Heimdal <acronym>KDC</acronym> Kerberos5 Key Distribution Center The Key Distribution Center (KDC) is the centralized authentication service that Kerberos provides. It is the computer that issues Kerberos tickets. The KDC is considered trusted by all other computers in the Kerberos realm, and thus has heightened security concerns. While running the Kerberos server requires very few computing resources, a dedicated machine acting only as a KDC is recommended for security reasons. To begin setting up a KDC, ensure that /etc/rc.conf contains the correct settings to act as a KDC. As required, adjust paths to reflect the system: kerberos5_server_enable="YES" kadmind5_server_enable="YES" Next, edit /etc/krb5.conf as follows: [libdefaults] default_realm = EXAMPLE.ORG [realms] EXAMPLE.ORG = { kdc = kerberos.example.org admin_server = kerberos.example.org } [domain_realm] .example.org = EXAMPLE.ORG This /etc/krb5.conf implies that the KDC will use the fully-qualified hostname kerberos.example.org. Add a CNAME (alias) entry to the zone file to accomplish this if the KDC has a different hostname. For large networks with a properly configured DNS server, the above example could be trimmed to: [libdefaults] default_realm = EXAMPLE.ORG With the following lines being appended to the example.org zone file: _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 For clients to be able to find the Kerberos services, it must have either a fully configured /etc/krb5.conf or a minimally configured /etc/krb5.conf and a properly configured DNS server. Next, create the Kerberos database which contains the keys of all principals encrypted with a master password. It is not required to remember this password as it will be stored in /var/heimdal/m-key. To create the master key, run &man.kstash.8; and enter a password. Once the master key has been created, initialize the database using kadmin -l. This option instructs &man.kadmin.8; to modify the local database files directly rather than going through the &man.kadmind.8; network service. This handles the chicken-and-egg problem of trying to connect to the database before it is created. At the &man.kadmin.8; prompt, use init to create the realm's initial database. Lastly, while still in &man.kadmin.8;, 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 &man.kadmin.8; prompt to see the available options. A sample database creation session is shown below: &prompt.root; kstash Master key: xxxxxxxx Verifying password - Master key: xxxxxxxx &prompt.root; kadmin -l kadmin> init EXAMPLE.ORG Realm max ticket life [unlimited]: kadmin> add tillman Max ticket life [unlimited]: Max renewable life [unlimited]: Attributes []: Password: xxxxxxxx Verifying password - Password: xxxxxxxx Next, start the KDC services. Run service kerberos start and service kadmind start to bring up the services. While there will not be any kerberized daemons running at this point, it is possible to confirm that the KDC is functioning by obtaining and listing a ticket for the principal (user) that was just created from the command-line of the KDC itself: &prompt.user; kinit tillman tillman@EXAMPLE.ORG's Password: &prompt.user; klist Credentials cache: FILE:/tmp/krb5cc_500 Principal: tillman@EXAMPLE.ORG Issued Expires Principal Aug 27 15:37:58 Aug 28 01:37:58 krbtgt/EXAMPLE.ORG@EXAMPLE.ORG The ticket can then be revoked when finished: &prompt.user; kdestroy <application>Kerberos</application> Enabling a Server with Heimdal Services Kerberos5 enabling services First, copy /etc/krb5.conf from the KDC to the client computer in a secure fashion, such as &man.scp.1;, or physically via removable media. Next, create /etc/krb5.keytab. This is the major difference between a server providing Kerberos enabled daemons and a workstation: the server must have a keytab. This file 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 keytab is transferred to the server using &man.kadmin.8;. This is handy because the host principal, the KDC end of the krb5.keytab, is also created using &man.kadmin.8;. A ticket must already be obtained and this ticket must be allowed to use the &man.kadmin.8; interface in the kadmind.acl. See the section titled Remote administration ininfo heimdal for details on designing access control lists. Instead of enabling remote &man.kadmin.8; access, the administrator can securely connect to the KDC via the local console or &man.ssh.1;, and perform administration locally using kadmin -l. After installing /etc/krb5.conf, use add --random-key from the Kerberos server. This adds the server's host principal. Then, use ext to extract the server's host principal to its own keytab. For example: &prompt.root; kadmin kadmin> add --random-key host/myserver.example.org Max ticket life [unlimited]: Max renewable life [unlimited]: Attributes []: kadmin> ext host/myserver.example.org kadmin> exit Note that ext stores the extracted key in /etc/krb5.keytab by default. If &man.kadmind.8; is not running on the KDC and there is no access to &man.kadmin.8; remotely, add the host principal (host/myserver.EXAMPLE.ORG) directly on the KDC and then extract it to a temporary file to avoid overwriting the /etc/krb5.keytab on the KDC, using something like this: &prompt.root; kadmin kadmin> ext --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 overwriting the keytab on the KDC. At this point, the server can communicate with the KDC using krb5.conf and it can prove its own identity with krb5.keytab. It is now ready for the Kerberos services to be enabled. For this example, the &man.telnetd.8; service is enabled in /etc/inetd.conf and &man.inetd.8; has been restarted with service inetd restart: telnet stream tcp nowait root /usr/libexec/telnetd telnetd -a user The critical change is that the authentication type is set to user. Refer to &man.telnetd.8; for more details. <application>Kerberos</application> Enabling a Client with Heimdal Kerberos5 configure clients Setting up a client computer is easy as only /etc/krb5.conf is needed. Securely copy this file over to the client computer from the KDC. Test the client by attempting to use &man.kinit.1;, &man.klist.1;, and &man.kdestroy.1; from the client to obtain, show, and then delete a ticket for the principal created above. 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. When testing a Kerberized application, try using a packet sniffer such as &man.tcpdump.1; to confirm that the password is not sent in the clear. Various non-core Kerberos client applications are available. The minimal installation in &os; installs &man.telnetd.8; as the only Kerberos enabled service. The Heimdal port installs Kerberos enabled versions of &man.ftpd.8;, &man.rshd.8;, &man.rcp.1;, &man.rlogind.8;, and a few other less common programs. The MIT port also contains a full suite of Kerberos client applications. User Configuration Files: <filename>.k5login</filename> and <filename>.k5users</filename> .k5login .k5users 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 .k5login and .k5users files, placed in a user's home directory, can be used to solve this problem. For example, if .k5login with the following contents is placed in the home directory of webdevelopers, both principals listed will have access to that account without requiring a shared password.: tillman@example.org jdoe@example.org Refer to &man.ksu.1; for more information about .k5users. <application>Kerberos</application> Tips, Tricks, and Troubleshooting When using either the Heimdal or MIT KerberosKerberos5troubleshooting ports, ensure that the PATH lists the Kerberos 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. describes how to synchronize clocks using NTP. MIT and Heimdal interoperate except for &man.kadmin.8;, which is not standardized. If the hostname is changed, the host/ principal must be changed and the keytab updated. This also applies to special keytab entries like the www/ principal used for Apache's www/mod_auth_kerb. All hosts in the realm must be both forward and reverse resolvable in DNS or, at a minimum, in /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 &man.ksu.1; to be setuid root. This means that &man.ksu.1; does not work. This is not a KDC error. With MIT Kerberos, in order to allow a principal to have a ticket life longer than the default 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. Then the principal can 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 &man.kinit.1; from a workstation, the Ticket Granting Ticket (TGT) is sent immediately upon running &man.kinit.1;, 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 &man.kinit.1; 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. To use long ticket lifetimes, such as a week, when using OpenSSH to connect to the machine where the ticket is stored, make sure that Kerberos is set to no in sshd_config or else tickets will be deleted at log out. 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 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 krb5.dict is one string per line. Creating a symbolic link to /usr/share/dict/words might be useful. Differences with the <acronym>MIT</acronym> Port The major difference between MIT and Heimdal relates to &man.kadmin.8; which has a different, but equivalent, set of commands and uses a different protocol. If the KDC is MIT, the Heimdal version of &man.kadmin.8; cannot be used to administer the KDC remotely, and vice versa. The client applications may also use slightly different command line options to accomplish the same tasks. Following the instructions on the MIT Kerberos web site is recommended. Be careful of path issues: the MIT port installs into /usr/local/ by default, and the normal system applications run instead of MIT versions if PATH lists the system directories first. With the &os; MIT security/krb5 port, be sure to read /usr/local/share/doc/krb5/README.FreeBSD installed by the port to understand why logins via &man.telnetd.8; and klogind behave somewhat oddly. Correcting the incorrect permissions on cache file behavior requires that the login.krb5 binary be used for authentication so that it can properly change ownership for the forwarded credentials. The following edits should also be made to rc.conf: kerberos5_server="/usr/local/sbin/krb5kdc" kadmind5_server="/usr/local/sbin/kadmind" kerberos5_server_flags="" kerberos5_server_enable="YES" kadmind5_server_enable="YES" This is done because the applications for MIT Kerberos installs binaries in the /usr/local hierarchy. Mitigating Limitations Found in <application>Kerberos</application> Kerberos5 limitations and shortcomings <application>Kerberos</application> is an All or Nothing Approach Every service enabled on the network must be modified to work with Kerberos, or be otherwise secured against network attacks, or else the user's credentials could be stolen and re-used. An example of this would be Kerberos enabling all remote shells but not converting the POP3 mail server which sends passwords in plain text. <application>Kerberos</application> is Intended for Single-User Workstations In a multi-user environment, Kerberos is less secure. This is because it stores the tickets in /tmp, which is readable by all users. If a user is sharing a computer with other users, it is possible that the user's tickets can be stolen or copied by another user. This can be overcome with the -c command-line option or, preferably, the KRB5CCNAME environment variable. Storing the ticket in the user's home directory and using file permissions are commonly used to mitigate this problem. 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. Additionally, 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. <application>Kerberos</application> Shortcomings 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 trojanned &man.kinit.1; could record all user names and passwords. Filesystem integrity checking tools like security/tripwire can alleviate this. Resources and Further Information Kerberos5 external resources The Kerberos FAQ Designing an Authentication System: a Dialog in Four Scenes RFC 1510, The Kerberos Network Authentication Service (V5) MIT Kerberos home page Heimdal Kerberos home page OpenSSL TomRhodesWritten by security OpenSSL The OpenSSL toolkit is included in &os;. It provides an encryption transport layer on top of the normal communications layer, allowing it to be intertwined with many network applications and services. Some uses of OpenSSL may include encrypted authentication of mail clients and web based transactions such as credit card payments. Many ports such as www/apache22, and mail/claws-mail offer compilation support for building with OpenSSL. In most cases, the Ports Collection will attempt to build the security/openssl port unless WITH_OPENSSL_BASE is explicitly set to yes. The version of OpenSSL included in &os; supports Secure Sockets Layer v2/v3 (SSLv2/SSLv3) and Transport Layer Security v1 (TLSv1) network security protocols and can be used as a general cryptographic library. While OpenSSL supports the IDEA algorithm, it is disabled by default due to United States patents. To use it, the license should be reviewed and, if the restrictions are acceptable, the MAKE_IDEA variable must be set in /etc/make.conf. One of the most common uses of OpenSSL is to provide certificates for use with software applications. These certificates ensure that the credentials of the company or individual are valid and not fraudulent. If the certificate in question has not been verified by a Certificate Authority (CA), a warning is produced. A CA is a company, such as VeriSign, signs certificates in order to validate the credentials of individuals or companies. This process has a cost associated with it and is not a requirement for using certificates; however, it can put users at ease. Generating Certificates OpenSSL certificate generation To generate a certificate, the following command is available: &prompt.root; openssl req -new -nodes -out req.pem -keyout cert.pem Generating a 1024 bit RSA private key ................++++++ .......................................++++++ writing new private key to 'cert.pem' ----- 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]:US State or Province Name (full name) [Some-State]:PA Locality Name (eg, city) []:Pittsburgh Organization Name (eg, company) [Internet Widgits Pty Ltd]:My Company Organizational Unit Name (eg, section) []:Systems Administrator Common Name (eg, YOUR name) []:localhost.example.org Email Address []:trhodes@FreeBSD.org Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []:SOME PASSWORD An optional company name []:Another Name Notice the response directly after the Common Name prompt shows a domain name. This prompt requires a server name to be entered for verification purposes and placing anything but a domain name yields a useless certificate. Other options, such as the expire time and alternate encryption algorithms, are available. A complete list of options is described in &man.openssl.1;. Two files should now exist in the directory in which this command was issued. The certificate request, req.pem, may be sent to a CA who will validate the entered credentials, sign the request, and return the signed certificate. The second file is named cert.pem and is the private key for the certificate and should be protected at all costs. If this falls in the hands of others it can be used to impersonate the user or the server. In cases where a signature from a CA is not required, a self signed certificate can be created. First, generate the RSA key: &prompt.root; openssl dsaparam -rand -genkey -out myRSA.key 1024 Next, generate the CA key: &prompt.root; openssl gendsa -des3 -out myca.key myRSA.key Use this key to create the certificate: &prompt.root; openssl req -new -x509 -days 365 -key myca.key -out new.crt Two new files should appear in the directory: a certificate authority signature file, myca.key and the certificate itself, new.crt. These should be placed in a directory, preferably under /etc, which is readable only by root. Permissions of 0700 are appropriate and can be set using &man.chmod.1;. Using Certificates One use for a certificate is to encrypt connections to the Sendmail MTA. This prevents the use of clear text authentication for users who send mail via the local MTA. Some MUAs will display error if the user has not installed the certificate locally. Refer to the documentation included with the software for more information on certificate installation. To configure Sendmail, the following lines should be placed in the local .mc file: dnl SSL Options define(`confCACERT_PATH',`/etc/certs')dnl define(`confCACERT',`/etc/certs/new.crt')dnl define(`confSERVER_CERT',`/etc/certs/new.crt')dnl define(`confSERVER_KEY',`/etc/certs/myca.key')dnl define(`confTLS_SRV_OPTIONS', `V')dnl In this example, /etc/certs/ stores the certificate and key files locally. After saving the edits, rebuild the local .cf file by typing make install within /etc/mail. Follow that up with make restart which should start the Sendmail daemon. If all went well, there will be no error messages in /var/log/maillog and Sendmail will show up in the process list. For a simple test, connect to the mail server using &man.telnet.1;: &prompt.root; telnet example.com 25 Trying 192.0.34.166... Connected to example.com. Escape character is '^]'. 220 example.com ESMTP Sendmail 8.12.10/8.12.10; Tue, 31 Aug 2004 03:41:22 -0400 (EDT) ehlo example.com 250-example.com Hello example.com [192.0.34.166], pleased to meet you 250-ENHANCEDSTATUSCODES 250-PIPELINING 250-8BITMIME 250-SIZE 250-DSN 250-ETRN 250-AUTH LOGIN PLAIN 250-STARTTLS 250-DELIVERBY 250 HELP quit 221 2.0.0 example.com closing connection Connection closed by foreign host. If the STARTTLS line appears in the output, everything is working correctly. <acronym>VPN</acronym> over IPsec NikClayton
nik@FreeBSD.org
Written by
IPsec Understanding IPsec Hiten M.Pandya
hmp@FreeBSD.org
Written by
This section demonstrates the process of setting up IPsec. It assumes familiarity with the concepts of building a custom kernel (see ). IPsec is a protocol which sits on top of the Internet Protocol (IP) layer. It allows two or more hosts to communicate in a secure manner. The &os; IPsec network stack is based on the KAME implementation, which has support for both IPv4 and IPv6. IPsec ESP IPsec AH IPsec consists of two sub-protocols: Encapsulated Security Payload ESP): this protocol protects the IP packet data from third party interference by encrypting the contents using symmetric cryptography algorithms such as Blowfish and 3DES. Authentication Header (AH): this protocol protects the IP packet header from third party interference and spoofing by computing a cryptographic checksum and hashing the IP packet header fields with a secure hashing function. This is then followed by an additional header that contains the hash, to allow the information in the packet to be authenticated. ESP and AH can either be used together or separately, depending on the environment. VPN virtual private network VPN IPsec can either be used to directly encrypt the traffic between two hosts using Transport Mode or to build virtual tunnels using Tunnel Mode. The latter mode is more commonly known as a Virtual Private Network (VPN). Consult &man.ipsec.4; for detailed information on the IPsec subsystem in &os;. To add IPsec support to the kernel, add the following options to the custom kernel configuration file: kernel options IPSEC options IPSEC #IP security device crypto kernel options IPSEC_DEBUG If IPsec debugging support is desired, the following kernel option should also be added: options IPSEC_DEBUG #debug for IP security
<acronym>VPN</acronym> Between a Home and Corporate Network VPN creating There is no standard for what constitutes a VPN. VPNs can be implemented using a number of different technologies, each of which has their own strengths and weaknesses. This section presents the strategies used for implementing a VPN for the following scenario: There are at least two sites where each site is using IP internally. Both sites are connected to the Internet through a gateway that is running &os;. The gateway on each network has at least one public IP address. The internal addresses of the two networks can be either public or private IP addresses. However, the address space must not collide. For example, both networks cannot use 192.168.1.x. Configuring IPsec on &os; TomRhodes
trhodes@FreeBSD.org
Written by
To begin, security/ipsec-tools must be installed from the Ports Collection. This software provides a number of applications which support the configuration. The next requirement is to create two &man.gif.4; pseudo-devices which will be used to tunnel packets and allow both networks to communicate properly. As root, run the following commands, replacing internal and external with the real IP addresses of the internal and external interfaces of the two gateways: &prompt.root; ifconfig gif0 create &prompt.root; ifconfig gif0 internal1 internal2 &prompt.root; ifconfig gif0 tunnel external1 external2 In this example, the corporate LAN's external IP address is 172.16.5.4 and its internal IP address is 10.246.38.1. The home LAN's external IP address is 192.168.1.12 and its internal private IP address is 10.0.0.5. If this is confusing, review the following example output from &man.ifconfig.8;: Gateway 1: gif0: flags=8051 mtu 1280 tunnel inet 172.16.5.4 --> 192.168.1.12 inet6 fe80::2e0:81ff:fe02:5881%gif0 prefixlen 64 scopeid 0x6 inet 10.246.38.1 --> 10.0.0.5 netmask 0xffffff00 Gateway 2: gif0: flags=8051 mtu 1280 tunnel inet 192.168.1.12 --> 172.16.5.4 inet 10.0.0.5 --> 10.246.38.1 netmask 0xffffff00 inet6 fe80::250:bfff:fe3a:c1f%gif0 prefixlen 64 scopeid 0x4 Once complete, both internal IP addresses should be reachable using &man.ping.8;: priv-net# ping 10.0.0.5 PING 10.0.0.5 (10.0.0.5): 56 data bytes 64 bytes from 10.0.0.5: icmp_seq=0 ttl=64 time=42.786 ms 64 bytes from 10.0.0.5: icmp_seq=1 ttl=64 time=19.255 ms 64 bytes from 10.0.0.5: icmp_seq=2 ttl=64 time=20.440 ms 64 bytes from 10.0.0.5: icmp_seq=3 ttl=64 time=21.036 ms --- 10.0.0.5 ping statistics --- 4 packets transmitted, 4 packets received, 0% packet loss round-trip min/avg/max/stddev = 19.255/25.879/42.786/9.782 ms corp-net# ping 10.246.38.1 PING 10.246.38.1 (10.246.38.1): 56 data bytes 64 bytes from 10.246.38.1: icmp_seq=0 ttl=64 time=28.106 ms 64 bytes from 10.246.38.1: icmp_seq=1 ttl=64 time=42.917 ms 64 bytes from 10.246.38.1: icmp_seq=2 ttl=64 time=127.525 ms 64 bytes from 10.246.38.1: icmp_seq=3 ttl=64 time=119.896 ms 64 bytes from 10.246.38.1: icmp_seq=4 ttl=64 time=154.524 ms --- 10.246.38.1 ping statistics --- 5 packets transmitted, 5 packets received, 0% packet loss round-trip min/avg/max/stddev = 28.106/94.594/154.524/49.814 ms As expected, both sides have the ability to send and receive ICMP packets from the privately configured addresses. Next, both gateways must be told how to route packets in order to correctly send traffic from either network. The following command will achieve this goal: &prompt.root; corp-net# route add 10.0.0.0 10.0.0.5 255.255.255.0 &prompt.root; corp-net# route add net 10.0.0.0: gateway 10.0.0.5 &prompt.root; priv-net# route add 10.246.38.0 10.246.38.1 255.255.255.0 &prompt.root; priv-net# route add host 10.246.38.0: gateway 10.246.38.1 At this point, internal machines should be reachable from each gateway as well as from machines behind the gateways. Again, use &man.ping.8; to confirm: corp-net# ping 10.0.0.8 PING 10.0.0.8 (10.0.0.8): 56 data bytes 64 bytes from 10.0.0.8: icmp_seq=0 ttl=63 time=92.391 ms 64 bytes from 10.0.0.8: icmp_seq=1 ttl=63 time=21.870 ms 64 bytes from 10.0.0.8: icmp_seq=2 ttl=63 time=198.022 ms 64 bytes from 10.0.0.8: icmp_seq=3 ttl=63 time=22.241 ms 64 bytes from 10.0.0.8: icmp_seq=4 ttl=63 time=174.705 ms --- 10.0.0.8 ping statistics --- 5 packets transmitted, 5 packets received, 0% packet loss round-trip min/avg/max/stddev = 21.870/101.846/198.022/74.001 ms priv-net# ping 10.246.38.107 PING 10.246.38.1 (10.246.38.107): 56 data bytes 64 bytes from 10.246.38.107: icmp_seq=0 ttl=64 time=53.491 ms 64 bytes from 10.246.38.107: icmp_seq=1 ttl=64 time=23.395 ms 64 bytes from 10.246.38.107: icmp_seq=2 ttl=64 time=23.865 ms 64 bytes from 10.246.38.107: icmp_seq=3 ttl=64 time=21.145 ms 64 bytes from 10.246.38.107: icmp_seq=4 ttl=64 time=36.708 ms --- 10.246.38.107 ping statistics --- 5 packets transmitted, 5 packets received, 0% packet loss round-trip min/avg/max/stddev = 21.145/31.721/53.491/12.179 ms Setting up the tunnels is the easy part. Configuring a secure link is a more in depth process. The following configuration uses pre-shared (PSK) RSA keys. Other than the IP addresses, the /usr/local/etc/racoon/racoon.conf on both gateways will be identical and look similar to: path pre_shared_key "/usr/local/etc/racoon/psk.txt"; #location of pre-shared key file log debug; #log verbosity setting: set to 'notify' when testing and debugging is complete padding # options are not to be changed { maximum_length 20; randomize off; strict_check off; exclusive_tail off; } timer # timing options. change as needed { counter 5; interval 20 sec; persend 1; # natt_keepalive 15 sec; phase1 30 sec; phase2 15 sec; } -listen # address [port] that racoon will listening on +listen # address [port] that racoon will listen on { isakmp 172.16.5.4 [500]; isakmp_natt 172.16.5.4 [4500]; } remote 192.168.1.12 [500] { exchange_mode main,aggressive; doi ipsec_doi; situation identity_only; my_identifier address 172.16.5.4; peers_identifier address 192.168.1.12; lifetime time 8 hour; passive off; proposal_check obey; # nat_traversal off; generate_policy off; proposal { encryption_algorithm blowfish; hash_algorithm md5; authentication_method pre_shared_key; lifetime time 30 sec; dh_group 1; } } sainfo (address 10.246.38.0/24 any address 10.0.0.0/24 any) # address $network/$netmask $type address $network/$netmask $type ( $type being any or esp) { # $network must be the two internal networks you are joining. pfs_group 1; lifetime time 36000 sec; encryption_algorithm blowfish,3des,des; authentication_algorithm hmac_md5,hmac_sha1; compression_algorithm deflate; } For descriptions of each available option, refer to the manual page for racoon.conf. The Security Policy Database (SPD) needs to be configured so that &os; and racoon are able to encrypt and decrypt network traffic between the hosts. This can be achieved with a shell script, similar to the following, on the corporate gateway. This file will be used during system initialization and should be saved as /usr/local/etc/racoon/setkey.conf. flush; spdflush; # To the home network spdadd 10.246.38.0/24 10.0.0.0/24 any -P out ipsec esp/tunnel/172.16.5.4-192.168.1.12/use; spdadd 10.0.0.0/24 10.246.38.0/24 any -P in ipsec esp/tunnel/192.168.1.12-172.16.5.4/use; Once in place, racoon may be started on both gateways using the following command: &prompt.root; /usr/local/sbin/racoon -F -f /usr/local/etc/racoon/racoon.conf -l /var/log/racoon.log The output should be similar to the following: corp-net# /usr/local/sbin/racoon -F -f /usr/local/etc/racoon/racoon.conf Foreground mode. 2006-01-30 01:35:47: INFO: begin Identity Protection mode. 2006-01-30 01:35:48: INFO: received Vendor ID: KAME/racoon 2006-01-30 01:35:55: INFO: received Vendor ID: KAME/racoon 2006-01-30 01:36:04: INFO: ISAKMP-SA established 172.16.5.4[500]-192.168.1.12[500] spi:623b9b3bd2492452:7deab82d54ff704a 2006-01-30 01:36:05: INFO: initiate new phase 2 negotiation: 172.16.5.4[0]192.168.1.12[0] 2006-01-30 01:36:09: INFO: IPsec-SA established: ESP/Tunnel 192.168.1.12[0]->172.16.5.4[0] spi=28496098(0x1b2d0e2) 2006-01-30 01:36:09: INFO: IPsec-SA established: ESP/Tunnel 172.16.5.4[0]->192.168.1.12[0] spi=47784998(0x2d92426) 2006-01-30 01:36:13: INFO: respond new phase 2 negotiation: 172.16.5.4[0]192.168.1.12[0] 2006-01-30 01:36:18: INFO: IPsec-SA established: ESP/Tunnel 192.168.1.12[0]->172.16.5.4[0] spi=124397467(0x76a279b) 2006-01-30 01:36:18: INFO: IPsec-SA established: ESP/Tunnel 172.16.5.4[0]->192.168.1.12[0] spi=175852902(0xa7b4d66) To ensure the tunnel is working properly, switch to another console and use &man.tcpdump.1; to view network traffic using the following command. Replace em0 with the network interface card as required: &prompt.root; tcpdump -i em0 host 172.16.5.4 and dst 192.168.1.12 Data similar to the following should appear on the console. If not, there is an issue and debugging the returned data will be required. 01:47:32.021683 IP corporatenetwork.com > 192.168.1.12.privatenetwork.com: ESP(spi=0x02acbf9f,seq=0xa) 01:47:33.022442 IP corporatenetwork.com > 192.168.1.12.privatenetwork.com: ESP(spi=0x02acbf9f,seq=0xb) 01:47:34.024218 IP corporatenetwork.com > 192.168.1.12.privatenetwork.com: ESP(spi=0x02acbf9f,seq=0xc) At this point, both networks should be available and seem to be part of the same network. Most likely both networks are protected by a firewall. To allow traffic to flow between them, rules need to be added to pass packets. For the &man.ipfw.8; firewall, add the following lines to the firewall configuration file: ipfw add 00201 allow log esp from any to any ipfw add 00202 allow log ah from any to any ipfw add 00203 allow log ipencap from any to any ipfw add 00204 allow log udp from any 500 to any The rule numbers may need to be altered depending on the current host configuration. For users of &man.pf.4; or &man.ipf.8;, the following rules should do the trick: pass in quick proto esp from any to any pass in quick proto ah from any to any pass in quick proto ipencap from any to any pass in quick proto udp from any port = 500 to any port = 500 pass in quick on gif0 from any to any pass out quick proto esp from any to any pass out quick proto ah from any to any pass out quick proto ipencap from any to any pass out quick proto udp from any port = 500 to any port = 500 pass out quick on gif0 from any to any Finally, to allow the machine to start support for the VPN during system initialization, add the following lines to /etc/rc.conf: ipsec_enable="YES" ipsec_program="/usr/local/sbin/setkey" ipsec_file="/usr/local/etc/racoon/setkey.conf" # allows setting up spd policies on boot racoon_enable="yes"
OpenSSH ChernLeeContributed by OpenSSH security OpenSSH OpenSSH is a set of network connectivity tools used to access remote machines securely. Additionally, TCP/IP connections can be tunneled/forwarded securely through SSH connections. OpenSSH encrypts all traffic to effectively eliminate eavesdropping, connection hijacking, and other network-level attacks. OpenSSH is maintained by the OpenBSD project and is installed by default in &os;. It is compatible with both SSH version 1 and 2 protocols. Advantages of Using <application>OpenSSH</application> 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. Enabling the SSH Server OpenSSH enabling To see if &man.sshd.8; is enabled, check /etc/rc.conf for this line: sshd_enable="YES" This will start &man.sshd.8;, the daemon program for OpenSSH, the next time the system initializes. Alternatively, it is possible to use &man.service.8; to start OpenSSH now: &prompt.root; service sshd start The SSH Client OpenSSH client To use &man.ssh.1; to connect to a system running &man.sshd.8;, specify the username and host to log into: &prompt.root; ssh user@example.com Host key not found from the list of known hosts. Are you sure you want to continue connecting (yes/no)? yes Host 'example.com' added to the list of known hosts. user@example.com's password: ******* SSH utilizes a key fingerprint system to verify the authenticity of the server when the client connects. The user is prompted to type yes when connecting for the first time. Future attempts to login are verified against the saved fingerprint key and the &man.ssh.1; client will display an alert if the saved fingerprint differs from the received fingerprint on future login attempts. The fingerprints are saved in ~/.ssh/known_hosts. By default, recent versions of &man.sshd.8; only accept SSH v2 connections. The client will use version 2 if possible and will fall back to version 1. The client can also be forced to use one or the other by passing it the or for version 1 or version 2, respectively. The version 1 compatibility is maintained in the client for backwards compatibility with older versions. Secure Copy OpenSSH secure copy &man.scp.1; Use &man.scp.1; to copy a file to or from a remote machine in a secure fashion. &prompt.root; scp user@example.com:/COPYRIGHT COPYRIGHT user@example.com's password: ******* COPYRIGHT 100% |*****************************| 4735 00:00 &prompt.root; Since the fingerprint was already saved for this host in the previous example, it is verified when using &man.scp.1; here. The arguments passed to &man.scp.1; are similar to &man.cp.1;, with the file or files to copy in the first argument, and the destination in the second. Since the file is fetched over the network, through an SSH, connection, one or more of the file arguments takes the form . Configuration OpenSSH configuration The system-wide configuration files for both the OpenSSH daemon and client reside in /etc/ssh. ssh_config configures the client settings, while sshd_config configures the daemon. Each file has its own manual page which describes the available configuration options. &man.ssh-keygen.1; Instead of using passwords, &man.ssh-keygen.1; can be used to generate DSA or RSA keys to authenticate a user: &prompt.user; ssh-keygen -t dsa Generating public/private dsa key pair. Enter file in which to save the key (/home/user/.ssh/id_dsa): Created directory '/home/user/.ssh'. Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/user/.ssh/id_dsa. Your public key has been saved in /home/user/.ssh/id_dsa.pub. The key fingerprint is: bb:48:db:f2:93:57:80:b6:aa:bc:f5:d5:ba:8f:79:17 user@host.example.com &man.ssh-keygen.1; will create a public and private key pair for use in authentication. The private key is stored in ~/.ssh/id_dsa or ~/.ssh/id_rsa, whereas the public key is stored in ~/.ssh/id_dsa.pub or ~/.ssh/id_rsa.pub, respectively for the DSA and RSA key types. The public key must be placed in ~/.ssh/authorized_keys on the remote machine for both RSA or DSA keys in order for the setup to work. This setup allows connections to the remote machine based upon SSH keys instead of passwords. Many users believe that keys are secure by design and will use a key without a passphrase. This is dangerous behavior and the method an administrator may use to verify keys have a passphrase is to view the key manually. If the private key file contains the word ENCRYPTED the key owner is using a passphrase. While it may still be a weak passphrase, at least if the system is compromised, access to other sites will still require some level of password guessing. In addition, to better secure end users, the from may be placed in the public key file. For example, adding from="192.168.10.5 in the front of ssh-rsa or rsa-dsa prefix will only allow that specific user to login from that host IP. If a passphrase is used in &man.ssh-keygen.1;, the user will be prompted for the passphrase each time in order to use the private key. &man.ssh-agent.1; can alleviate the strain of repeatedly entering long passphrases, and is explored in . The various options and files can be different according to the OpenSSH version. To avoid problems, consult &man.ssh-keygen.1;. Using SSH Agent to Cache Keys To load SSH keys into memory for use, without needing to type the passphrase each time, use &man.ssh-agent.1; and &man.ssh-add.1;. Authentication is handled by &man.ssh-agent.1;, using the private key(s) that are loaded into it. Then, &man.ssh-agent.1; should be used to launch another application. At the most basic level, it could spawn a shell or a window manager. To use &man.ssh-agent.1; in a shell, start it with a shell as an argument. Next, add the identity by running &man.ssh-add.1; and providing it the passphrase for the private key. Once these steps have been completed, the user will be able to &man.ssh.1; to any host that has the corresponding public key installed. For example: &prompt.user; ssh-agent csh &prompt.user; ssh-add Enter passphrase for /home/user/.ssh/id_dsa: Identity added: /home/user/.ssh/id_dsa (/home/user/.ssh/id_dsa) &prompt.user; To use &man.ssh-agent.1; in &xorg;, a call to &man.ssh-agent.1; needs to be placed in ~/.xinitrc. This provides the &man.ssh-agent.1; services to all programs launched in &xorg;. An example ~/.xinitrc might look like this: exec ssh-agent startxfce4 This launches &man.ssh-agent.1;, which in turn launches XFCE, every time &xorg; starts. Once &xorg; has been restarted so that the changes can take effect, run &man.ssh-add.1; to load all of the SSH keys. <acronym>SSH</acronym> Tunneling OpenSSH 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 for &man.telnet.1;: &prompt.user; ssh -2 -N -f -L 5023:localhost:23 user@foo.example.com &prompt.user; This example uses the following options: Forces &man.ssh.1; to use version 2 to connect to the server. Indicates no command, or tunnel only. If omitted, &man.ssh.1; initiates a normal session. Forces &man.ssh.1; to run in the background. Indicates a local tunnel in localport:remotehost:remoteport format. 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 port. It then forwards any connections received on the local host/port via the SSH connection to the specified remote host and port. In the example, port 5023 on localhost is forwarded to port 23 on localhost of the remote machine. Since 23 is used by &man.telnet.1;, this creates an encrypted &man.telnet.1; session through an SSH tunnel. This can be used to wrap any number of insecure TCP protocols such as SMTP, POP3, and FTP. Using &man.ssh.1; to Create a Secure Tunnel for SMTP &prompt.user; ssh -2 -N -f -L 5025:localhost:25 user@mailserver.example.com user@mailserver.example.com's password: ***** &prompt.user; telnet localhost 5025 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. 220 mailserver.example.com ESMTP This can be used in conjunction with &man.ssh-keygen.1; and additional user accounts to create a more seamless SSH tunneling environment. Keys can be used in place of typing a password, and the tunnels can be run as a separate user. Practical <acronym>SSH</acronym> Tunneling Examples Secure Access of a POP3 Server In this example, there is an SSH server that accepts connections from the outside. On the same network resides a mail server running a POP3 server. To check email in a secure manner, create an SSH connection to the SSH server, and tunnel through to the mail server. &prompt.user; ssh -2 -N -f -L 2110:mail.example.com:110 user@ssh-server.example.com user@ssh-server.example.com's password: ****** Once the tunnel is up and running, point the email client to send POP3 requests to localhost on port 2110. This connection will be forwarded securely across the tunnel to mail.example.com. Bypassing a Draconian Firewall Some network administrators impose firewall rules which filter both incoming and outgoing connections. For example, it might limit access from remote machines to ports 22 and 80 to only allow &man.ssh.1; and web surfing. This prevents access to any other service which uses a port other than 22 or 80. The solution is to create an SSH connection to a machine outside of the network's firewall and use it to tunnel to the desired service. &prompt.user; ssh -2 -N -f -L 8888:music.example.com:8000 user@unfirewalled-system.example.org user@unfirewalled-system.example.org's password: ******* In this example, a streaming Ogg Vorbis client can now be pointed to localhost port 8888, which will be forwarded over to music.example.com on port 8000, successfully bypassing the firewall. The <varname>AllowUsers</varname> Option It is often a good idea to limit which users can log in and from where using AllowUsers. For example, to only allow root to log in from 192.168.1.32, add this line to /etc/ssh/sshd_config: AllowUsers root@192.168.1.32 To allow admin to log in from anywhere, list that username by itself: AllowUsers admin Multiple users should be listed on the same line, like so: AllowUsers root@192.168.1.32 admin It is important to list each user that needs to log into this machine; otherwise, they will be locked out. After making changes to /etc/ssh/sshd_config, tell &man.sshd.8; to reload its configuration file by running: &prompt.root; service sshd reload Further Reading The OpenSSH website. &man.ssh.1;, &man.scp.1;, &man.ssh-keygen.1;, &man.ssh-agent.1;, &man.ssh-add.1;, and &man.ssh.config.5; for client options. &man.sshd.8;, &man.sftp-server.8;, and &man.sshd.config.5; for server options. Filesystem Access Control Lists (<acronym>ACL</acronym>)s TomRhodesContributed by ACL Filesystem Access Control Lists (ACLs) extend the standard &unix; permission model in a &posix;.1e compatible way. This permits an administrator to make use of and take advantage of a more sophisticated security model. The &os; GENERIC kernel provides ACL support for UFS file systems. Users who prefer to compile a custom kernel must include the following option in their custom kernel configuration file: options UFS_ACL If this option is not compiled in, a warning message will be displayed when attempting to mount a filesystem supporting ACLs. ACLs rely on extended attributes being enabled on the filesystem. Extended attributes are natively supported in UFS2. A higher level of administrative overhead is required to configure extended attributes on UFS1 than on UFS2. The performance of extended attributes on UFS2 is also substantially higher. As a result, UFS2 is recommended for use with ACLs. ACLs are enabled by the mount-time administrative flag, , which may be added to /etc/fstab. The mount-time flag can also be automatically set in a persistent manner using &man.tunefs.8; to modify a superblock ACLs flag in the filesystem header. In general, it is preferred to use the superblock flag for several reasons: The mount-time ACLs flag cannot be changed by a remount using . It requires a complete &man.umount.8; and fresh &man.mount.8;. This means that ACLs cannot be enabled on the root filesystem after boot. It also means that the disposition of a filesystem cannot be changed once it is in use. Setting the superblock flag will cause the filesystem to always be mounted with ACLs enabled, even if there is not an fstab entry or if the devices re-order. This prevents accidental mounting of the filesystem without ACLs enabled, which can result in the security problem of ACLs being improperly enforced. It is desirable to discourage accidental mounting without ACLs enabled, because nasty things can happen if ACLs are enabled, then disabled, then re-enabled without flushing the extended attributes. In general, once ACLs are enabled on a filesystem, they should not be disabled, as the resulting file protections may not be compatible with those intended by the users of the system, and re-enabling ACLs may re-attach the previous ACLs to files that have since had their permissions changed, resulting in unpredictable behavior. Filesystems with ACLs enabled will show a + (plus) sign in their permission settings when viewed. For example: drwx------ 2 robert robert 512 Dec 27 11:54 private drwxrwx---+ 2 robert robert 512 Dec 23 10:57 directory1 drwxrwx---+ 2 robert robert 512 Dec 22 10:20 directory2 drwxrwx---+ 2 robert robert 512 Dec 27 11:57 directory3 drwxr-xr-x 2 robert robert 512 Nov 10 11:54 public_html In this example, directory1, directory2, and directory3 are all taking advantage of ACLs, whereas public_html is not. Making Use of <acronym>ACL</acronym>s Filesystem ACLs can be viewed using &man.getfacl.1;. For instance, to view the ACL settings on test: &prompt.user; getfacl test #file:test #owner:1001 #group:1001 user::rw- group::r-- other::r-- To change the ACL settings on this file, use &man.setfacl.1;: &prompt.user; setfacl -k test To remove all of the currently defined ACLs from a file or filesystem, one can use . However, the preferred method is to use as it leaves the basic fields required for ACLs to work. &prompt.user; setfacl -m u:trhodes:rwx,group:web:r--,o::--- test In this example, is used to modify the default ACL entries. Since there were no pre-defined entries, as they were removed by the previous command, it restores the default options and assign the options listed. If a user or group is added which does not exist on the system, an Invalid argument error will be displayed. Monitoring Third Party Security Issues TomRhodesContributed by portaudit 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 &os; releases advisories for the base system, doing so for every third party utility is beyond the &os; Project's capability. There is a way to mitigate third party vulnerabilities and warn administrators of known security issues. A &os; add on utility known as portaudit exists solely for this purpose. The ports-mgmt/portaudit port polls a database, which is updated and maintained by the &os; Security Team and ports developers, for known security issues. To install portaudit from the Ports Collection: &prompt.root; cd /usr/ports/ports-mgmt/portaudit && make install clean During the installation, the configuration files for &man.periodic.8; will be updated, permitting portaudit output in the daily security runs. Ensure that the daily security run emails, which are sent to root's email account, are being read. No other configuration is required. After installation, an administrator can update the database and view known vulnerabilities in installed packages by invoking the following command: &prompt.root; portaudit -Fda The database is automatically updated during the &man.periodic.8; run. The above command is optional and can be used to manually update the database now. To audit the third party utilities installed as part of the Ports Collection at anytime, an administrator can run the following command: &prompt.root; portaudit -a portaudit will display messages for any installed vulnerable packages: Affected package: cups-base-1.1.22.0_1 Type of problem: cups-base -- HPGL buffer overflow vulnerability. Reference: <http://www.FreeBSD.org/ports/portaudit/40a3bca2-6809-11d9-a9e7-0001020eed82.html> 1 problem(s) in your installed packages found. You are advised to update or deinstall the affected package(s) immediately. 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 &os; port version, along with other web sites which may contain security advisories. portaudit is a powerful utility and is extremely useful when coupled with the portmaster port. &os; Security Advisories TomRhodesContributed by &os; Security Advisories Like many production quality operating systems, &os; publishes Security Advisories. These advisories are usually mailed to the security lists and noted in the Errata only after the appropriate releases have been patched. This section explains what an advisory is, how to understand it, and what measures to take in order to patch a system. What Does an Advisory Look Like? &os; security advisories use the format seen in this example: ============================================================================= FreeBSD-SA-XX:XX.UTIL Security Advisory The FreeBSD Project Topic: denial of service due to some problem Category: core Module: sys Announced: 2003-09-23 Credits: Person Affects: All releases of &os; &os; 4-STABLE prior to the correction date Corrected: 2003-09-23 16:42:59 UTC (RELENG_4, 4.9-PRERELEASE) 2003-09-23 20:08:42 UTC (RELENG_5_1, 5.1-RELEASE-p6) 2003-09-23 20:07:06 UTC (RELENG_5_0, 5.0-RELEASE-p15) 2003-09-23 16:44:58 UTC (RELENG_4_8, 4.8-RELEASE-p8) 2003-09-23 16:47:34 UTC (RELENG_4_7, 4.7-RELEASE-p18) 2003-09-23 16:49:46 UTC (RELENG_4_6, 4.6-RELEASE-p21) 2003-09-23 16:51:24 UTC (RELENG_4_5, 4.5-RELEASE-p33) 2003-09-23 16:52:45 UTC (RELENG_4_4, 4.4-RELEASE-p43) 2003-09-23 16:54:39 UTC (RELENG_4_3, 4.3-RELEASE-p39) CVE Name: CVE-XXXX-XXXX For general information regarding FreeBSD Security Advisories, including descriptions of the fields above, security branches, and the following sections, please visit http://www.FreeBSD.org/security/. I. Background II. Problem Description III. Impact IV. Workaround V. Solution VI. Correction details VII. References The Topic field specifies the problem. It provides an introduction to the security advisory and notes the utility affected by 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 &os; operating system. The contrib category means that the vulnerability affects software contributed to the &os; Project, such as Sendmail. The ports category indicates that the vulnerability affects add on software available through the Ports Collection. The Module field refers to the component location. In this example, the sys module is affected; therefore, this vulnerability affects a component used within the kernel. The Announced field reflects the date the security advisory was published, or announced to the world. This means that the security team has verified that the problem exists and that a patch has been committed to the &os; 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 &os; are affected by this vulnerability. For the kernel, a quick look over the output from &man.ident.1; on the affected files will help in determining the revision. For ports, the version number is listed after the port name in /var/db/pkg. If the system does not sync with the &os; Subversion repository and is not rebuilt daily, chances are that it is affected. The Corrected field indicates the date, time, time offset, and release that was corrected. Reserved for the identification information used to look up vulnerabilities in the Common Vulnerabilities and Exposures database. The Background field gives information about the affected utility. Most of the time this is why the utility exists in &os;, what it is used for, and a bit of information on how the utility came to be. The Problem Description field explains the security hole in depth. This can include information on flawed code, or even how the utility could be maliciously used to open a security hole. The Impact field describes what type of impact the problem could have on a system. For example, this could be anything from a denial of service attack, to extra privileges available to users, or even giving the attacker superuser access. The Workaround field offers a workaround to system administrators who cannot upgrade the system due to time constraints, network availability, or other reasons. Security should not be taken lightly, and an affected system should either be patched or the workaround implemented. The Solution field offers 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 the Subversion branch or release name with the periods changed to underscore characters. It also shows the revision number of the affected files within each branch. The References field usually offers sources of other information. This can include web URLs, books, mailing lists, and newsgroups. Process Accounting TomRhodesContributed by 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. This indeed 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. Enabling and Utilizing Process Accounting Before using process accounting, it must be enabled using the following commands: &prompt.root; touch /var/account/acct &prompt.root; chmod 600 /var/account/acct &prompt.root; accton /var/account/acct &prompt.root; echo 'accounting_enable="YES"' >> /etc/rc.conf 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. To view information about commands being issued, use &man.lastcomm.1;. This command displays the commands issued by users on specific &man.ttys.5;. For example, this command prints out all known usage of &man.ls.1; by trhodes on the ttyp1 terminal: &prompt.root; lastcomm ls trhodes ttyp1 Many other useful options exist and are explained in &man.lastcomm.1;, &man.acct.5;, and &man.sa.8;. Resource Limits TomRhodesContributed by Resource limits For years, &os; has used a resource limits database controlled through a flat file, /etc/login.conf. While it has been discussed previously and is still supported, it is not the most optimal method of controlling resources. The flat file requires users to be divided into various group labels known as classes, which require changes not only to this flat file but also the password database. Potentially a single, more constrained user would require an additional label to be added, the resource database rebuilt using cap_mkdb, and edits made to /etc/master.passwd. In addition, the password database must be rebuilt using pwd_mkdb. This multi-step process could be very time consuming depending on how many users must be singled out. A new command in &os;, &man.rctl.8;, allows for a more fine grained method of controlling resources limits for users. This command will support much more than users, it will also set resource constraints on processes, jails, and the original login class. These advanced features provide administrators and users with methods to control resources through the command line and set rules on system initialization using a configuration file. To enable this feature, add these lines to GENERIC, or the custom kernel configuration file, and rebuild.: options RACCT options RCTL The entire system will need rebuilt. See , which will provide instructions for the process. Once this is complete, rctl may be used to set rules for the system. Rule syntax is simple, controlled through the use of a subject, a subject-id, resource, and action. Take the following example rule: user:trhodes:maxproc:deny=10/user This rule shows a basic premise of a rule, here the subject is user and the subject-id is trhodes. The maxproc is, of course, max number of processes, which is considered the resource. The action here is set to deny, which blocks any new processes from being created. In the previous example, the user, trhodes will be constrained to 10 (ten) processes and no greater. Other actions are available and could be log to the console, pass a notification to &man.devd.8;, or send a sigterm to the process. Some care must be taken while adding rules. The one above will unfortunately block my user from doing the most simple tasks after I have logged in and executed a screen session. When a resource limit has been hit, an error will be printed, as in this example: &prompt.user; man test /usr/bin/man: Cannot fork: Resource temporarily unavailable eval: Cannot fork: Resource temporarily unavailable For another example, &man.rctl.8; can be used to prevent a jail from exceeding a memory limit. This rule could be written as: &prompt.root; rctl -a jail:httpd:memoryuse:deny=2G/jail Rules may also persist across reboots if they have been added to /etc/rctl.conf. The format is a rule, without the preceding command. For example, the previous rule could be added like the following: # Block jail from using more than 2G memory: jail:httpd:memoryuse:deny=2G/jail To remove a rule, just ask rctl to remove it from the list: &prompt.root; rctl -r user:trhodes:maxproc:deny=10/user The manual page shows a method for removing all rules; however, if removing all rules for a single user is required, this command may be issued: &prompt.root; rctl -r user:trhodes Many other resources exist which can be used to exert additional control over various subjects. See &man.rctl.8; to learn about them.