Jump to contentJump to page navigation: previous page [access key p]/next page [access key n]
documentation.suse.com / Documentação do SUSE Linux Enterprise Server / Security and Hardening Guide / Local security / User management
Applies to SUSE Linux Enterprise Server 15 SP4

14 User management

14.1 Various account checks

14.1.1 Unlocked accounts

It is important that all system and vendor accounts that are not used for logins are locked. To get a list of unlocked accounts on your system, you can check for accounts that do not have an encrypted password string starting with ! or * in the /etc/shadow file. If you lock an account using either passwd -l or usermod -L, it puts a ! in front of the encrypted password, effectively disabling the password. Many system and shared accounts are locked by default by having a * ,!! or !* as the password field which renders the encrypted password into an invalid string. Hence, to get a list of all unlocked (encryptable) accounts, run the following command:

# egrep -v ':\*|:\!' /etc/shadow | awk -F: '{print $1}'

Also make sure all accounts have an x in the password field in /etc/passwd. The following command lists all accounts that do not have a x in the password field:

# grep -v ':x:' /etc/passwd

An x in the password field means that the password has been shadowed, for example, the encrypted password needs to be looked up in the /etc/shadow file. If the password field in /etc/passwd is empty, then the system will not look up the shadow file and it will not prompt the user for a password at the login prompt.

14.1.2 Unused accounts

All system or vendor accounts that are not being used by users, applications, by the system or by daemons should be removed from the system. You can use the following command to find out if there are any files owned by a specific account:

# find / -path /proc -prune -o -user ACCOUNT -ls

The -prune option in this example is used to skip the /proc file system. If you are sure that an account can be deleted, you can remove the account using the following command:

# userdel -r ACCOUNT

Without the -r option, userdel will not delete the user's home directory and mail spool (/var/spool/mail/USER). Note that many system accounts have no home directory.

14.2 Enabling password aging

Password expiration is a general best practice, but might need to be excluded for some system and shared accounts (for example, Oracle). Expiring passwords on those accounts could lead to system outages if the application account expires.

Typically a corporate policy should be developed that dictates rules/procedures regarding password changes for system and shared accounts. However, normal user account passwords should expire automatically. The following example shows how password expiration can be set up for individual user accounts.

The following files and parameters in the table can be used when a new account is created with the useradd command. Settings such as these are stored for each user account in the /etc/shadow file. If using the YaST tool (User and Group Management) to add users, the settings are available on a per-user basis. Here are the various settings, some of which can also be system-wide (for example, modification of /etc/login.defs and /etc/default/useradd):



Maximum number of days a password is valid.



Minimum number of days before a user can change the password since the last change.



Number of days between the last password change and the next password change reminder.



Number of days after password expiration until the account is disabled.



Account expiration date in the format YYYY-MM-DD.

Note: Existing users not affected

Users created prior to these modifications will not be affected.

Ensure that the above parameters are changed in the /etc/login.defs and /etc/default/useradd files. Review of the /etc/shadow file will show how these settings are stored after adding a user.

To create a new user account, execute the following command:

# useradd -c "TEST_USER" -g USERS TEST

The -g option specifies the primary group for this account:

# id TEST
uid=509(test) gid=100(users) groups=100(users)

The settings in /etc/login.defs and /etc/default/useradd are recorded for the test user in the /etc/shadow file as follows:

# grep TEST /etc/shadow

Password aging can be modified at any time by use of the chage command. To disable password aging for system and shared accounts, you can run the following chage command:


To get password expiration information:


For example:

# chage -l TEST
Minimum: 7
Maximum: 60
Warning: 7
Inactive: 14
Last Change: Jan 11, 2015
Password Expires: Mar 12, 2015
Password Inactive: Mar 26, 2015
Account Expires: Never

14.3 Stronger password enforcement

On an audited system, it is important to restrict people from using simple passwords that can be cracked too easily. Writing down complex passwords is all right as long as they are stored securely. Some will argue that strong passwords protect you against dictionary attacks, and those types of attacks can be defeated by locking accounts after a few failed attempts. However, this is not always an option. If set up like this, locking system accounts could bring down your applications and systems, which would be nothing short of a denial-of-service attack—another issue.

At any rate, it is important to practice effective password management security. Most companies require that passwords have, at the very least, a number, one lowercase letter, and one uppercase letter. Policies vary, but maintaining a balance between password strength/complexity and management can be difficult.

14.4 Password and login management with PAM

Linux-PAM (Pluggable Authentication Modules for Linux) is a suite of shared libraries that enable the local system administrator to choose how applications authenticate users.

It is strongly recommended to familiarize oneself with the capabilities of PAM and how this architecture can be leveraged to provide the best authentication setup for an environment. This configuration can be done once, and implemented across all systems (a standard), or can be enhanced for individual hosts (enhanced security—by host/service/application). The key is to realize how flexible the architecture is.

To learn more about the PAM architecture, find PAM documentation in the /usr/share/doc/packages/pam directory (in a variety of formats).

The following discussions are examples of how to modify the default PAM stacks—specifically around password policies—for example password strength, password re-use, and account locking. While these are only a few of the possibilities, they serve as a good start and demonstrate PAM's flexibility.

Important: pam-config limitations

The pam-config tool can be used to configure the common-{account,auth,password,session} PAM configuration files, which contain global options. These files include the following comment:

# This file is autogenerated by pam-config. All changes
# will be overwritten.

Individual service files, such as login, password, sshd, and su must be edited directly. You can elect to edit all files directly, and not use pam-config, though pam-config includes useful features such as converting an older configuration, updating your current configuration, and sanity checks. For more information, see man 8 pam-config.

14.4.1 Password strength

SUSE Linux Enterprise Server can leverage the pam_cracklib library to test for weak passwords—and to suggest using a stronger one if it determines obvious weakness. The following parameters represent an example that could be part of a corporate password policy or something required because of audit constraints.

The PAM libraries follow a defined flow. The best way to design the perfect stack usually is to consider all of the requirements and policies and draw out a flow chart.

Table 14.1: Sample rules/constraints for password enforcement



Minimum length of password is 8



Minimum number of lowercase letters is 1



Minimum number of uppercase letters is 1



Minimum number of digits is 1



Minimum number of other characters is 1

To set up these password restrictions, use the pam-config tool to specify the parameters you want to configure. For example, the minimum length parameter could be modified like this:

> sudo pam-config -a --cracklib-minlen=8 --cracklib-retry=3 \
--cracklib-lcredit=-1 --cracklib-ucredit=-1 --cracklib-dcredit=-1 \
--cracklib-ocredit=-1 --cracklib

Now verify that the new password restrictions work for new passwords. Log in to a non-root account and change the password using the passwd command. Note that the above requirements are not enforced if you run the passwd command under root.

14.4.2 Restricting use of previous passwords

The pam_pwhistory module can be used to configure the number of previous passwords that cannot be reused. The following command implements password restrictions on a system so that a password cannot be reused for at least six months:

> sudo pam-config -a --pwhistory --pwhistory-remember=26

Recall that in the section Section 14.2, “Enabling password aging” we set PASS_MIN_DAYS to 7, which specifies the minimum number of days allowed between password changes. Therefore, if pam_unix is configured to remember 26 passwords, then the previously used passwords cannot be reused for at least six months (26*7 days).

The PAM configuration (/etc/pam.d/common-auth) resulting from the pam-config command looks like the following:

auth      required   pam_env.so
auth      required   pam_unix.so     try_first_pass
account   required   pam_unix.so     try_first_pass
password  requisit   pam_cracklib.so
password  required   pam_pwhistory.so        remember=26
password  optional   pam_gnome_keyring.so    use_authtok
password  required   pam_unix.so     use_authtok nullok shadow try_first_pass
session   required   pam_limits.so
session   required   pam_unix.so     try_first_pass
session   optional   pam_umask.so

14.4.3 Locking user accounts after too many login failures

Locking accounts after a defined number of failed ssh, login, su, or sudo attempts is a common security practice. However, this could lead to outages if an application, admin, or root user is locked out.

Important: Denial-of-service attacks

Password failure counts can easily be abused to cause denial-of-service attacks by deliberately creating login failures.

Only use password failure counts if you have to. Restrict locking to the necessary minimum, and do not lock critical accounts. Keep in mind that locking not only applies to human users but also to system accounts used to provide services.

SUSE Linux Enterprise Server does not lock accounts by default, but provides PAM module pam_tally2 to easily implement password failure counts. Add the following line to the top of /etc/pam.d/login to lock out all users (except for root) after six failed logins, and to automatically unlock the accounts after ten minutes:

auth required pam_tally2.so deny=6 unlock_time=600

This is an example of a complete /etc/pam.d/login file:

auth     requisite      pam_nologin.so
auth     include        common-auth
auth     required       pam_tally2.so deny=6 unlock_time=600
account  include        common-account
account  required       pam_tally2.so
password include        common-password
session  required       pam_loginuid.so
session  include        common-session
#session  optional       pam_lastlog.so nowtmp showfailed
session  optional       pam_mail.so standard

You can also lock out root, though obviously you must be very certain you want to do this:

auth required pam_tally2.so deny=6 even_deny_root unlock_time=600

You can define a different lockout time for root:

auth required pam_tally2.so deny=6 root_unlock_time=120  unlock_time=600

If you want to require the administrator to unlock accounts, leave out the unlock_time option. The next two example commands display the number of failed login attempts and how to unlock a user account:

> sudo pam_tally2 -u username
Login           Failures Latest failure     From
username            6    12/17/19 13:49:43  pts/1

> sudo pam_tally2 -r -u username

The default location for attempted accesses is recorded in /var/log/tallylog.

If the user succeeds in logging in after the login timeout expires, or after the administrator resets their account, the counter resets to 0.

Configure other login services to use pam_tally2 in their individual configuration files in /etc/pam.d/: sshd, su, sudo, sudo-i, and su-l.

14.5 Restricting root logins

By default, the root user is assigned a password and can log in using various methods—for example, on a local terminal, in a graphical session, or remotely via SSH. These methods should be restricted as far as possible. Shared usage of the root account should be avoided. Instead, individual administrators should use tools such as su or sudo (for more information, type man 1 su or man 8 sudo) to obtain elevated privileges. This allows associating root logins with particular users. This also adds another layer of security; not only the root password, but both the root and the password of an administrator's regular account would need to be compromised to gain full root access. This section explains how to limit direct root logins on the different levels of the system.

14.5.1 Restricting local text console logins

TTY devices provide text-mode system access via the console. For desktop systems these are accessed via the local keyboard or—in case of server systems—via input devices connected to a KVM switch or a remote management card (for example, ILO and DRAC). By default, Linux offers six different consoles, which can be switched to via the key combinations AltF1 to AltF6, when running in text mode, or CtrlAltF1 to CtrlAltF6 when running in a graphical session. The associated terminal devices are named tty1 to tty6.

The following steps restrict root access to the first TTY. Even this access method is only meant for emergency access to the system and should never be used for everyday system administration tasks.


The steps shown here are tailored towards PC architectures (x86 and AMD64/Intel 64). On architectures such as POWER, different terminal device names than tty1 can be used. Be careful not to lock yourself out completely by specifying wrong terminal device names. You can determine the device name of the terminal you are currently logged in to by running the tty command. Be careful not to do this in a virtual terminal, such as via SSH or in a graphical session (device names /dev/pts/N), but only from an actual login terminal reachable via AltFN.

Procedure 14.1: Restricting root logins on local TTYs
  1. Ensure that the PAM stack configuration file /etc/pam.d/login contains the pam_securetty module in the auth block:

    auth     requisite      pam_nologin.so
     auth     [user_unknown=ignore success=ok ignore=ignore auth_err=die default=bad] pam_securetty.so noconsole
     auth     include        common-auth

    This will include the pam_securetty module during the authentication process on local consoles, which restricts root to logging in only on TTY devices that are listed in the file /etc/securetty.

  2. Remove all entries from /etc/securetty except one. This limits the access to TTY devices for root.

    # This file contains the device names of tty lines (one per line,
    # without leading /dev/) on which root is allowed to login.
  3. Check whether logins to other terminals will be rejected for root. A login on tty2, for example, should be rejected immediately, without even querying the account password. Also make sure that you can still successfully log in to tty1 and thus that root is not locked out of the system completely.

Important: Do not add pam_securetty module

Do not add the pam_securetty module to the /etc/pam.d/common-auth file. This would break the su and sudo commands, because these tools would then also reject root authentications.


These configuration changes will also cause root logins on serial consoles such as /dev/ttyS0 to be denied. In case you require such use cases, you need to list the respective TTY devices additionally in the /etc/securetty file.

14.5.2 Restricting graphical session logins

To improve security on your server, avoid using graphical environments at all. Graphical programs are often not designed to be run as root and are more likely to contain security issues than console programs. If you require a graphical login, use a non-root login. Configure your system to disallow root from logging in to graphical sessions.

To prevent root from logging in to graphical sessions, you can apply the same basic steps as outlined in Section 14.5.1, “Restricting local text console logins”. Just add the pam_securetty module to the PAM stack file belonging to the display manager—for example, /etc/pam.d/gdm for GDM. The graphical session also runs on a TTY device: by default, tty7. Therefore, if you restrict root logins to tty1, then root will be denied login in the graphical session.

14.5.3 Restricting SSH logins

By default, the root user is also allowed to log in to a machine remotely via the SSH network protocol (if the SSH port is not blocked by the firewall). To restrict this, make the following change to the OpenSSH configuration:

  1. Edit /etc/ssh/sshd_config and adjust the following parameter:

    PermitRootLogin no
  2. Restart the sshd service to make the changes effective:

    systemctl restart sshd.service

Using the PAM pam_securetty module is not suitable in case of OpenSSH, because not all SSH logins go through the PAM stack during authorization (for example, when using SSH public-key authentication). In addition, an attacker could differentiate between a wrong password and a successful login that was only rejected later on by policy.

14.6 Restricting sudo users

The sudo command allows users to execute commands in the context of another user, typically the root user. The sudo configuration consists of a rule-set that defines the mappings between commands to execute and their allowed source and target users and groups. The configuration is stored in the file /etc/sudoers. For more information about sudo, refer to Chapter 2, sudo basics.

By default, sudo asks for the root password on SUSE systems. Unlike su however, sudo remembers the password and allows further commands to be executed as root without asking for the password again for five minutes. Therefore, sudo should be enabled for selected administrator users only.

Procedure 14.2: Restricting sudo for normal users
  1. Edit file /etc/sudoers, for example by executing visudo.

  2. Comment out the line that allows every user to run every command as long as they know the password of the user they want to use. Afterwards, it should look like this:

    #ALL ALL=(ALL) ALL # WARNING! Only use this together with 'Defaults targetpw'!
  3. Uncomment the following line:

    %wheel ALL=(ALL) ALL

    This limits the functionality described above to members of the group wheel. You can use a different group as wheel might have other implications that may not be suitable depending on your setup.

  4. Add users that should be allowed to use sudo to the chosen group. To add the user tux to the group wheel, use:

    usermod -aG wheel tux

    To get the new group membership, users have to log out and back in again.

  5. Verify the change by running a command with a user not in the group you have chosen for access control. You should see the error message:

    wilber is not in the sudoers file.  This incident will be reported.

    Next, try the same with a member of the group. They should still be able to execute commands via sudo.

Please note that this configuration only limits the sudo functionality. The su command is still available to all users. If there are other ways to access the system, users with knowledge of the root password can easily execute commands via this vector.

14.7 Setting an inactivity timeout for interactive shell sessions

It can be a good idea to terminate an interactive shell session after a certain period of inactivity. For example, to prevent open, unguarded sessions, or to avoid wasting system resources.

By default, there is no inactivity timeout for shells. Nothing will happen if a shell stays open and unused for days or even years. However, it is possible to configure most shells so that idle sessions terminate automatically after a certain amount of time. The following example shows how to set an inactivity timeout for a number of common types of shells.

The inactivity timeout can be configured for login shells only or for all interactive shells. In the latter case, the inactivity timeout runs individually for each shell instance. This means that timeouts will accumulate. When a sub- or child-shell is started, a new timeout begins for the sub- or child-shell, and only afterwards will the timeout of the parent continue running.

The following table contains configuration details for a selection of common shells shipped with SUSE Linux Enterprise Server:

packageshell personalitiesshell variabletime unitreadonly settingconfig path (only login shell)config path (all shells)


bash, sh



read-only TMOUT=

/etc/profile.local, /etc/profile.d/



ksh, lksh, mksh, pdksh



read-only TMOUT=

/etc/profile.local, /etc/profile.d/



csh, tcsh



set -r autologout=







readonly TMOUT=

/etc/profile.local, /etc/profile.d/


Every listed shell supports an internal timeout shell variable that can be set to a specific time value to cause the inactivity timeout. If you want to prevent users from overriding the timeout setting, you can mark the corresponding shell timeout variable as read-only. The corresponding variable declaration syntax is also found in the table above.

Note: No protection from hostile users

This feature is only helpful for avoiding risks if a user is forgetful or follows unsafe practices. It does not protect against hostile users. The timeout only applies to interactive wait states of a shell. A malicious user can always find ways to circumvent the timeout and keep their session open regardless.

To configure the inactivity timeout, you need to add the matching timeout variable declaration to each shell's start-up script. Use either the path for login shells only, or the one for all shells, as listed in the table. The following example uses paths and settings that are suitable for bash and ksh to set up a read-only login shell timeout that cannot be overridden by users. Create the file /etc/profile.d/timeout.sh with the following content:

# /etc/profile.d/timeout.sh for SUSE Linux
# Timeout in seconds until the bash/ksh session is terminated
# in case of inactivity.
# 24h = 86400 sec
readonly TMOUT=86400

We recommend using the screen tool in order to detach sessions before logging out. screen sessions are not terminated and can be re-attached whenever required. An active session can be locked without logging out (read about CtrlAX / lockscreen in man screen for details).

14.8 Preventing accidental denial of service

Linux allows you to set limits on the amount of system resources that users and groups can consume. This is also very handy if bugs in programs cause them to use up too many resources (for example, memory leaks), slow down the machine, or even render the system unusable. Incorrect settings can allow programs to use too many resources, which may make the server unresponsive to new connections or even local logins (for example, if a program uses up all available file handles on the host). This can also be a security concern if someone is allowed to consume all system resources and therefore cause a denial-of-service attack—either unplanned, or worse, planned. Setting resource limits for users and groups may be an effective way to protect systems, depending on the environment.

14.8.1 Example for restricting system resources

The following example demonstrates the practical usage of setting or restricting system resource consumption for an Oracle user account. For a list of system resource settings, see /etc/security/limits.conf or man limits.conf.

Most shells, such as Bash, provide control over various resources (for example, the maximum allowable number of open file descriptors or the maximum number of processes) that are available on a per-user basis. To examine all current limits in the shell, execute:

# ulimit -a

For more information on ulimit for the Bash shell, examine the Bash man pages.

Important: Setting limits for SSH sessions

Setting hard and soft limits might not have the expected results when using an SSH session. To see valid behavior, it may be necessary to log in as root, and then su to the ID with limits (for example, Oracle in these examples). Resource limits should also work assuming the application was started automatically during the boot process. It may be necessary to set UsePrivilegeSeparation in /etc/ssh/sshd_config to no and restart the SSH daemon (systemctl restart sshd) if it seems that the changes to resource limits are not working (via SSH). However, this is not generally recommended, as it weakens a system's security.

Tip: Disabling password logins via ssh

You can add some extra security to your server by disabling password authentication for SSH. Remember that you need to have SSH keys configured, otherwise you cannot access the server. To disable password login, add the following lines to /etc/ssh/sshd_config:

UseLogin no
UsePAM no
PasswordAuthentication no
PubkeyAuthentication yes

In this example, a change to the number of file handles or open files that the user oracle can use is made by editing /etc/security/limits.conf as root making the following changes:

oracle           soft    nofile          4096
oracle           hard    nofile          63536

The soft limit in the first line defines the limit on the number of file handles (open files) that the oracle user will have after login. If the user sees error messages about running out of file handles, then the user can increase the number of file handles like in this example up to the hard limit (in this example 63536) by executing:

# ulimit -n 63536

You can set the soft and hard limits higher if necessary.

Note: Caution with using ulimits

It is important to be judicious with the usage of ulimits. Allowing a hard limit for nofile for a user that is equal to the kernel limit (/proc/sys/fs/file-max) is very bad! If the user consumes all the available file handles, the system cannot initiate new logins, since it will not be possible to access the PAM modules required to perform a login.

You also need to ensure that pam_limits is either configured globally in /etc/pam.d/common-auth, or for individual services like SSH, su, login, and telnet in:

/etc/pam.d/sshd (for SSH)
/etc/pam.d/su (for su)
/etc/pam.d/login (local logins and telnet)

If you do not want to enable it for all logins, there is a specific PAM module that will read the /etc/security/limits.conf file. Entries in PAM configuration directives will have entries like:

session     required      /lib/security/pam_limits.so
session     required      /lib/security/pam_unix.so

It is important to note that changes are not immediate and require a new login session:

# su - oracle
> ulimit -n

Note that these examples are specific to the Bash shell; ulimit options are different for other shells. The default limit for the user oracle is 4096. To increase the number of file handles the user oracle can use to 63536, execute:

# su - oracle
> ulimit -n
> ulimit -n 63536
> ulimit -n

Making this permanent requires the addition of the setting, ulimit -n 63536, (again, for Bash) to the user's profile (~/.bashrc or ~/.profile file), which is the user start-up file for the Bash shell on SUSE Linux Enterprise Server (to verify your shell, run: echo $SHELL). To do this you could run the following commands for the Bash shell of the user oracle:

# su - oracle
> cat >> ~oracle/.bash_profile << EOF
ulimit -n 63536

14.9 Displaying login banners

It is often necessary to place a banner on login screens on all servers for legal/audit policy reasons or to give security instructions to users.

If you want to print a login banner after a user logs in on a text based terminal, for example, using SSH or on a local console, you can use the file /etc/motd (motd = message of the day). The file exists by default on SUSE Linux Enterprise Server, but it is empty. Simply add content to the file that is applicable/required by the organization.

Note: Banner length

Try to keep the login banner content to a single terminal page (or less), as it will scroll the screen if it does not fit, making it more difficult to read.

You can also have a login banner printed before a user logs in on a text based terminal. For local console logins, you can edit the /etc/issue file, which will cause the banner to be displayed before the login prompt. For logins via SSH, you can edit the Banner parameter in the /etc/ssh/sshd_config file, which will then appropriately display the banner text before the SSH login prompt.

For graphical logins via GDM, you can follow the GNOME admin guide to set up a login banner. Furthermore, you can make the following changes to require a user to acknowledge the legal banner by selecting Yes or No. Edit the /etc/gdm/Xsession file and add the following lines at the beginning of the script:

if ! /usr/bin/gdialog --yesno '\nThis system is classified...\n' 10 10; then
    /usr/bin/gdialog --infobox 'Aborting login'
    exit 1;

The text This system is classified... needs to be replaced with the desired banner text. It is important to note that this dialog will not prevent a login from progressing. For more information about GDM scripting, refer to the GDM Admin Manual.

14.10 Connection accounting utilities

Here is a list of commands you can use to get data about user logins:

who Lists currently logged in users.

w Shows who is logged in and what they are doing.

last Shows a list of the most recent logged in users, including login time, logout time, login IP address, etc.

lastb Same as last, except that by default it shows /var/log/btmp, which contains all the bad login attempts.

lastlog This command reports data maintained in /var/log/lastlog, which is a record of the last time a user logged in.

ac Available after installing the acct package. Prints the connect time in hours on a per-user basis or daily basis, etc. This command reads /var/log/wtmp.

dump-utmp Converts raw data from /var/run/utmp or /var/log/wtmp into ASCII-parseable format.

Also check the /var/log/messages file, or the output of journalctl if no logging facility is running. See Chapter 21, journalctl: Query the systemd journal for more information on the systemd journal.