Samba 4.15.13 配置参数详解
逐项实测 Samba 4.15.13 的 smb.conf 核心参数:testparm 校验与热重载、map to guest 协议分流、valid users/write list 权限矩阵、create mask/force mode/map archive 落盘权限、hide dot files 三态验证、veto files、recycle 回收站 VFS、POSIX ACL 叠加与 fail2ban/iptables 防爆破,每个参数都是修改-验证闭环。
Samba 4.15.13 配置参数详解
目标:把 Samba 4.15.13(Ubuntu 22.04 仓库版)的 smb.conf 核心参数逐项讲透——每个参数都给出"修改 → 重载 → 客户端验证 → 观察服务端落盘"的实测闭环。全部命令与输出均在真实双机环境实测,回显逐行照抄。
一、环境信息
| 项目 | 值 |
|---|---|
| 服务端操作系统 | Ubuntu 22.04.5 LTS(x86_64) |
| 服务端主机名 / IP | fileserver / 10.89.56.10 |
| Samba 版本 | samba 2:4.15.13+dfsg-0ubuntu1.13(smbd --version 显示 Version 4.15.13-Ubuntu) |
| 客户端 | Ubuntu 22.04.5 LTS,主机名 client,IP 10.89.56.20 |
| 客户端工具 | smbclient 2:4.15.13+dfsg-0ubuntu1.13、cifs-utils 2:6.14-1ubuntu0.7 |
| 配置文件 | /etc/samba/smb.conf |
| 共享目录 | /srv/samba/public(匿名)、/srv/samba/team(认证+回收站)、/srv/samba/archive(只读+admin 可写) |
| 演示账号 | admin、dev1(密码均为 q1w2e3r4),组 smbteam |
| 安装与首个共享配置 | 见《Ubuntu 22.04 安装 Samba 4.15.13 指南》 |
本文所有参数实验基于以下最终配置(cat /etc/samba/smb.conf 实测):
[global]
workgroup = WORKGROUP
server string = Samba Server %v
security = user
map to guest = Bad User
log file = /var/log/samba/log.%m
max log size = 1000
log level = 1 auth:5
[public]
comment = Anonymous public share
path = /srv/samba/public
browseable = yes
writable = yes
guest ok = yes
guest only = yes
force create mode = 0666
force directory mode = 0777
[team]
comment = Authenticated team share
path = /srv/samba/team
browseable = yes
writable = yes
guest ok = no
valid users = @smbteam
create mask = 0664
hide dot files = yes
directory mask = 0775
vfs objects = recycle
recycle:repository = .recycle
recycle:keeptree = yes
recycle:versions = yes
recycle:touch = yes
recycle:maxsize = 0
recycle:exclude = *.tmp
[archive]
comment = Read-only archive, admin writable
path = /srv/samba/archive
browseable = yes
read only = yes
write list = admin
valid users = @smbteam
create mask = 0664
hide dot files = yes
directory mask = 0775
veto files = /*.exe/*.tmp/
二、配置文件结构与校验工具
2.1 smb.conf 的段与参数语法
smb.conf 由三类内容构成:[global] 全局段、[共享名] 共享段、参数名 = 值 行。共享段未显式写的参数继承全局默认值;以 # 或 ; 开头的行为注释。testparm 是官方校验器,改完必跑:
testparm -s
实测输出(当前配置全量):
Load smb config files from /etc/samba/smb.conf
Loaded services file OK.
Weak crypto is allowed
Server role: ROLE_STANDALONE
# Global parameters
[global]
log file = /var/log/samba/log.%m
map to guest = Bad User
max log size = 1000
security = USER
server string = Samba Server %v
idmap config * : backend = tdb
[public]
comment = Anonymous public share
force create mode = 0666
force directory mode = 0777
guest ok = Yes
guest only = Yes
path = /srv/samba/public
read only = No
[team]
comment = Authenticated team share
create mask = 0664
directory mask = 0775
path = /srv/samba/team
read only = No
valid users = @smbteam
vfs objects = recycle
recycle:exclude = *.tmp
recycle:maxsize = 0
recycle:touch = yes
recycle:versions = yes
recycle:keeptree = yes
recycle:repository = .recycle
[archive]
comment = Read-only archive, admin writable
create mask = 0664
directory mask = 0775
path = /srv/samba/archive
valid users = @smbteam
veto files = /*.exe/*.tmp/
write list = admin
两个关键现象:其一,Loaded services file OK. 表示语法与参数名全部合法;其二,testparm 只回显非默认值参数——workgroup、hide dot files、map archive 等默认值恰好等于当前配置的参数不会出现(如 hide dot files = yes 就是默认值),这在 5.4 节还会复证。
2.2 testparm 校验与未知参数告警
故意把 map to guest 拼成 map too guest 追加到配置尾部再校验:
echo " map too guest = yes" >> /etc/samba/smb.conf
testparm -s 2>&1 >/dev/null | head -4
sed -i "/map too guest = yes/d" /etc/samba/smb.conf
testparm -s 2>&1 >/dev/null | head -2
实测输出:
Load smb config files from /etc/samba/smb.conf
Unknown parameter encountered: "map too guest"
Ignoring unknown parameter "map too guest"
Loaded services file OK.
Load smb config files from /etc/samba/smb.conf
Loaded services file OK.
testparm 对拼错的参数给出 Unknown parameter encountered 并 Ignoring 后继续——Samba 不会因未知参数拒绝启动,这种"静默忽略"正是配置错误最隐蔽的来源,所以每次改动后必须看一眼 testparm 的 stderr。删除该行后校验恢复干净。
2.3 用 testparm 查询参数与段(--parameter-name / --section-name)
testparm -s --parameter-name='map to guest' 2>/dev/null
testparm -s --parameter-name='workgroup' 2>/dev/null
testparm -s --section-name=team 2>/dev/null
实测输出(前两条各输出一行,第三条输出整个 [team] 段):
Bad User
WORKGROUP
[team]
comment = Authenticated team share
create mask = 0664
directory mask = 0775
path = /srv/samba/team
read only = No
valid users = @smbteam
vfs objects = recycle
recycle:exclude = *.tmp
recycle:maxsize = 0
recycle:touch = yes
recycle:versions = yes
recycle:keeptree = yes
recycle:repository = .recycle
--parameter-name 适合脚本里取单个值(无需自己 grep),--section-name 直接展开某个共享段的生效值。
2.4 修改如何生效:reload-config 与 restart
改完 smb.conf 有两种生效方式:systemctl restart smbd(全量重启,断开所有会话)与 smbcontrol all reload-config(热重载,共享参数与多数全局参数即时生效,不断会话)。本文全部实验使用热重载:
smbcontrol all reload-config
实测输出:无任何回显(成功即静默),改动立即可在客户端复测生效(后续各节的"修改→验证"闭环均依赖此命令)。
三、全局段核心参数
3.1 workgroup 与 server string
workgroup 是 SMB 工作组/域名,server string 是浏览列表里的备注。smbclient -L 的输出直接体现 server string:
smbclient -L //10.89.56.10 -N
实测输出:
Sharename Type Comment
--------- ---- -------
public Disk Anonymous public share
team Disk Authenticated team share
archive Disk Read-only archive, admin writable
IPC$ IPC IPC Service (Samba Server 4.15.13-Ubuntu)
SMB1 disabled -- no workgroup available
IPC Service (Samba Server 4.15.13-Ubuntu) 即来自 server string = Samba Server %v(%v 变量替换为版本号)。
3.2 security 与 map to guest:匿名与未知用户的分流
security = user 是 4.15 的默认值(standalone 部署的标准形态),真正影响行为的是 map to guest。实测两种取值对"不存在的用户"的不同处理:
当前 map to guest = Bad User 时(未知用户被映射为 guest,进入共享后因 guest ok = no 被拒):
smbclient //10.89.56.10/team -U nosuchuser%q1w2e3r4 -c ls
实测输出:
tree connect failed: NT_STATUS_ACCESS_DENIED
改为 map to guest = Never(未知用户不再映射,认证阶段直接失败):
sed -i 's/map to guest = Bad User/map to guest = Never/' /etc/samba/smb.conf
smbcontrol all reload-config
smbclient //10.89.56.10/team -U nosuchuser%q1w2e3r4 -c ls
实测输出:
session setup failed: NT_STATUS_LOGON_FAILURE
改回 map to guest = Bad User 并重载,输出恢复为 tree connect failed: NT_STATUS_ACCESS_DENIED。闭环结论:Bad User 把"用户名不存在"的会话放行为 guest(密码错仍拒绝),错误推迟到共享连接阶段;Never 在会话建立阶段就返回 NT_STATUS_LOGON_FAILURE。对公网暴露的服务,Never 能避免向扫描器泄露"该用户是否存在"之外的额外行为差异;对内网宽松共享,Bad User 配合 guest ok = yes 才能实现"无账号也能进公开共享"。
3.3 log file 与 %m 变量
log file = /var/log/samba/log.%m 中的 %m 是客户端 NetBIOS/主机名变量,每个客户端一个独立日志文件。实测 ls -la /var/log/samba/:
total 32
drwxr-x--- 3 root adm 4096 Oct 26 08:00 .
drwxr-xr-x 1 root root 4096 Oct 26 08:06 ..
drwx------ 5 root root 4096 Oct 26 07:57 cores
-rw-r--r-- 1 root root 0 Oct 26 08:00 log.10.89.56.20
-rw-r--r-- 1 root root 256 Oct 26 08:04 log.client
-rw-r--r-- 1 root root 396 Oct 26 07:58 log.nmbd
-rw-r--r-- 1 root root 1096 Oct 26 08:07 log.samba-bgqd
-rw-r--r-- 1 root root 1622 Oct 26 08:07 log.smbd
同一台客户端既产生了 log.client(按主机名)又产生了 log.10.89.56.20(IP 解析不出名时回退),%m 的取值取决于客户端是否注册 NetBIOS 名。max log size = 1000 表示单文件 1000 KB 后轮转。
3.4 log level:认证失败的日志取证
当前配置 log level = 1 auth:5 表示全局级别 1、认证模块级别 5。客户端用错密码登录一次后,在服务端 grep 认证日志:
grep -r "FAILED with error" /var/log/samba/
实测输出:
/var/log/samba/log.10.89.56.20: auth_check_ntlm_password: sam_ignoredomain authentication for user [dev1] FAILED with error NT_STATUS_WRONG_PASSWORD, authoritative=1
/var/log/samba/log.10.89.56.20: check_ntlm_password: Authentication for user [dev1] -> [dev1] FAILED with error NT_STATUS_WRONG_PASSWORD, authoritative=1
默认 log level = 1 时这两行不会出现——auth:5 才能让 check_ntlm_password 子系统留下失败明细。同理,共享层拒绝会记录在 log.client 中(Access denied on file d.txt: rejected by share access mask),见 4.4 节。
3.5 server min protocol:协议协商的下限
Samba 4.11 起 server min protocol 默认值升为 SMB2_02,SMB1(NT1)被彻底拒绝。客户端强制用 NT1 连接实测:
smbclient -m NT1 //10.89.56.10/public -N -c ls
smbclient -m SMB2 //10.89.56.10/public -N -c ls
实测输出:
lp_load_ex: Max protocol NT1 is less than min protocol SMB2_02.
protocol negotiation failed: NT_STATUS_INVALID_PARAMETER_MIX
hello.txt A 47 Mon Oct 26 09:09:21 2026
464118080 blocks of size 1024. 335197928 blocks available
NT1 在本地参数检查阶段即报 NT_STATUS_INVALID_PARAMETER_MIX;SMB2 正常列出文件。老设备(XP、老旧 NAS)若必须接入才需要显式调低 server min protocol——这会同时关闭传输加密与签名强度,生产环境不建议。
四、共享段访问控制参数
4.1 browseable:隐藏但不禁止
browseable = no 只让共享不出现在浏览列表,直接按名连接仍然可用。把 [archive] 改为 browseable = no 并重载,先看改动前列表:
public Disk Anonymous public share
team Disk Authenticated team share
archive Disk Read-only archive, admin writable
改为 no 后 smbclient -L //10.89.56.10 -U dev1%q1w2e3r4 的列表里 archive 一行消失(grep 无输出),但直接连接照常工作:
smbclient //10.89.56.10/archive -U admin%q1w2e3r4 -c ls
实测输出(尾部):
.. D 0 Mon Oct 26 09:08:28 2026
464118080 blocks of size 1024. 335197320 blocks available
验证后改回 browseable = yes。典型用途是 [IPC$]、 [homes] 这类不该被围观的功能性共享。
4.2 guest ok 与 guest only:匿名共享的属主落盘
[public] 的 guest ok = yes 允许 guest 连接,guest only = yes 强制所有连接(哪怕带了正确账号)一律按 guest 处理。匿名上传实测(客户端):
echo "hello from client $(date)" > /tmp/hello.txt
smbclient //10.89.56.10/public -N -c "put /tmp/hello.txt hello.txt; ls"
实测输出:
putting file /tmp/hello.txt as \hello.txt (45.9 kb/s) (average 45.9 kb/s)
Try "help" to get a list of possible commands.
. D 0 Mon Oct 26 08:00:55 2026
.. D 0 Mon Oct 26 07:59:31 2026
hello.txt A 47 Mon Oct 26 08:00:55 2026
464118080 blocks of size 1024. 336461396 blocks available
服务端验证属主与权限:
total 4
-rwxrw-rw- 1 nobody nogroup 47 Oct 26 08:00 hello.txt
hello from client Mon Oct 26 08:00:41 UTC 2026
nobody:nogroup 766
guest only = yes 下文件属主是 nobody:nogroup(Samba 默认 guest account = nobody);权限 766 中 666 来自 force create mode,属主多出的 x 来自 map archive(见 5.3)。匿名建目录同理(mkdir force-dir-test):
drwxrwxrwx 2 nobody nogroup 4096 Oct 26 09:27 /srv/samba/public/force-dir-test
force directory mode = 0777 精确落盘。匿名共享的目录属主永远是 nobody,服务端脚本清理时注意按组处理。
4.3 valid users:用户与组白名单
[team] 配置 valid users = @smbteam(@ 前缀表示 Unix 组)。dev1、admin 均在组内可正常访问;不存在的用户被 map to guest 映射为 guest 后,同样卡在 valid users 上(tree connect failed: NT_STATUS_ACCESS_DENIED,见 3.2 节)。把用户加入/移出组是日常授权的主要手段,改组后无需动 smb.conf。
4.4 read only 与 write list:只读共享的例外
[archive] 配置 read only = yes(等同 writable = no)+ write list = admin——全员只读,白名单内的 admin 可写。dev1 与 admin 分别实测:
smbclient //10.89.56.10/archive -U dev1%q1w2e3r4 -c ls
smbclient //10.89.56.10/archive -U dev1%q1w2e3r4 -c "put /tmp/d.txt d.txt"
smbclient //10.89.56.10/archive -U admin%q1w2e3r4 -c "put /tmp/d.txt d.txt"
smbclient //10.89.56.10/archive -U admin%q1w2e3r4 -c ls
实测输出:
464118080 blocks of size 1024. 335792760 blocks available
NT_STATUS_ACCESS_DENIED opening remote file \d.txt
putting file /tmp/d.txt as \d.txt (7.8 kb/s) (average 7.8 kb/s)
d.txt A 8 Mon Oct 26 08:04:49 2026
464118080 blocks of size 1024. 335784556 blocks available
dev1 读成功、写被拒;admin 读写都成功。服务端 log.client 里同步留下拒绝明细:
[2026/10/26 08:04:49.571854, 0] ../../source3/smbd/open.c:3318(smbd_calculate_access_mask_fsp)
smbd_calculate_access_mask_fsp: Access denied on file d.txt: rejected by share access mask[0x001F00A9] orig[0x0012019F] mapped[0x0012019F] reject[0x00000116]
rejected by share access mask 明确指向共享层(read only)而非文件系统权限——排查写失败时先看这一行能少走弯路。
五、文件与目录权限类参数
5.1 create mask 与 directory mask
[team] 的 create mask = 0664 / directory mask = 0775 是新建文件/目录权限的"上限掩码":客户端请求的任何位,掩码里没有的都会被剥掉。cifs 挂载写入 readme.md 后服务端实测 664(-rw-rw-r-- 1 dev1 smbteam),SMB 建目录实测:
smbclient //10.89.56.10/team -U dev1%q1w2e3r4 -c "mkdir dirmask-test"
服务端:
drwxrwsr-x 2 dev1 smbteam 4096 Oct 26 09:25 /srv/samba/team/dirmask-test
775 与掩码一致;多出的 s(SGID)来自父目录 /srv/samba/team 本身是 2775,属组 smbteam 随 SGID 继承——新建文件同理(属组均为 smbteam)。
5.2 force create mode 与 force directory mode
与 mask 相反,force 是"保底 OR":最终权限无论客户端请求什么都保证含这些位。[public] 的 force create mode = 0666 使匿名上传的 hello.txt 落盘为 766(666 再叠加 map archive 的 x,见 5.3);force directory mode = 0777 使匿名建的目录为 777(见 4.2 实测)。两者组合的语义:mask 决定"最多能给多少",force 决定"至少要给多少"。
5.3 map archive:为什么多出一个 x 位
Samba 默认 map archive = yes:客户端上传文件时设置的 DOS archive 属性(smbclient put 后 ls 里文件带 A 标记,见 4.2 实测输出)被映射为属主 x 位。对照实验:
- [public](force create mode 0666,无 mask 限制):smbclient 上传 → 服务端 766(
-rwxrw-rw-),x 位来自 archive 映射; - [team](create mask 0664):smbclient 上传 from-dev1.txt → 服务端 getfacl 实测
user::rw- / group::rw- / other::r--(664),archive 的 x 被 mask 剥掉; - cifs 内核客户端写入不带 archive 属性 → 服务端 664(见《Ubuntu 22.04 安装 Samba 4.15.13 指南》8.4 节)。
结论:看到"莫名多出的 x 位"先查 map archive 与 mask 的组合,不要误判为安全隐患。
5.4 hide dot files:DOS 隐藏属性而非从列表移除
hide dot files = yes(默认值)给点开头文件打上 DOS hidden 属性。三态闭环实测——先上传 .plan.md,切换参数(每次改后 smbcontrol all reload-config):
=== A. hide dot files = yes 时 ls ===
. D 0 Mon Oct 26 09:09:34 2026
.. D 0 Mon Oct 26 09:08:28 2026
.plan.md AH 12 Mon Oct 26 09:09:34 2026
464118080 blocks of size 1024. 335216324 blocks available
=== B. hide dot files = no 时 ls ===
. D 0 Mon Oct 26 09:09:34 2026
.. D 0 Mon Oct 26 09:08:28 2026
.plan.md A 12 Mon Oct 26 09:09:34 2026
464118080 blocks of size 1024. 335216292 blocks available
=== C. 恢复 yes 后 ls ===
.plan.md AH 12 Mon Oct 26 09:09:34 2026
属性位 AH → A → AH 随参数切换。两种语义差异要点:yes 时文件仍在 smbclient ls 里可见(只是带 H 标记),Windows 资源管理器默认不显示 hidden 文件才"看不见";想彻底从列表剔除要用 hide files 或 veto files。另外 2.1 节的复证:恢复 yes 后 testparm -s | grep 'hide dot' 无输出——因为它等于默认值。
5.5 veto files:按模式禁断
[archive] 配置 veto files = /*.exe/*.tmp/(斜杠分隔的模式列表)。实测上传 .exe 被断、.log 正常:
smbclient //10.89.56.10/archive -U admin%q1w2e3r4 -c "put /tmp/setup.exe setup.exe"
smbclient //10.89.56.10/archive -U admin%q1w2e3r4 -c "put /tmp/ok.log ok.log"
实测输出:
NT_STATUS_OBJECT_NAME_NOT_FOUND opening remote file \setup.exe
putting file /tmp/ok.log as \ok.log (2.0 kb/s) (average 2.0 kb/s)
veto 的表现为"文件不存在"(OBJECT_NAME_NOT_FOUND)而非权限拒绝——服务端直接假装目标不可见。注意 veto files 会拖慢每个文件操作(逐个模式匹配),并可能让 Windows 客户端复制目录时报错,仅在强合规场景使用。
六、VFS 扩展模块:recycle 回收站
6.1 参数组合与加载
[team] 通过 vfs objects = recycle 加载回收站模块,recycle: 前缀参数为模块私有:
| 参数 | 值 | 含义 |
|---|---|---|
| recycle:repository | .recycle | 回收站目录(相对共享根,SMB 视角下默认隐藏) |
| recycle:keeptree | yes | 保留删除前的目录层级 |
| recycle:versions | yes | 同名文件再删时自动加"Copy #x of"前缀 |
| recycle:touch | yes | 回收后更新文件时间戳 |
| recycle:maxsize | 0 | 不限制可回收文件大小(单位 KB) |
| recycle:exclude | *.tmp | 匹配的文件直接真删,不进回收站 |
6.2 删除→回收闭环实测
客户端建 docs/plan.txt 再删除:
smbclient //10.89.56.10/team -U dev1%q1w2e3r4 -c "put /tmp/d.txt docs/plan.txt"
smbclient //10.89.56.10/team -U dev1%q1w2e3r4 -c "del docs/plan.txt"
smbclient //10.89.56.10/team -U dev1%q1w2e3r4 -c ls
实测输出:
putting file /tmp/d.txt as \docs\plan.txt (80000.0 kb/s) (average inf kb/s)
. D 0 Mon Oct 26 08:05:24 2026
.. D 0 Mon Oct 26 08:04:41 2026
.recycle DH 0 Mon Oct 26 08:05:24 2026
docs D 0 Mon Oct 26 08:05:24 2026
季度报表-Q3.xlsx A 0 Mon Oct 26 08:02:11 2026
464118080 blocks of size 1024. 335783980 blocks available
plan.txt 从共享根消失,.recycle 目录出现(DH = 目录+隐藏)。服务端验证回收层级与属主:
3965164 4 drwxrwsr-x 3 root smbteam 4096 Oct 26 08:05 /srv/samba/team/.recycle
3965196 4 drwx--S--- 2 dev1 smbteam 4096 Oct 26 08:05 /srv/samba/team/.recycle/docs
3965194 4 -rw-rw-r-- 1 dev1 smbteam 8 Oct 26 08:05 /srv/samba/team/.recycle/docs/plan.txt
keeptree 生效(.recycle/docs/plan.txt 保留原路径),属主 dev1 保留,权限 664 与 create mask 一致。恢复文件用服务端 mv 回原位即可(SMB 端把 .recycle 当普通隐藏目录也能直接拖回)。注意 recycle 只拦截 SMB 发起的删除——服务端本地 rm 不经过 VFS,不会进回收站。
七、POSIX ACL 与 Samba 权限的叠加
7.1 setfacl 授权
smb.conf 之外还有一层 Linux 文系统 ACL。服务端安装 acl 工具后,给 dev1 上传的文件追加 admin 的 rwx 授权:
apt-get install -y acl
ls -l /srv/samba/team/from-dev1.txt
getfacl -p /srv/samba/team/from-dev1.txt | grep -E "^user|^group|^other"
setfacl -m u:admin:rwx /srv/samba/team/from-dev1.txt
getfacl -p /srv/samba/team/from-dev1.txt | grep -E "^user|^group|^mask|^other"
实测输出(改前/改后):
user::rw-
group::rw-
other::r--
user::rw-
user:admin:rwx
group::rw-
mask::rwx
other::r--
7.2 经 SMB 验证 ACL 生效
admin 此前对该文件无权限(664、属主 dev1),授权后经 SMB 直接读写:
smbclient //10.89.56.10/team -U admin%q1w2e3r4 -c "get from-dev1.txt /tmp/got.txt"
smbclient //10.89.56.10/team -U admin%q1w2e3r4 -c "put /tmp/d.txt from-dev1.txt"
实测输出:
getting file \from-dev1.txt of size 8 as /tmp/got.txt (80000.0 KiloBytes/sec) (average inf KiloBytes/sec)
putting file /tmp/d.txt as \from-dev1.txt (7.8 kb/s) (average 7.8 kb/s)
未授权会话依旧被共享层拦截(nosuchuser 映射 guest 后 tree connect failed: NT_STATUS_ACCESS_DENIED)——SMB 会话准入(valid users/guest)与文件层 ACL 是两道独立闸门,都通过才能读写。
八、安全加固:fail2ban 防爆破与连接限速
8.1 fail2ban 部署与三大坑
Ubuntu 22.04 仓库版 fail2ban(0.11.2-6)直接启用 samba jail 会失败,journalctl -u fail2ban 实测:
Oct 26 08:06:25 fileserver fail2ban-server[4657]: ERROR Found no accessible config files for 'filter.d/samba' under /etc/fail2ban
Oct 26 08:06:25 fileserver fail2ban-server[4657]: ERROR Unable to read the filter 'samba'
Oct 26 08:06:25 fileserver fail2ban-server[4657]: ERROR Errors in jail 'samba'. Skipping...
Oct 26 08:06:25 fileserver fail2ban-server[4657]: ERROR Failed during configuration: Have not found any log file for sshd jail
Oct 26 08:06:25 fileserver fail2ban-server[4657]: ERROR Async configuration of server failed
Oct 26 08:06:25 fileserver systemd[1]: fail2ban.service: Failed with result 'exit-code'.
坑一:该版本未自带 samba 过滤器(filter.d/samba 不存在),需自写 /etc/fail2ban/filter.d/smbd-auth.conf 匹配 3.4 节的 check_ntlm_password ... FAILED 日志行(用 fail2ban-regex 调试正则时注意必须含 failure-id 捕获组,否则报 No failure-id group)。坑二:默认 jail.conf 的 sshd 在无 /var/log/auth.log 的环境会因 Have not found any log file for sshd jail 整体启动失败,需在 jail.local 里 [sshd] enabled = false。坑三(决定性):smbd 独立模式下认证失败明细写在 log.%m 中,失败行本身不含客户端 IP(IP 只出现在文件名里),fail2ban 的过滤器拿不到 IP、无法自动封禁——因此对 Samba 防爆破,fail2ban 只能退化为手动封禁工具,或改用下节的 iptables 限速。
修好配置后 jail 正常加载:
systemctl restart fail2ban
fail2ban-client status
fail2ban-client status smbd-auth
实测输出:
Status
|- Number of jail: 1
`- Jail list: smbd-auth
Status for the jail: smbd-auth
|- Filter
| |- Currently failed: 0
| |- Total failed: 0
| `- File list: /var/log/samba/log.smbd /var/log/samba/log.nmbd /var/log/samba/log.client /var/log/samba/log.samba-bgqd /var/log/samba/log.10.89.56.20
`- Actions
|- Currently banned: 0
|- Total banned: 0
`- Banned IP list:
8.2 手动封禁与解封(banip/unbanip)
fail2ban-client set smbd-auth banip 10.89.56.20
iptables -L f2b-smbd-auth -n --line-numbers
实测输出:
Chain f2b-smbd-auth (1 references)
num target prot opt source destination
1 REJECT all -- 10.89.56.20 0.0.0.0/0 reject-with icmp-port-unreachable
2 RETURN all -- 0.0.0.0/0 0.0.0.0/0
客户端立即复测:
smbclient -L //10.89.56.10 -U dev1%q1w2e3r4
实测输出:
do_connect: Connection to 10.89.56.10 failed (Error NT_STATUS_CONNECTION_REFUSED)
fail2ban-client set smbd-auth unbanip 10.89.56.20 解封后恢复访问。REJECT 以 icmp-port-unreachable 形式拒绝,客户端表现为连接被拒而非超时。
8.3 iptables recent 连接限速
针对爆破的更实用手段是限制 445 端口新建连接的频率(IP 白名单场景绕开):
iptables -A INPUT -p tcp --dport 445 -m conntrack --ctstate NEW -m recent --set --name SMBBRUTE
iptables -A INPUT -p tcp --dport 445 -m conntrack --ctstate NEW -m recent --update --seconds 60 --hitcount 8 --name SMBBRUTE -j DROP
实测输出:无回显,iptables -L INPUT -n --line-numbers 确认规则在列(recent: SET name: SMBBRUTE 与 DROP ... hit_count: 8)。限速开启后客户端 10 连发实测:成功=5 失败=5,被限后的失败形态为:
do_connect: Connection to 10.89.56.10 failed (Error NT_STATUS_IO_TIMEOUT)
与 8.2 的 CONNECTION_REFUSED 形成对照:DROP 静默丢包(超时),REJECT 主动拒绝(立即失败)。正常用户每 60 秒内 7 次以内新建连接不受影响,爆破工具的高频连接被吸收掉。
九、常见配置错误与排查对照表
| 现象/报错 | 根因参数 | 处置 |
|---|---|---|
| session setup failed: NT_STATUS_LOGON_FAILURE | 系统用户未 smbpasswd -a,或密码错,或 map to guest = Never 拒绝未知用户 | 加账号/核对密码/确认 map to guest 取值 |
| tree connect failed: NT_STATUS_ACCESS_DENIED | valid users 不含(映射后的)用户,或 guest ok = no 拒绝匿名 | 核对白名单与 guest 参数组合 |
| NT_STATUS_ACCESS_DENIED opening remote file \文件 | read only/write list、veto files、Linux 目录权限 | 服务端 log.client 找 rejected by share access mask 定位层次 |
| NT_STATUS_OBJECT_NAME_NOT_FOUND(上传时) | veto files 命中,或 put 缺远端文件名 | 调整 veto 模式;put 补全远端名 |
| protocol negotiation failed: NT_STATUS_INVALID_PARAMETER_MIX | 客户端 -m NT1 低于 server min protocol(默认 SMB2_02) | 客户端升级;确需 NT1 才调低服务端下限 |
| NT_STATUS_IO_TIMEOUT | iptables recent/DROP 限速触发 | 核对 iptables -L INPUT,调高 hitcount/seconds |
| 改了配置不生效 | 未 reload/restart | smbcontrol all reload-config 或 systemctl restart smbd |
| 参数写了没作用 | 拼写错误被 testparm Ignoring unknown parameter 静默忽略 | 每次 testparm -s 检查 stderr |
| testparm 看不到某参数 | 该参数等于默认值,testparm 只回显非默认项 | 用 --parameter-name 显式查询 |
十、参考链接
- smb.conf 手册(参数权威定义) https://www.samba.org/samba/docs/current/man-html/smb.conf.5.html (检索日期 2026-10-26)
- Samba 官方 Wiki:VFS 模块 recycle https://wiki.samba.org/index.php/VFS_module_recycle (检索日期 2026-10-26)
- fail2ban 官方仓库 https://github.com/fail2ban/fail2ban (检索日期 2026-10-26)
- 本站相关文档:Samba 4.15.13 介绍与选型指南
- 本站相关文档:Ubuntu 22.04 安装 Samba 4.15.13 指南