0
0
Fork 0
mirror of https://github.com/atmoz/sftp.git synced 2024-11-24 12:59:24 -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
-----
- Define users as last arguments to `docker run`, one user per argument
(syntax: `user:pass[:e][:[uid][:gid]]`).
- Define users as command arguments, STDIN or mounted in /etc/sftp-users.conf
(syntax: `user:pass[:e][:uid[:gid]]...`).
- 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.
- Mount volumes in user's home folder.
@ -18,7 +18,7 @@ Usage
Examples
--------
### Single user and volume
### Simple example
```
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
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 \
-v /host/users.conf:/etc/sftp-users.conf:ro \
-v /host/share:/home/foo/share \
-v /host/documents:/home/foo/documents \
-v /host/http:/home/bar/http \
-p 2222:22 -d atmoz/sftp \
foo:123:1001 \
bar:abc:1002
-p 2222:22 -d atmoz/sftp
```
### Encrypted password
@ -69,7 +75,7 @@ docker run \
```
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)

View file

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

View file

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