本镜像时基于 atmoz/sftp 镜像,构建的 centos 版本。支持以下功能:
- 将容器
\data
目录做为 sftp 的根目录 - 指定用户访问的目录
- 密码加密存储
- 挂载 obs 至文件系统
以下功能未经验证:
- 使用 SSH keys 登陆
- 使用自定义 SSH host key
- Execute custom scripts or applications
- Bindmount dirs from another location
- sftp 账号有三种定义方式:(1) 命令参数,(2)
SFTP_USERS
环境变量,(3)/etc/sftp/users.conf
配置文件。语法:user:pass[:e][:uid[:gid[:dir1[,dir2]...]]] ...
,具体详见后面实例。- 自动创建用户账号和密码
- 自动创建用户目录,并分配具体的权限
- 指定共享目录:( 默认为:/data)
- 本项目以 /data 目录为sftp den
- 想要实现 /home/user/mounted-directory 访问效果的是使用被 fork 原始项目。
docker run -p 20022:22 -d sftp foo:pass:::foo_dir
创建 foo 用户 密码为 pass,具有 foo_dir 文件夹完整访问权限。宿主机器使用 20022 端口
docker run -it -p 20025:22 --privileged=true --name sftp3 \
-e OBS_URL=obs.cn-east-2.myhuaweicloud.com \
-e AK=FHH****************O \
-e SK=0**************************************6 \
-e BUCKET_NAME=bucket-demo \
-e MOUNT_PATH=/obs_data
sftp foo:pass:::foo_dir
docker run -it -p 20025:22 --privileged=true --name sftp3 \
sftp foo:pass:::foo_dir
# 测试时使用 --privileged=true,权限过大,建议使用以下方式:
# 注意rhel上可能还会用到selinux,也可以做一些类似的设置。--device /dev/fuse就是说把host上的/dev/fuse设备挂载到容器中,--cap-add SYS_ADMIN允许容器中运行的进程执行系统管理任务,如挂载/卸载文件系统,设置磁盘配额,开/关交换设备和文件等。
docker run -it --rm --device /dev/fuse --security-opt seccomp:unconfined --cap-add SYS_ADMIN image-registry:5000/ubuntu:16.04-sshfs /bin/bash
# --privileged=true 权限太大,推荐使用以下方式
docker run -it -p 20025:22 --name sftp3 \
--device /dev/fuse --security-opt seccomp:unconfined --cap-add SYS_ADMIN \
-e OBS_URL=obs.cn-east-2.myhuaweicloud.com \
-e AK=FHH****************O \
-e SK=0**************************************6 \
-e BUCKET_NAME=bucket-demo \
sftp foo:pass:::foo_dir
docker run -it -p 20026:22 --name sftp4 \
--device /dev/fuse --cap-add SYS_ADMIN \
-e OBS_URL=obs.cn-east-2.myhuaweicloud.com \
-e AK=FHH****************O \
-e SK=0**************************************6 \
-e BUCKET_NAME=bucket-demo \
sftp foo2:pass:::foo_dir2
docker run -it -p 20025:22 --privileged=true --name sftp3 \
-e OBS_URL=obs.cn-east-2.myhuaweicloud.com \
-e AK=FHH****************O \
-e SK=0**************************************6 \
-e BUCKET_NAME=bucket-demo \
sftp foo3:pass:::foo_dir3
并挂载一个文件系统并设置用户组
docker run \
-v /host/upload:/home/foo/upload \
-p 2222:22 -d atmoz/sftp \
foo:pass:1001
sftp:
image: atmoz/sftp
volumes:
- /host/upload:/home/foo/upload
ports:
- "2222:22"
command: foo:pass:1001
OpenSSH 默认端口 22,本例将容器端口 22 映射至宿主机端口 2222。采用以下命令登陆 sftp: sftp -P 2222 foo@<host-ip>
docker run \
-v /host/users.conf:/etc/sftp/users.conf:ro \
-v mySftpVolume:/home \
-p 2222:22 -d atmoz/sftp
/host/users.conf:
foo:123:1001:100
bar:abc:1002:100
baz:xyz:1003:100
在密码后面添加 :e
表明密码是加密的,在命令行中使用单引号存放账号信息。
docker run \
-v /host/share:/home/foo/share \
-p 2222:22 -d atmoz/sftp \
'foo:$1$0G2g0GSt$ewU0t6GXG15.0hWoOX8X9.:e:1001'
TIP: 你可以使用 atmoz/makepasswd 生成加密密码
echo -n "your-password" | docker run -i --rm atmoz/makepasswd --crypt-md5 --clearfrom=-
在centos 中可以使用 openssl passwd 命令生成加密密码。
openssl passwd -1 "your-password"
Mount public keys in the user's .ssh/keys/
directory. All keys are 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 \
-v /host/id_rsa.pub:/home/foo/.ssh/keys/id_rsa.pub:ro \
-v /host/id_other.pub:/home/foo/.ssh/keys/id_other.pub:ro \
-v /host/share:/home/foo/share \
-p 2222:22 -d atmoz/sftp \
foo::1001
新建容器时会创建新的SSH host key,容器重新创建生成新的 host key,用户继续访问 sftp 服务时会产生 MITM warning,需要进入~/.ssh/known_hosts
文件将已信任的 host key 删除。建议用户自己生成 host key 文件,并挂载至容器。
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: 生成 host key 命令如下
ssh-keygen -t ed25519 -f ssh_host_ed25519_key < /dev/null
ssh-keygen -t rsa -b 4096 -f ssh_host_rsa_key < /dev/null
Put your programs in /etc/sftp.d/
and it will automatically run when the container starts.
See next section for an example.
If you are using --volumes-from
or just want to make a custom directory available in user's home directory, you can add a script to /etc/sftp.d/
that bindmounts after container starts.
#!/bin/bash
# File mounted as: /etc/sftp.d/bindmount.sh
# Just an example (make your own)
function bindmount() {
if [ -d "$1" ]; then
mkdir -p "$2"
fi
mount --bind $3 "$1" "$2"
}
# Remember permissions, you may have to fix them:
# chown -R :users /data/common
bindmount /data/admin-tools /home/admin/tools
bindmount /data/common /home/dave/common
bindmount /data/common /home/peter/common
bindmount /data/docs /home/peter/docs --read-only
NOTE: Using mount
requires that your container runs with the CAP_SYS_ADMIN
capability turned on. See this answer for more information.