Jephe Wu - http://linuxtechres.blogspot.com
Objective: explain all kinds of ways for disablinig user shell access under Linux and their pros and cons
Environment: CentOS 6.4 64bit
Methods:
1. using /sbin/nologin or /bin/false
useradd jephe -s /sbin/nologin
or
chsh -s /sbin/nologin
pros: disable shell access
cons: doesn't disable SSH tcp port forwarding.
e.g. user can use ssh to server to enable port forwarding as follows without actual shell access:
ssh -N -L 2222:remote:22 server
2. password lock/unlock
passwd -l jephe and passwd -u jephe
usermod -L jephe and usermod -U jephe
Pros: disable shell access with using /etc/shadow password
cons: if user had configured public key authentication before you lock password, user can still ssh in.
related command: chage -d 0 # to make user password expire so that user have to change password immediately upon login, you can run 'chage -l user' to check.
chage -d 0 is different with chage -E0, chage -d 0, make password expire, to force user to change password after login, chage -E0, make account expire, totally disable user for the system.
3. make user account expire totally
chage -E0 jephe and reverse it by chage -E-1 jephe
Pros and cons: totally disable user account, user is unable to ssh anyway
If you need to totally disable user ssh, you should use this way.
[root@server1 ~]# chage -E0 corkroo
[root@server1 ~]# getent shadow corkroo
corkroo:$6$ewLIUEu8$VNk7OC2ybTHDaeXX1xuCI9DHGLig3IhasJ3VbLUwRMt123/kT1NAtshYuq2yQKZab82D1FEPZXnM3zTt5krKl0:15992:0:99999:7::0:
[root@server1 ~]# chage -E-1 corkroo
[root@server1 ~]# getent shadow corkroo
corkroo:$6$ewLIUEu8$VNk7OC2ybTHDaeXX1xuCI9DHGLig3IhasJ3VbLUwRMt123/kT1NAtshYuq2yQKZab82D1FEPZXnM3zTt5krKl0:15992:0:99999:7:::
4. force sftp access only, not ssh
User still have normal shell /bin/bash, but configure /etc/ssh/sshd_config to force user to use sftp only, not shell access
[root@server1 ~]# tail -7 /etc/ssh/sshd_config
Subsystem sftp internal-sftp
Match User corkroo
X11Forwarding no
AllowTcpForwarding no
ForceCommand internal-sftp
[root@server1 ~]# getent passwd corkroo
corkroo:x:504:505::/home/corkroo:/bin/bash
[root@server1 ~]# ssh corkroo@localhost
Password: # then it's hanging here.
How to disable user ssh login under Linux
Enable password age and complexity for production Linux servers for auditing
Jephe Wu - http://linuxtechres.blogspot.com
Objective: Enable password age and complexity for production Linux servers for auditing
Environment: CentOS 5
Steps:
1. modify /etc/login.defs
PASS_MAX_DAYS 60
PASS_MIN_DAYS 7 (days between password change)
PASS_MIN_LEN 8
PASS_WARN_AGE 28
2. make sure the following appears in /etc/default/useradd
INACTIVE=-1
EXPIRE=
note: this will disable password inactivity settings, INACTIVATE sets the number of days of inactivity after a password has expired before the account is locked. Normally, we don't set it by useradd or chage.
3. change the existing user password ages
chage -m 7 -M 60 -W 28 jephe
chage -m 7 -M 60 -W 28 user1
note: some other useful commands:
chage -l jephe
chage -d 0 jephe (to immediately make the password expire so that the user has to change password upon login next time,
chage -d -1 jephe (to make password not expired)
If you encounters the following issues after password expiry, you might need to change ssh configuration
UsePrivilegeSeparation from yes to no, seems openssh 3.8 and above has already fixed
this issue
$ ssh jephe@servername
jephe@servername's password:
You are required to change your password immediately (password aged)
Your password has expired, the session cannot proceed.
Connection to localhost closed.
passwd -l jephe (lock user)
passwd -u jephe (unlock user)
usermod -L jephe
usermod -U jephe
note: How do I force users to change their passwords upon the first login?
1.) Firstly, lock the account to prevent the user from using the login until the change has been made:
# usermod -L jephe# chage -d 0 jephe (make password expiry immediately) # usermod -U jephe (unlock user account)
or
According to Redhat knowledge base, you can directly push a encrypted password string to /etc/shadow.
run command 'python', the salt can be a combination of exactly 2 upper or lower case alphabetic characters, digits, the dot (.) character, or the slash (/) character such as cd or 34
import crypt; print crypt.crypt("password","salt")
The output is the encrypted password similar to
15CsBd8FAc9DN
- ctrl -d to exit python
usermod -p "15CsBd8FAc9DN" jephe
or you might set a empty password:usermod -p "" jephe
4. enable password complexity
make sure /etc/security/opasswd exists, otherwise, create it:
touch /etc/security/opasswd
chown root:root /etc/security/opasswd
chmod 600 /etc/security/opasswd
note: opasswd maintains a list of old passwords for every user prohibiting the reuse of old passwords. The list is located in the /etc/security/opasswd file. This is not a plain text file, but should be protected the same as the /etc/shadow file. This is normally referred to as password history.
vi /etc/pam.d/system-auth to make it looks like this:
password requisite pam_cracklib.so try_first_pass retry=3 minlen=8 lcredit=-1 ucredit=-1 dcredit=-1 ocredit=-1 difok=3
password sufficient pam_unix.so md5 shadow nullok try_first_pass use_authtok remember=6
note: minimum 8 characters, 1 lowercase, 1 upper case, 1 number, 1 special character, the new password must have 3 characters which are different with the previous one, remember the last 6 passwords which cannot be used for new password.
According to my test, you have to use lcredit=-1 ucredit=-1 dcredit=-1 ocredit=-1, not lcredit=1 ucredit=1 dcredit=1 ocredit=1, otherwise, it doesn't actually enforce that which mentioned above.
5. References
a. Securing and Hardening Red Hat Linux Production Systems- http://www.puschitz.com/SecuringLinux.shtml
b. Linux Password Policy - http://www.brandonhutchinson.com/wiki/Linux_Password_Policy
c. redhat acknowledge base - doc7382