文章目录

前段时间项目组客户端同事需要一个公共的http服务作为客户端的下载更新服务,由他来上传需要更新的内容。首先想到的是使用nginx作为文件服务支持,然后提供一个ftp的方式让他上传。查了一些资料后,发现nginx本身也可以支持上传,于是写了 容器中使用ngnix搭建支持上传下载的文件服务器一文,但是这种方式对多个文件或者目录不太友好,不适合这种使用场景。

本文将使用最初的想法,使用nginx+sftp的方式来实现。由于ftp不安全,基本上被淘汰了,取而代之的sftp,即使用安全的加密方式来传输内容。sftp 与 ftp 有着几乎一样的语法和功能。还有一个非常重要的便利性,安装了ssh包即包含了SFTP(Secure File Transfer Protocol)安全文件信息传输子系统,不需要再额外安装ftp服务软件。SFTP本身没有单独的守护进程,它必须使用sshd守护进程(端口号默认是22)来完成相应的连接和答复操作。

一、下载并安装最新的nginx容器

1sudo podman pull docker.io/library/nginx:latest
2sudo podman -d --name nginx -p 83:80 -p 2222:22 docker.io/library/nginx:latest

进入容器中:

1sudo podman exec -it nginx /bin/bash

二、设置系统

1.设置更新源

可以先把之前的/etc/apt/sources.list先删除掉或者改名,再执行下面的指令:

1echo "deb https://mirrors.tencent.com/debian/ bullseye main non-free contrib
2deb-src https://mirrors.tencent.com/debian/ bullseye main non-free contrib
3deb https://mirrors.tencent.com/debian-security/ bullseye-security main
4deb-src https://mirrors.tencent.com/debian-security/ bullseye-security main
5deb https://mirrors.tencent.com/debian/ bullseye-updates main non-free contrib
6deb-src https://mirrors.tencent.com/debian/ bullseye-updates main non-free contrib
7deb https://mirrors.tencent.com/debian/ bullseye-backports main non-free contrib
8deb-src https://mirrors.tencent.com/debian/ bullseye-backports main non-free contrib" >> /etc/apt/sources.list

2.更新

1apt update

3.设置本地时区

1cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

三、准备sftp账号

1.添加ftp组

1groupadd ftp

2. 添加ftp账号

我们希望ftp账号拥有自己的Home目录,且只能访问该目录。

添加工作目录:

1mkdir /home/ftp
2chown root:ftp /home/ftp

需要注意,用户目录的所有者一定要是root,而且必须是755权限,否则使用账号ftp会连接不上。同时/home/ftp是针对账号ftp是只读,不可写。

添加账号ftp

1useradd -g ftp ftp -d /home/ftp -s /sbin/nologin

该命令创建一个ftp用户,并加入ftp组,指定Home目录为/home/ftp,不能使用shell登录。

设置密码:

1passwd ftp

如果前面没有指定Home目录,也可以使用下面的命令来指定

1usermod -d /home/ftp ftp

由于/home/ftp针对账号ftp是只读的,需要创建可读写目录:

1mkdir /home/ftp/share
2chown ftp:ftp /home/ftp/share

由于我们需要使用ftp用户上传文件,所以需要保证/home/ftp/share目录的所有者为ftp,否则无法上传。

四、安装sshd

1. 安装 openssh-server

1apt install openssh-server

2. 配置

配置sshd_config文件,这里需要使用到vi或者vim,如果容器中的系统没有自带vi,则需要手动安装vim:

1 apt install vim
1vim /etc/ssh/sshd_config

在文件中注释掉行

1Subsystem sftp /usr/libexec/openssh/sftp-server

最后添加上:

1Subsystem sftp internal-sftp
2Match user ftp
3ChrootDirectory %h

3. 运行sshd

1/usr/sbin/sshd -D

如果报错:

1Missing privilege separation directory: /run/sshd

则创建一个目录:

1mkdir /run/sshd

再次运行

1/usr/sbin/sshd -D&

五、配置nginx

修改/etc/nginx/conf.d/default.conf,使其作为文件服务器:

 1server {
 2    ……
 3    charset utf-8; # 设置字符编码,避免中文乱码
 4    location / {
 5            root   /home/ftp/share; # 根目录
 6            autoindex   on;  # 开启索引功能
 7            autoindex_exact_size off; # 关闭计算文件确切大小(单位bytes),只显示大概大小(单位kb、mb、gb)
 8            autoindex_localtime on; # 显示本地时间
 9        }
10}

使用nginx -s reload让配置生效。

六、容器启动自动运行sshd

通过前面的设置已经完成了相应的功能,但是如果容器重启后,sshd服务不会自动运行。 为了让sshd在容器启动时自动运行,针对docker.io/library/nginx容器,使用 配置与管理Ubuntu 21.10一文中介绍的 让容器启动即运行SSH服务不生效,因为该容器不会在容器启动时执行/etc/profile.d/中的sh文件。

解决方案:

/docker-entrypoint.d目录中新建一个文件40-sshd.sh,内容如下:

1#!/bin/sh
2
3/usr/sbin/sshd -D&

加上可执行权限:

1chmod +x /docker-entrypoint.d/40-sshd.sh

七、美化页面

由于nginx的autoindex显示页面比较简陋,可以对其进行美化,可以参见笔者的下一篇博文: nginx文件服务器美化autoindex显示