So I decided to give this idea an overhaul after I was asked to find a way to create these accounts from PHP in the web server
I definitely would not go as far to say that I regard myself as a programmer, so there are probably things I’ve done in the script below that would make a veteran programmer cringe, but this is a massive improvement from the way it was as well as it really only being designed for my own usage.
The other new main requirement is that Apache can write to the new user’s SFTP directory so they can upload data, and get reporting on their services.
Because of security concerns it was decided that it wouldn’t be wise to allow a PHP script to be executing shell commands from the web server as root no matter how we went about it so the idea for the changes here are in relation to the next version creating a cron job to run the shell commands independently.
So the idea here is that there is a PHP script that when required will generate a simple file with the new username and password, and there will be a cron job running every few minutes looking for that file.
If there is the request to add a public key, this will search for it and add it as well.
It also generates an output file which contains the information for the new account, along with the bottom 5 lines of /var/log/secure to confirm that the permissions were applied correctly.
As said in previous post on the matter you must have your sshd_config setup as so:
Prerequisites:
OpenSSH 5 (I had to upgrade OpenSSH manually because CentOS 5 natively supports a previous version that wouldn’t suffice for this purpose).
…if by chance you need to do the same on CentOS or another RPM distro that has the same limitation, follow the installation instructions in this guide:
Installing OpenSSH 5 in CentOS 5
Add group SFTP:
In the script below I added, but haven’t yet tested a few lines which checks to see if group exists and creates it but it’s not enabled by default. Otherwise simply run this command.
# groupadd sftponly
Configuring:
Locate your sshd_config file and open with your desired text editor.
Locate out the following line and comment out with a # if not already done so:
# Subsystem sftp /usr/libexec/openssh/sftp-server
Scroll down and append the following to the end:
Subsystem sftp internal-sftp
Match Group sftponly
ChrootDirectory /home/%u
ForceCommand internal-sftp
AllowTcpForwarding no
The script:
Change the paths for lusername, pubkey & output file
#!/bin/bash
## Creates user and necessary SFTP directory permissions
## Refined Version 16th June 2014 --Chris. Tested CentOS 5+6
## Change file paths edit in getPaths function to suit:
## *lusername:
## *pubkey:
## *outputFilePath:
## Note: Pre-Configuration for group sftponly in sshd_config
## for SFTP is necessary.
isRoot() {
# Check if the current user is root or not !
if [ $EUID = 0 ]; then
return 0
else
return 1
fi
}
getPaths() {
lusername="/var/www/html/newsftp"
outputFilePath="/home/admin/"
pubkey="/var/www/html/newsftpkey"
hostName=$(hostname)
}
findUsername() {
##path to user data file in format <username> <password>
findUserPass=$(find $lusername)
if [[ $findUserPass == $lusername ]]
then
echo "found username file"
else
echo "no username file match" && exit
fi
}
checkSFTPonly() {
mksftpGrp=$(cat /etc/group | grep sftponly | sed s/:/" "/g | awk '{print $1}')
mksftpTrue=$(echo "sftponly")
if [[ $mksftpGrp == $mksftpTrue ]]; then
echo "group exists!"; else
echo "group doesn't exist!"; /usr/sbin/groupadd sftponly;
echo "group sftponly created"; fi
}
outputKeys() {
outputFile="$outputFilePath"/"$user"_sftp
echo "Your SFTP account details are: " >> $outputFile
echo "Username: "$user"" >> $outputFile
echo "Password: "$pass"" >> $outputFile
echo "Directory for files: /sftp" >> $outputFile
echo "Port: 222" >> $outputFile
echo "Example: sftp -oPort=222 "$user"@"$hostName":/sftp" >> $outputFile
echo "Looking for public key in path "$pubkey""
##If pubkey is found at path it adds to .ssh/authorized_keys
findPubkey=$(find "$pubkey")
if [[ $findPubkey == $pubkey ]]
then
echo "pubkey found - adding to authorized_keys..";
cat $pubkey >> "/home/"$user"/.ssh/authorized_keys";
else
echo "pubkey not found - you will have to add manually" | tee -a $outputFile; exit
fi
##Adds lines spacing to Account Info Output
echo -e "Public key added to authorized_keys: " >> $outputFile;
sed -i '0~1 a\ ' $outputFile;
echo -e "$pub \n" >> $outputFile;
echo -e "Log output to confirm\debug: \n"
##Copies Secure Log output lines CentOS\RHEL only!
tail -5 /var/log/secure | tee -a $outputFile;
echo -e "\n Account info can be found at $outputFile";
mv $lusername /home/admin/sftp_"$user"
mv $pubkey /home/admin/"$user"_key
}
assignUserPass() {
pub=$(cat $pubkey)
echo $pub
##Get user and pass variables
getUserPass=$(cat "$lusername")
user=$(echo $getUserPass | awk '{ print $1 }')
pass=$(echo $getUserPass | awk '{ print $2 }')
echo $user $pass
##Add user
echo "creating account for "$user"..."
/usr/sbin/useradd -m "$user" -p "$pass"
##Add to group 'sftponly'
/usr/sbin/usermod -G sftponly $user
##Strip account of shell priv.
/usr/sbin/usermod -s /bin/false $user
##Change owner ~/ directory to root
chown root:root /home/$user
##Jail the user folder
chmod 755 /home/$user/
chmod 755 /home/$user
##Create directory for file transfers
mkdir /home/$user/sftp
echo "/home/"$user"/sftp directory created"
##Give user ownership sftponly group ownership
chown $user:sftponly /home/$user/sftp
##Allow sftponly group to write and enable Apache to write to directory
/usr/sbin/usermod -aG apache sftponly
chmod g+w /home/$user/sftp
##Make and lock down .ssh directory & authorised keys file
mkdir /home/$user/.ssh/
touch /home/$user/.ssh/authorized_keys
chown $user:$user /home/$user/.ssh
chmod 700 /home/$user/.ssh/
chmod 700 /home/$user/.ssh
chown $user:$user /home/$user/.ssh/authorized_keys
chmod 600 /home/$user/.ssh/authorized_keys
}
if [ isRoot = 0 ];
then
echo "Not root. Exiting.." && exit
else
getPaths;findUsername;checkSFTPonly;assignUserPass;outputKeys
fi