0
0
Fork 0
mirror of https://github.com/atmoz/sftp.git synced 2024-11-17 12:51:33 -05:00

Add users from STDIN or config file

This commit is contained in:
Adrian Dvergsdal 2015-12-07 10:10:24 +01:00
parent bd37434f5c
commit 8d310f3af0
3 changed files with 87 additions and 24 deletions

View file

@ -6,8 +6,8 @@ Easy to use SFTP ([SSH File Transfer Protocol](https://en.wikipedia.org/wiki/SSH
Usage Usage
----- -----
- Define users as last arguments to `docker run`, one user per argument - Define users as command arguments, STDIN or mounted in /etc/sftp-users.conf
(syntax: `user:pass[:e][:[uid][:gid]]`). (syntax: `user:pass[:e][:uid[:gid]]...`).
- You must set custom UID for your users if you want them to make changes to - You must set custom UID for your users if you want them to make changes to
your mounted volumes with permissions matching your host filesystem. your mounted volumes with permissions matching your host filesystem.
- Mount volumes in user's home folder. - Mount volumes in user's home folder.
@ -18,7 +18,7 @@ Usage
Examples Examples
-------- --------
### Single user and volume ### Simple example
``` ```
docker run \ docker run \
@ -45,16 +45,22 @@ The OpenSSH server runs by default on port 22, and in this example, we are
forwarding the container's port 22 to the host's port 2222. To log in with an forwarding the container's port 22 to the host's port 2222. To log in with an
OpenSSH client, run: `sftp -P 2222 foo@<host-ip>` OpenSSH client, run: `sftp -P 2222 foo@<host-ip>`
### Multiple users and volumes ### Store users in config
/host/users.conf:
```
foo:123:1001
bar:abc:1002
```
``` ```
docker run \ docker run \
-v /host/users.conf:/etc/sftp-users.conf:ro \
-v /host/share:/home/foo/share \ -v /host/share:/home/foo/share \
-v /host/documents:/home/foo/documents \ -v /host/documents:/home/foo/documents \
-v /host/http:/home/bar/http \ -v /host/http:/home/bar/http \
-p 2222:22 -d atmoz/sftp \ -p 2222:22 -d atmoz/sftp
foo:123:1001 \
bar:abc:1002
``` ```
### Encrypted password ### Encrypted password
@ -69,7 +75,7 @@ docker run \
``` ```
Tip: you can use makepasswd to generate encrypted passwords: Tip: you can use makepasswd to generate encrypted passwords:
`echo -n 123 | makepasswd --crypt-md5 --clearfrom -` `echo -n "password" | makepasswd --crypt-md5 --clearfrom -`
### Using SSH key (without password) ### Using SSH key (without password)

View file

@ -1,12 +1,17 @@
#!/bin/bash #!/bin/bash
userConfPath="/etc/sftp-users.conf"
userConfFinalPath="/var/run/sftp-users.conf"
function printHelp() { function printHelp() {
echo "Syntax: user:pass[:e][:[uid][:gid]]..." echo "Add users as command arguments, STDIN or mounted in $userConfPath"
echo "Use --readme for information and examples." echo "Syntax: user:pass[:e][:uid[:gid]]..."
echo "Use --readme for more information and examples."
} }
function printReadme() { function printReadme() {
cat /README.md cat /README.md
echo "TIP: Read this in HTML format here: https://github.com/atmoz/sftp"
} }
function createUser() { function createUser() {
@ -14,8 +19,8 @@ function createUser() {
user="${param[0]}" user="${param[0]}"
pass="${param[1]}" pass="${param[1]}"
if [ -z "$user" -o -z "$pass" ]; then if [ -z "$user" ]; then
echo "You must at least provide a username and a password." echo "You must at least provide a username."
printHelp printHelp
exit 1 exit 1
fi fi
@ -29,7 +34,7 @@ function createUser() {
gid="${param[3]}" gid="${param[3]}"
fi fi
useraddOptions="--create-home --no-user-group" useraddOptions="--no-user-group"
if [ -n "$uid" ]; then if [ -n "$uid" ]; then
useraddOptions="$useraddOptions --non-unique --uid $uid" useraddOptions="$useraddOptions --non-unique --uid $uid"
@ -37,7 +42,10 @@ function createUser() {
if [ -n "$gid" ]; then if [ -n "$gid" ]; then
useraddOptions="$useraddOptions --gid $gid" useraddOptions="$useraddOptions --gid $gid"
groupadd --gid $gid $gid
if [ "$(cat /etc/group | cut -d : -f3 | grep -q "$gid")" ]; then
groupadd --gid $gid $gid
fi
fi fi
useradd $useraddOptions $user useradd $useraddOptions $user
@ -56,7 +64,7 @@ function createUser() {
chmod 600 /home/$user/.ssh/authorized_keys chmod 600 /home/$user/.ssh/authorized_keys
} }
if [[ -z $1 || $1 =~ ^--help$|^-h$ ]]; then if [[ $1 =~ ^--help$|^-h$ ]]; then
printHelp printHelp
exit 0 exit 0
fi fi
@ -66,8 +74,30 @@ if [ "$1" == "--readme" ]; then
exit 0 exit 0
fi fi
# Append mounted config to final config
if [ -f "$userConfPath" ]; then
cat "$userConfPath" >> "$userConfFinalPath"
fi
# Append users from arguments to final config
for user in "$@"; do for user in "$@"; do
createUser $user echo "$user" >> "$userConfFinalPath"
done done
# Append users from STDIN to final config
while IFS= read -r user || [[ -n "$user" ]]; do
echo "$user" >> "$userConfFinalPath"
done
if [ ! -f "$userConfFinalPath" ]; then
echo "ERROR: Missing users!"
printHelp
exit 1
fi
# Import users from final conf file
while IFS= read -r user || [[ -n "$user" ]]; do
createUser "$user";
done < "$userConfFinalPath"
exec /usr/sbin/sshd -D exec /usr/sbin/sshd -D

View file

@ -6,9 +6,19 @@ buildDir="$scriptDir/.."
tmpDir="/tmp/atmoz_sftp_test" tmpDir="/tmp/atmoz_sftp_test"
build=${1:-"build"} build=${1:-"build"}
output=${2:-"quiet"}
cleanup=${3:-"cleanup"}
sftpImageName="atmoz/sftp_test" sftpImageName="atmoz/sftp_test"
sftpContainerName="atmoz_sftp_test" sftpContainerName="atmoz_sftp_test"
if [ "$output" == "quiet" ]; then
redirect="/dev/null"
else
redirect=$'&1'
fi
##############################################################################
function beforeTest() { function beforeTest() {
if [ "$build" == "build" ]; then if [ "$build" == "build" ]; then
docker build --pull=true --tag "$sftpImageName" "$buildDir" docker build --pull=true --tag "$sftpImageName" "$buildDir"
@ -20,20 +30,27 @@ function beforeTest() {
rm -rf "$tmpDir" # clean state rm -rf "$tmpDir" # clean state
mkdir "$tmpDir" mkdir "$tmpDir"
echo "test::$(id -u):$(id -g)" >> "$tmpDir/users"
docker run \ docker run \
-v "$tmpDir/users:/etc/sftp-users.conf:ro" \
-v "$scriptDir/id_rsa.pub":/home/test/.ssh/keys/id_rsa.pub:ro \ -v "$scriptDir/id_rsa.pub":/home/test/.ssh/keys/id_rsa.pub:ro \
-v "$tmpDir":/home/test/share \ -v "$tmpDir":/home/test/share \
--name "$sftpContainerName" \ --name "$sftpContainerName" \
--expose 22 \ --expose 22 \
-d "$sftpImageName" \ -d "$sftpImageName" \
test:123:$(id -u):$(id -g) \ > "$redirect"
> /dev/null
sleep 1 # wait for sftp server to get ready sleep 1 # wait for sftp server to get ready
} }
function afterTest() { function afterTest() {
docker rm -fv "$sftpContainerName" > /dev/null if [ "$output" != "quiet" ]; then
rm -rf "$tmpDir" docker logs "$sftpContainerName"
fi
if [ "$cleanup" == "cleanup" ]; then
docker rm -fv "$sftpContainerName" > "$redirect"
rm -rf "$tmpDir"
fi
} }
function getSftpIp() { function getSftpIp() {
@ -42,14 +59,22 @@ function getSftpIp() {
function runSftpCommands() { function runSftpCommands() {
ip="$(getSftpIp)" ip="$(getSftpIp)"
echo "$@" | sftp \
commands=""
for cmd in "$@"; do
commands="$commands$cmd"$'\n'
done
echo "$commands" | sftp \
-i "$scriptDir/id_rsa" \ -i "$scriptDir/id_rsa" \
-oStrictHostKeyChecking=no \ -oStrictHostKeyChecking=no \
-oUserKnownHostsFile=/dev/null \ -oUserKnownHostsFile=/dev/null \
-b - test@$ip \ -b - test@$ip \
> /dev/null 2>&1 > "$redirect" 2>&1
} }
##############################################################################
function testContainerIsRunning() { function testContainerIsRunning() {
ps="$(docker ps -q -f name="$sftpContainerName")" ps="$(docker ps -q -f name="$sftpContainerName")"
assertNotEqual "$ps" "" assertNotEqual "$ps" ""
@ -61,11 +86,13 @@ function testLoginUsingSshKey() {
} }
function testWritePermission() { function testWritePermission() {
runSftpCommands $'cd share\nmkdir test' runSftpCommands "cd share" "mkdir test" "exit"
test -d "$tmpDir/test" test -d "$tmpDir/test"
assertReturn $? 0 assertReturn $? 0
} }
##############################################################################
# Run tests # Run tests
source "$scriptDir/bashunit.bash" source "$scriptDir/bashunit.bash"
# Nothing happens after this # Nothing happens after this