Create-user bash script
Overview
You can create SFTP users in the web admin portal. But if you need to create many users at once, it might be easier and less error-prone to script this process.
This article goes over how to create an SFTP user via the command line. This involves creating a bash script using the code in this article.
IMPORTANT: If you're on version 3.5.0 or newer of SFTP Gateway, make sure to edit the script on line 119
so the endpoint for generating the OAuth token is set to http://127.0.0.1:8080/login
NOT http://127.0.0.1:8080/oauth/token
.
Install dependencies
The create-user script relies on jq
, which is a command line utility for working with json objects.
SSH into the VM and run the following commands to install this:
sudo su
snap install jq
Create the script
In this section, you will create the bash script.
Paste in the following commands:
cd /usr/local/bin
wget https://thorntech-products.s3.amazonaws.com/sftpgateway/create-user-script/create-user.sh
chmod +x create-user.sh
These commands get the create-user.sh
script, and make it executable.
Create a credentials file
The create-user script uses the credentials of your web admin portal user. So you will need to save these credentials in a text file.
First, create a credentials file:
cd /usr/local/bin/
touch credentials.txt
nano credentials.txt
Paste the following properties into the file:
admin.username=
admin.password=
Make sure you populate these values with your web admin credentials. For example:
admin.username=robadmin
admin.password=password
Usage
Run the script to create an SFTP user with a password:
create-user.sh -f credentials.txt -u user -p password
Note: Replace user
and password
with the credentials of your SFTP user.
You can create users with an SSH public key:
create-user.sh -f credentials.txt -u user1 -k "ssh-rsa AAAAB3NzaC1"
The script also supports multiple SSH public keys. Just use the -k
flag for each public key you want to add:
create-user.sh -f credentials.txt -u user1 \
-k "ssh-rsa AAAAB3NzaC1" \
-k "ssh-rsa AAAAB3NzaC2"
Video Reference
Home directory
The script creates an SFTP user that points to their default Home Folder location. For example:
/users/robtest
The user creation process attempts to create this Home Folder location.
Note: If this Folder already exists, the user creation process will fail.
Troubleshooting
When you run the script, you will see the following output when successful:
{"createdDate":"2022-09-29T17:50:57.238372Z","credentialsExpired":false,"enabled":true...}
This section covers a few common error scenarios.
- Make sure you are using
sudo
, or running as root. - Make sure you include the
-u
or--username
parameter, which is required - You must specify either a password or SSH key
- Make sure your credential file exists and contains working values
- When creating an SFTP user with a password, make sure the password meets complexity requirements
- Make sure the SFTP user doesn't already exist
- Make sure the default Home Folder for this username doesn't already exist
Script contents
Here are the contents of the create-user.sh
file:
#!/bin/bash
PUBLIC_KEY_ARRAY=()
while [[ $# -gt 0 ]]; do
key="$1"
case $key in
-u|--username)
SFTP_USERNAME="$2"
shift
shift
;;
-p|--password)
SFTP_PASSWORD="$2"
shift
shift
;;
-k|--pubkey)
PUBLIC_KEY_ARRAY+=("$2")
shift
shift
;;
-f|--file)
CREDENTIAL_FILE="$2"
shift
shift
;;
*)
break
;;
esac
done
USAGE_FLAG=false
function generaterandomstring {
head /dev/urandom | tr -dc a-zA-Z0-9 | head -c ${1} ; echo ''
}
function usage {
echo "Usage when setting a password: sudo $0 -f credential.txt -u sftpuser -p $(generaterandomstring 15)"
echo "Usage when setting public key: sudo $0 -f credential.txt -u sftpuser -k \"ssh-rsa AAAAB3NzaC1\" -k \"ssh-rsa AAAAB3NzaC2\""
echo ""
exit 1
}
if [[ `whoami` != "root" ]]; then
echo ""
echo "Please run this script using sudo or as root."
USAGE_FLAG=true
fi
if [[ -z $SFTP_USERNAME ]]; then
echo ""
echo "Please provide a username."
USAGE_FLAG=true
fi
if [[ -z $SFTP_PASSWORD ]] && [[ -z $PUBLIC_KEY_ARRAY ]]; then
echo ""
echo "Please provide either a password or public key(s)."
USAGE_FLAG=true
fi
function credential-file-usage {
echo ""
echo "Please provide a path to a valid credential file, which contains the following contents:"
echo ""
echo "admin.username=admin"
echo "admin.password=$(generaterandomstring 15)"
}
function extractPropValueFromSourceFile {
local prefix="${1}"
local str=`grep "${prefix}" ${2} 2>/dev/null`
echo "${str#$prefix}" | xargs
}
if [[ -f $CREDENTIAL_FILE ]]; then
ADMIN_USERNAME=$(extractPropValueFromSourceFile admin.username= $CREDENTIAL_FILE)
ADMIN_PASSWORD=$(extractPropValueFromSourceFile admin.password= $CREDENTIAL_FILE)
fi
if [[ ! -f $CREDENTIAL_FILE ]]; then
credential-file-usage
USAGE_FLAG=true
elif [[ -z $ADMIN_USERNAME ]] || [[ -z $ADMIN_PASSWORD ]]; then
credential-file-usage
USAGE_FLAG=true
fi
if [[ $USAGE_FLAG = true ]]; then
echo ""
usage
fi
APPLICATION_PROPERTIES=/opt/sftpgw/application.properties
CLIENT_ID=$(extractPropValueFromSourceFile "security.client-id=" ${APPLICATION_PROPERTIES})
CLIENT_SECRET=$(extractPropValueFromSourceFile "security.client-secret=" ${APPLICATION_PROPERTIES})
CURRENT_JSON=$(jq -n --arg SFTP_USERNAME "${SFTP_USERNAME}" '{username: $SFTP_USERNAME}')
if [[ -n ${SFTP_PASSWORD} ]]; then
CURRENT_JSON=$(echo $CURRENT_JSON | jq --arg SFTP_PASSWORD "${SFTP_PASSWORD}" '.password |= $SFTP_PASSWORD')
fi
function generaterandomnumber {
head /dev/urandom | tr -dc 0-9 | head -c ${1} ; echo ''
}
for PUBLIC_KEY in "${PUBLIC_KEY_ARRAY[@]}"; do
RANDOM_STRING="$(generaterandomnumber 9)"
KEY_NAME="key-${RANDOM_STRING}"
CURRENT_JSON=$(echo $CURRENT_JSON | jq --arg KEY_NAME "${KEY_NAME}" --arg PUBLIC_KEY "${PUBLIC_KEY}" '.publicKeys += [{"name": $KEY_NAME, "value": $PUBLIC_KEY}]')
done
#echo $CURRENT_JSON
RESPONSE=$(curl --location --request POST 'http://127.0.0.1:8080/oauth/token' -u ${CLIENT_ID}:${CLIENT_SECRET} --form 'grant_type="password"' --form "username=\"${ADMIN_USERNAME}\"" --form "password=\"${ADMIN_PASSWORD}\"" --form 'scope="read"' --silent)
ACCESS_TOKEN=$(echo $RESPONSE | python3 -c "import sys, json; print(json.load(sys.stdin)['access_token'])")
#echo "ACCESS_TOKEN: $ACCESS_TOKEN"
curl -s --insecure --location --request POST 'https://127.0.0.1:443/backend/3.0.0/users' --header 'Content-Type: application/json' --header "Authorization: Bearer ${ACCESS_TOKEN}" --data-raw "$CURRENT_JSON"
echo ""