With just a few one-line text file edits, you can control who can access your servers.
I can't cite statistics, but my experience in lending a hand to friends and clients has led me to the conclusion that most sites have an "all or nothing" approach to creating and managing user accounts on their machines. If the site uses NIS, their nsswitch.conf file says to use NIS for user account information. If the site uses LDAP, they use LDAP for user account information. The problem here is that this implies that every single account in the directory is actually a valid account on any machine, whether those users belong there or not.
Of course, there are firewalls, router ACLs, and all manner of security appliances and software between servers and users who shouldn't have access to them—but data centers are run by humans, and humans make mistakes, especially in large, complex networks. Mistype the VLAN tag on a switch port, for example, and all of a sudden anyone from Engineering can SSH to your production application server. This hack shows you how a few simple text edits will allow you to limit which users in an NIS directory can access the local machine.
The entries in the /etc/nsswitch.conf file on a Linux system determine how it resolves requests for information about users, groups, and other host information. Let's concentrate on just the passwd
line. If you're using NIS, it might look something like this:
passwd files nis
This means that when the system is trying to find information about a user account, such as the user's login shell or what name a numeric UID maps to, it'll first look in /etc/passwd, and then fall back on NIS. If a user is listed in either of these resources, it's a valid account and (barring any other protections) the operation succeeds.
But suppose you want only a handful of people to have valid accounts on the machines, instead of everyone in the entire NIS domain. We can do that! As an example, let's add two lines to the bottom of the /etc/passwd file:
+@admins +jonesy
The first line makes all the users in the admins netgroup valid accounts on this machine. The second line makes jonesy a valid account on this machine. All other accounts will be invalid when we complete the configuration. The only thing left for us to do is to edit the /etc/nsswitch.conf file to make it look something like this:
passwd: compat passwd_compat: nis
The first line says to call the nss_compat module, and the second line tells the nss_compat module to use NIS for the lookup (other valid values here are nisplus
or ldap
). Now, to test, run the following command:
$ getent passwd jonesy
This will consult the /etc/nsswitch.conf file to figure out where to get the information. When it sees compat
, it will go to the /etc/passwd file to see if jonesy is listed there. If the account is not listed, it will not display any output. If it is listed, it will query the NIS server and retrieve the account record, which will look something like this:
jonesy:x:1001:100:Brian Jones:/home/jonesy:/bin/bash
In addition, running getent passwd
without arguments will return records for every valid account on the system, which in our example will include all of the users in the admins netgroup, the jonesy account, and (of course) all of the system accounts that were in the /etc/passwd file before we ever touched it.
It's often desirable to be able to access user information for accounts that are not valid on the machine, though—and in other circumstances, accounts that should be valid on a particular machine shouldn't actually be able to log into that machine. For example, I don't want users logging onto my mail server, but my mail server needs to be able to map inbound mail to account names in order to accept mail. In cases such as these, you can add this line at the bottom of your /etc/passwd file:
+::::::/sbin/nologin
Now, running the getent passwd
command will show you all the system accounts, then the accounts you added earlier, and then every other account. It will show full records for all accounts, but the login shell for the accounts at the end will be /sbin/nologin, which will keep those users from logging into the machine and getting a shell. Note that this line needs to be the last line in the password file, since lines are read and resolved in order. If the line above came before the +jonesy
line, for example, it would find a record for me with the /sbin/nologin shell first, and I would not be able to log onto the machine, even though the +jonesy
line appears later in the file.
Note that in addition to using the +
sign to add valid users, you can use the–sign to exclude users. If you want all but a handful of accounts to be valid, it's easy to do. For example, if you wanted all accounts to be valid login accounts except for those accounts in the badguys netgroup, you could add a line like this to the /etc/passwd file:
-@badguys
Those accounts would no longer be able to log in on the machine in question.
Get Linux Server Hacks, Volume Two now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.