本文涉及一种在容器中部署 sftp 服务的方法。经验证,可达到预期目标,并能应用在实际工作中。

一、引言

因工作需要,需部署 sftp 服务器进行数据测试。

二、技术小结

  • dockerhub 上相关镜像,直接拉取可用。

  • 运行时需要注意用户名和home目录,如使用foo用户,则需要挂载到/home/foo目录。

  • 需要手动设置ssh key,否则每次重启都会产生新的key。

  • 上传权限问题暂未解决。

三、实践

3.1 下载

命令:

docker pull atmoz/sftp

测试运行:

docker run \
    -v /tmp/upload:/home/foo/upload \
    --name sftp \
    -p 2222:22 -itd atmoz/sftp \
    foo:pass:1000

注:挂载 tmp/upload到容器home的同名目录下,账号密码分别为foopassUID与执行此命令的主机用户一样,即1000(可通过/etc/passwd文件查看知)。

测试连接:

sftp -P 2222 foo@localhost
foo@localhost's password: 
Connected to localhost.
sftp> ls
upload  
sftp> cd upload/
sftp> put webdemo
Uploading webdemo to /upload/webdemo
remote open("/upload/webdemo"): Permission denied

提示权限不足,在容器中修改 upload 目录权限:

$ docker exec -it sftp bash
root@35f5c9abeb71:/# cd home/
root@35f5c9abeb71:/home/foo# ls -lh
total 0
drwxr-xr-x. 2 root root 6 May 10 07:05 upload
root@35f5c9abeb71:/home/foo# chmod 777 upload/ -R
root@35f5c9abeb71:/home/foo# ls -lh
total 0
drwxrwxrwx. 2 root root 21 May 10 07:27 upload

则可以正常上传

sftp> put webdemo
Uploading webdemo to /upload/webdemo
webdemo                                       100% 6706KB  53.1MB/s   00:00  
sftp> exit

四、sftp常用命令

登陆:
sftp -P <端口> <用户名>@<IP>

?:查看帮助
quit:退出
cd lcd:进入某目录 (注:有l前缀表示是宿主机)
ls lls:查看目录
pwd lpwd:查看当前路径
mdir :创建目录
put:上传文件(目录:-r)
get:下载文件

五、指定ssh key

默认情况下,每次重新服务,都会产生新的key,需要用户确认(见附录)。可以手动指定key,解决该问题。

mkdir ssh
cd ssh
ssh-keygen -t ed25519 -f ssh_host_ed25519_key < /dev/null
ssh-keygen -t rsa -b 4096 -f ssh_host_rsa_key < /dev/null

在运行添加如下参数:

-v <host-dir>/ssh_host_ed25519_key:/etc/ssh/ssh_host_ed25519_key \
-v <host-dir>/ssh_host_rsa_key:/etc/ssh/ssh_host_rsa_key \

六、docker-compose部署

对应的yaml文件如下:

version: "2"
services:
  sftp:
    image: atmoz/sftp
    container_name: sftp
    volumes:
      - ./upload:/home/aftp/
      - ./ssh/ssh_host_ed25519_key:/etc/ssh/ssh_host_ed25519_key
      - ./ssh/ssh_host_rsa_key:/etc/ssh/ssh_host_rsa_key
    ports:
      - "2222:22"
    command: aftp:passworld:1000

注:本例中将当前目录的upload目录直接挂载到用户的home目录,不似上述在upload目录。这样客户端连接后的根目录就是宿主机的upload目录,较方便。

七、参考

sftp 镜像:https://hub.docker.com/r/atmoz/sftp

网上有文章在运行容器命令时添加--privileged=true参数。

首次运行时,用sftp命令连接时,需要确认,提示如下:

The authenticity of host '[localhost]:2222 ([::1]:2222)' can't be established.
ED25526 key fingerprint is SHA256:FUCkkcufctB3fasdf45sszVCaqRQTY7+Qasjw235A+XwCg.
ED25526 key fingerprint is MD5:17:fu:ck:3d:bb:aa:00:35:79:ac:bc:cc:dc:ec:71:bb.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[localhost]:2222' (ED25526) to the list of known hosts.

如果重新启动(这样也算是首次运行),则会提示:

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the ED25519 key sent by the remote host is
SHA256:FTKtctB6yBQasdfasdfasdf3fasdf7+QSBTLyyasdfasdfasdfCg.
Please contact your system administrator.
Add correct host key in /home/lateee/.ssh/known_hosts to get rid of this message.
Offending ED25526 key in /home/lateee/.ssh/known_hosts:4

此时,需要编辑/home/lateee/.ssh/known_hosts文件,删除对应的那一行信息(本文中,会带有 2222 字样)。

疑问:如果使用程序连接,首次出现上述提示,如何输入yes?待研究。

在一次用 docker-compose 运行时,客户端连接出现:

$ sftp -P2222 foo@127.0.0.1
Connection closed by 127.0.0.1 port 2222
Couldn't read packet: Connection reset by peer

经查,是因为 sftp 服务器目录在 Windows 系统,改为 Linux 系统,问题解决。(为减少虚拟机空间占用,并方便调试,笔者习惯使用虚拟机的共享目录,在 Linux 中操作 Windows 硬盘。)

2021.5.10

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐