基于树莓派搭建私有VSFTPD服务器
前言:
FTP作为一项古老的技术,现今已逐渐被云盘技术所取代了,云盘技术区别于FTP技术的最大优势就是文件的自动同步功能,当然,还有云盘技术一般还配备了一个易于使用的手机端的应用,这些是FTP技术无法比拟的。然而,假若你对文件的同步的需求不是很大,只想作一个文件分享或文件中转的服务器,那么FTP服务依然是不错的选择,而事实上,国内很多企业或学校依然还在其内网保留着FTP服务器用于文件分享。FTP技术依然被大量应用,很简单的一点的原因是,简单的需求,就用简单的方式去实现。
本教程将会以树莓派作为基本的硬件设备,之所以使用树莓派,一是此硬件易于获取并且中文信息资源较多,二是作为全天在线并且轻度使用的FTP服务器,我们必须考虑其功耗。树莓派的待机功耗不足3W,对于作为轻度使用的私有FTP服务器,其提供一个月的FTP服务仅需2至3元,可谓非常的环保。事实上,对于仅运行单FTP服务的树莓派,私有使用的话,你可能使用不足5%的CPU资源。题外话,不要尝试将树莓派应用于大并发量的环境,其IO性能并不允许你这么做,实际上,树莓派的IO性能连实现软件阵列都非常有难度。另有一点非常重要,使用私有的FTP服务器,你不需要担心云运营商会可能会获取你的敏感数据!!!
作为一篇基于VSFTPD程序搭建的FTP服务器,其过程和网上的同类教程基本想同,但本教程将尽量说明一些参数或选项的作用,以方便读者调整配置以实现个性化的FTP服务。另外本教程非常值得关注的一点是,同时实现虚拟用户与本地用户登录使用,这是网上任何一篇教程都无法实现的,至少,在我架设私有FTP服务器,网上并不存在虚拟用户与本地用户同时存在的实现教程。
一、建站环境
本教程在以下环境下搭建测试通过!
-
硬件 :树莓派 3 B+
-
操作系统 :raspbian-stretch-lite
-
VSFTPD版本 :version 3.0.3
-
BerkeleyDB数据库版本 :Berkeley DB 5.3.28
-
代码测试日期:2019年09月11日
二、操作系统基本安全配置
由于FTP服务将暴露于公网,此处有必要对树莓派上的操作系统作一些必要的安全配置,使用树莓派操作系统的默认配置而将树莓派暴露于公网,这是一个极不明智的做法。当然,如果你只是仅将FTP的端口[20、21]映射出公网,这不会有太大问题,但实际上,你极有可能同时将你的SSH端口影射出公网,以方便你对服务器的管理,此时,操作系统上的默认配置将是非常的危险!
以下的配置并不局限于安全方面,有部分是属于管理上的优化,这是本教程总结的一套基于树莓默认操作系统的基本优化方案,优化内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# 以下为本教程总结的对于树莓派系统的一此优化内容,可按需选择配置; # 修改的内容如下: # 1.修改了语言编码、时区、软件源[适合国内使用]; # 2.使用自定义的用户代替了系统默认的'pi'用户; # 3.变更服务的默认名称[个性化]; # 设定系统语言编码,命令运行后是一个类图形界面; # 请自行设定语言编码,国内使用建议使用'zh_CN.UTF-8'编码; sudo raspi-config # 设定上海时区[也可以上述类图形界面中设置]; # 本人感觉使用命令更简单; sudo timedatectl set-timezone Asia/Shanghai # 设定替换镜像源为国内镜像源; # 树莓派内置两个软件源,分别如下: # '/etc/apt/sources.list'记录树莓派开发者默认的软件源; # '/etc/apt/sources.list.d/raspi.list'记录树莓派基金会默认的软件源; # 实际上基于基金会软件源提供的软件非常少,但在系统全局更新时,基金会中软件又不能忽略更新; # 这会导致在更新基金会软件时将连接至国外网站,造成更新缓慢! # 本处开发者源使用阿里云,基金会源使用中科大,读者可按需更换为其它软件源; sudo sed -i 's#http://raspbian.raspberrypi.org#https://mirrors.aliyun.com/raspbian#g' /etc/apt/sources.list sudo sed -i 's#http://archive.raspberrypi.org#https://mirrors.ustc.edu.cn/archive.raspberrypi.org#g' /etc/apt/sources.list.d/raspi.list # 软件源索引更新及系统更新; # 其中第二条命令系统更新实际上非必要,非完美主义者可以忽略; sudo apt-get update sudo apt-get upgrade # 创建新用户'Fiona'并设定密码[用于代替默认的pi用户名][安全考虑]; sudo useradd -u 1001 -g 1000 -d /home/Fiona -s /bin/bash -m Fiona # 设定新用户'Fiona'的密码; sudo passwd Fiona # 设定新用户'Fiona'与'pi'拥有相同用户组; sudo usermod -G $(groups pi | cut -c 6- | sed 's/ /,/g') Fiona # 设定新用户'Fiona'具有SUDO免密码权限; sudo chmod u+w /etc/sudoers echo "Fiona ALL=(ALL) NOPASSWD: ALL" | sudo tee -a /etc/sudoers sudo chmod u-w /etc/sudoers # 禁用默认的'pi'用户; # 进行此步前请确认新创建的'Fiona'用户密码正确,并能正常通过SSH服务登录; # 否则你可能需要另一台LINUX系统的电脑,修改'/etc/shadow'文件以重新启用'pi'用户以登录设备; sudo passwd -l pi # 设定服务器名称为“FtpServer”; # 注意:“/etc/hostname”及“/etc/hosts”这两份文件作用是有区别的; # 设定服务器名称为“FtpServer”; echo "FtpServer" | sudo tee /etc/hostname sudo sed -i "s/raspberrypi/FtpServer/g" /etc/hosts # 服务器名称变更后,请重启设备,否则会报错; # 这是因为系统名称的环境变量位于内存而未实时更新造成的; sudo reboot |
三、软件安装
安装VSFTPD程序及BerkeleyDB程序,其中BerkeleyDB程序是为实现虚拟用户登录FTP而需要的,操作命令如下:
1 2 3 4 5 6 7 8 9 10 11 12 |
# 安装VSFTPD程序[版本为3.0.3]; sudo apt-get install vsftpd -y # 补充:VSFTPD版本查询; vsftpd -v # 安装BerkeleyDB数据库[版本为5.3.28]; sudo apt-get install db5.3-util -y # 补充:BerkeleyDB版本查询; # BerkeleyDB任何一个可执行命令使用[-V]参数均可查询; db5.3_archive -V |
四、FTP服务的环境配置
以下命令包括了FTP默认根目录的设备,虚拟用户的宿主用户创建,虚拟用户数据库文件创建、认证模块配置等内容;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# 创建FTP默认根目录位置[注意目录的用户与权限]; # 本处为使用'Fiona'用户登录; # 实际上如果你严格按照本教程的过程操作,并不需要特别关心权限问题; mkdir -p /home/Fiona/FTP # 建立VSFTPD虚拟用户的宿主用户'FriendFtp'[本地用户]; # 注意: # 本处一定要建立宿主用户的'HOME'目录, # 否则当配置文件中启用[guest_enable=YES]功能时,VSFTPD服务识别所有用户为虚拟用户, # 由于缺少初始的登录点,FTP客户端将提示不一定正确的'无法登录'的提示信息; # 当虚拟用户功能启用时,VSFTPD服务应该是先登录至宿主用户的主录, # 再切换至配置文件中[local_root=]指定的主目录; sudo useradd -u 1002 -g 1000 -d /home/FriendFtp -s /usr/sbin/nologin -m FriendFtp # 创建记录虚拟用户用户名与密码的相关文件以生成对应数据库; # 创建'/etc/vsftpd'文件夹及文件'/etc/vsftpd/FriendFtp.txt' # 为生成虚拟用户对应的数据库 格式为单数行代表用户名,双数行为其对应密码; # 本例将只创建一个用户名为'Friend' 密码为'FriendPasswd'的虚拟用户; # 数据库内的所有虚拟用户将影射至'FriendFtp'这个宿主用户; # 'FriendFtp.db'是基于'FriendFtp.txt'文件生成的数据库; # 最后调整数据库的权限保证安全; sudo mkdir -p /etc/vsftpd/UserConf sudo touch /etc/vsftpd/FriendFtp.txt echo "Friend" | sudo tee /etc/vsftpd/FriendFtp.txt echo "FriendPasswd" | sudo tee -a /etc/vsftpd/FriendFtp.txt sudo db5.3_load -T -t hash -f /etc/vsftpd/FriendFtp.txt /etc/vsftpd/FriendFtp.db sudo chmod 600 /etc/vsftpd/FriendFtp.db # 本处使用LINUX自带的PAM认证模块进行对FTP用户合法性认证; # 关于PAM模块配置定义及运行方式请自行百度或谷歌; # 这将需要修改'/etc/pam.d/vsftpd'这份配置文件; # 请注意以下字方式A与B的区别: # 方式A:'auth sufficient /lib/arm-linux-gnueabihf/security/pam_userdb.so db=/etc/vsftpd/FriendFtp.db' # 方式B:'auth sufficient /lib/arm-linux-gnueabihf/security/pam_userdb.so db=/etc/vsftpd/FriendFtp' # 即最后的'.db' 请注意下面的操作命令 并没有带文件名的后缀 即'.db'; # 但实际上是指向'/etc/vsftpd/FriendFtp.db'这份文件的; # 如果按照'pam_userdb.so'的官方文档,正确的写法应该是方式A; # 但测试过程中方式A并不适用于树莓派架设VSFTPD,本处应该使用方式B; sudo cp /etc/pam.d/vsftpd /etc/pam.d/vsftpd.bak sudo sed -i 1i'auth sufficient /lib/arm-linux-gnueabihf/security/pam_userdb.so db=/etc/vsftpd/FriendFtp' /etc/pam.d/vsftpd sudo sed -i 1a'account sufficient /lib/arm-linux-gnueabihf/security/pam_userdb.so db=/etc/vsftpd/FriendFtp' /etc/pam.d/vsftpd |
五、VSFTPD的配置文件
在配置完成VSFTPD程序的基本环境后,现修改VSFTPD的配置文件,以下为配置文件的内容[可直接复制使用],读者也可按实际需求进行修改,但建议应先按本配置文件,将服务正常运行起来后,再按个性化修改,以方便确认修改后的问题判断。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
# ---------------------------------------------- # 默认全局配置项目[优化] # ---------------------------------------------- # 本处为VSFTPD默认的配置文件中的所有功能指令 # 本配置进行了简单优化 # NO设定服务器独立运行[非守护进程模式] listen=NO # YES设定启用IPV6支持 listen_ipv6=YES # NO设定禁止匿名用户登录 anonymous_enable=NO # YES设定允许本地用户登录 local_enable=YES # YES设定允许本地用户具有写权限 write_enable=YES # 设定本地用户上传文件时的UMASK码[默认值077] local_umask=022 # YES设定允许匿名用户上传文件 # anon_upload_enable=YES # YES设定允许匿名用户新建文件夹 # anon_mkdir_write_enable=YES # YES设定显示目录说明文件[需要手工创建'.message'文件] # 保持默认设定 dirmessage_enable=YES # YES设定使用本地系统上的时间 use_localtime=YES # YES设定启用VSFTPD自带的上传下载日志记录功能 xferlog_enable=YES # YES设定保证金数据传输端口为20[ftp-data] connect_from_port_20=YES # 当匿名文件上传时 可即时改变文件的拥有者权限 # 可以是本地系统上的任意用户 不建议使用'root'用户 # chown_uploads=YES # chown_username=whoever # 指定使用VSFTPD自带日志记录功能时 日志文件的保存位置 xferlog_file=/var/log/vsftpd.log # YES设定指定日志条目的格式[格式定义由'/var/log/xferlog'文件进行配置] # xferlog_std_format=YES # 设定默认的断开不活跃session的时间 idle_session_timeout=300 # 设定数据传输超时时间 data_connection_timeout=60 # 本处为建议在本地系统上创建一个唯一的用户 并以该用户运行VSFTPD服务 # 隔离FTP服务与其它本地用户的权限 使其真正独立运行 将更加安全 # nopriv_user=ftpsecure # YES设定启用可识别ABOR请求[官方不建议启用] # async_abor_enable=YES # YES设定强制启用ASCII模式进行文件上传或下载 # 易受DoS攻击[官方不建议启用] # ascii_upload_enable=YES # ascii_download_enable=YES # 当在SHELL登录到VSFTPD服务器时将显示本条欢迎信息 # ftpd_banner=Welcome to blah FTP service. # YES设定启用电子邮件黑名单[可防止名单上黑客实行DoS攻击] # 设定黑名单文件的保存位置[默认'/etc/vsftpd.banned_emails'] # deny_email_enable=YES # banned_email_file=/etc/vsftpd.banned_emails # YES设定所有本地用户将被限制在其HOME目录下或指定的主目录下 # YES设定启用例外列表 # 设定例外列表文件的保存位置[默认'/etc/vsftpd.chroot_list'] # chroot_local_user=YES # chroot_list_enable=YES # chroot_list_file=/etc/vsftpd/vsftpd.chroot_list # YES设定启用'ls'命令的'-R'参数[部分FTP客户端可能需要启用本项] # 官方建议启用 ls_recurse_enable=YES # 用于在执行不需要文件系统访问的操作时 将守护程序锁定在不可写的文件夹中 # 此条必需启用 保持默认设定 secure_chroot_dir=/var/run/vsftpd/empty # VSFTPD将使用PAM服务的配置文件的名称 # 本处的'vsftpd'实际指向位置为'/etc/pam.d/vsftpd'文件 pam_service_name=vsftpd # 设定基于SSL协议的安全加密传输服务[SFTP] # 保持默认设定[默认未启用] rsa_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem rsa_private_key_file=/etc/ssl/private/ssl-cert-snakeoil.key ssl_enable=NO # YES设定VSFTPD服务进程将使用UTF-8文字编码 utf8_filesystem=YES # ---------------------------------------------- # 自定义配置项目[新增] # ---------------------------------------------- # 本处为额外增加的功能指令 更多指令请查看官方文档 # YES设定将VSFTPD的日志条目记录在系统的日志文档内[/log/etc/message] # VSFTPD的日志功能对中文不友好 无法正常显示中文 # 启用本功能能解决中文显示问题 但此方法不利于VSFTPD的日志的单独管理 #syslog_enable=YES # 设置所有用户登陆后其主目录 local_root=/home/Fiona/FTP # 定义单个用户个性配置文件的目录 # 目录的文件名对应用户名 自定义配置指定写在相关文件内即可 user_config_dir=/etc/vsftpd/UserConf # ---------------------------------------------- # 自定义虚拟用户部分[新增] # ---------------------------------------------- # 本处为额外增加的功能指令 更多指令请查看官方文档 # 如果要同时启用本地用户与虚拟用户 同时要求本地用户具有不止读的权限 # 则[guest_enable=YES|NO]为关键指命 必须在个人配置文件中定义此指令的启用或禁用 # 以切换VSFTPD服务对用户的识别状态[虚拟用户状态|本地用户状态] # YES设定启用虚拟用户登录功能 # 当本指令被启用[YES] 则所有登录用户均被识别为虚拟用户 应用虚拟用户的权限 # 当本指令被禁用[NO] 则所有登录用户均被识别为本地用户 应用本地用户的权限 guest_enable=YES # VSFTPD虚拟用户对应的本地用户[宿主用户] guest_username=FriendFtp |
当配置文件编写完成后,应替换服务器上的原配置文件,并重启VSFTPD服务以应用新配置;
1 2 3 4 5 6 7 8 9 |
# 备份VSFTPD原配置文件; sudo cp /etc/vsftpd.conf /etc/vsftpd.conf.bak # 用新编写的配置文件替换原VSFTPD配置文件; # 本处假定新编写的'vsftpd.conf'文件已上传至当前目录下; sudo cp vsftpd.conf /etc/vsftpd.conf # 重启VSFTPD服务; sudo service vsftpd restart |
六、识别本地用户
至此,你可以测试VSFTPD服务是否可能正常运行了,你会发现无论是本地用户还是虚拟用户均能正常登录,同时你也会发现,即使你在全局配置文件开启了本地用户的写权限,但在使用本地用户登录时,依然无法上传文件,这是因为全局配置文件中设定了[guest_enable=YES],所以即使实际上是本地用户,但VSFTPD服务进程还是将其实识别为虚拟用户。
要解决这一问题,我们只需要定义并配置登录用户的个性化配置文件即可;方法为:在个性化的配置文件中,禁用虚拟用户功能即可[guest_enable=NO];以下为示例配置方法。
1 2 3 4 5 |
# 在全局配置中启用虚拟用户功能[guest_enable=YES] 所有登录用户均被VSFTPD识别为虚拟用户 # 写权限被限制 本处建立本地用户的额外配置文件 设定当使用本地用户登录时 关闭虚拟用户功能[guest_enable=NO] # 如此 使全局配置中有关本地用户的权限设定能被正确识别 使本地用户登录时具有读写权限 sudo touch /etc/vsftpd/UserConf/Fiona echo "guest_enable=NO" | sudo tee /etc/vsftpd/UserConf/Fiona |
七、提供公网服务
至此,你的FTP服务已经能在内网正常访问了,将其映射出公网还需要一些条件,本教程将讨论无固定公网IP的方法[注:家庭宽带如有公网IP,一般为动态公网IP,另外由于IPV4资源的缺乏,目前大部分国内宽带运营商默认都不会分配公网IP给拨号用户]。首先,需要确定你的家庭宽带拨号能获取到公网IP,然后使用网上免费的DDNS服务实现动态域名解释[如花生壳],再使用路由器上的端口映射服务将FTP端口映射出公网即可。对于DDNS与端口映射功能,普通的家用路由器也配备。关于DDNS与端口映射的使用方法,不在本教程的讨论范围,请参照网上其它教程。
八、结语
最后,本篇《基于树莓派搭建私有VSFTPD服务器》的教程已全部结束。本教程的重点是虚拟用户与本地用户同时共存,现在,你可以将你的虚拟用户分享给你的朋友或同事,方便的文件分享,而不需要担心他们修改你的文件或破坏你的系统,因为他们仅有读权限[下载],而且可访问范围也被严格限制;而你可以使用本地用户登录,你可以做任何你想做的事[上传、下载、新建、切换至真正的根目录],唯一需要的就是,你的本地用户的权限允许。
你好.....
2020-04-28 下午9:35依教程執行後本地用戶可登入,虛擬用戶出現認證失敗如下
狀態: 正在連線到 192.168.43.219 ...
回應: fzSftp started
指令: open "[email protected]" 22
指令: 信任新的主機金鑰:一次
指令: Pass: ************
錯誤: 認證失敗.
錯誤: 嚴重錯誤
錯誤: 無法連線到伺服器
請問是哪裡出錯了?.........麻煩了,謝謝^_^
你好,我没想到这个博客有人在看……代码我当时是测试过没问题的,建议先使用未作任何更改的官方系统直接复制代码[不作任何修改],确认服务能正常运行再按自己的意愿修改[排除代码错误]。你的情况应该是密码错误,注意是否输入了正确的密码。如果确认密码没问题,可以尝试重新生成虚拟用户的用户与密码的数据库文件[“四、FTP服务的环境配置”代码中的24-27命令]。另外,你也可以尝试使用“四、FTP服务的环境配置”代码中的30-42中方式A。另外完全断电设备再重启,很多时候能解决很多不可预期的意外报错。
2020-05-24 上午12:54另外,注意下建立服务时的系统环境,比如操作系统的版本,软件的版本,有时官方更新后会修改一些BUG,或变更一些东西,这都可能影响到原来代码的有效性。这些教程其实随时都可能会过时,建议你了解那些代码到底是做了什么,为什么这么做[有些命令只能运行一次,因为是向原配置文件中插入了新的配置],这样,无论官方如何更新,你都能保证调整少量配置,以保证服务能正常运行。另外,从你创建服务的时间来看,你应该使用了官方更新后的操作系统了[树莓派4],本文未在新系统上测试,但正常情况一般不影响。
2020-05-24 上午1:08