How to replicate user passwords across hosts
Today I received an interesting requirement. A customer wanted their FTP users on several new servers (having the same username) to have the same password as that of the users on an older server. The problem was that they did not actually know the passwords of the users on the old servers. Also, the process had to be largely automated because it needed to be repeated on multiple machines. So, after some research, I was able to come up with a solution. The solution to this problem was to use the user entries from the /etc/shadow file. How to replicate user passwords across hosts Linux.
Before we delve into the details of how the /etc/shadow file entries for some users could allow us to replicate their passwords across several machines, let’s first understand the different fields of the /etc/shadow file.
The /etc/shadow file is a text file and has permissions set to 400 i.e. -r——– and its ownership is set to root:root.
This implies that it can be read by the root user only and is implemented as a needed security mechanism.
Let’s view an entry from the file
[root@arkit-redhat ~]# grep sahil /etc/shadow sahil:$6$ufcRl1.z$HC2JFSgFZkFiprGQ/dzWIH9NcxmF.WqldAbbmy.ra4/uoAOdST.NhRZp/BKalt0JEOEdXSJj48uGJxnImuyRo0:17517:0:99999:7:::
As you might’ve observed the /etc/shadow file uses the colon (:) as a delimiter to separate different fields.
This is similar to the /etc/passwd file.
The /etc/shadow has 8 different fields which are as follows
Shadow file Columns
Username
Username is user’s login name. Its created on system whenever a user is created using useradd command.
Encrypted password
Its user’s password in encrypted format.
Last password change
Its number of days since 1 Jan 1970, that password was last changed.
Min days
Its minimum number of days between two password changes of that account.
That means the user can not change his password again unless min days have passed since his last password change.
This field can be tweaked using chage command. This is set to 7 days generally but can be 1 too depends on your organization security norms.
Max days
Its maximum number of days for which user password is valid.
Once this period exhausted, the user is forced to change his/her password.
This value can be altered using chage command. It is generally set to 30 days but value differs as per your security demands.
Warn days
Its number of days before password expiry, the user will start seeing a warning about his password expiration after login.
Generally, it is set to 7 but it is up to you or your organization to decide this value as per organizational security policies.
Inactive days
The number of days after password expiry, the account will be disabled. Means if a user doesn’t log in to the system after his/her password expiry (so he doesn’t change the password) then after these many days account will be disabled. Once the account is disabled system admin needs to unlock it.
Expiry
This is the number of days since 1 Jan 1970, the account has been disabled.
For our particular requirement, we need the first two fields only. The remaining fields are related to password aging as we have already described.
The trick is that if we replace the encrypted password entry for a user in the 2nd field of the /etc/shadow file on one machine with an encrypted password entry from the /etc/shadow file on another machine, we are effectively modifying the password of the user and setting it to the password indicated by the encrypted password field in the /etc/shadow file. So, I did not need to know the passwords of all the FTP users in the source server. I just needed their /etc/shadow file entries.
Now I will describe the steps I followed to complete my task of replicating the passwords
Step 1: How to replicate user passwords across hosts
I compiled a list of the required user names whose password had to be updated in a file.
Step 2
Next, I extracted the username and the encrypted password entry from the /etc/shadow file on the source server. For this, I used the below one-liner for loop
for i in `cat user_list`; do sudo grep -w $i /etc/shadow |awk -F: '{OFS=":"} {print $1,$2}' ; done >> user_shadow_entry
This extracts the first and second fields i.e. the username and encrypted password entry for the required users and stores them in a file.
Step 3
For the final step, I created the below short script that would replace the /etc/shadow file entires on the destination server with the entry that I obtained from the output file in the previous step.
#!/bin/bash ############################################################## #Author: Sahil Suri #Date: 08/01/2018 #Purpose: Replace /etc/shadow entry for a user #version: v1.0 ############################################################## IFS=: cat user_shadow_entry | while read USER NEW_SHADOW_ENTRY do OLD_SHADOW_ENTRY=$(grep ${USER} /etc/shadow | awk -F: '{print $2}') sed -i "s~$OLD_SHADOW_ENTRY~$NEW_SHADOW_ENTRY~" /etc/shadow | grep ${USER} done
I then executed this script across the servers that I needed to and that was it.
Let’s describe the working of the script now:
- We first changed the value of the input field separator variable IFS to :.Its default value is generally whitespace and new line.
It’s value needed to be changed for the while loop that followed to work because the entries in the user_shadow_entry file were separated by a colon (:). - To allow the while loop to treat the username and the encrypted password entry as distinct inputs, the value of IFS had to be set to :.
- Next, we search for the username in the /etc/shadow file on the destination machine and extract the 2nd field i.e. the encrypted password entry and store it in a variable.
- Finally, we have a sed command which searches for the original encrypted password entry in the /etc/shadow file and replaces it with the encrypted password entry for the corresponding user entry in the current iteration of the loop. For those familiar with sed may wonder why we’ve not used the default syntax with the sed command. The reason for this is that the encrypted password entries contain many special characters and to effectively escape them we had to use the non-default syntax.
Conclusion
In this article, we described the different fields of the /etc/shadow file and we showed you how to use entries for users in this file to replicate the passwords for users when you actually do not know what the passwords are. We hope that you’ve found this article interesting and helpful and we look forward towards your feedback and suggestions.
Related Articles
Add user to Linux without using useradd command
Create Multiple Users using single command
Thanks for your wonderful Support and Encouragement