In this chapter, we've covered many methods of securing the boot and login environments. It's probably no surprise that you can further control who can log into your system and when: Unix systems contain many built-in mechanisms, allowing you to choose the most appropriate means and policy for your network.
Furthermore, the defaults may not always suit your needs. Do you really want users to be logged into multiple terminals when they can effectively do their work from one? For that matter, do you want any user, including nonemployees, to try his hand at logging into your systems at any hour of the night and day? Here's how to tighten up some defaults.
Since users log into terminals, a logical file to secure is the terminal configuration file, /etc/ttys. We briefly saw this file in [Hack #24] when we password protected single-user mode.
This file is divided into three sections, one for each of the three types of terminals. Let's concern ourselves with the virtual terminals, ttyv, which are the terminals available for users physically seated at the system's keyboard.
# grep ttyv /etc/ttys ttyv0 "/usr/libexec/getty Pc" cons25 on secure ttyv1 "/usr/libexec/getty Pc" cons25 on secure ttyv2 "/usr/libexec/getty Pc" cons25 on secure ttyv3 "/usr/libexec/getty Pc" cons25 on secure ttyv4 "/usr/libexec/getty Pc" cons25 on secure ttyv5 "/usr/libexec/getty Pc" cons25 on secure ttyv6 "/usr/libexec/getty Pc" cons25 on secure ttyv7 "/usr/libexec/getty Pc" cons25 on secure ttyv8 "/usr/X11R6/bin/xdm -nodaemon" xterm off secure
The word on indicates that that terminal is available for logins. By default, the first eight terminals, ttyv0 through ttyv7, will accept logins. You've probably discovered this yourself by pressing Alt-Fx, where x is a number between 1 and 8. On a server system, you may need only one virtual terminal. Disable the other terminals by changing the word on to off.
The word secure means that the system is physically secure, implying that it's okay for a user to walk up to the keyboard and log in as root. Since it's never okay for a user to log in as root, you should disable that default. For whatever virtual terminals you've left on, either change the word secure to insecure or simply remove the word secure.
Now let's see what can be done with /etc/login.access. At its most stringent, you can use this file to prevent all remote logins, meaning you can log in only if you are physically sitting at that system:
-:ALL:ALL EXCEPT LOCAL
Note the syntax that is used for each line in this file. The - means access denied. Its alter ego is +, which means access granted. The first ALL is a wildcard for all users. The second ALL is a wildcard for all locations. The EXCEPT LOCAL is the exception that allows just the local location.
You could modify that rule slightly to disallow remote and local root logins:
Take some care when modifying this file. Its syntax supports both user and group names, allowing you to specify exactly who is allowed to log into a system. This can be extremely useful in limiting access to a server system.
The syntax also supports IP addresses. This can also be useful in ensuring that only hosts in your network or a particular subnet can access certain systems. But, as in any security mechanism that relies on IP addresses, do keep in mind that IP addresses can be spoofed.
Finally, if you make changes to this file, test your changes immediately. If you restrict access to certain users, ensure those users can still log in. Further, try to log in as other users to ensure that they are actually being denied access.
Think for a moment. Other than logins to virtual terminals, how else do your users log into systems? Most likely (and, hopefully) through ssh. You can control exactly who can ssh into a system by adding a line to the /etc/ssh/sshd_config file of the system running the SSH daemon.
There are two ways you can control this. One is through AllowGroups. By default, all groups meaning all users can ssh into a system. The other way is through AllowUsers, where again, all users are allowed by default.
Suppose I want to allow only the users genisis, biko, and dru to ssh into a particular system. I could create a group called remote that contains those users:
# grep 100 /etc/group # # pw groupadd remote -g 100 -M genisis biko dru
In this example, I first double-checked that the group ID of 100 was not currently in use. I then created, with pw groupadd, the remote group with a GID of 100 (-g 100) and with those three members (-M genisis biko dru).
Now I can limit ssh access to just the members of that group:
# echo 'AllowGroups remote' >> /etc/ssh/sshd_config
Alternatively, I could have just added those three users directly:
# echo 'AllowUsers genisis biko dru' >> /etc/ssh/sshd_config
Any user who does not match either AllowGroups or AllowUsers will still receive a password prompt when attempting to connect to the SSH daemon. However, the connection attempt will fail with a permission denied message, even if the user provides a correct username and password. The SSH daemon will print a message regarding the failed attempt to its console, sending a copy to /var/log/messages and emailing to root as part of the daily security run output.
To be even pickier, if your users always log in from the same system, you can do this:
AllowUsers firstname.lastname@example.org email@example.com firstname.lastname@example.org
However, don't be that picky if your users don't have static IPs!
Remember, if you make any changes to the SSH daemon's configuration file, you'll need to send a "signal one" to sshd to notify it of the changes:
# killall -1 sshd
After informing sshd of the changes, immediately use a ssh client to test your changes. For example, if I instead add the line Allowusers genisis biko dru, I'll find that user nastygirl is still able to connect. Why? The parameters in /etc/ssh/sshd_config are case-sensitive. You don't want to find out six months later that anyone was allowed to connect when you thought you had restricted connections to certain users.
We've restricted who can log in and from where for both local and remote ssh logins, but we still haven't restricted when those users can log in. To do that, let's look at some other options that are available in our old friend /etc/login.conf [Hack #30] .
This file supports the options times.allow and times.deny. For example, to allow all users to log in between 9:00 AM and 5:00 PM every Monday through Friday, add this line to the default:\ section:
Once you introduce the times.allow option, access will automatically be denied for the time period not listed.
The converse also works. That is, you can specify the denied times in times.deny, and all other times will be allowed.
Remember, whenever you make a change to /etc/login.conf, rebuild the database with cap_mkdb /etc/login.conf and test your changes.
3.12.5 See Also