0
0
Fork 0
mirror of https://github.com/atmoz/sftp.git synced 2025-03-09 15:16:00 -04:00

Merge branch 'master' into alpine-3.5

This commit is contained in:
Adrian Dvergsdal 2017-06-25 16:38:35 +02:00
commit 5009551bd7
3 changed files with 88 additions and 14 deletions

View file

@ -12,7 +12,7 @@ This is an automated build linked with the [debian](https://hub.docker.com/_/deb
# Usage # Usage
- Required: define users as command arguments, STDIN or mounted in `/etc/sftp-users.conf` - Required: define users as command arguments, STDIN or mounted in `/etc/sftp/users.conf`
(syntax: `user:pass[:e][:uid[:gid[:dir1[,dir2]...]]]...`). (syntax: `user:pass[:e][:uid[:gid[:dir1[,dir2]...]]]...`).
- Set UID/GID manually for your users if you want them to make changes to - Set UID/GID manually 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.
@ -74,7 +74,7 @@ OpenSSH client, run: `sftp -P 2222 foo@<host-ip>`
``` ```
docker run \ docker run \
-v /host/users.conf:/etc/sftp-users.conf:ro \ -v /host/users.conf:/etc/sftp/users.conf:ro \
-v mySftpVolume:/home \ -v mySftpVolume:/home \
-v /host/ssh_host_rsa_key:/etc/ssh/ssh_host_rsa_key \ -v /host/ssh_host_rsa_key:/etc/ssh/ssh_host_rsa_key \
-v /host/ssh_host_rsa_key.pub:/etc/ssh/ssh_host_rsa_key.pub \ -v /host/ssh_host_rsa_key.pub:/etc/ssh/ssh_host_rsa_key.pub \
@ -103,10 +103,13 @@ docker run \
Tip: you can use [atmoz/makepasswd](https://hub.docker.com/r/atmoz/makepasswd/) to generate encrypted passwords: Tip: you can use [atmoz/makepasswd](https://hub.docker.com/r/atmoz/makepasswd/) to generate encrypted passwords:
`echo -n "your-password" | docker run -i --rm atmoz/makepasswd --crypt-md5 --clearfrom=-` `echo -n "your-password" | docker run -i --rm atmoz/makepasswd --crypt-md5 --clearfrom=-`
## Using SSH key (and no password) ## Logging in with SSH keys
Mount all public keys in the user's `.ssh/keys/` directory. All keys are automatically Mount public keys in the user's `.ssh/keys/` directory. All keys are
appended to `.ssh/authorized_keys`. automatically appended to `.ssh/authorized_keys` (you can't mount this file
directly, because OpenSSH requires limited file permissions). In this example,
we do not provide any password, so the user `foo` can only login with his SSH
key.
``` ```
docker run \ docker run \
@ -117,6 +120,28 @@ docker run \
foo::1001 foo::1001
``` ```
## Providing your own SSH host key
This container will generate new SSH host keys at first run. To avoid that your
users get a MITM warning when you recreate your container (and the host keys
changes), you can mount your own host keys.
```
docker run \
-v /host/ssh_host_ed25519_key:/etc/ssh/ssh_host_ed25519_key \
-v /host/ssh_host_rsa_key:/etc/ssh/ssh_host_rsa_key \
-v /host/share:/home/foo/share \
-p 2222:22 -d atmoz/sftp \
foo::1001
```
Tip: you can generate your keys with these commands:
```
ssh-keygen -t ed25519 -f /host/ssh_host_ed25519_key < /dev/null
ssh-keygen -t rsa -b 4096 -f /etc/ssh/ssh_host_rsa_key < /dev/null
```
## Execute custom scripts or applications ## Execute custom scripts or applications
Put your programs in `/etc/sftp.d/` and it will automatically run when the container starts. Put your programs in `/etc/sftp.d/` and it will automatically run when the container starts.

View file

@ -2,8 +2,9 @@
set -e set -e
export DEBIAN_FRONTEND=noninteractive export DEBIAN_FRONTEND=noninteractive
userConfPath="/etc/sftp-users.conf" userConfPath="/etc/sftp/users.conf"
userConfFinalPath="/var/run/sftp-users.conf" userConfPathLegacy="/etc/sftp-users.conf"
userConfFinalPath="/var/run/sftp/users.conf"
function printHelp() { function printHelp() {
echo "Add users as command arguments, STDIN or mounted in $userConfPath" echo "Add users as command arguments, STDIN or mounted in $userConfPath"
@ -61,6 +62,10 @@ function createUser() {
chown root:root /home/$user chown root:root /home/$user
chmod 755 /home/$user chmod 755 /home/$user
# Retrieving user id to use it in chown commands instead of the user name
# to avoid problems on alpine when the user name contains a '.'
uid=`id $user -u`
if [ -n "$pass" ]; then if [ -n "$pass" ]; then
echo "$user:$pass" | chpasswd $chpasswdOptions echo "$user:$pass" | chpasswd $chpasswdOptions
else else
@ -70,7 +75,7 @@ function createUser() {
# Add SSH keys to authorized_keys with valid permissions # Add SSH keys to authorized_keys with valid permissions
if [ -d /home/$user/.ssh/keys ]; then if [ -d /home/$user/.ssh/keys ]; then
cat /home/$user/.ssh/keys/* >> /home/$user/.ssh/authorized_keys cat /home/$user/.ssh/keys/* >> /home/$user/.ssh/authorized_keys
chown $user /home/$user/.ssh/authorized_keys chown $uid /home/$user/.ssh/authorized_keys
chmod 600 /home/$user/.ssh/authorized_keys chmod 600 /home/$user/.ssh/authorized_keys
fi fi
@ -81,7 +86,7 @@ function createUser() {
dirPath=/home/$user/$dirPath dirPath=/home/$user/$dirPath
echo "Creating and/or setting permissions on $dirPath" echo "Creating and/or setting permissions on $dirPath"
mkdir -p $dirPath mkdir -p $dirPath
chown -R $user:users $dirPath chown -R $uid:users $dirPath
done done
fi fi
} }
@ -96,8 +101,15 @@ if [ "$1" == "--readme" ]; then
exit 0 exit 0
fi fi
# Backward compatibility with legacy config path
if [ ! -f "$userConfPath" -a -f "$userConfPathLegacy" ]; then
mkdir -p "$(dirname $userConfPath)"
ln -s "$userConfPathLegacy" "$userConfPath"
fi
# Create users only on first run # Create users only on first run
if [ ! -f "$userConfFinalPath" ]; then if [ ! -f "$userConfFinalPath" ]; then
mkdir -p "$(dirname $userConfFinalPath)"
# Append mounted config to final config # Append mounted config to final config
if [ -f "$userConfPath" ]; then if [ -f "$userConfPath" ]; then

View file

@ -44,9 +44,11 @@ function beforeTest() {
mkdir "$tmpDir" mkdir "$tmpDir"
echo "test::$(id -u):$(id -g):dir1,dir2" >> "$tmpDir/users" echo "test::$(id -u):$(id -g):dir1,dir2" >> "$tmpDir/users"
echo "user.with.dot::$(id -u):$(id -g)" >> "$tmpDir/users"
$sudo docker run \ $sudo docker run \
-v "$tmpDir/users:/etc/sftp-users.conf:ro" \ -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 "$scriptDir/id_rsa.pub":/home/user.with.dot/.ssh/keys/id_rsa.pub:ro \
-v "$tmpDir":/home/test/share \ -v "$tmpDir":/home/test/share \
--name "$sftpContainerName" \ --name "$sftpContainerName" \
--expose 22 \ --expose 22 \
@ -96,19 +98,19 @@ function runSftpCommands() {
function waitForServer() { function waitForServer() {
containerName="$1" containerName="$1"
echo -n "Waiting for $containerName to open port 22 " echo -n "Waiting for $containerName to open port 22 ..."
for i in {1..30}; do for i in {1..30}; do
sleep 1 sleep 1
ip="$(getSftpIp $containerName)" ip="$(getSftpIp $containerName)"
echo -n "." echo -n "."
if nc -z $ip 22; then if [ -n "$ip" ] && nc -z $ip 22; then
echo " OK" echo " OPEN"
return 0; return 0;
fi fi
done done
echo " FAIL" echo " TIMEOUT"
return 1 return 1
} }
@ -132,6 +134,13 @@ function testLoginUsingSshKey() {
assertReturn $? 0 assertReturn $? 0
} }
function testUserWithDotLogin() {
$skipAllTests && skip && return 0
runSftpCommands "$sftpContainerName" "user.with.dot" "exit"
assertReturn $? 0
}
function testWritePermission() { function testWritePermission() {
$skipAllTests && skip && return 0 $skipAllTests && skip && return 0
@ -189,6 +198,34 @@ function testMinimalContainerStart() {
fi fi
} }
function testLegacyConfigPath() {
$skipAllTests && skip && return 0
tmpContainerName="$sftpContainerName""_legacy"
echo "test::$(id -u):$(id -g)" >> "$tmpDir/legacy_users"
$sudo docker run \
-v "$tmpDir/legacy_users:/etc/sftp-users.conf:ro" \
--name "$tmpContainerName" \
--expose 22 \
-d "$sftpImageName" \
> "$redirect"
waitForServer $tmpContainerName
ps="$($sudo docker ps -q -f name="$tmpContainerName")"
assertNotEqual "$ps" ""
if [ "$output" != "quiet" ]; then
$sudo docker logs "$tmpContainerName"
fi
if [ "$cleanup" == "cleanup" ]; then
$sudo docker rm -fv "$tmpContainerName" > "$redirect"
fi
}
# Bind-mount folder using script in /etc/sftp.d/ # Bind-mount folder using script in /etc/sftp.d/
function testCustomContainerStart() { function testCustomContainerStart() {
$skipAllTests && skip && return 0 $skipAllTests && skip && return 0