All our Linux servers support users accounts, these are the essential way people connect and do work. This article focuses on server side user accounts for ssh and console access methods. However similar principles and awareness should be applied to any service that implements logins, including websites.
User accounts depend on a number of backend tools to provide authentication and control access. The main library used is called Linux-PAM (Pluggable Authentication Modules for Linux). This is a suite of shared libraries that enables a local system administrator to choose how applications authenticate users. Our installs have a reasonable default setup, so you wont need to mess with this normally. See PAM online documentation for more fine grained info.
Account details including usernames, group membership and encrypted passwords, are typically stored by PAM in flat files inside /etc.
Very simply, during logins, a user connects, and supplies the password. Pam hashes the password and checks against /etc/shadow. If that user exists in /etc/passwd and the hash matches (along with a few other checks), the user is granted access to the server. A success or failure message is logged by the system.
The level of access granted depends on a variety of things. For example a user may have full shell access. Or they may be restricted to a particular folder (ie jailed). Or they may not have shell access at all, eg for an email only account.
When a user connects to your server, on a new install the user may see a login or shell prompt right away. Sometime there is a banner that includes system information. An example of the default ssh banner on our latest Ubuntu 16.04 install is below.
Welcome to Ubuntu 16.04.2 LTS (GNU/Linux 4.4.56-rh74-20170322144434.xenU.x86_64 x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
This server was originally provisioned by RimuHosting
Get support with our sysadmin services per:
https://rimuhosting.com/knowledgebase/rimuhosting/syadmin-services
2 packages can be updated.
0 updates are security updates.
The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.
root@server:~#
You may want to hide some of those details. You may also want to explicitly advise users they they will be monitored while using the server.
Also depending on your legal jurisdiction, unauthorized access is only provable if the offender knew at the time that the access they intended to obtain was unauthorized. Having a good banner removes any question of this.
The following links have starters on how to achieve the ideal banner, and where to set that up on various distributions.
At a minimum, all login attempts are recorded with the username, apparent source ip, and the time. Logs are typically stored in files under /var/log. Some logs are only readable and writable by the root user to prevent leaking information to non-privileged users.
Check in auth.log and also maybe syslog or messages (the global server logs). Additionally there is a binary log that can be accessed using the last command, eg...
root@server:~# last
root pts/0 65.99.223.183 Fri Mar 24 03:14 still logged in
root pts/0 65.99.223.183 Fri Mar 24 01:33 - 01:43 (00:10)
reboot system boot 4.4.56-rh74-2017 Mon Mar 20 03:12 still running
wtmp begins Mon Mar 20 03:12:51 2017
This is not always enough to provide a detailed audit trail. Consider installing the acct daemon. The package includes "lastcomm" which can help you track all the commands run under a user account.
root@server:~# ac -p
root 0.63
total 0.63
root@server:~# lastcomm
sshd S root __ 0.00 secs Fri Mar 24 03:43
sshd SF sshd __ 0.00 secs Fri Mar 24 03:43
ac root pts/0 0.00 secs Fri Mar 24 03:42
...
Most shells also provide the "history" command.
See also Logging user activity using process accounting
User accounts can be useful for a number of things. The main one is to provide dedicated space for different staff or customers on the same server. Benefits of having seperate users account include:
* finer access control, through permissions and access isolation
* better auditing, via logs, command history, etc
* risk reduction, for example users typically do not have root access
User accounts can belong to one or more groups, normally when created they are added to a group with the same name as the user account. Groups and users can both have passwords set, although typically groups do not. Permissions are grouped into three levels, user, group users, and 'other' or 'all users'. You may see those described with the letters u, g, and o. Each level has read, write and execute permissions.
To check ownership and permissions on a file or folder, you can use the long format listing with the 'ls' command, like so...
~$ echo "hello world" > test
~$ ls -l test
-rw-rw-r-- 1 someuser someuser 12 Mar 28 16:12 test
The intial permisions are set based on the umask assigned to a user account.
Understanding Linux File Permissions
The main command used to create accounts is 'adduser'. It may also be useful to learn about the 'groupadd' and 'usermod' commands. Under centos 'adduser' links directly to the low level 'useradd' command, on Ubuntu/Debian installs 'adduser' is a friendlier wrapper script around 'useradd'. It should look like this...
~# adduser someuser
Adding user `someuser' ...
Adding new group `someuser' (1000) ...
Adding new user `someuser' (1000) with group `someuser' ...
Creating home directory `/home/someuser' ...
Copying files from `/etc/skel' ...
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
Changing the user information for someuser
Enter the new value, or press ENTER for the default
Full Name []:
Room Number []:
Work Phone []:
Home Phone []:
Other []:
Is the information correct? [Y/n]
When creating users accounts from scripts, it is better to call useradd directly, since it does not require user interaction.
Once created, you can find out the numeric id of a user account, and its group membership with the 'id' command.
~# id someuser
uid=1000(someuser) gid=1000(someuser) groups=1000(someuser)
Sometimes you may want to jail a user, ie only allow access files under their own account. Generally this involves involves providing a restricted shell account. There are a bunch of different ways. One method is discussed on SFTP: Easy jailed accounts
You may want to prevent other users from seeing files inside your account. You can do this by restricting 'group' and other' access to your home folder. On some distributions (eg Ubuntu) default permissions for users accounts tends to look like "drwxr-xr-x" or "755". You can set those to manually to look like the default on CentOS, eg "drwx------" or "700". For example say your home folder is in /home/someuser
# see what is set currently
ls -la /home
# change the permissions
chmod 700 /home/someuser
# check
ls -la /home
You can also use the same trick for subfolders instead.
Caveats:
* changing permissions may break chroot/jails inside /home/someuser
* could also affect some hosting setups, such as those provided by Virtualmin that use /home/someuser/public_html
To change the default permissions on account folders, look for the UMASK value in /etc/login.defs. Be very careful though, make sure you read the documentation for that file first, there is an excellent man page.
Sometimes you want to disable an account without removing it. You can do so as follows, where 'someuser' is the account you want to modify...
#lock account from shell logins
passwd -l someuser
# prevent ssh key logins as well
chage -E 0 someuser
# optionally prevent shell on any type of logins
usermod -s /sbin/nologin someuser
To restore access you can reverse the above operations...
# unlock account from shell logins
passwd -u someuser
# allow logins by ssh key again. Instead of -1 you can also set an expiry date some time in future
chage -E -1 someuser
# allow shell again
usermod -s /bin/bash someuser
Another solution specific to ssh only, would be to add a line explicitly granting access only to certain users, or better, groups of users directly in your ssh configuration.
echo "AllowUsers USER1 USER2 USER3 USER4" >> /etc/sshd/sshd_config
/etc/init.d/sshd restart
#create new group
groupadd shellusers
#add members to group
usermod -a -G shellusers USER
#add directive to ssh configuration
echo "AllowGroups shellusers" >> /etc/sshd/sshd_config
In order to remove user accounts, use the deluser command. This will remove the /etc/passwd entry and associated access. Typically the home folder for that user is left behind with permissions unchanged, unless you explicitly pass in the option to remove that as well. See the man page for the userdel command for more options.
# Remove user
userdel someuser
It can be really tempting to set a simple password, something short that allows you to quickly test an account. This is really bad, and we recommend at least the following best practices.
Our installs have distribution supplied defaults, if you need stronger restrictions you can tweak those. Be careful when doing so as you can make your server inaccessible with a typo. There are a bunch of good articles about doing that with the pam libraries, here are a few.
Securing Debian:Password security in PAM
Computerworld: Enforce password complexity on Linux
Linux Audit: Configure the minimum password length on Linux systems
Even worse than a weak password is no password at all. You can quickly check for those with the following script.
awk -F: '$2 == "!!" { print $1, "has empty password!" }' /etc/shadow
System accounts without shell access probably don't have existing passwords so the following script will turn up some users without passwords which are perfectly safe. (i.e. the postfix user would be an example of that).
It is a good idea to disable or even remove unused accounts. This minimizes the chance they will be forgotten and potentially abused at a later date.
Many distributions include a long list of entries in /etc/passwd for system users. Often these users will exist for packages that you don't even have installed. Leaving these users around is fine.
If you don't know whether or not an account is active, you can try to determine this by searching for files owned by that user and checking their last modified date.
Finding files owned by a user:
#print file names/locations
[root@server ~]# find / -user USER
#check last modified date
[root@server ~]# ls -lu FILENAME
If the user doesn't own any files, it might be safe to go ahead and remove that user from your system. At the very least, if you don't remove the user you can disable shell access as described above.