服务器文件访问协议
- 摘要
- NFS、CIFS、SMB概述
- SMB
-
- [Windows SMB](#Windows SMB)
- [Linux Samba](#Linux Samba)
- [Python SMB](#Python SMB)
- NFS
摘要
本篇博客参考网上文档和博客,对基于网络的服务器/主机的文件访问、共享协议进行简要总结,完整内容将会不断更新,以便加深理解和记忆
NFS、CIFS、SMB概述
在网络环境中,NFS和CIFS(基于SMB协议)使用IP/TCP协议在服务器和客户端之间共享文件
比较 | NFS | CIFS |
---|---|---|
名称 | 网络文件系统 | 通用互联网文件系统 |
当前版本 | 4 | 被SMBv3取代 |
适用 | Unix网络架构(Windows可通过第三方软件包使用) | Windows架构(Linux也可通过Samba服务使用) |
共享资源 | 文件和目录 | 文件目录和网络资源(如打印机) |
身份验证 | 基于IP(有限) | 基于用户(更安全) |
文件锁定(避免多客户端同时写入发生冲出) | 由客户处理(无状态,服务器不跟踪) | 由服务器处理(文件锁) |
性能 | 高 | 低 |
SMB
SMB(Server Message Block)是一个网络文件共享协议,允许应用程序和终端用户从远端的文件服务器访问文件资源(文件下载和上传)
Windows SMB
- Windows 10 开启SMBv1(重启计算机)
-
创建共享:文件夹右键→共享→高级共享→设置共享名→设置共享权限(建议共享权限为everyone完全共享,everyone是指本机下的所有用户)(基于445端口,微软系统默认开启445端口)
- 本地登录时,只受NTFS权限的影响
- 远程登陆时,将受NTFS权限和共享权限的共同影响(取交集)
-
访问共享:在
开始-运行
或我的电脑-地址栏
中输入UNC地址(通用命名规则,Universal Naming Convention,(局域)网络上资源的完整windows名称)(需要Netbios-ns137、138以及TCP139端口,查看本地打开的端口号:netstat -an
)\\{IP或服务器名}\{共享文件夹名称}\{共享文件名称}
,\\DESKTOP-8MHVICE\book
或\\127.0.0.1\book
- 隐藏文件夹的共享与访问:共享名 ,访问: ' I P 或服务器名 { 共享文件名称 ,访问:`\\{IP或服务器名}\{共享文件名称 ,访问:'IP或服务器名{共享文件名称}`
- 共享相关命令
shell# 列出共享列表 net share # 创建共享 net share {共享名}={共享路径} # 删除共享 # IPC$无法通过/del命令取消共享,且通过此共享名可以访问此电脑所有文件 net share book /del
- 屏蔽系统所有分区隐藏共享自动产生(当取消共享系统隐藏共享文件夹时,重启后,这些文件夹会自动恢复共享状态)
打开注册表:
win+r
键入regedit
定位到共享注册表位置
HKEY_Local_MACHINE\System\CurrentControlSet\Services\LanmanServer\Parameters
右键新建
REG_DWORD
类型的AutoShareServer
键,值为0
-
关闭端口
-
关闭445端口
- 打开services.msc(win+r services.msc)停止并禁用server服务
- 防火墙限制规则(Win7、Win2008及以上系统):控制面板→防火墙→高级设置→入站规则(右键、新建入站规则)→协议和端口:由于445端口的特殊性,需要新建两个规则,分别选则TCP和UDP,并在下方输入框中输入445→下一步
- 关闭139端口:控制面板→网络和Internet→网络连接(右键属性)→TCP/IP协议(右键属性)→高级→WINS中设置启用或禁用NBT(NetBIOS over TCP/IP)
-
Linux Samba
shell
# 1.关闭防火墙
## 确保防火墙允许 Samba 服务端口
sudo ufw allow Samba
## 查看防火墙状态
systemctl status firewalld.service
## 关闭防火墙
# systemctl stop firewalld.service
## 永久关闭防火墙
# systemctl disable firewalld.service
## 2.安装samba服务
# yum(centos默认)
yum install -y samba
# apt(Ubuntu默认)
apt install samba
# 3.修改samba配置文件
## 备份
cp /etc/samba/smb.conf /etc/samba/smb.conf.bak
## 在[global]下增加配置
map to guest = Bad User
# map to guest = never
#### 指定 Samba 使用用户级别安全性,要求每个连接都有指定的用户名和密码
security = user
#### 强制 Samba 使用 SMB1 协议
min protocol = NT1
max protocol = NT1
## 在文末添加[share]配置
[share]
comment = This is samba dir
# 路径
path = /home/share
read only = no
create mask = 0777
directory mask = 0777
writable = yes
browseable = yes
guest ok = yes
# 限制只有 sambauser 用户可以访问共享
valid users = sambauser
# 4.创建共享文件夹
mkdir /home/share
## 给文件夹赋最高权限
# sudo chown nobody:nogroup /home/share
chmod -R 777 /home/share
# 6.添加samba用户
## 创建系统用户(如果尚未创建)
sudo useradd -M -s /sbin/nologin sambauser
smbpasswd -a sambauser
# 7.重启samba服务
systemctl restart smb
# 8.设置samba开机自启
systemctl enable smb
systemctl enable smb.service
# 9.查看 Samba 使用的端口(TCP 139 - NetBIOS 会话服务;TCP 445 - 直接 TCP/IP CIFS)
sudo ss -tuln | grep ':139\|:445'
## sudo netstat -tuln | grep ':139\|:445'
## sudo lsof -i -P -n | grep smbd
# 10.查看 Samba 服务状态
sudo systemctl status smbd
# 11.使用 smbclient 进行测试(在本地或远程测试 Samba 共享连接)
# https://blog.csdn.net/yexiangCSDN/article/details/82867469
smbclient //localhost/shared -U sambauser
# 12.nmbd(NetBIOS)配置
"""
(1)nmbd 是 NetBIOS 名称服务的守护进程,用于在局域网(LAN)环境中解析主机名。假如你需要通过主机名而不是 IP 地址访问局域网 Samba 服务器,可以配置使用 nmbd。
(2)但是,nmbd 和 NetBIOS 广播在公网环境中不可用,因为:
①NetBIOS 依赖局域网广播:NetBIOS 使用 UDP 广播进行名称解析,只能在局域网内工作,无法跨越路由器、NAT 网关或互联网进行解析
②安全性问题:在公网中启用 nmbd 并开放 UDP 137 和 138 端口可能带来安全风险,因为这些端口容易受到攻击
③标准的主机名解析应使用 DNS:在公网或跨网环境中,推荐使用 DNS 服务器进行主机名解析,安全性和稳定性更高
(3)nmbd 监听的端口:UDP 137 - NetBIOS 名称服务:用于名称解析;UDP 138 - NetBIOS 数据报服务:用于浏览和发现服务
"""
## 确保 nmbd 启用(启用 nmbd 服务,使得主机名可以在局域网中被发现和解析)
sudo systemctl start nmbd
sudo systemctl enable nmbd
## 配置 NetBIOS 名称:在 /etc/samba/smb.conf 的 [global] 部分设置 netbios name:
[global]
netbios name = debian # 将此处的名称更改为你的主机名
## 检查 nmbd 监听端口
sudo ss -uln | grep ':137\|:138'
## 使用主机名连接
\\debian\shared
## 禁用 nmbd
sudo systemctl stop nmbd
sudo systemctl disable nmbd
# 13.公网主机名访问 SMB 的正确方法
## 配置 DNS 解析: 在公网环境中,通过购买域名并在 DNS 服务器中配置 A 记录,将服务器 IP 地址与主机名关联
\\{HostName}.{domain}.com\shared
## 修改Hosts文件: 对于临时使用,可以在客户端的 Hosts 文件中手动添加主机名和 IP 地址的映射
{云服务器的公网IP} {HostName}
Python SMB
python
# pip install pysmb
# 1.登录到SMB服务器
from smb.SMBConnection import SMBConnection
host="xxx.xxx.xxx.xxx" #ip或域名
username="xxxxxx" #用户名
password="xxxxxx" #密码
conn=SMBConnection(username,password,"","",use_ntlm_v2 = True)
result = conn.connect(host, 445) # smb协议默认端口445
# 2.上传文件到smb服务器
"""
rb代表read+binary模式,即"读二进制文件".注意如果是二进制文件,比如zip包,需要加上参数b,即binary模式,默认是t模式,即text文本模式。上传二进制文件时,如果打开本地文件没有加上参数b,会抛出异常:
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xbc in position 2: invalid start byte
这是因为文件被当作文本文件,二进制文件无法转码成普通字符。因此需要改成二进制文件读取。
"""
localFile=open("本地文件路径","rb")
## "共享文件夹名称"是一个文件夹,即smb共享文件夹。"存放路径"是相对共享文件夹下的文件
## 上传文件到smb服务器,默认超时30秒,可以添加参数修改:timeout=xx。
conn.storeFile("共享文件夹名称","存放路径",localFile)
localFile.close()
# 3.从smb服务器下载文件到本地,b同上
localFile=open("下载后的文件路径","wb") # 写二进制文件
## 从smb服务器下载文件到本地,默认超时30秒,可以修改:timeout=xx。"文件所在路径"是相对共享文件夹的路径,不需要加"/".
conn.retrieveFile("共享文件夹名称","文件所在路径",localFile)
localFile.close()
# 4.关闭连接
conn.close()