mirror of
https://github.com/atmoz/sftp.git
synced 2024-12-01 13:00:56 -05:00
Merge branch 'master' into alpine
This commit is contained in:
commit
9518f6342b
2 changed files with 91 additions and 46 deletions
58
README.md
58
README.md
|
@ -1,8 +1,8 @@
|
|||
# Supported tags and respective `Dockerfile` links
|
||||
|
||||
- [`debian-jessie`, `debian`, `latest` (*Dockerfile*)](https://github.com/atmoz/sftp/blob/master/Dockerfile) [![](https://images.microbadger.com/badges/image/atmoz/sftp.svg)](http://microbadger.com/images/atmoz/sftp "Get your own image badge on microbadger.com")
|
||||
- [`alpine-3.4` (*Dockerfile*)](https://github.com/atmoz/sftp/blob/alpine-3.4/Dockerfile) [![](https://images.microbadger.com/badges/image/atmoz/sftp:alpine-3.4.svg)](http://microbadger.com/images/atmoz/sftp:alpine-3.4 "Get your own image badge on microbadger.com")
|
||||
- [`alpine-3.5`, `alpine` (*Dockerfile*)](https://github.com/atmoz/sftp/blob/alpine/Dockerfile) [![](https://images.microbadger.com/badges/image/atmoz/sftp:alpine.svg)](http://microbadger.com/images/atmoz/sftp:alpine "Get your own image badge on microbadger.com")
|
||||
- [`alpine-3.4` (*Dockerfile*)](https://github.com/atmoz/sftp/blob/alpine-3.4/Dockerfile) [![](https://images.microbadger.com/badges/image/atmoz/sftp:alpine-3.4.svg)](http://microbadger.com/images/atmoz/sftp:alpine-3.4 "Get your own image badge on microbadger.com")
|
||||
|
||||
# Securely share your files
|
||||
|
||||
|
@ -11,22 +11,23 @@ This is an automated build linked with the [debian](https://hub.docker.com/_/deb
|
|||
|
||||
# Usage
|
||||
|
||||
- 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]...]]]...`).
|
||||
- Set UID/GID manually for your users if you want them to make changes to
|
||||
your mounted volumes with permissions matching your host filesystem.
|
||||
- Add directory names at the end, if you want to create them and/or set user
|
||||
ownership. Perfect when you just want a fast way to upload something without
|
||||
mounting any directories, or you want to make sure a directory is owned by
|
||||
a user (chown -R).
|
||||
- Mount volumes in user's home directory.
|
||||
- The users are chrooted to their home directory, so you must mount the
|
||||
- Add directory names at the end, if you want to create them under the user's
|
||||
home directory. Perfect when you just want a fast way to upload something.
|
||||
- Optional (but recommended): mount volumes.
|
||||
- The users are chrooted to their home directory, so you can mount the
|
||||
volumes in separate directories inside the user's home directory
|
||||
(/home/user/**mounted-directory**).
|
||||
(/home/user/**mounted-directory**) or just mount the whole **/home** directory.
|
||||
Just remember that the users can't create new files directly under their
|
||||
own home directory, so make sure there are at least one subdirectory if you
|
||||
want them to upload files.
|
||||
- For consistent server fingerprint, mount your own host keys (i.e. `/etc/ssh/ssh_host_*`)
|
||||
|
||||
# Examples
|
||||
|
||||
|
||||
## Simplest docker run example
|
||||
|
||||
```
|
||||
|
@ -37,13 +38,15 @@ User "foo" with password "pass" can login with sftp and upload files to a folder
|
|||
|
||||
## Sharing a directory from your computer
|
||||
|
||||
Let's mount a directory and set UID:
|
||||
Let's mount a directory and set UID (we will also provide our own hostkeys):
|
||||
|
||||
```
|
||||
docker run \
|
||||
-v /host/share:/home/foo/share \
|
||||
-v /host/upload:/home/foo/upload \
|
||||
-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 \
|
||||
-p 2222:22 -d atmoz/sftp \
|
||||
foo:123:1001
|
||||
foo:pass:1001
|
||||
```
|
||||
|
||||
### Using Docker Compose:
|
||||
|
@ -52,10 +55,12 @@ docker run \
|
|||
sftp:
|
||||
image: atmoz/sftp
|
||||
volumes:
|
||||
- /host/share:/home/foo/share
|
||||
- /host/upload:/home/foo/upload
|
||||
- /host/ssh_host_rsa_key:/etc/ssh/ssh_host_rsa_key
|
||||
- /host/ssh_host_rsa_key.pub:/etc/ssh/ssh_host_rsa_key.pub
|
||||
ports:
|
||||
- "2222:22"
|
||||
command: foo:123:1001
|
||||
command: foo:pass:1001
|
||||
```
|
||||
|
||||
### Logging in
|
||||
|
@ -69,17 +74,18 @@ OpenSSH client, run: `sftp -P 2222 foo@<host-ip>`
|
|||
```
|
||||
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 \
|
||||
-v mySftpVolume:/home \
|
||||
-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 \
|
||||
-p 2222:22 -d atmoz/sftp
|
||||
```
|
||||
|
||||
/host/users.conf:
|
||||
|
||||
```
|
||||
foo:123:1001
|
||||
bar:abc:1002
|
||||
foo:123:1001:100
|
||||
bar:abc:1002:100
|
||||
baz:xyz:1003:100
|
||||
```
|
||||
|
||||
## Encrypted password
|
||||
|
@ -141,3 +147,15 @@ bindmount /data/common /home/dave/common
|
|||
bindmount /data/common /home/peter/common
|
||||
bindmount /data/docs /home/peter/docs --read-only
|
||||
```
|
||||
|
||||
# What's the difference between Debian and Alpine?
|
||||
|
||||
The biggest differences are in size and OpenSSH version.
|
||||
[Alpine](https://hub.docker.com/_/alpine/) is 10 times smaller than
|
||||
[Debian](https://hub.docker.com/_/debian/). OpenSSH version can also differ, as
|
||||
it's two different teams maintaining the packages. Debian is generally
|
||||
considered more stable and only bugfixes and security fixes are added after
|
||||
each Debian release (about 2 years). Alpine has a faster release cycle (about 6
|
||||
months) and therefore newer versions of OpenSSH. As I'm writing this, Debian
|
||||
has version 6.7 while Alpine has version 7.4. Recommended reading:
|
||||
[Comparing Debian vs Alpine for container & Docker apps](https://www.turnkeylinux.org/blog/alpine-vs-debian)
|
||||
|
|
79
tests/run
79
tests/run
|
@ -7,6 +7,9 @@ scriptDir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
|||
buildDir="$scriptDir/.."
|
||||
tmpDir="/tmp/atmoz_sftp_test"
|
||||
|
||||
sudo="sudo"
|
||||
cache="--no-cache"
|
||||
|
||||
build=${1:-"build"}
|
||||
output=${2:-"quiet"}
|
||||
cleanup=${3:-"cleanup"}
|
||||
|
@ -25,10 +28,10 @@ buildOptions="--tag $sftpImageName"
|
|||
|
||||
function beforeTest() {
|
||||
if [ "$build" == "build" ]; then
|
||||
buildOptions="$buildOptions --no-cache --pull=true"
|
||||
buildOptions="$buildOptions $cache --pull=true"
|
||||
fi
|
||||
|
||||
docker build $buildOptions "$buildDir"
|
||||
$sudo docker build $buildOptions "$buildDir"
|
||||
if [ $? -gt 0 ]; then
|
||||
echo "Build failed"
|
||||
exit 1
|
||||
|
@ -41,7 +44,7 @@ function beforeTest() {
|
|||
mkdir "$tmpDir"
|
||||
|
||||
echo "test::$(id -u):$(id -g):dir1,dir2" >> "$tmpDir/users"
|
||||
docker run \
|
||||
$sudo 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 \
|
||||
|
@ -49,23 +52,24 @@ function beforeTest() {
|
|||
--expose 22 \
|
||||
-d "$sftpImageName" \
|
||||
> "$redirect"
|
||||
sleep 2 # wait for sftp server to get ready
|
||||
|
||||
waitForServer $sftpContainerName
|
||||
}
|
||||
|
||||
function afterTest() {
|
||||
if [ "$output" != "quiet" ]; then
|
||||
echo "Docker logs:"
|
||||
docker logs "$sftpContainerName"
|
||||
$sudo docker logs "$sftpContainerName"
|
||||
fi
|
||||
|
||||
if [ "$cleanup" == "cleanup" ]; then
|
||||
docker rm -fv "$sftpContainerName" > "$redirect"
|
||||
$sudo docker rm -fv "$sftpContainerName" > "$redirect"
|
||||
rm -rf "$tmpDir"
|
||||
fi
|
||||
}
|
||||
|
||||
function getSftpIp() {
|
||||
docker inspect -f {{.NetworkSettings.IPAddress}} "$1"
|
||||
$sudo docker inspect -f {{.NetworkSettings.IPAddress}} "$1"
|
||||
}
|
||||
|
||||
function runSftpCommands() {
|
||||
|
@ -85,6 +89,27 @@ function runSftpCommands() {
|
|||
-b - $user@$ip \
|
||||
> "$redirect" 2>&1
|
||||
|
||||
status=$?
|
||||
sleep 1 # wait for commands to finish
|
||||
return $status
|
||||
}
|
||||
|
||||
function waitForServer() {
|
||||
containerName="$1"
|
||||
echo -n "Waiting for $containerName to open port 22 "
|
||||
|
||||
for i in {1..30}; do
|
||||
sleep 1
|
||||
ip="$(getSftpIp $containerName)"
|
||||
echo -n "."
|
||||
if nc -z $ip 22; then
|
||||
echo " OK"
|
||||
return 0;
|
||||
fi
|
||||
done
|
||||
|
||||
echo " FAIL"
|
||||
return 1
|
||||
}
|
||||
|
||||
##############################################################################
|
||||
|
@ -92,7 +117,7 @@ function runSftpCommands() {
|
|||
function testContainerIsRunning() {
|
||||
$skipAllTests && skip && return 0
|
||||
|
||||
ps="$(docker ps -q -f name="$sftpContainerName")"
|
||||
ps="$($sudo docker ps -q -f name="$sftpContainerName")"
|
||||
assertNotEqual "$ps" ""
|
||||
|
||||
if [ -z "$ps" ]; then
|
||||
|
@ -103,17 +128,14 @@ function testContainerIsRunning() {
|
|||
function testLoginUsingSshKey() {
|
||||
$skipAllTests && skip && return 0
|
||||
|
||||
runSftpCommands "$sftpContainerName" \
|
||||
"test" \
|
||||
"exit"
|
||||
runSftpCommands "$sftpContainerName" "test" "exit"
|
||||
assertReturn $? 0
|
||||
}
|
||||
|
||||
function testWritePermission() {
|
||||
$skipAllTests && skip && return 0
|
||||
|
||||
runSftpCommands "$sftpContainerName" \
|
||||
"test" \
|
||||
runSftpCommands "$sftpContainerName" "test" \
|
||||
"cd share" \
|
||||
"mkdir test" \
|
||||
"exit"
|
||||
|
@ -124,8 +146,7 @@ function testWritePermission() {
|
|||
function testDir() {
|
||||
$skipAllTests && skip && return 0
|
||||
|
||||
runSftpCommands "$sftpContainerName" \
|
||||
"test" \
|
||||
runSftpCommands "$sftpContainerName" "test" \
|
||||
"cd dir1" \
|
||||
"mkdir test-dir1" \
|
||||
"get -rf test-dir1 $tmpDir/" \
|
||||
|
@ -144,14 +165,15 @@ function testMinimalContainerStart() {
|
|||
|
||||
tmpContainerName="$sftpContainerName""_minimal"
|
||||
|
||||
docker run \
|
||||
$sudo docker run \
|
||||
--name "$tmpContainerName" \
|
||||
-d "$sftpImageName" \
|
||||
minimal \
|
||||
> "$redirect"
|
||||
sleep 2
|
||||
|
||||
ps="$(docker ps -q -f name="$tmpContainerName")"
|
||||
waitForServer $tmpContainerName
|
||||
|
||||
ps="$($sudo docker ps -q -f name="$tmpContainerName")"
|
||||
assertNotEqual "$ps" ""
|
||||
|
||||
if [ -z "$ps" ]; then
|
||||
|
@ -159,11 +181,11 @@ function testMinimalContainerStart() {
|
|||
fi
|
||||
|
||||
if [ "$output" != "quiet" ]; then
|
||||
docker logs "$tmpContainerName"
|
||||
$sudo docker logs "$tmpContainerName"
|
||||
fi
|
||||
|
||||
if [ "$cleanup" == "cleanup" ]; then
|
||||
docker rm -fv "$tmpContainerName" > "$redirect"
|
||||
$sudo docker rm -fv "$tmpContainerName" > "$redirect"
|
||||
fi
|
||||
}
|
||||
|
||||
|
@ -180,7 +202,7 @@ function testCustomContainerStart() {
|
|||
> "$tmpDir/mount.sh"
|
||||
chmod +x "$tmpDir/mount.sh"
|
||||
|
||||
docker run \
|
||||
$sudo docker run \
|
||||
--privileged=true \
|
||||
--name "$tmpContainerName" \
|
||||
-v "$scriptDir/id_rsa.pub":/home/custom/.ssh/keys/id_rsa.pub:ro \
|
||||
|
@ -190,21 +212,26 @@ function testCustomContainerStart() {
|
|||
-d "$sftpImageName" \
|
||||
custom:123 \
|
||||
> "$redirect"
|
||||
sleep 2
|
||||
|
||||
ps="$(docker ps -q -f name="$tmpContainerName")"
|
||||
waitForServer $tmpContainerName
|
||||
|
||||
ps="$($sudo docker ps -q -f name="$tmpContainerName")"
|
||||
assertNotEqual "$ps" ""
|
||||
|
||||
runSftpCommands "$tmpContainerName" "custom" "cd bindmount" "mkdir test" "exit"
|
||||
runSftpCommands "$tmpContainerName" "custom" \
|
||||
"cd bindmount" \
|
||||
"mkdir test" \
|
||||
"exit"
|
||||
|
||||
test -d "$tmpDir/custom/bindmount/test"
|
||||
assertReturn $? 0
|
||||
|
||||
if [ "$output" != "quiet" ]; then
|
||||
docker logs "$tmpContainerName"
|
||||
$sudo docker logs "$tmpContainerName"
|
||||
fi
|
||||
|
||||
if [ "$cleanup" == "cleanup" ]; then
|
||||
docker rm -fv "$tmpContainerName" > "$redirect"
|
||||
$sudo docker rm -fv "$tmpContainerName" > "$redirect"
|
||||
fi
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue