FTP服务简介

前言

网络的诞生其实最早是 冷战期间美国和苏联对抗时,美国担心苏联对它进行核打击,一旦指挥部被摧毁的话,整个战争将对美国不利。所以美国为了避免指挥中心集中化,一旦被攻击就会处于不利局面。美国开始发展网络技术,最初的网络有四个节点,这四个节点任何一个节点都可以作为指挥中心来进行工作。所以说,一个节点被苏联军事打击,其他节点也能工作。

  • 通过网络的连接进行去中心化,多节点共存,进行资源共享,这也是网络诞生最初的动因
  • 互联网刚诞生时完全是为了资源共享,安全没有人关心。大家只要能共享资源,最早资源共享的形式,就是文件,那时没有数据库、网站什么的。
  • 文件服务的话题非常久远,比web还要早,就是因为太久远,当初设计的时候没有考虑安全功能。之后往文件功能加安全功能,总感觉捉襟见肘。所以,文件服务被很多重视安全领域的抛弃,大家已不再使用基本的文件共享功能,转而使用一些提供了安全特性的文件共享方式。

FTP(File Transfer Protocol)

  • 早期互联网的重要服务
  • 产生于安全出现之前
  • 基于明文传输
  • 目前主要用于公开提供的文件下载服务
  • 使用简单、兼容性好
  • SFTP、FTPS

FTP服务端软件:

  • windows平台使用Server U
  • Linux平台使用vsftpd、proftpd

处于安全考虑

  • 独立部署于企业防火墙之外。 有些情况下会需要客户端提供上传文件功能,上传文件到它的服务器上去,所以一般来说,ftp服务器不会部署在企业内部网路里面。这样,如果ftp服务器被入侵了,受损失的只是一台服务器的操作系统被控制了,但如果ftp服务器部署在了企业内部网络,一旦ftp服务器被入侵了,黑客会以ftp服务器为跳板,渗透到公司内网去,给企业造成巨大损失。
  • 只读挂载存储或采用只读存储设备(CD / DVD)

vsftp管理

Vsftpd

灵活、安全的FTP的服务端软件

安装登录

1
2
3
sudo apt install vsftpd

在安装过程在生成一个ftp账号,也就是匿名账号(anonymous)

ftp账号

1
2
3
4
5
6
7
cat /etc/passwd        # /bin/false   不允许本地使用终端进行登录,也不允许ssh远程进行登录
cat /etc/shadow # *

/srv/ftp # ftp用户主目录


ftp 172.16.247.128 # 使用系统账号登录成功,默认在系统的主目录下

常见的FTP客户端

  • 浏览器
  • FTP命令
  • FTP客户端程序(Filezilla)
  • 文件同步客户端软件

使用filezilla的ftp客户端软件登录:

配置模式

  • anonymous # 匿名模式(使用于公共共享文件)
  • Standard # 认证模式

配置文件 /etc/vsftpd.conf

设置匿名模式:

vsftpd默认禁止匿名登录

1
2
3
4
5
6
7
8
sudo vi /etc/vsftpd.conf       # 修改配置文件

anonymous_enable=YES # 启动匿名账号登录
local_enable=NO # 禁用认证用户登录


sudo systemctl restart vsftpd.service # 重启服务
sudo systemctl status vsftpd.service # 查看服务状态

匿名模式下的配置

匿名模式下默认是不能文件上传的

开启匿名账号上传

1
2
3
4
5
6
7
8
9
sudo vi /etc/vsftpd.conf     
# 修改配置文件

write_enable=YES # 全局设置,任何人想要向服务端上传文件,都要开启
anon_upload_enable=YES # 允许匿名用户向服务器上传文件,不包括在ftp服务器新建目录
anon_mkdir_write_enable=YES # 允许匿名创建目录


sudo systemctl restart vsftpd.service # 重启服务

匿名上传

1
2
3
4
vsftpd强制禁止在根目录下匿名上传
sudo mkdir/src/ftp/upload #创建上传目录
sudo chown ftp:ftp upload # 配置文件系统权限

1
2
3
4
5
6
7
# 可以看到上传文件的权限,所有主的权限是读和写,但是我要把所有上传上来的文件的权限都修改成不一样的

sudo vi /etc/vsftpd.conf # 修改配置文件

# 添加配置
anon_umask=022 # 上传文件权限掩码
anon_other_write_enable=YES # 允许删除和重命名文件/ 目录

修改FTP主目录

1
2
3
# 默认ftp服务器的主目录是/src/ftp,可以修改
sudo mkdir /src/files/ # 想把files作为主目录
sudo chown root:ftp files/ # 权限修改

文件传输日志

在配置文件里配置

1
2
3
4
sudo vi /etc/vsftpd.conf

xferlog_enable=YES # 默认开启
xferlog_file=/var/log/vsftpd.log # 默认日志目录

其他配置

1
2
3
4
5
# sudo vi /etc/vsftpd.conf

idle_session_timeout=600 # 会话超时时长
no_anon_password=YES # 命令行登录禁用密码提示
hide_ids=YES # 显示属主/属组名称(默认uid)

数据传输模式

  • 主动模式 :受客户端防火墙影响
  • 被动模式 : 兼容性好(建议方式)
  • ftp -p 10.1.1.1 被动方式链接

会话指令通信端口:TCP 21

限定被动模式数据通信端口

  • pasv_min_port=40001
  • pasv_max_port=40100

在服务器端边界防火墙上开放上述 100个端口

身份认证登录FTP

  • 这是默认配置
  • 但不能上传,只能下载
  • 可回溯到根目录(安全隐患)

解决方法:

利用chroot将登录用户锁定在自己的主目录里

1
2
3
4
5
6
7
sudo vi /etc/vsftpd.conf

# 启用配置
chroot_local_user=YES

# 重启服务
sudo systemctl restart vsftpd.service

默认主目录可写,而chroot的功能禁止进入的所在目录有写的权限,这样就不能登陆了。而这样就与 这个主目录要有可写的权限的需求矛盾了。

法1: 为FTP登录指定新的主目录

当cwz这个用户以ftp服务登录进来时,ftp获得的主目录将不再是cwz的主目录,而是另外一个目录。

1
2
3
4
5
6
7
8
9
10
mkdir ~/ftp     # 创建ftp主目录
chmod -w ftp/ # 删除写权限

sudo vim /etc/vsftpd.conf

# 添加如下配置
local_root=/home/cwz/ftp

# 重启服务
sudo systemctl restart vsftpd.service

法2: 允许根目录写入

不修改主目录的情况下登录

1
2
3
4
5
6
7
sudo vim /etc/vsftpd.conf

# 修改、添加配置
chroot_local_user=YES
write_enable=YES
local_root=/home/cwz
allow_writeable_chroot=YES # 运行chroot登录可写

从安全角度,更建议使用第一种方法。vsfpd的官方文档上,强烈不建议在chroot的根目录下开启可写权限。

指定chroot的用户列表

之前是启用的全局配置 chroot_local_user=YES

1
2
3
4
5
6
7
8
9
sudo vi /etc/vsftpd.conf

# 修改启用配置,不启用全局配置 chroot_local_user=YES
chroot_list_enable=YES
chroot_list_file=/etc/vsftpd.chroot_list # 账户列表,默认是没有的,需要手动创建,添加账号,如添加'cwz'

sudo vim /etc/vsftpd.chroot_list
# 添加用户
cwz

如果启用全局配置 chroot_local_user=YES,又有chroot_list_enable,那chroot就不绑定主目录的用户列表,还是会回溯到根目录。

1
2
3
sudo vim /etc/ftpusers         
# 默认禁止FTP登录账号,加到这个列表,禁止登录
# 这是一个用户列表,有root\demon\sys\bin\nobody

其他配置

上传文件权限掩码: local_umask=022, 原来文件权限为666上传过来就会变为644

文件同步客户端

能够周期性的、自动的将文件上传到ftp服务器,这样如果本机文件丢失也还有备份。

安全方面

FTPS: FTP over Secure Socket Layer (SSL),基于证书的加密。

  • 建议ftp账户不要有shell登录权限

SFTP: 基于SSH加密通道传输文件

  • 账号需要shell登录权限(可设置禁止权限)

开启FTPS

1
2
3
4
5
6
7
8
9
sudo vi /etc/vsftpd.conf

# 启用配置
ssl_enable=YES # 启动证书
rsa_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem #证书
rsa_private_key_file=/etc/ssl/private/ssl-cert-snakeoil.key # 私钥


sudo systemctl restart vsftpd.service # 重启服务

不启用ssl,ftp传输使用的是明文。

客户端连接上ftp服务器, FTP服务器会发一个含有公钥的证书, 以后客户端所有发送的数据都要经过公钥加密之后才会发送给服务器,服务器然后用私钥解密

替换默认证书

这是出于安全考虑

生成证书的过程:

  • 先生成一对秘钥,一个公钥一个私钥
  • 拿着公钥去生成一个证书申请文件
  • 再由证书颁发机构对提交的证书申请文件,申请这张证书。
  • 生成完的证书再交给你使用

生成密钥文件:

1
openssl genrsa -des3 -out ftp.key 2048

生成不加密的密钥

1
2
3
4
5
openssl rsa -in ftp.key -out ftp.key.insecure    # 需要临时解密,使用里面的秘钥文件,使用完就删掉

mv ftp.key ftp.key.secure # 重命名加密的秘钥文件

mv ftp.key.insecure ftp.key # 这样ftp.key就是明文文件了

生成证书请求文件

1
openssl req -new -key ftp.key -out ftp.csr

生成自签名证书,唯一的缺陷就是不能做身份认证,除此之外,加密的功能都有。

1
openssl x509 -req -days 365 -in ftp.csr -signkey ftp.key -out ftp.pem        

生产环境建议有证书颁发机构签名生成证书

部署证书:

1
2
3
4
5
6
7
8
9
10
11
12
13
sudo cp ftp.key /etc/ssl/private

sudo cp ftp.pem /etc/ssl/certs

sudo vi /etc/vsftpd.conf
# 修改证书文件位置
rsa_cert_file=/etc/ssl/certs/ftp.pem
rsa_private_key_file=/etc/ssl/private/ftp.key
ssl_enable=YES


# 重启服务
sudo systemctl restart vsftpd.service

上述过程可以一条命令生成:

1
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/vsftp.key -out /etc/ssl/certs/vsftpd.pem

NFS服务

NFS ——Network File System,网络文件系统

介绍

  • 最早由SUN公司开发
  • 类unix平台最主要的文件共享服务
  • 基于RPC(Remote Procedure Call) 协议, 此协议可以跨网络进程间通信
    • NFS是一个RPC Server (v3 / v4)
  • 协议本身不加密,可结合SSH kerberos加密
  • 隐藏式身份验证,客户端本地用户的身份去尝试登录服务器端
  • 权限配置是关键
  • 服务端口 TCP 2049

安装

1
2
sudo apt install nfs-kernel-server            # 服务端
sudo apt install nfs-common # 客户端

查看RPC和 NFS服务进程:

1
2
3
4
5
6
7
8
9
10
ps -ef | grep rpc


ps -ef | grep nfs

rpcbind # RPC服务进程
nfsd # NFS主进程(身份识别)
mountd # 根据/etc/exports 配置验证
lockd # 锁定(需要C/S同时启用)
statd # 一致性(需C/S同时启用)

身份识别

客户端访问服务端,默认情况下,客户端登录操作系统的用户,以这个身份的uid、gid。当客户端登录nfs服务器,会使用客户端本机的账号的uid、gid这个身份,去访问服务端的nfs的共享目录,而且试图使用客户端的uid去登录服务器端,完成身份认证,去访问共享文件夹。

客户端以当前登录账号的uid向服务器端进行身份认证,如果服务器端相应的相同的uid对文件夹有访问权限的话,客户端就自动获得服务器相同uid账号的权限去访问服务器的那个文件夹。这是在服务端和客户端相同uid的情况下。

如果在客户端和服务端uid不相同的情况下,只有一种结果,客户端无论使用什么账号,只要你uid和服务器端具有访问权限访问文件夹的那个uid不相同,客户端无论你是谁,你都被映射为nobody主账号、nogroup组账号。

如果客户端uid和服务端相同,将获得服务端账号的权限;如果不相同,客户端的用户在访问服务器获得的就只有nobody匿名账号的权限。除非一种情况,你客户端的用户是root账号,而且服务端允许客户端的root账号在服务器端不被映射成nobody,而是映射成root,启用这条配置,客户端才会获得服务端的root权限。

  • 客户端提供UID /GID ,与用户名、组名无关
  • 服务器按客户端UID/GID付权
  • 服务器无客户端UID/GID账号,则将客户端映射为匿名账号
    • nobody / nogroup 在Ubuntu中uid默认是 65534
  • 客户端使用root账号(UID 0), 默认映射为匿名账号
    • 可修改配置文件映射UID 0为服务器ROOT(这样存在安全隐患)

配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
sudo vi /etc/exports      # 主配置文件

# 一行配置都没有,需要手动添加

/export 172.16.247.0/24(rw,sync,no_subtree_check) # 指定ip网段访问 可读可写, 数据先放到内存里(async), 不对子目录进行检查
# 也可以指定域名,或者让所有人访问可以 使用*
no_root_spuash # 禁用root默认映射为nobdy, 还是root权限


sudo mkdir /export # 设置共享目录

sudo systemctl restart nfs-kernel-server.service # 重启服务

sudo chown nobody:nogroup /export/ # 将文件夹的权限设置为nobody

sudo systemctl restart nfs-kernel-server # 重启服务

sudo exportfs # 查看共享目录


cat /var/lib/nfs/etab # 查看共享目录的信息
cat /var/lib/nfs/xtab # 客户端信息

权限

  • 共享权限
  • 文件系统权限
  • ro / rw # 只读 / 读写
  • sync / async 同步写入硬盘 / 暂时存于内存中
  • all_squash 所有用户全部映射为nobody
  • anonuid / anongid 指明匿名ID(默认 65534)
  • secure / insecure 使用1024以下 / 以上端口
  • hide / no_hide 共享 / 不共享NFS子目录

客户端挂载

1
2
3
4
5
6
mkdir nfs      # 先在本机创建挂载目录

sudo mount 172.16.247.128:/export /nfs/ # 将服务器端的export目录挂载到本机的nfs上

ls -ld nfs
drwxr-xr-x 2 nobody nogroup 4096 2月 6 16:02 nfs

启动时挂载

1
2
3
4
5
6
sudo vim /etc/fstab  
# 在fstab文件中添加配置:

172.16.247.128:/home /nfs/ nfs auto,nofail,noatime,nolock,intr,tcp,actimeo=1800 0 0

# 这样有个问题,当nfs有问题,客户端本机启动的速度会异常缓慢

其他命令

1
2
3
4
rpcinfo -p 172.16.247.128       # 查询RPC服务注册状态
tail /var/log/kern.log # 服务器日志
showmount -e localhost # 显示共享目录
df -h # 客户端查看挂载

当企业环境有统一域名和身份认证系统时

1
2
3
sudo vi /etc/idmapd.conf

Domain = lab.com

SAMBA服务

SAMBA文件共享

SMB/CIFS协议

  • Server message block / Common internet file system
  • 最早由IBM研发, 后由微软采用并不断完善
  • 利用微软 WINDOS文件和打印共享 使用SAMBA服务
  • TCP 139 445 端口 / UDP 137 138 端口
  • SAMBA是开源世界逆向了SMB协议后打造的兼容微软SMB的文件共享服务

NFS只适用类UNIX系统环境,适用于Windows Linux混合环境的文件共享需要。

SAMBA实现了CIFS服务四个基本功能

  • 文件和打印共享
  • 认证和授权
  • 名称解析
  • 服务宣告

传输协议

最初在设计SMB的时候,TCP/IP还没有称为标准, 所以在设计网络通信的时候 ,使用的是NetBIOS 协议 . 后来当TCP/IP协议称为通信的事实协议标准,为了让NetBIOS能够跨网段使用,微软就开发了一个NetBIOS over TCP/IP, 也就是用TCP/IP去封装打包NetBIOS的数据格式.

后台进程:

  • smbd 文件共享主进程 TCP139 / 445
  • nmbd wins通信 名称解析UDP 137 / 138
  • winbindd 同步系统账号
  • 其他10多个进程

SAMBA服务器安装使用

1
sudo apt install samba libpam-winbind       # 安装包

配置文件 /etc/samba/

  • dhcp.conf 指定wins服务器
  • smb.conf 主配置文件

需要身份认证的samba服务器配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
sudo vim /etc/samba/smb.conf
# 修改配置文件

[global]
workgroup = WORKGROUP # 工作组

# 增加共享文件夹的配置
[private]
comment = private # 描述
path= /srv/private/ # 共享路径
browseable = yes # 可浏览(完整路径) 就是让不让显示在打开的窗口里,写no,就必须访问明确的文件夹名
guest ok = no # 禁用来宾账号,guest权限很低
writable = yes # 可读写(read only = yes)
create mask = 0755 # 客户端向服务端写入的文件权限
valid users = @samba # 可访问共享的用户组,我只想让公司几个人来访问,即使其他人也有合法的权限,也不想让他们访问。设置了samba组,如果访问者不是samba组里面的成员,就不能打开。

创建用户/组/共享文件夹

1
2
3
4
5
6
7
8
9
10
11
12
13
14
sudo adduser smb1              # 新增用户smb1
sudo groupadd samba # 创建组samba
sudo gpasswd -a smb1 samba # 将smb1账号添加到samba组
sudo smbpasswd -a smb1 # 针对smb1这个用户单独设置用户SMB密码(不同于系统账号密码)

sudo mkdir /srv/private # 创建共享目录

sudo setfacl -R -m "g:samba:rwx" /srv/private/ # 设置组ACL权限,对这个目录,samba组有rwx权限。但是这个过程没有更改属主属组

getfacl private/ # 查看更细致的权限

testparm # 测试samba配置,检测是否正常有无错误

sudo systemctl restart smbd.service nmbd.service # 重启服务

补充命令:

  • setfacl 命令设置设置更为细致的权限
  • getfacl命令查看更为细致的权限 如getfacl private/

客户端访问

Windows客户端

  • 直接在地址栏访问: \\172.16.247.128

  • 利用cmd命令行访问

1
2
3
4
net use \\172.16.247.128\private/user:user1 password  # 访问共享目录 
net use \\172.16.247.128\private /delete # 删除挂载
net use s: \\172.16.247.128\private # 挂载到window盘符s
net config workstation # 查看工作组

linux客户端

1
2
3
4
5
6
sudo apt install smbclient

smbclient -L //172.16.247.128 # 查看
smbclient -L //172.16.247.128 -U smb1
sudo mount -t cifs -o username=smb1,password=qwe123 //172.16.247.128/private /mnt
# 把共享目录挂载到mnt目录

创建公开的共享文件夹

不对访问者进行身份验证

将不提供登录账号的用户映射为guest,无需输入密码

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
sudo vim /etc/samba/smb.conf

# 全局配置
[Global]
workgroup = WORKGROUP
security = user # 在新的samba服务器里支持五种安全类型,通过security=什么来指明安全类型,如果等于user,必须使用用户账号来进行身份验证。 第二种:share已废止 Domian(将samba加入微软域里面) ADS Server

map to guest = bad user # 映射为guest, 当你没有用户名密码的这种user来访问,我就映射为guest user 从而实现公开共享文件夹
guest ok = yes



# 局部配置
[Public]
comment = public share
path = /srv/public/
browseable = yes
writeable = yes
guest ok = yes


# 添加完配置,创建public文件夹,设置权限,重启服务
sudo mkdir /srv/public
sudo setfacl -R -m "u:nobody:rwx" /srv/public/ # 给guest用户权限
sudo systemctl restart smbd.service nmbd.service

samba服务器信息

1
2
smbd --version       # 软件包的版本
sudo smbstatus # Samba共享信息