网络安全技能大赛加固清单:Windows/Linux配置与验证实战
简介:《2021年全国职业院校技能大赛网络安全竞赛试题》是一份面向职业院校网络安全赛项选手、指导教师及安全运维初学者的赛题文档,围绕竞赛常见任务组织内容,可用于备赛训练、课堂实训与命题参考。压缩包共1个docx文件,约119KB,篇幅紧凑,便于打印或对照环境逐项练习。文档覆盖Windows与Linux双平台的登录安全加固、密码与用户管理、MySQL数据库加固、HTTP到HTTPS重定向、事件审核监控,以及SSH、VSFTPD、IIS服务加固和防火墙策略等任务,并延伸至网络安全事件响应、数字取证调查与应用安全模块,能帮助读者理解赛题要求、梳理加固思路并核对关键配置。该赛题已有959人学习,适合需要系统刷题和查漏补缺的竞赛选手使用。
1. 从一份赛题说起:它更像一份能照着做的加固清单
「网络安全 技能大赛」的题,很多人只在赛前翻一遍就扔进网盘吃灰。我这次把一份 2021 年的赛题当成作业本重做,发现它其实是一份结构相当完整的加固与应急清单:A 模块六个任务,横跨 Windows 和 Linux 两个平台,从账户策略、数据库降权、Web 强制 HTTPS,一路做到审计、服务加固和防火墙收口;B 模块直接给一个失陷现场,要求从内存、流量、端口三个入口倒推攻击链。适合谁?刚接手上机整改清单、知道要改什么却不知道改到哪个文件的人;也适合已经会敲命令,但缺一套「改完怎么读回来验证」习惯的运维。下面按加固顺序往下走,每一处都给可复制的配置、参数含义和失败时的观察点。
2. 账户与登录面加固:16 位密码、Banner 和 5 分钟超时落到哪
账户和登录是攻击面里最靠前的一层,也是整改单上最容易被写成「已按要求配置」却没人验证的一层。这一章把四项东西拆开:密码最小长度、登录横幅、非活动会话超时、单个用户的登录时段与来源限制。它们分散在四五个文件或策略节点里,Windows 和 Linux 的实现路径完全不同,但考核点是一样的——不是「改过」,而是「改完还能登录,且策略真的拦得住」。
2.1 密码策略:Windows 本地安全策略与 login.defs 的双写
Linux 侧的第一反应是/etc/login.defs,题面也是这么写的:把PASS_MIN_LEN改成 16。这一步没错,但要清楚它管的是passwd、chpasswd这类工具在创建或修改口令时的长度校验,走 PAM 的登录流程未必读它。真正在现代发行版上生效的是pam_pwquality,也就是/etc/security/pwquality.conf里的minlen。两处都写,才不会有「文件改了但用户仍能设 8 位密码」的尴尬。
# 先备份,改配置文件永远留一份原件 cp /etc/login.defs /etc/login.defs.bak # 匹配行首的 PASS_MIN_LEN;如果这行被注释掉,sed 不会命中,要先 grep 确认 sed -i 's/^PASS_MIN_LEN.*/PASS_MIN_LEN\t16/' /etc/login.defs grep -E '^PASS_MIN_LEN' /etc/login.defs # PAM 层同步收紧,minlen 才是 passwd 真正读的默认值 sed -i 's/^# *minlen.*/minlen = 16/' /etc/security/pwquality.conf grep -E '^minlen' /etc/security/pwquality.confsed那条里\t是制表符,login.defs用空白分隔字段,写成空格也能解析,但保持制表符更贴近原文件风格。第二段的# *minlen是为了兼容默认文件里# minlen = 8这种带注释的写法,不同发行版注释后有没有空格不一致,# *两种都能匹配。改完不要立刻登出,开一个新终端试一次改密码,能设 15 位被拒、16 位通过,这条才算落地。
Windows 侧有图形路径:管理工具 → 本地安全策略 → 账户策略 → 密码策略 → 最小密码长度。命令行等价物是net accounts,但这里有个版本边界要先说清楚:net accounts /minpwlen:在部分系统上上限是 14,想设 16 会直接报参数错误,而图形界面和组策略可以设到更高。所以命令行改不动不是命令写错了,是接口本身的限制。
:: 先看当前值,确认改的是本地 SAM 而不是域策略 net accounts :: 最小长度 16;若报“参数无效”,改用 secpol.msc 图形界面或组策略 net accounts /minpwlen:16 :: 顺带把最长使用期和密码历史一起收紧,单改长度意义有限 net accounts /maxpwage:90 /uniquepw:5net accounts的改动只作用于本机 SAM 数据库,域环境里成员机真正生效的是「默认域策略」里那条同名项,本地改了也会被域策略覆盖。所以复现赛题时先确认机器是不是加域状态,没加域才有意义。/maxpwage单位是天,/uniquepw是记住多少个历史密码,这两个参数题面没要求,但实际整改里几乎总是一起出现,顺手带上不吃亏。
2.2 登录横幅:issue、sshd Banner 和交互式登录消息
横幅看着是个形式主义的需求,其实是合规检查里最容易被抽查的一条:登录前后必须出现「仅限授权用户」的提示。Linux 上有两个不同的位置,本地控制台和远程 SSH 各管各的,很多人只改了一个就交差。
# 本地 tty 在 getty 登录提示前打印,注意这里不要用反斜杠开头的转义 cat > /etc/issue <<'EOF' For authorized users only EOF # SSH 横幅单独一个文件,权限要求 root 可读、其他用户不可写 cat > /etc/ssh/banner <<'EOF' For authorized users only EOF chmod 644 /etc/ssh/banner # sshd_config 里 Banner 默认是注释状态,sed 兼容有井号和无井号两种写法 sed -i 's|^#\?Banner.*|Banner /etc/ssh/banner|' /etc/ssh/sshd_config sshd -t && systemctl reload sshdsshd -t是语法自检,配置写错时它会给出行号,比直接 reload 后连不上再回头找要省事得多。这里用reload不用restart,是为了不打断已经建立的会话。文件权限那条别省:sshd在StrictModes yes(默认值)下会检查横幅文件的属主和写权限,如果文件对 other 可写,横幅会被静默忽略,日志里只留一行不太好找的警告。/etc/issue里的\n、\r、\m会被 getty 展开成系统信息,写欢迎语时避开反斜杠开头,否则会出现莫名其妙的换行或主机名。
Windows 侧对应的是「交互式登录:试图登录的用户的消息标题」和「消息文本」两条策略,在本地安全策略 → 本地策略 → 安全选项里。图形界面之外,直接写注册表更快,而且立刻生效、不用重启:
# 这两条注册表项就是 secpol 里那两条策略的落点 $path = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" New-ItemProperty -Path $path -Name "LegalNoticeCaption" -Value "For authorized users only" -PropertyType String -Force New-ItemProperty -Path $path -Name "LegalNoticeText" -Value "For authorized users only" -PropertyType String -Force-Force的作用是值已存在时覆盖,不加会报「属性已存在」。标题和正文是两条独立的项,题面要求出现「For authorized users only」这句提示,写在标题或正文里都能显示,但截图时只截标题栏往往看不出内容,稳妥做法是两条都填。这条策略对远程桌面同样生效,所以 RDP 登录前也会弹一次。
2.3 会话超时:ClientAliveInterval 的乘法题与 RDP-Tcp 的三档时间
「非活动会话连接超时应小于等于 5 分钟」这句在两地实现差异最大。Linux 的 SSH 不是靠一个参数,而是两个参数相乘:ClientAliveInterval是探活间隔,ClientAliveCountMax是连续多少次没响应就断开,实际超时 = 间隔 × 次数。题面只提了这两个参数名,没说取值,这里就是最容易算错的地方。
# 300 秒探活一次,1 次无响应即断开,合计 300 秒,满足“小于等于 5 分钟” sed -i 's|^#\?ClientAliveInterval.*|ClientAliveInterval 300|' /etc/ssh/sshd_config sed -i 's|^#\?ClientAliveCountMax.*|ClientAliveCountMax 1|' /etc/ssh/sshd_config sshd -t && systemctl reload sshd # 复核实际生效值,sshd -T 会打印合并后的配置 sshd -T | grep -i clientaliveClientAliveCountMax设成 0 的含义是「一次间隔后直接断开」,不是「不断开」,语义上和很多人直觉相反。用 300 × 1 是最好解释的组合;如果想更细,60 × 5 也是 5 分钟,但探活频率高了会多出一些无谓流量。sshd -T这个命令值得记住,它输出的是 sshd 真正加载后的完整配置,比翻文件可靠,也能顺手验证PermitRootLogin、Port有没有改对。
Windows 的 RDP 超时在「远程桌面会话主机设置」里,对应 RDP-Tcp 连接属性的「会话」页三档:活动会话时间限制、活动但空闲的会话时间限制、断开的会话时间限制。题面要求的是非活动超时,盯的是第二档。注册表里对应MaxIdleTime和MaxDisconnectionTime,单位是毫秒:
$rdp = "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" # 5 分钟 = 300000 毫秒 Set-ItemProperty -Path $rdp -Name "MaxIdleTime" -Value 300000 Set-ItemProperty -Path $rdp -Name "MaxDisconnectionTime" -Value 300000 Get-ItemProperty -Path $rdp | Select-Object MaxIdleTime, MaxDisconnectionTime两个值的含义不同:MaxIdleTime是会话空闲到点直接断开,MaxDisconnectionTime是网络断了以后保留会话(让用户还能接回来)的时长。整改单上通常两条都要设,只设前者的话,拔网线的那种「断连」场景不会在 5 分钟内清掉。改注册表后需要重启远程桌面服务或者重启系统才完全生效,这一点和 SSH 的 reload 不一样。
2.4 user1 的登录时段与「从网络访问此计算机」白名单
题面里user1只能在周一至周五 9:00 到 18:00 登录,命令行的写法很紧凑,但格式错一个字符就会静默失败或者报语法错误。
:: M=周一 F=周五,24 小时制,逗号分隔时段,不要加空格 net user user1 /time:M-F,9:00-18:00 :: 复核,输出里会有一行 Logon hours allowed net user user1/time:后面如果留空,效果是清空所有限制、允许全天登录,所以这条命令误操作的方向是「放开」而不是「收紧」,执行前务必确认。图形界面上「登录时间」的最小单位是小时,命令行填到分钟在界面上会显示成整点区间,赛题要求截图,本质就是让你证明在界面上能看到这段时间被涂蓝。域用户走的是账户属性 → 帐户 → 登录时间,路径不同但语义一致。
「只允许管理员账号从网络访问本机」这条在组策略里:计算机配置 → Windows 设置 → 安全设置 → 本地策略 → 用户权限分配 → 从网络访问此计算机。默认包含Everyone、Users、Power Users等,要全部删掉,只留Administrators。这里有个连带影响:如果这台机器上跑着 IIS,应用程序池用的是普通账户,删掉Users之后站点访问共享目录或走网络身份验证会直接 401 或 500。常见做法是先确认机器上有没有依赖网络登录的服务账户,有的话单独加回那一个,而不是把Users整组放回去。
3. 数据库与 Web 传输:MySQL 降权与 IIS 强制 HTTPS
中间层的加固比系统层更容易出「配了但没生效」的问题,因为涉及服务和配置文件两套加载顺序。这一章处理 MySQL 的运行账户、默认库与管理账号、口令哈希、最小权限授权,以及 IIS 上把 80 端口的流量钉到 443 的那条重写规则。数据库部分能直接跑 SQL,Web 部分落到web.config。
3.1 用普通账户跑 mysqld:user 参数、目录属主与启动链
「禁止 mysql 以管理员权限运行」这句话落到实现上就是让mysqld进程的属主不是 root。my.cnf的[mysqld]段里user=这一项,作用是当服务以 root 启动时,进程降权到指定用户。注意它的前提是「以 root 启动」,如果 systemd 单元里已经写了User=mysql,那进程压根不会以 root 起来,my.cnf里的user=就是个冗余但无害的保险。
# 确认 [mysqld] 段存在,再把 user=mysql 插到它后面一行 grep -n "^\[mysqld\]" /etc/my.cnf sed -i '/^\[mysqld\]/a user=mysql' /etc/my.cnf # 数据目录属主必须跟着是 mysql,否则重启直接失败 chown -R mysql:mysql /var/lib/mysql systemctl restart mysqld # 验证进程属主,第一列是 mysql 才算降权成功 ps -o user,pid,cmd -C mysqldps -o user这一列是最直接的证据,比看配置文件有说服力。sed的/a是追加到匹配行之后,如果my.cnf里已经有user=,跑两次会出现重复项,MySQL 对重复参数的处理是后者覆盖前者,不至于启动失败,但配置文件会越来越脏,跑之前grep '^user' /etc/my.cnf看一眼更稳。chown那步不能省,尤其是从别处拷过来的数据目录,属主不对时错误日志里给的是权限拒绝,不会直接告诉你是属主问题。
3.2 删 test 库、把管理员改名:DROP 与 RENAME USER 的差别
删默认库没什么争议,DROP DATABASE IF EXISTS test;就够,IF EXISTS是为了让脚本可重复执行。改管理员用户名这一步,题面给的是update user set user='SuperRoot' where user='root';,这条在 MySQL 5.x 上能跑通,在 8.x 上则要面对权限表结构变化和一堆连带问题。更稳的写法是RENAME USER,它会把权限行、主键、索引一起搬过去。
-- 删之前先看有没有业务库挂在 test 名下 SHOW DATABASES; DROP DATABASE IF EXISTS test; -- 改名用专门语句,别直接 UPDATE mysql.user RENAME USER 'root'@'localhost' TO 'SuperRoot'@'localhost'; FLUSH PRIVILEGES; -- 复核:原来的 root@localhost 应该消失 SELECT user, host FROM mysql.user ORDER BY user;RENAME USER的语法要求用户名和主机部分都写全,只写'SuperRoot'会报错。这里还有个高频遗漏:mysql.user里往往同时存在root@localhost、root@127.0.0.1、root@::1三条记录,题面只说改管理员用户,只改localhost那条的话,用 IP 连进来仍然是 root。整改时按SELECT user,host FROM mysql.user WHERE user='root';把结果全改一遍,或者干脆确认业务只走 socket 连接。FLUSH PRIVILEGES在RENAME USER之后其实不是必须的(权限表由语句本身维护),但在直接 UPDATE 权限表的场景下必须执行,养成习惯没坏处。
3.3 密码那一行:MD5()、PASSWORD() 与 authentication_string
题面写的是Update user set password=md5(password) where user="user1";,这条语句的语义是「把 password 字段的现有值再做一次 MD5」,而不是「把明文 P@ssw0rd1! 做 MD5 写进去」。照抄的结果是得到一个谁也不知道原文的哈希,用户直接登不上。正确的意图是把明文口令哈希后写入认证字段。
-- 5.7 及更早:字段名叫 password UPDATE mysql.user SET password = MD5('P@ssw0rd1!') WHERE user = 'user1' AND host = 'localhost'; -- 8.0:字段改名为 authentication_string,且默认插件不再是 mysql_native_password UPDATE mysql.user SET authentication_string = MD5('P@ssw0rd1!') WHERE user = 'user1' AND host = 'localhost'; FLUSH PRIVILEGES;字段名这块要先DESC mysql.user;看一眼再动手,两个版本的列名不一样,写错列名报的是「Unknown column」,比较好排查;麻烦的是写对了列但插件不对——MySQL 8 默认caching_sha2_password,直接塞一个 32 位十六进制的 MD5 进去,认证阶段会失败,因为长度和格式都不匹配。赛题环境一般是 5.x,按老写法来;真实环境里 MD5 存口令本身已经是应该淘汰的做法,用ALTER USER ... IDENTIFIED BY让服务端自己算哈希才是现在的常规操作。这里把边界说清楚,比背一条 SQL 有用。
3.4 最小权限授权与 IIS 的 HTTP 到 HTTPS 强制跳转
授权这条题面写得很清楚:user1对testdb所有表只有增删改查。落地就一句GRANT,但顺序有讲究——GRANT在用户不存在时会顺手创建用户,而且创建出来的是空密码账户。
-- 先建用户设密码,再授权,避免 GRANT 隐式创建空密码账户 CREATE USER IF NOT EXISTS 'user1'@'localhost' IDENTIFIED BY 'P@ssw0rd1!'; GRANT SELECT, INSERT, UPDATE, DELETE ON testdb.* TO 'user1'@'localhost'; FLUSH PRIVILEGES; -- 复核:应当只有 USAGE 加四条 DML,没有 DDL、没有 GRANT OPTION SHOW GRANTS FOR 'user1'@'localhost';testdb.*是库级授权,表级写成testdb.表名。SHOW GRANTS的输出是唯一可信的验证方式,USAGE那行表示「能连但没权限」,是正常现象。注意别顺手加上WITH GRANT OPTION,那等于把授权能力也给了业务账户,最小权限就破了。
IIS 那边的目标是 80 进来的请求全部 301 到 443,做法是在站点根目录放一条 URL Rewrite 规则。前提有两个:服务器装了 URL Rewrite 模块,站点已经绑好 443 和证书。
<configuration> <system.webServer> <rewrite> <rules> <rule name="Force HTTPS" stopProcessing="true"> <match url="(.*)" /> <conditions> <!-- 只在明文请求时跳,避免 443 上再跳一次形成循环 --> <add input="{HTTPS}" pattern="^OFF$" /> </conditions> <action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="Permanent" /> </rule> </rules> </rewrite> </system.webServer> </configuration>redirectType="Permanent"是 301,浏览器会缓存,调试阶段建议先用Found(302),确认没问题再换 301,否则改错了要清浏览器缓存才能看到效果,这个坑我踩过不止一次。{R:1}是正则里第一个捕获组,也就是路径部分,写成{URL}会丢掉查询串之外的一些细节。条件判断放在<conditions>里而不是写进<match>,是这条规则能不能避免循环重定向的关键。
4. 审计、服务与防火墙:把该记的记下来,把该关的关掉
这一章的三个部分彼此独立但顺序有讲究:先开审计,才有日志可查;再加固服务,改动才留痕;最后收防火墙,避免前面改端口时把自己关在门外。顺序反了,排查时你连「谁在什么时候改的」都找不到。
4.1 审核策略:四类子类别和它们在事件查看器里的落点
题面要求开四类:登录事件成功/失败、特权使用成功、策略更改成功/失败、进程跟踪成功/失败。图形路径是组策略里的「审核策略」,命令行用auditpol更快,但中文系统上子类别的名字是中文,直接照英文写会报「找不到子类别」。
:: 先列出本机实际的子类别名称,中文系统上是中文 auditpol /get /category:* :: 按题面四类逐条开,子类别名以实际输出为准 auditpol /set /subcategory:"Logon" /success:enable /failure:enable auditpol /set /subcategory:"Privilege Use" /success:enable auditpol /set /subcategory:"Policy Change" /success:enable /failure:enable auditpol /set /subcategory:"Process Tracking" /success:enable /failure:enable :: 复核 auditpol /get /category:*事件落点要心里有数:登录成功 4624、失败 4625,特权使用 4672,策略更改 4739,进程创建 4688。Process Tracking这一类默认只记进程启动,不带命令行,需要在「审核进程创建」里额外打开「包括命令行」才有完整参数。这类事件量很大,磁盘和日志滚动策略要提前规划,否则一两天就把安全日志撑满,反而把关键事件挤掉。改完策略不用重启,但审计策略属于「计算机配置」,域环境下会被域策略覆盖,本地测试要确认没加域。
4.2 SSH:端口 2222 与 PermitRootLogin 的两处连带改动
改 SSH 端口这件事,配置文件只是第一步,真正让人连不上的是后面两道门:SELinux 和防火墙。
cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak sed -i 's/^#\?Port .*/Port 2222/' /etc/ssh/sshd_config sed -i 's/^#\?PermitRootLogin .*/PermitRootLogin no/' /etc/ssh/sshd_config # 语法自检,出错会给行号 sshd -t systemctl restart sshd # SELinux 放行新端口;不加这条,服务起来但连接被拒 semanage port -a -t ssh_port_t -p tcp 2222 # 防火墙放行 firewall-cmd --permanent --add-port=2222/tcp && firewall-cmd --reload # 验证:端口在听、横幅能出来 ss -lntp | grep 2222 ssh -p 2222 -o BatchMode=yes 127.0.0.1 true 2>&1 | head -3semanage port -a在端口已存在时会报错,改已有条目用-m。ss -lntp能看到 2222 在监听,说明 sshd 起来了;此时从外部连不上,问题一定在 SELinux 或防火墙,这两处是独立的门,缺一个就是「服务正常但连不上」。PermitRootLogin no生效后,用 root 直接连会被拒,得先用普通用户登录再su或sudo,测试时别把自己锁在外面——这也是为什么先开一个新终端验证、再关旧终端。sshd -T能打印合并后的最终配置,比翻文件可靠。
4.3 VSFTPD:匿名开关与那一族 timeout 参数
anonymous_enable=NO是最基本的一条,但只改这一条,匿名用户在某些配置下仍然能上传,因为anon_upload_enable是独立开关。超时这块题目给了一组参数,其中idle_session_timeout=600和「无任何操作超时 5 分钟」是对不上的——600 秒是 10 分钟。
CONF=/etc/vsftpd/vsftpd.conf # 匿名相关三条一起关 sed -i 's/^anonymous_enable=.*/anonymous_enable=NO/' $CONF sed -i 's/^#\?anon_upload_enable=.*/anon_upload_enable=NO/' $CONF sed -i 's/^#\?anon_mkdir_write_enable=.*/anon_mkdir_write_enable=NO/' $CONF # 无操作超时按 5 分钟写 300 秒,先删旧值再加,避免重复项 sed -i '/^idle_session_timeout/d' $CONF echo 'idle_session_timeout=300' >> $CONF echo 'data_connection_timeout=300' >> $CONF systemctl restart vsftpd grep -E 'anonymous|timeout' $CONF参数含义要分清:idle_session_timeout是控制连接上多久没敲命令就踢,data_connection_timeout是数据传输连接多久没数据就断,connect_timeout和accept_timeout分别是主动模式和被动模式下建立连接的超时。题面把这几个并列写出来,考核点其实是「知道哪个对应无操作」。另外不同发行版的配置文件路径不一样,有的在/etc/vsftpd.conf,有的在/etc/vsftpd/vsftpd.conf,改之前rpm -qc vsftpd或dpkg -L vsftpd | grep conf确认一下,别改了个没被加载的文件。
4.4 IIS 日志字段与最大并发连接数
IIS 日志要求 W3C 格式,只记录日期、时间、客户端 IP、用户名、方法五项。图形路径是网站 → 日志 → 选择字段;命令行用WebAdministration模块。
Import-Module WebAdministration $site = "IIS:\Sites\Default Web Site" # W3C 格式 Set-ItemProperty $site -Name logFile.format -Value W3C # 字段用 W3C 内部名,不是界面上的中文 Set-ItemProperty $site -Name logFile.fields -Value "Date,Time,c-ip,cs-username,cs-method" # 最大并发连接数 1000 Set-ItemProperty $site -Name limits.maxconnections -Value 1000 # 复核 Get-ItemProperty $site | Select-Object logFile, limitslogFile.fields的取值是 W3C 规范的内部字段名,写「日期」「时间」会直接报错,这一点在只有中文界面的环境里很容易卡住。limits.maxconnections就是高级设置里「限制」下的「最大并发连接数」,设太小会直接 503,设 1000 是题面要求,实际生产要看压测结果。日志字段砍到五项之后,排查时就没有sc-status和time-taken了,这是按题面要求做的取舍,真实环境建议至少保留状态码。
4.5 iptables:23 端口、禁 ping 与 SSH 白名单的顺序问题
防火墙这块题面给了一条iptables -A INPUT -p tcp --dport 23 -j DROP,这条本身没错。问题出在第 18 条:要求「禁止所有人通过 SSH 连接,除了 172.16.1.1」,题面给的命令只有一条 ACCEPT,没有配套的 DROP,照抄等于什么都没限制。
# 禁用 23 端口(telnet) iptables -A INPUT -p tcp --dport 23 -j DROP # 禁 ping:只挡 echo request(type 8),不影响本机 ping 出去 iptables -A INPUT -p icmp --icmp-type 8 -j DROP # SSH 白名单:ACCEPT 必须在 DROP 之前,顺序反了白名单也进不来 iptables -A INPUT -s 172.16.1.1 -p tcp --dport 22 -j ACCEPT iptables -A INPUT -p tcp --dport 22 -j DROP # 落盘,否则重启后规则全丢 iptables-save > /etc/sysconfig/iptables iptables -S | grep -E 'dport (22|23)|icmp'iptables 是按顺序逐条匹配,命中即执行目标动作,所以-A(追加到链尾)的顺序就是执行顺序,ACCEPT 写在 DROP 后面等于白写。--icmp-type 8是 echo request,只挡别人 ping 你,你自己 ping 外面不受影响;想彻底关掉 ICMP 应答也可以走 sysctl:
# 临时生效,重启失效 echo 0 > /proc/sys/net/ipv4/icmp_echo_ignore_all # 永久生效:0 是允许 ping,1 才是禁止,写反了就是“改了没用”的经典现场 echo 'net.ipv4.icmp_echo_ignore_all = 1' >> /etc/sysctl.conf sysctl -p cat /proc/sys/net/ipv4/icmp_echo_ignore_allsysctl -p是从文件重新加载,不执行这一步,/etc/sysctl.conf改了也不会立刻生效,这是禁 ping 失败最常见的原因之一。另外icmp_echo_ignore_all和 iptables 的 ICMP 规则是两套机制,同时开着不冲突,但排查时要分清到底是哪一层在挡。
5. 避坑与排查:五个「明明改了却没生效」的现场
这一章按现象写,每条都能对上前面某一节。加固类任务最耗时间的从来不是改,而是改完不确定有没有生效,
本文还有配套的精品资源,点击获取