vsftpd部署流程和常见问题详解

article/2025/8/25 16:06:44

vsftpd部署流程和常见问题详解

⭐️ 网上关于在云服务器里配置vsftpd的文章鱼龙混杂,没有一篇是可以彻底解决问题的,有些问题虽简单,但也让初学者感到困惑。本文详细说明vsftpd的部署流程和一些常见问题的解决方法,详述用户创建过程,并且可以在Windows平台下直接访问vsftpd服务器,实现文件传输。——©️ Sylvan Ding

vsftpd简介

vsftpd是“very secure FTP daemon”的缩写,安全性是它的一个最大的特点。vsftpd 是一个 UNIX 类操作系统上运行的服务器的名字,它可以运行在诸如 Linux、BSD、Solaris、 HP-UNIX等系统上面,是一个完全免费的、开放源代码的ftp服务器软件,支持很多其他的 FTP 服务器所不支持的特征。比如:非常高的安全性需求、带宽限制、良好的可伸缩性、可创建虚拟用户、支持IPv6、速率高等[1]。

vsftpd 利用 chroot() 这个函式进行改换根目录的动作,使得系统工具不会被 vsftpd 这支服务所误用。上层程序中,依然使用 chroot() 的功能来限制使用者的执行权限。

环境说明

  • 服务器:腾讯云服务器/轻量应用服务器
  • 操作系统:Ubuntu Server 18.04.1 LTS 64bit
  • vsftpd版本:version 3.0.3

安装vsftpd

ubuntu@VM-12-6-ubuntu:~$ sudo su # 切换到root
root@VM-12-6-ubuntu:/home/ubuntu apt-get install vsftpd # 安装vsftpd
root@VM-12-6-ubuntu:/home/ubuntu# vsftpd -version # 查看vsftpd版本,验证是否安装成功

⚠️ 注意:之后的操作环境都是在root权限下进行!

修改配置文件

root@VM-12-6-ubuntu:/home/ubuntu# whereis vsftpd # 查找配置文件 vsftpd.conf 路径
vsftpd: /usr/sbin/vsftpd /etc/vsftpd.chroot_list /etc/vsftpd.conf /usr/share/man/man8/vsftpd.8.gz
vim /etc/vsftpd.conf # 修改配置文件

重点关注如下参数(我们不设置匿名访问,所以和anonymous有关的参数我们都不修改,也不做解释):

  1. local_enable(默认YES, 允许本地用户登陆)
  2. write_enable(是否允许登陆用户有写权限,需要取消该行注释,即设置write_enable=YES
  3. local_umask(屏蔽用户创建的目录/文件的初始权限)
  4. chroot_local_user, chroot_list_enable(将用户限制在主目录下)

local_umask

在linux系统中,创建一个新的文件或者目录的时候,这些新的文件或目录都会有默认的访问权限,umask命令与文件和目录的默认访问权限有关。若用户创建一个文件,则文件的默认访问权限为-rw-rw-rw-,创建目录的默认权限 drwxrwxrwx,而umask值则表明了需要从默认权限中去掉哪些权限来成为最终的默认权限值[2]。

例如,用vsftpd创建一个文件夹,文件夹的权限是 777,此时设置local_umask=077,即使用其默认值,那么最终文件夹的权限是 700 = 777 - 077 (二进制相减),即由用户创建的文件夹仅对该用户有RWX的权利。

Linux权限管理—基本权限

chroot

很多情况下,希望限制ftp用户只能在其主目录下(root dir)下活动,不允许他们跳出主目录之外浏览服务器上的其他目录,这时候我就需要使用到chroot_local_user, chroot_list_enable, chroot_list_file这三个选项了[3]。

  • chroot_local_user 是否将所有用户限制在主目录,YES为启用 NO禁用. (该项默认值是NO,即在安装vsftpd后不做配置的话,ftp用户是可以向上切换到要目录之外的)
  • chroot_list_enable 是否启动限制用户的名单 YES为启用 NO禁用(包括注释掉也为禁用)
  • chroot_list_file=/etc/vsftpd.chroot_list 是否限制在主目录下的用户名单,至于是限制名单还是排除名单,这取决于chroot_local_user的值.

对于chroot_local_userchroot_list_enable的组合效果,可以参考下表:

chroot_local_user=YESchroot_local_user=NO
chroot_list_enable=YES1.所有用户都被限制在其主目录下 2.使用chroot_list_file指定的用户列表,这些用户作为“例外”,不受限制1.所有用户都不被限制其主目录下 2.使用chroot_list_file指定的用户列表,这些用户作为“例外”,受到限制
chroot_list_enable=NO1.所有用户都被限制在其主目录下 2.不使用chroot_list_file指定的用户列表,没有任何“例外”用户1.所有用户都不被限制其主目录下 2.不使用chroot_list_file指定的用户列表,没有任何“例外”用户

重启vsftpd让修改的配置文件生效:

/etc/init.d/vsftpd restart

设置防火墙

需要在腾讯云服务器中开放FTP服务端口(21),否则将无法连接这个端口。

在这里插入图片描述

创建用户

useradd -d <home_dir> <username> # 添加用户
passwd <username> # 修改密码
chown -R <username> <home_dir> # 修改家目录所有者
  • -d 设定使用者的家目录为 home_dir ,即登陆后的初始目录

检查监听端口

netstat -antup | grep ftp # 检查端口是否开放

正常情况下应该返回,表明正vsftpd正监听21端口:

tcp6       0      0 :::21                   :::*                    LISTEN      5747/vsftpd

问题解决:500 OOPS: vsftpd: refusing…

这时使用上述账户登陆ftp会报错:500 OOPS: vsftpd: refusing to run with writable root inside chroot() ,这是新版vsftpd加了安全认证导致的,即如果开启了chroot 来控制用户路径,则用户不能再具有该用户根目录的写的权限。 解决方法:在配置文件/etc/vsftpd.conf中末尾添加allow_writeable_chroot=YES,表明允许该用户对根目录的写的权限[6]。别忘了重启vsftpd:/etc/init.d/vsftpd restart.

禁止用户登陆

为确保创建的用户只能通过ftp访问对应的文件夹,而不能在命令行下操作系统,故需要禁止用户登陆。

usermod -s /sbin/nologin <username>
  • -s 修改用户登入后所使用的shell,系统账号的shell使用/sbin/nologin,此时无法登录系统,即时给了密码也不行. 所谓“无法登录”,指的是仅是这个用户无法使用bash或者其他shell来登录系统而已,并不是说这个账号就无法使用系统资源[4]。

设置禁止登陆后,客户端尝试登陆 ftp,但提示vsftpd 530 Login incorrect. 此时,需要更新/etc/shells. vsftpd 通过 pam 进行验证 shell,而 nologin 和 false 是不在 /etc/shells 中的,所以验证不能通过,自然不能登录了[5]。解决方法是在 /etc/shells 添加 nologin 即可。

问题解决:Windows访问FTP文件夹错误

在这里插入图片描述

使用Windows的文件系统访问FTP文件夹(MacOS在访达中连接ftp时却不会出现这样的问题):

ftp://<username>:<pwd>@<host>:21/

此时,报 FTP文件夹错误 提示。原因是Windows默认使用ftp被动模式(PASV)连接,而服务器端vsftpd使用主动模式(PORT). PORT(主动)模式模式只要开启服务器的21和20端口,而PASV(被动)模式需要开启服务器大于1024所有tcp端口和21端口。

主动模式,指的是FTP服务器“主动”去连接客户端的数据端口来传输数据,其过程具体是:客户端从一个任意的非特权端口N(N>1024)连接到FTP服务器的命令端口(即tcp 21端口),紧接着客户端开始监听端口N+1,并发送FTP命令“port N+1”到FTP服务器。然后服务器会从它自己的数据端口(20)“主动”连接到客户端指定的数据端口(N+1),这样客户端就可以和ftp服务器建立数据传输通道了。被动模式,指的是FTP服务器“被动”等待客户端来连接自己的数据端口,其过程具体是:当开启一个FTP连接时,客户端打开两个任意的非特权本地端口(N >1024和N+1)。第一个端口连接服务器的21端口,向服务器提交PASV命令。这样做的结果是服务器会开启一个任意的非特权端口(P > 1024),并发送PORT P命令给客户端。然后客户端发起从本地端口N+1到服务器的端口P的连接用来传送数据[7].(注意此模式下的FTP服务器不需要开启tcp 20端口了)

解决方法是通过修改配置文件,在配置文件/etc/vsftpd.conf末尾添加:(别忘了重启/etc/init.d/vsftpd restart

pasv_enable=YES # 允许pasv模式
pasv_max_port=11000 # pasv使用的最大端口
pasv_min_port=10100 # pasv使用的最小端口

接着,在防火墙中开放pasv使用的端口,例如:

在这里插入图片描述

其他云主机可能需要设置系统内的防火墙哦~

❤️ 原创文章,转载请注明出处!©️ Sylvan Ding

参考文献

  1. vsftpd(百度百科)
  2. linux命令–umask
  3. vsftpd 配置:chroot_local_user与chroot_list_enable详解
  4. Linux中Shell——sbin/nologin的理解
  5. vsftpd将shell设置成为nologin后不能登录解决办法
  6. 500 OOPS: vsftpd: refusing to run with writable root inside chroot() 错误的解决方式
  7. vsftpd的主动模式与被动模式

http://chatgpt.dhexx.cn/article/87upr7oX.shtml

相关文章

Linux vsFTPd服务详解——vsFTPd基础知识

今天继续给大家介绍Linux运维相关内容&#xff0c;本文主要内容是Linux的vsFTPd服务。 一、vsFTPd服务简介与安装 FTP服务&#xff0c;即File Transfer Protocol、文件传输服务&#xff0c;用于在互联网上提供文件存储和访问服务。有关FTP的原理请参见以下文章&#xff1a;FT…

vsftpd的安装和使用

目录 1、vsftpd的简介... 2 2、特点... 2 3、安装... 2 4、创建虚拟用户... 2 5、vsftpd服务器的配置... 4 6、vsftpd配置文件说明... 7 7、防火墙的配置... 8 8、vsftpd的验证... 9 9、vsftpd的常用命令... 10 10、反复需要验证ftp身份问题解决... 10 1、vsftpd的简…

Number、parseInt和parseFloat的区别

1、Number() 可以把任何类型的数据转换为数值或NaN(not a number)&#xff0c;parseInt()和parseFloat()只能把字符串或数值转换为数值&#xff1b; 2、Number()和parseFloat()会有效解析浮点数&#xff08;如"324.11abc"转为324.11&#xff09;&#xff0c;而parse…

parseFloat()函数的使用

定义&#xff1a; parseFloat() 函数可解析一个字符串&#xff0c;并返回一个浮点数。该函数指定字符串中的首个字符是否是数字。如果是&#xff0c;则对字符串进行解析&#xff0c;直到到达数字的末端为止&#xff0c;然后以数字返回该数字&#xff0c;而不是作为字符串。 语…

Float.parseFloat()的作用

parseFloat()方法用于返回与给定String表示形式相对应的float值 类型转换: string转float

java float.parsefloat_java.lang.Float.parseFloat()方法实例

全屏 java.lang.Float.parseFloat()方法返回一个为指定String表示新的浮点初始化值&#xff0c;由Float类的valueOf方法执行的值。 声明 以下是java.lang.Float.parseFloat()方法的声明public static float parseFloat(String s) throws NumberFormatException 参数s -- 这是要…

从ES规范和引擎细谈 js 中 parseInt 和 parseFloat 的执行机制

从ES规范和引擎细谈 js 中 parseInt 和 parseFloat 的执行机制 parseInt()和parseFloat()这两个常用 API 其实还是有很多“坑”的&#xff0c;以此文统一梳理一下。&#xff08;本文比较适合常与数字打交道的 jser 或对这两 API 运作感兴趣的同学&#xff09; &#xff08;git…

python实现简单的聊天小程序

概要 这是一个使用python实现一个简单的聊天室的功能,里面包含群聊,私聊两种聊天方式.实现的方式是使用套接字编程的一个使用TCP协议 c/s结构的聊天室 实现思路 x01 服务端的建立 首先,在服务端,使用socket进行消息的接受,每接受一个socket的请求,就开启一个新的线程来管理…

微信小程序调出选择好友聊天窗口

微信小程序分享好友 点击分享&#xff0c;弹出层选择“分享给微信好友”&#xff0c;点击‘“分享给微信好友”&#xff0c;直接调出选择好友聊天窗口。 如图&#xff1a; 微信小程序API&#xff1a;onShareAppMessage 定义 onShareAppMessage 函数&#xff0c;设置该页面的…

小程序mqtt实现聊天功能

mqtt是什么&#xff1f; MQTT是一个轻量级传输协议&#xff0c;它被设计用于轻量级的发布/订阅式消息传输&#xff0c;MQTT协议针对低带宽网络&#xff0c;低计算能力的设备&#xff0c;做了特殊的优化。是一种简单、稳定、开放、轻量级易于实现的消息协议&#xff0c;在物联网…

微信小程序接入腾讯IM即时通讯,实现在线聊天

最近在帮朋友写一个二手交易平台&#xff0c;买卖双方在线沟通的功能(类似于某鱼&#xff09; 先上传做完的效果图&#xff0c;后续再更新源码&#xff0c;目前实现了消息列表显示未读数量&#xff0c;显示最后一条信息内容&#xff0c;收到信息后刷新列表。聊天页面 不要吐槽…

应用实战|微信小程序开发示例--多人聊天互动空间

“超能力”数据库&#xff5e;拿来即用&#xff0c;应用开发人员再也不用为撰写API而发愁。MemFire Cloud 为开发者提供了简单易用的云数据库&#xff08;表编辑器、自动生成API、SQL编辑器、备份恢复、托管运维&#xff09;&#xff0c;很大地降低开发者的使用门槛。 本示例是…

微信小程序实现websocket及单人聊天功能

一、什么是websocket&#xff1a; WebSocket是HTML5下一种新的协议&#xff08;websocket协议本质上是一个基于tcp的协议&#xff09;它实现了浏览器与服务器全双工通信&#xff0c;能更好的节省服务器资源和带宽并达到实时通讯的目的Websocket是一个持久化的协议 二、websoc…

uni-app+websocket实现语音聊天小程序

uni-appwebsocket 开发语音聊天咨询小程序

微信小程序中百分百实现聊天界面

众所周知,全网来看,微信的聊天界面看着就是舒服,那能否在微信小程序中实现该功能,同时可以实现输入文本和语音功能,而且在输入文本时,键盘可以弹起。话不多说,上界面看看。 wxml实现如下: <view> <scroll-view scroll-y scroll-into-view={{toView}} style=h…

图灵聊天机器人小程序

历时半年整理出了十多万字的学习笔记&#xff0c;目前依旧在更新 欢迎点赞和支持&#xff5e;&#x1f973;&#x1f973;&#x1f973; 博客 项目描述&#xff1a; 根据图灵API向聊天机器人发送聊天信息&#xff0c;并渲染返回的数据。具有清空聊天记录的按钮。本来是想上线…

微信小程序-模仿绘制聊天界面

参考文章 1、小程序模仿微信聊天界面 2、微信小程序实现仿微信聊天界面(各种细节处理) 3、微信小程序之页面中关于聊天框三角形的制作和使用 4、仿微信聊天记录时间显示 5、微信小程序-同时获取麦克风、相机权限、获取多个权限 6、【uni-app】模仿微信实现简易发送/取发语音功…

微信聊天小程序——(二、账号的注册与登录)

具体效果&#xff1a; 目录 二、账号的注册与登录 步骤一、获取用户信息 步骤二、用户输入账号密码&#xff08;在注册页面中&#xff09; 步骤三、将获取到的值放到我们的数据库中&#xff08;在注册页面中&#xff09; 步骤四、登录的页面逻辑 步骤五、登录页面的实现 …

微信聊天小程序——(三、获取好友列表)

三、获取好友列表 步骤一、展示所有好友的推荐列表&#xff08;friends页面&#xff09; 具体效果&#xff1a; 实现思路&#xff1a; 我们有我们的用户数据库表即&#xff1a;uers循环我们的数据库用户表&#xff0c;达到所有的用户信息&#xff0c;即&#xff1a;userLi…

微信聊天小程序——(五、添加好友)

五、添加好友 步骤一、通过搜索添加好友 具体效果&#xff1a; 思路&#xff1a; 本质上来讲&#xff0c;就是通过输入框得到好友账号信息&#xff0c;之后再数据库中查询&#xff0c;最后返回并渲染查询结果。首先&#xff0c;得到输入框的值&#xff0c;并传递到我们的页面…