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:
parent
bd37434f5c
commit
8d310f3af0
3 changed files with 87 additions and 24 deletions
24
README.md
24
README.md
|
@ -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
|
||||
|
@ -68,8 +74,8 @@ docker run \
|
|||
'foo:$1$0G2g0GSt$ewU0t6GXG15.0hWoOX8X9.:e:1001'
|
||||
```
|
||||
|
||||
Tip: you can use makepasswd to generate encrypted passwords:
|
||||
`echo -n 123 | makepasswd --crypt-md5 --clearfrom -`
|
||||
Tip: you can use makepasswd to generate encrypted passwords:
|
||||
`echo -n "password" | makepasswd --crypt-md5 --clearfrom -`
|
||||
|
||||
### Using SSH key (without password)
|
||||
|
||||
|
|
46
entrypoint
46
entrypoint
|
@ -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
|
||||
|
|
41
tests/run
41
tests/run
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue