LinuxNFS实验和Samba实验

作者:

在

NFS基础服务部署和远程挂载使用

# 两台机器初始化均关闭防火墙和selinux
systemctl stop firewalld      # 停止防火墙
systemctl disable firewalld   # 禁用防火墙
setenforce 0
vim /etc/selinux/config # 改为disable
SELINUX=disabled

# 机器1
192.168.18.129/24  # 部署nfs服务端

# 命令合集
dnf install nfs-utils  # 安装nfs服务相关组件  # 新的协议不用rpcbind管理,直接nfs服务
mkdir /nfsdir      # 共享此目录(可以考虑如何加一块新盘共享)
vim /etc/exports  # 写入下方内容
/nfsdir 192.168.18.142(rw,sync,no_root_squash) # 共享的本地路径/nfsdir,允许访问的客户端IP地址,(读写权限|同步写入|客户端以 root 用户访问时,服务端保留其 root 身份,不对其进行降权)
systemctl start rpcbind.service   # 启动rpc服务
systemctl enable rpcbind.service  # 开机允许自启
systemctl start nfs-server.service  # 启动nfs服务端
systemctl enable nfs-server.service # 开机允许自启
exportfs -v   # 查看本机所有nfs共享 -r 参数可用于reload

# 机器2
192.168.18.142/24  # 客户端,将nfs目录挂载为远程目录,可读写

# 命令合集
dnf install showmount
showmount -e 192.168.18.129  # 查看目标nfs服务器有哪些可挂载点
mkdir /mnt/nfs        # 创建挂载点
mount 192.168.18.129:/nfsdir /mnt/nfs/   #挂载
df -Th  # 查看挂载信息
# 也可以永久挂载
vim /etc/fstab
192.168.18.129:/nfsdir                  /mnt/nfs/      nfs4     defaults        0 0 

image-20260803191412925

image-20260803205558182

autofs自动挂载

做此步骤前先将上一步骤挂载的文件系统卸载,且如果永久挂在,删除/etc/fstab中配置文件

dnf install -y autofs
vim /etc/auto.master
/mnt/nfs        /etc/auto.nfs   # 增加此行,意味着后续auto.nfs中配置的挂载信息,将会自动挂载到/mnt/nfs下
vim /etc/auto.nfs               #新建子配置文件
servernfsdir -fstype=nfs4,rw,soft    192.168.18.129:/nfsdir  # 将nfs服务器的nfsdir以servernfsdir名称挂载,效果是,当访问/mnt/nfs/servernfsdir目录,会自动触发nfs挂载
systemctl start autofs.service  # 启动自动挂载服务
systemctl enable autofs.service

# 测试
df -Th # 此时没有nfs
cd /mnt/nfs && ls  # 此时没有任何文件夹
cd /mnt/nfs/servernfsdir # 此时触发自动挂载
df -Th # 可以看到nfs挂载条目

image-20260803213607796


/etc/auto.master 的作用

这是 autofs 的总控配置文件,定义了:

  1. 监控哪些目录
  2. 每个监控目录对应的子配置文件
  3. 全局超时时间

==原理==:

┌─────────────────────────────────────────────────────────────────────────────┐ │ 用户访问流程 │ └─────────────────────────────────────────────────────────────────────────────┘

                         用户执行
                            ↓
                cd /mnt/nfs/servernfsdir
                            ↓
                ┌───────────────────────┐
                │  autofs 接管访问请求  │
                └───────────────────────┘
                            ↓
                ┌───────────────────────┐
                │  读取 /etc/auto.master │
                │  找到 /mnt/nfs 对应   │
                │  /etc/auto.nfs        │
                └───────────────────────┘
                            ↓
                ┌───────────────────────┐
                │  读取 /etc/auto.nfs   │
                │  查找 "servernfsdir"  │
                │  找到映射规则:       │
                │  192.168.226.6:/nfsshare│
                └───────────────────────┘
                            ↓
                ┌───────────────────────┐
                │  执行挂载命令          │
                │  mount -t nfs4 -o     │
                │  rw,soft              │
                │  192.168.226.6:/nfsshare│
                │  /mnt/nfs/servernfsdir│
                └───────────────────────┘
                            ↓
                ┌───────────────────────┐
                │  挂载成功!            │
                │  用户进入              │
                │  /mnt/nfs/servernfsdir │
                └───────────────────────┘
                            ↓
                ┌───────────────────────┐
                │  5分钟不访问          │
                │  → 自动卸载           │
                │  (释放资源)          │
                └───────────────────────┘

映射关系图 text ┌─────────────────────────────────────────────────────────────────────────────┐ │ 映射关系 │ ├─────────────────────────────────────────────────────────────────────────────┤ │ │ │ 用户访问入口 真实挂载目标 │ │ ┌─────────────────────┐ ┌─────────────────────────┐ │ │ │ /mnt/nfs/ │ │ 192.168.226.6:/nfsshare│ │ │ │ servernfsdir │ ═══════════► │ (NFS服务器共享目录) │ │ │ └─────────────────────┘ └─────────────────────────┘ │ │ │ │ │ │ │ │ │ │ ▼ ▼ │ │ ┌─────────────────────────────────────────────────────────────────┐ │ │ │ /etc/auto.nfs 映射规则 │ │ │ │ │ │ │ │ servernfsdir -fstype=nfs4,rw,soft 192.168.226.6:/nfsshare │ │ │ │ ↑ ↑ ↑ │ │ │ │ │ │ │ │ │ │ │ 触发点名称 挂载选项 真实服务器:共享目录 │ │ │ └─────────────────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────────────────┐ │ autofs = 监控系统 + 触发器 │ ├─────────────────────────────────────────────────────────────────────────────┤ │ │ │ 1. 监控功能:autofs 是一个守护进程,持续监控指定的目录访问 │ │ │ │ 2. 触发功能:一旦检测到用户尝试访问监控目录,autofs 立即响应 │ │ │ │ 3. 执行动作:根据配置文件执行对应的挂载操作 │ │ │ │ 4. 清理功能:监控闲置时间,超时自动卸载 │ │ │ └─────────────────────────────────────────────────────────────────────────────┘

案例参考课件部分

其他参考

角色Web 世界网络文件系统世界
具体软件 / 业务应用浏览器 & Web 服务器 (如 Chrome / Nginx)负责处理网页如何展示、网站业务逻辑NFS 客户端 & NFS 服务端 (内核模块)负责处理文件打开、读写、权限等文件逻辑
底层应用层通信协议HTTP 协议规定了请求怎么发(GET/POST)、数据怎么打包(JSON/HTML)ONC RPC 协议规定了远程函数怎么调用(Call/Reply)、数据怎么打包(XDR)

NFSv2/3

[ 客户端 (Client) ]                                       [ 服务端 (Server) ]
        |                                                         |
        |======= 第一轮:控制面服务寻址 (Portmapper) ======================|
        |                                                         |
        |--- (1) 查号: mountd 在哪个端口? [基于 ONC RPC] --------->| Port 111
        |<-- (2) 告知: 今天在端口 32768 --------------------------| (Portmapper)
        |                                                         |
        |======= 第二轮:控制面文件挂载 (mountd) ==========================|
        |                                                         |
        |--- (3) 挂载请求: 验证权限并请求目录句柄 -------------------->| Port 32768
        |<-- (4) 挂载成功: 返回根目录的文件句柄 (File Handle) ------| (mountd)
        |                                                         |
        |======= 第三轮:数据面文件读写 (nfsd) ============================|
        |                                                         |
        |--- (5) 读数据: 携带句柄、偏移量、读取长度 ------------------>| Port 2049
        |<-- (6) 返回数据: 传输真实的二进制文件内容 -------------------| (nfsd)
        |                                                         |

NFSv4

[ 客户端 (Client) ]                                       [ 服务端 (Server) ]
        |                                                         |        |                                                         |
        |======= 核心控制与数据复合传输 (TCP Single Pipe) =================|
        |                                                         |
        |--- (1) 发送 COMPOUND 复合操作打包报文 -------------------->| Port 2049
        |        |                                                | (nfsd 核心引擎)
        |        +-- [内含操作 1]: PUTROOTFH (定位根句柄)            |
        |        +-- [内含操作 2]: LOOKUP    (寻找路径)             |-- 服务端内核
        |        +-- [内含操作 3]: OPEN/LOCK (打开并加锁)           |   收到处理返回        
        |        +-- [内含操作 4]: READ      (直接读数据)           |   
        |                                                         |   
        |                                                         |
        |<-- (2) 返回 COMPOUND 复合回复报文 ------------------------|
        |        |                                                |
        |        +-- [回复 1]: 状态 NFS4_OK                       |
        |        +-- [回复 2]: 状态 NFS4_OK                       |
        |        +-- [回复 3]: 状态 NFS4_OK (锁定成功)             |
        |        +-- [回复 4]: 状态 NFS4_OK + [真实文件数据]       |
        |                                                         |

==总结==:

1.rpcbind和nfs服务端关系

核心关系:服务发现与端口映射

NFS 服务在设计上依赖一种叫做 RPC(远程过程调用) 的通信机制。RPC 服务的一个核心特点是,它们会在系统启动时随机监听一个端口,而不是像 Web 服务那样固定使用 80 或 443 端口。

这就产生了一个问题:客户端想访问 NFS 共享,但不知道 NFS 服务程序此刻具体开在哪个端口上。rpcbind 就是用来解决这个问题的。

  • rpcbind 的作用:它是一个 RPC 端口映射器。它的任务就是”记住”系统上每个 RPC 服务(比如 NFS 的核心服务 nfsd、挂载服务 mountd 等)所使用的端口号。rpcbind 自身固定占用 111 端口。
  • 工作流程:

部署顺序与服务启动

你截图中的机器作为 NFS 服务端,安装和启动服务的正确顺序是固定的:

  1. 先安装 rpcbind,后安装 NFS 服务:因为 NFS 服务运行依赖 rpcbind 环境。
  2. 先启动 rpcbind,后启动 NFS 服务:必须确保 rpcbind 已经在运行,NFS 服务启动时才能成功向它注册端口信息。

重要补充:NFSv4 的例外情况

需要注意,有一个重要的例外:NFSv4 版本不再强制依赖 rpcbind。

因为 NFSv4 协议做了简化,规定所有通信都固定使用 2049 端口,绕过了动态端口映射的过程。因此,如果客户端和服务端都确定只使用 NFSv4,理论上可以不安装或禁用 rpcbind。不过在很多通用教程和传统部署中,为兼容性考虑,仍会默认安装和启动它。


2. 核心原因:NFS 是“客户端-服务器”架构

NFS(网络文件系统)在设计上就是明确区分服务端和客户端的,这是由它“通过网络共享文件”的本质决定的。

  • 机器1 (服务端):是数据的实际拥有者。它的任务是把本地磁盘上的目录(/nfsdir)“发布”或“导出”到网络上,并管理访问权限。因此,它需要运行 nfs-server 服务,并维护 /etc/exports 配置文件。
  • 机器2 (客户端):是数据的使用者。它本身没有这些数据,而是通过网络,将服务端共享出来的目录“挂载”到自己的本地目录(/mnt/nfs)下,像一个本地磁盘一样使用它。

为什么不能都在一台机器上?

这种分工是为了满足跨机器共享存储的需求。如果都在一台机器上,就失去了 NFS 存在的意义——那只是本机内部的目录操作。

在一个标准的生产环境中:

  • 服务端(机器1)通常是专门的存储服务器或文件服务器,集中存放数据。
  • 客户端(机器2及更多机器)则通过网络访问这份集中的数据,实现数据共享、统一备份或集中管理。

3. 客户端和服务端必须是不同的机器

  • 服务端:提供共享目录(192.168.226.6)
  • 客户端:挂载并使用共享目录(192.168.226.7)
  • 虽然可以本机挂载自己(localhost),但实际应用场景都是跨机器

服务端的 /etc/exports 必须明确标注允许的客户端 IP

bash

# 格式:共享目录 允许的客户端IP(权限)
/nfsshare 192.168.226.7(rw,sync,no_root_squash)
#           ↑
#    必须是客户端的真实 IP

text

┌─────────────────────────┐         ┌─────────────────────────┐
│   NFS 服务器             │         │   NFS 客户端            │
│   192.168.226.6         │         │   192.168.226.7         │
│                         │         │                         │
│  /etc/exports:          │         │  执行挂载命令:          │
│  /nfsshare 192.168.226.7│◄────────│  mount 192.168.226.6:/nfsshare /mnt/nfs
│                         │  允许   │                         │
│  共享目录:/nfsshare    │         │  挂载点:/mnt/nfs       │
└─────────────────────────┘         └─────────────────────────┘

Samba实验

Samba主配置文件

主配置文件:/etc/samba/smb.conf 帮助参看:man smb.conf

语法检查: testparm [-v] [/etc/samba/smb.conf]

[global]
   workgroup = WORKGROUP        # 工作组名称
   server string = Samba Server # 服务器描述
   security = user              # 认证模式
   log file = /var/log/samba/log.%m # 日志文件路径
   max log size = 50            # 最大日志文件大小(KB)
   dns proxy = no               # 禁用 DNS 代理

[shared]
   path = /srv/samba/shared      # 共享路径
   browseable = yes              # 是否可浏览
   writable = yes                # 是否可写
   valid users = @smbgroup       # 允许访问的用户/组

安装Samba服务

[root@localhost ~]# yum -y install samba
[root@localhost ~]# systemctl enable --now smb
[root@localhost ~]# systemctl enable --now nmb
[root@localhost ~]# ss -nlt
State    Recv-Q   Send-Q     Local Address:Port       Peer Address:Port   Process
LISTEN   0        50               0.0.0.0:445             0.0.0.0:*
LISTEN   0        50               0.0.0.0:139             0.0.0.0:*
LISTEN   0        128              0.0.0.0:22              0.0.0.0:*
LISTEN   0        50                  [::]:445                [::]:*
LISTEN   0        50                  [::]:139                [::]:*
LISTEN   0        128                 [::]:22                 [::]:*

配置Samba用户

  • 包:samba-common-tools
  • 工具:smbpasswd pdbedit
  • 用户数据库:/var/lib/samba/private/passdb.tdb

说明:samba用户须是Linux用户,建议使用/sbin/nologin

一、创建系统用户

[root@localhost ~]# useradd -s /sbin/nologin smbuser
[root@localhost ~]# echo 123 | passwd --stdin smbuser
Changing password for user smbuser.
passwd: all authentication tokens updated successfully.

二、创建Samba用户

[root@localhost ~]# smbpasswd -a smbuser
New SMB password:
Retype new SMB password:
Added user smbuser.
[root@localhost ~]# smbpasswd -e smbuser        # 启用用户
Enabled user smbuser.

基于特定用户或组的共享

服务端操作

一、创建共享目录

共享目录为:/data/samba

[root@localhost ~]# mkdir -p /data/samba
[root@localhost ~]# chown -R smbuser:smbuser /data/samba
[root@localhost ~]# chmod -R 2770 /data/samba #任何用户在该目录下新建的文件或子目录,其所属组会自动继承该目录的组,而不是创建者自己的默认组。

二、添加配置文件

[root@localhost ~]# vim /etc/samba/smb.conf
......
[shared]
   path = /data/samba
   browseable = yes
   writable = yes
   valid users = @smbuser
   create mask = 0660
   directory mask = 2770

三、关闭防火墙与SELinux

[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# setenforce 0

四、重启smb服务

[root@localhost ~]# systemctl restart smb

实践

Windows客户端界面

image-20260803233859456

image-20260803233951812

image-20260803234931956

image-20260804000208079

image-20260804000338341


Linux的smbclient界面

image-20260804130029308

==手动挂载cifs文件系统==:

image-20260804131906928

自动挂载(另一种方式):

开机自动挂载:

[root@localhost ~]# vim /etc/fstab
//192.168.226.7/shared  /mnt/smb        cifs    defaults,username=smbuser,password=123 0 0
[root@localhost ~]# systemctl daemon-reload
[root@localhost ~]# mount -a
[root@localhost ~]# df -h
Filesystem              Size  Used Avail Use% Mounted on
devtmpfs                4.0M     0  4.0M   0% /dev
tmpfs                   872M     0  872M   0% /dev/shm
tmpfs                   349M  5.2M  344M   2% /run
/dev/mapper/rl-root      17G  1.7G   16G  10% /
/dev/nvme0n1p1          960M  261M  700M  28% /boot
//192.168.88.10/shared   17G  1.7G   16G  10% /mnt/smb
tmpfs                   175M     0  175M   0% /run/user/0

==进程实战最终目标==:针对不同用户配置不同访问目录

服务端

一、创建并启用用户

创建三个samba用户,分别为smb1、smb2、smb3。密码均为:123

[root@localhost ~]# useradd -s /sbin/nologin -r smb1        # -r 不创建家目录
[root@localhost ~]# useradd -s /sbin/nologin -r smb2
[root@localhost ~]# useradd -s /sbin/nologin -r smb3
[root@localhost ~]#
[root@localhost ~]# smbpasswd -a smb1
New SMB password:
Retype new SMB password:
Added user smb1.
[root@localhost ~]# smbpasswd -a smb2
New SMB password:
Retype new SMB password:
Added user smb2.
[root@localhost ~]# smbpasswd -a smb3
New SMB password:
Retype new SMB password:
Added user smb3.
[root@localhost ~]# smbpasswd -e smb1
Enabled user smb1.
[root@localhost ~]# smbpasswd -e smb2
Enabled user smb2.
[root@localhost ~]# smbpasswd -e smb3
Enabled user smb3.

# 查看smb用户
[root@localhost ~]# pdbedit -L
smbuser:1000:
smb2:986:
smb1:987:
smb3:985:

二、修改Samba配置文件如下

[root@localhost ~]# vim /etc/samba/smb.conf
# 在global中添加该字段
[global]
config file = /etc/samba/conf.d/%U        # 变量%U表示匹配用户名

# 新建共享配置
[share]
        path = /data/samba/share
        browseable = yes
        writable = yes
        Guest ok = yes
        create mask = 0660
        directory mask = 2770

三、配置共享目录和文件

[root@localhost ~]# mkdir -p /data/samba/share
[root@localhost ~]# mkdir -p /data/samba/smb1
[root@localhost ~]# mkdir -p /data/samba/smb2
[root@localhost ~]# touch /data/samba/share/share.txt        # 共享目录及文件
[root@localhost ~]# touch /data/samba/smb1/smb1.txt            # smb1目录及文件
[root@localhost ~]# touch /data/samba/smb2/smb2.txt            # smb2目录及文件
[root@localhost ~]# tree /data/samba/
/data/samba/
├── file.txt
├── server2.txt
├── share
│   └── share.txt
├── smb1
│   └── smb1.txt
└── smb2
    └── smb2.txt

# 将/data/samba目录权限放开
[root@localhost ~]# chmod 777 -R /data/samba

四、针对smb1用户和smb2用户单独编辑配置文件

[root@localhost ~]# vim /etc/samba/conf.d/smb1
[share]
        path = /data/samba/smb1
        writable = yes
        create mask = 0660
        browseable = yes
[root@localhost ~]# vim /etc/samba/conf.d/smb2
[share]
        path = /data/samba/smb2
        writable = yes
        create mask = 0660
        browseable = yes

五、重启相关服务

[root@localhost ~]# systemctl restart smb
[root@localhost ~]# systemctl restart nmb

image-20260804170327300

image-20260804170725583

image-20260804171343174

image-20260804171543723

image-20260804171706552

image-20260804171948688

在文件末尾或 [global] 段中添加:

ini [global]

其他已有配置保持不变…

# 添加子配置文件目录
config include = /etc/samba/conf.d/%U        # 这会让samba自己加载conf.d目录以smb{1,2,3}为名字的子配置文件这会让 Samba 自动加载 /etc/samba/conf.d/ 目录下所有 用户名匹配的子配置文件。

修改主配置文件,增加共享路径 同样在 /etc/samba/smb.conf 中,在文件末尾添加一个公共共享:

对smb1用户和smb2用户单独编辑配置文件

[root@localhost ~]# vim /etc/samba/conf.d/smb1
[share]
        path = /data/samba/smb1
        writable = yes
        create mask = 0660
        browseable = yes
[root@localhost ~]# vim /etc/samba/conf.d/smb2
[share]
        path = /data/samba/smb2
        writable = yes
        create mask = 0660
        browseable = yes

五、重启相关服务

[root@localhost ~]# systemctl restart smb

==注意==:==生效的是配置文件里的路径,开头的global,print,share标识符只是为了人类可读区分·无任何意义==

实际出现问题

image-20260804182431966

image-20260804182446627

配置中有这两行:

ini

valid users = @smbuser
Guest ok = yes

这两行是冲突的,而且 valid users = @smbuser 优先级更高。实际效果是:

  • Guest ok = yes 被忽略了
  • 只有属于 smbuser 用户组的用户才能访问
  • 你的 smb1 用户不在 smbuser 组中,所以被拒绝访问

image-20260804183347706

image-20260804183403233

==生产环境总结==

text

╔═══════════════════════════════════════════════════════════════════╗
║                    Samba 生产环境架构图                           ║
╚═══════════════════════════════════════════════════════════════════╝

┌─────────────────┐  ┌─────────────────┐  ┌─────────────────────┐
│   开发人员 PC    │  │   运维人员 PC    │  │   应用服务器集群     │
│   (Windows)     │  │   (Linux/Mac)   │  │   (Linux)           │
├─────────────────┤  ├─────────────────┤  ├─────────────────────┤
│ • 写代码        │  │ • 部署应用      │  │ • 读取配置          │
│ • 编译打包      │  │ • 查日志排障    │  │ • 写日志            │
│ • 改配置        │  │ • 备份恢复      │  │ • 共享静态资源      │
└────────┬────────┘  └────────┬────────┘  └──────────┬──────────┘
         │                    │                       │
         │  映射网络驱动器    │  mount 挂载           │  mount/挂载
         │  (Z:/X:/)         │  (smbclient)          │  (cifs/nfs)
         └────────┬───────────┴───────────────────────┘
                  │
                  ▼
         ╔═══════════════════════════════════════════╗
         ║         Samba 服务器 (192.168.226.7)      ║
         ╠═══════════════════════════════════════════╣
         ║  /data/samba/                            ║
         ║  ├── deploy/      ← 部署包中转站         ║
         ║  ├── config/      ← 配置中心             ║
         ║  ├── logs/        ← 日志汇聚             ║
         ║  ├── backup/      ← 备份存储             ║
         ║  └── exchange/    ← 跨系统数据交换       ║
         ╚═══════════════════════════════════════════╝
                  │
                  ▼
         ┌─────────────────────────────────────────────┐
         │         异地备份 / 对象存储归档              │
         │   (定时同步到 OSS / 异地机房 / 磁带库)      │
         └─────────────────────────────────────────────┘


═══════════════════════════════════════════════════════════════════════

【数据流向说明】

① 开发 → Samba      : 上传部署包、修改配置文件
② 运维 → Samba      : 拉取部署包、查看日志、备份数据
③ Samba → 应用服务器 : 应用启动时读取配置、运行时写日志
④ 应用服务器 → Samba : 日志回写、数据交换
⑤ Samba → 异地备份   : 定期归档到灾备中心

═══════════════════════════════════════════════════════════════════════