
Linux服务器被扫、被爆破、被提权几乎是每个运维和网络安全从业者都会遇到的日常。很多人第一次接触Linux安全配置是因为某天早上打开监控发现SSH登录失败日志里躺着几千条陌生IP的尝试记录也有人是因为等保测评、内部安全审计或者渗透测试报告里被点了一堆高危项。这篇东西就是把这些年我在生产环境里反复做、反复踩坑、最后沉淀下来的一整套Linux操作系统安全配置思路和操作细节摊开来讲。它既不是一份干巴巴的命令清单也不是只讲概念的科普而是从威胁模型出发一层一层把账号、权限、服务、网络、文件系统、日志审计这些环节的配置逻辑讲透让你知道每条命令背后为什么这么写、不这么写会出什么问题。适合刚入行的运维、想转网络安全的新手也适合有一定基础但配置总是零零散散、缺乏体系化的朋友。文中涉及的操作以主流发行版CentOS/RHEL系与Debian/Ubuntu系为主其他发行版思路一致命令细节自行对应即可。1. Linux安全配置到底在防什么先把威胁模型想清楚动手敲命令之前我最想强调的一件事是别把安全配置当成打勾清单。很多人拿到一份Linux加固十条逐条执行完就以为万事大吉结果真正出事的时候发现该进的还是进了。问题出在没想清楚自己在防谁、防什么。安全配置的本质是缩小攻击面、提高攻击成本、留下追溯证据这三件事对应三种不同的配置方向混在一起做就容易顾此失彼。1.1 从默认配置谈起出厂状态为什么不安全Linux发行版安装完之后的默认状态是为开箱即用、方便上手服务的不是为安全服务的。这句话是理解所有加固动作的起点。举个最典型的例子很多发行版默认允许root通过SSH直接登录密码认证默认开启这意味着攻击者只要能猜到或者爆破出密码就直接拿到了最高权限一步到位。再比如默认安装会启动一堆你可能根本用不到的服务打印服务、蓝牙、某些桌面组件每一个监听端口的服务都是一个潜在入口。还有默认的umask值通常是022意味着新建文件是644、目录是755同组用户和其他用户都能读放在多用户或者对权限敏感的目录里就不合适。理解默认配置为什么不安全比记住要改哪几个文件重要得多。因为发行版在变、默认值在变但**默认服务方便优先、安全其次这个底层逻辑不变**。你只有抓住这个逻辑才能在面对一个没见过的发行版时也能快速判断哪些地方需要收敛。我自己的习惯是拿到一台新装的机器第一件事不是装软件而是先跑一遍ss -tulnp看清楚现在开了哪些端口、每个端口后面是哪个进程再对照业务需求逐个确认这个服务我真的需要吗。这个动作花不了五分钟但能帮你建立起对这台机器当前攻击面的清晰认知。1.2 安全配置的优先级排序逻辑手上有几十项要配置的时候先做哪个后做哪个直接影响投入产出比。我的排序逻辑是这样的账户与认证 网络与服务暴露面 文件系统权限 审计与监控 内核参数微调。为什么这么排账户与认证排第一是因为绝大多数入侵的第一步都是拿到一个合法账号无论是爆破、弱口令还是凭据泄露堵住这条路的收益最高、成本最低。网络与服务暴露面排第二因为它是攻击者能看到你的窗口关掉不必要的端口等于直接把门焊死。文件系统权限排第三它决定了一旦某个低权限账号被拿下攻击者能不能横向读取敏感文件或者提权。审计与监控排第四它不阻止入侵但决定了出事之后你能不能查清楚、能不能及时响应。内核参数微调放最后因为它通常是针对特定攻击手法的精细调优收益相对小、误伤风险相对高急不得。这个顺序不是绝对的比如你的机器直接暴露在公网、业务又特别敏感那网络层的收敛就该和账户加固并行。但总体原则是先堵最大的口子再做精细活。一上来就纠结某个内核参数的值却留着root密码登录开着属于典型的捡芝麻丢西瓜。1.3 配置前的准备工作备份、快照、测试环境这一条是我用血泪换来的。早年间我在一台生产服务器上直接改SSH配置改完重启服务因为一个参数写错把自己锁在了门外最后只能通过机房KVM本地控制台进去救回来。从那以后我给自己立了规矩任何涉及远程访问的配置变更动手之前必须保证有三条退路。三条退路具体是第一配置文件的备份改之前先cp sshd_config sshd_config.bak.$(date %F)这个是最基本的第二保持一个已经登录的SSH会话不要断开改完新开一个终端测试能不能连上确认没问题再关掉旧会话这样即使新配置有问题你手里那个已建立的连接还能用第三如果是虚拟机改之前打个快照出问题直接回滚这是最省事的兜底。注意涉及sshd_config、防火墙规则、/etc/fstab这三类文件的修改务必留退路。前两个改错了会让你连不上机器fstab改错了会让系统直接起不来。同时如果你管的是批量服务器强烈建议先在测试机上验证整套配置流程确认业务不受影响之后再推到生产。用配置管理工具Ansible等做批量下发的时候也要留好回滚脚本。安全配置本身是为了让系统更稳千万别因为操作鲁莽把系统搞挂那就本末倒置了。2. 账号与权限体系加固把钥匙管好账户与权限是Linux安全的地基也是最容易被忽视的地方。我见过太多服务器上面躺着十几个早已离职员工的账号或者一堆用来跑服务的账号却配置了可登录的shell。这些幽灵账号平时不显山不露水一旦被利用就是现成的后门。这一章把账号梳理、密码策略、sudo精细化、文件权限、SSH加固这几件事拆开讲每一件都给你可落地的做法。2.1 用户账号清理与密码策略先做减法。用awk -F: ($31000){print $1} /etc/passwd列出所有UID大于等于1000的普通用户逐个确认是不是都在用。系统账号UID小于1000通常是各种服务用的把它们的shell改成/sbin/nologin或/bin/false防止被拿来登录。命令是usermod -s /sbin/nologin 用户名。这一步能砍掉相当一部分潜在登录点因为服务账号通常不需要交互式登录。对于确实需要登录的账号密码策略必须管起来。核心工具是pam_pwquality老系统叫pam_cracklib。配置文件在/etc/security/pwquality.conf几个关键参数minlen控制最小长度我一般设12minclass控制字符类别数设3或4强制大小写字母、数字、特殊符号混合retry控制输错几次重来。配合/etc/login.defs里的PASS_MAX_DAYS密码最长有效期我设90天、PASS_MIN_DAYS最短使用天数设1防止改密码绕过历史、PASS_WARN_AGE提前几天提醒设7。还有两个容易被忽略的点。一是密码历史通过pam_pwhistory模块的remember参数比如设5防止用户改密码时循环用几个旧密码。二是账户锁定通过pam_faillock现代发行版推荐或pam_tally2老版本配置连续输错5次锁定15分钟这对付SSH爆破特别有效直接在认证层就把暴力尝试卡住了。# 查看账户锁定情况pam_faillock faillock --user 用户名 # 手动解锁 faillock --user 用户名 --reset需要提醒的是pam_faillock的配置要分auth和account两段写在/etc/pam.d/system-authRHEL系或/etc/pam.d/common-authDebian系里改之前一定备份改错了会导致所有账号都登不进去。我一般会先在一个测试账号上验证确认lockout和unlock行为都正常再全量推。2.2 sudo权限精细化控制很多团队图省事直接给运维账号ALL(ALL) ALL等于把所有权限都放开了。更糟的是有人图方便直接su到root干活这样所有操作都记在root名下出了事根本查不出是谁干的。这两个习惯都该改。sudo的正确用法是最小权限可审计。/etc/sudoers里针对每个用户或用户组只授予它完成工作所必需的命令。比如某个账号只需要重启某个服务就写用户名 ALL(root) /bin/systemctl restart nginx而不是给全部权限。命令路径要用which查出来的绝对路径防止有人通过修改PATH来劫持。如果确实需要给较高权限可以配置Defaults选项增强审计和安全性Defaults logfile/var/log/sudo.log单独记录sudo操作日志Defaults timestamp_timeout5把免密时间缩短到5分钟默认是15分钟太长的话别人趁你离开工位就能直接操作Defaults requiretty部分场景限制只能在终端里用sudo。提示编辑sudoers永远用visudo命令不要直接用vi打开。visudo会在保存时做语法检查避免因为一个拼写错误导致所有sudo都失效。还有一个细节/etc/sudoers里默认有一行%wheel ALL(ALL) ALL意思是wheel组的成员拥有全部sudo权限。如果你想做更细的控制可以考虑把这行注释掉改成按用户、按命令粒度授权。权限给得越细出事时能追责的颗粒度就越细。2.3 文件权限与特殊位检查文件权限里藏着提权的机会尤其是那几个特殊位SUID、SGID、Sticky。SUID的作用是让普通用户执行某个程序时临时拥有程序属主的权限比如/usr/bin/passwd就需要SUID才能改密码。但如果有攻击者能往一个SUID程序里注入代码或者把某个普通文件误设成SUID属主是root那就等于给了提权通道。所以定期排查系统里所有SUID/SGID文件是必要的# 查找所有SUID文件 find / -perm -4000 -type f 2/dev/null # 查找所有SGID文件 find / -perm -2000 -type f 2/dev/null # 查找所有人可写且带SUID的文件极度危险 find / -perm -4002 -type f 2/dev/null拿到列表之后对照发行版的标准SUID清单通常是passwd、su、sudo、mount、umount、ping等少数几个逐个核对多出来的就要问一句这是干嘛的。我之前就在一台线上机器上查出一个业务程序自带的SUID文件属主是root谁都能执行这基本等于埋了个雷。除了特殊位还有几个关键文件的权限要盯死。/etc/passwd应该644/etc/shadow和/etc/gshadow应该000或400只有root可读/etc/group是644。.ssh目录应该是700里面的authorized_keys是600。家目录建议750或700防止同机其他用户翻你的东西。还有一个万能兜底检查find / -perm -ow -type d 2/dev/null找出所有其他人可写的目录这种目录如果出现在系统路径里比如/tmp之外的/usr下某个子目录那就非常可疑。正向的合理权限之外我更想说说为什么权限管理难坚持。难就难在业务上线时经常有人图快用chmod 777糊弄过去当时能跑但埋下的是长期隐患。我的做法是在CI或者部署流程里加一道权限检查部署完自动扫一遍有没有777文件和异常SUID有就报警。人靠自觉靠不住靠自动化兜底才稳。2.4 SSH登录安全加固SSH是攻击者最爱的入口没有之一。加固SSH效果立竿见影。/etc/ssh/sshd_config里几个必须改的项配置项推荐值作用说明PermitRootLoginno禁止root直接SSH登录逼攻击者必须先拿到普通账号PasswordAuthenticationno关闭密码认证只留密钥登录直接免疫密码爆破PubkeyAuthenticationyes开启公钥认证PermitEmptyPasswordsno禁止空密码登录MaxAuthTries3单次连接最多尝试3次认证ClientAliveInterval3005分钟无操作发一次保活探测ClientAliveCountMax2两次探测无响应就断开AllowUsers指定用户列表白名单制只允许特定用户登录关于密钥登录有两个细节新手容易踩。一是私钥权限私钥文件必须是600.ssh目录必须是700权限不对SSH会直接拒绝使用很多人被这个卡半天。二是密钥类型和长度现在推荐用ed25519比RSA更短更安全ssh-keygen -t ed25519即可如果必须用RSA长度至少4096位。改完配置的重启命令是systemctl restart sshdDebian系服务名是ssh但记住前面说的重启前先测试配置语法sshd -t重启时保持一个旧会话不断开。注意关闭密码认证之前务必确认你已经能用密钥正常登录并且这个密钥在别的机器上有备份。否则一旦私钥丢失加上密码认证已关你就真的进不去了。另外一个常被忽略的加固点是登录横幅和SSH协议版本。横幅Banner不影响安全但影响合规很多等保要求有警告语。SSH协议版本现在默认就是2老系统上还是1的要强制改掉v1有已知缺陷。还有LoginGraceTime默认2分钟有点长可以缩到30秒减少未认证连接的占用时间。3. 服务与网络层收敛能关的门全关上账号加固解决的是谁能进来服务与网络收敛解决的是从哪儿能进来。这两层是互补的。就算你的账号再干净如果上面跑着一个存在漏洞的老版本服务、端口还对着公网开放那照样会被拿下。这一章讲服务最小化、防火墙配置、内核网络参数三件事。3.1 服务与端口最小化原则只有六个字不用的全关掉。做法分三步。第一步systemctl list-unit-files --typeservice --stateenabled列出所有开机自启的服务逐个问这个业务需要吗。像cups打印、avahi-daemon局域网发现、rpcbind这类服务器上基本用不到systemctl disable --now 服务名关掉。第二步ss -tulnp看当前所有监听端口对照业务确认多出来的查清楚是什么。第三步检查xinetd/inetd这类老式超级守护进程有没有被装上来它们管理的服务往往容易被忘掉。有个细节要注意disable和mask的区别。disable只是取消开机自启但服务依赖启动时还可能被拉起来mask是直接软链到/dev/null让服务彻底无法启动对于确定永远用不到的服务比如某些被漏洞缠身的组件用mask更彻底。反过来有些服务你只是暂时不需要那就别急着卸载disable就够了卸载可能破坏依赖关系。3.2 防火墙规则配置防火墙是网络层的总闸。现代Linux主流用firewalldRHEL系或ufwUbuntu系底层都是nftables或iptables。我的建议是默认拒绝只放行明确需要的。以firewalld为例# 查看当前规则 firewall-cmd --list-all # 只放行特定来源访问SSH比直接开放给所有人安全得多 firewall-cmd --permanent --add-rich-rulerule familyipv4 source address10.0.0.0/24 port protocoltcp port22 accept # 移除默认对所有人的SSH放行 firewall-cmd --permanent --remove-servicessh firewall-cmd --reload上面这段的意图是把SSH访问限制在管理网段内而不是让全网都能连。这是我在实际环境里最常做、也最有效的收敛动作。即使密码策略、密钥策略做得再到位把SSH暴露给全世界本身就是风险。如果业务必须对公网提供HTTPS那就只放行443其他一律挡掉。放行规则要尽量具体明确源地址、明确端口、明确协议避免用大范围的放行整个网段的所有端口这种写法。规则写完一定要测试从允许的来源试连从不允许的来源也应该试连确认被拒两边都对才算配置到位。改防火墙规则之前同样要留退路firewall-cmd --runtime-to-permanent可以把当前运行的规则固化改挂了可以--reload恢复。3.3 内核网络参数调优/etc/sysctl.conf或/etc/sysctl.d/下的文件里有一批网络相关的参数能挡掉一批常见的探测和攻击。挑几个最有用的说net.ipv4.conf.all.rp_filter1开启反向路径过滤丢弃源地址看起来不合理的数据包能防一部分IP欺骗。net.ipv4.tcp_syncookies1开启SYN Cookie缓解SYN Flood这类半连接洪水攻击。net.ipv4.conf.all.accept_redirects0和net.ipv4.conf.all.send_redirects0不接受、不发送ICMP重定向防止路由被恶意篡改。net.ipv4.conf.all.accept_source_route0拒绝源路由数据包源路由常被用来绕过网络策略。net.ipv4.icmp_echo_ignore_broadcasts1忽略广播ICMP防止被用作放大攻击的反射点。net.ipv4.conf.all.log_martians1记录源地址可疑的数据包便于事后排查。改完用sysctl -p让它生效或者写入/etc/sysctl.d/99-security.conf然后sysctl --system。这些参数里syncookies和rp_filter是我的必选项其余根据业务环境取舍。提示内核参数调优的收益是渐进的误伤风险却可能是突发的。比如你关闭了ICMP某些依赖ping做健康检查的监控就会误报。所以每一批参数最好单独上线、单独观察别一次改一大串。我吃过一次改了一堆参数导致某台机器的负载均衡健康检查全失败的亏排了半天才发现是一个看似无关的accept_redirects。4. 文件系统与日志审计留下可追溯的痕迹前三层做下来攻击面已经小了很多。但现实里没有绝对安全的系统一定会有漏网的。这一层的意义是万一真出事了你要能发现、能定位、能追溯。文件系统权限、审计系统、日志管理这三件事决定了你在事后有没有主动权。4.1 关键目录权限与挂载选项挂载选项能通过限制目录能力的方式加一层防护。/etc/fstab里可以给特定分区加安全选项。最常用的是给/tmp加noexec,nosuid,nodevnoexec让/tmp下的文件无法执行堵死攻击者往临时目录扔木马执行的常见套路nosuid让/tmp下文件的SUID位失效nodev禁止解析设备文件。同理/var/tmp、/dev/shm这些全世界可写的地方都建议加上这三个选项。# /etc/fstab 示例先加tmpfs挂载再给/tmp指定安全选项 tmpfs /tmp tmpfs defaults,noexec,nosuid,nodev,size2G 0 0这里有个坑要提前说加了noexec之后某些软件把临时文件放/tmp并需要执行的地方会失败比如一些安装程序、某些语言的运行时会报错。所以上线前要评估业务是否依赖/tmp执行实在不行可以只加nosuid,nodev放弃noexec。另外改fstab务必用mount -o remount先测试不要直接重启验证改错了系统起不来的代价太大。除了挂载选项关键文件还要用chattr做不可变保护。比如给/etc/passwd、/etc/shadow、/etc/sudoers加上不可修改属性chattr i /etc/passwd。加了这个连root都不能直接改这些文件要先chattr -i能有效阻止攻击者篡改认证相关文件留后门。但要注意加i之后正常的用户管理操作useradd、passwd也会失败所以更适合在配置稳定期、不需要频繁改用户的机器上使用或者只给最核心的几个文件加。4.2 审计系统auditd配置auditd是Linux自带的审计框架能记录系统调用级别的操作是排查入侵的利器。默认安装后规则很少需要自己加。核心是/etc/audit/rules.d/下的规则文件加完用augenrules --load加载。几条我必配的规则# 监控用户和组文件的修改 -w /etc/passwd -p wa -k identity -w /etc/shadow -p wa -k identity -w /etc/sudoers -p wa -k privilege # 监控敏感目录 -w /etc/ssh/sshd_config -p wa -k sshd # 记录所有提权操作 -a always,exit -F archb64 -S execve -F euid0 -F auid1000 -k rootcmd # 记录文件删除操作 -a always,exit -F archb64 -S unlink -S rmdir -S rename -k delete-w表示监控某个文件或目录-p指定监控的操作类型w写、a属性变更、x执行-k是给这条记录打的标签方便事后用ausearch -k identity按标签检索。最后一条记录所有euid变成0也就是提权的操作特别有用谁在什么时候用sudo干了什么一目了然。auditd的规则要控制数量规则越多性能开销越大。我一般只监控认证相关文件、关键配置、提权操作、敏感目录访问这几类。另外日志的管理也重要audit日志本身也要防篡改最好通过audisp-remote或者syslog转发到远程的日志服务器本地删了远程还有。这一点在排查问题时是决定性的攻击者拿到root之后第一件事往往就是清本地日志。4.3 日志集中与轮转日志分散在各台机器上出事时一台台翻是很痛苦的。集中化是刚需。用rsyslog或者syslog-ng把关键日志认证、sudo、audit转发到一台专门的日志服务器或者用更现代的方案做采集。转发本身还能起到异地留存的作用本地被清空了远程还在。轮转也别忘了。logrotate默认会处理大部分日志但要检查/etc/logrotate.conf和/etc/logrotate.d/下的配置确认关键日志比如/var/log/secure或/var/log/auth.log、/var/log/audit/audit.log的保留周期够长。默认可能只留四周对安全审计来说太短我一般设成保留半年甚至一年具体看合规要求和磁盘空间。磁盘空间要算好audit日志增长可能很快配了详细规则之后尤其要注意给/var/log留足空间否则日志写满会导致服务异常。还有一点容易被忽略日志文件的权限。/var/log/secure、/var/log/audit/目录这类含敏感信息的日志权限应该收紧只让root和特定组读。写个脚本定期检查日志文件的属主和权限有没有被改也是防篡改的一部分。5. 常见问题排查实录与避坑清单前面四章讲的是怎么做这一章讲做的时候会出什么问题。很多配置手法本身不难难的是出错之后怎么快速定位。我把这些年踩过的坑整理出来你遇到类似情况可以直接对号入座。5.1 配置完连不上服务器怎么办这是最高频的事故没有之一。改完SSH、防火墙或者fstab之后机器连不上了心跳立刻上到一百八。冷静按这个顺序排查。第一步确认是不是网络层挡的。如果你改的是防火墙最可能的情况是规则把SSH端口封了。这时候如果你还有另一个已经建立的SSH连接那就有救了——通过它进去把规则回滚比如firewall-cmd --reload恢复或者临时插入一条放行你当前IP的规则。如果连接全断了就得走带外管理机房KVM、云控制台的VNC、串口控制台。第二步如果网络通但SSH连不上多半是sshd_config改错了。同样有活动连接就从活动连接进没有就走带外控制台把配置备份还原sshd -t检查语法重启服务。第三步如果是改完fstab重启后系统起不来那就只能进单用户模式或者救援模式编辑fstab去掉导致问题的挂载项。这就是为什么我前面反复强调fstab要用remount先测、不要直接重启验证。根本的预防手段就一句话永远保留一条能进去的路。活动会话别断、带外管理要确保可用、改配置前有备份、虚拟机有快照。这四条里至少要有两条同时满足才动远程访问相关的配置。5.2 常见问题速查表把日常最高频的问题整理成表方便对照现象可能原因排查与解决SSH用密钥登录提示Permissions too open私钥或.ssh目录权限不对私钥chmod 600.ssh目录chmod 700用户被锁死无法登录触发pam_faillock锁定faillock --user 用户名查看--reset解锁或调整锁定阈值sudo提示不在sudoers文件中用户没被授权用visudo添加对应授权确认加入了正确用户组服务启动失败提示权限被拒文件权限或SELinux限制检查文件属主权限ausearch或journalctl看拒绝详情改了sysctl后网络异常参数误伤逐条注释回滚sysctl -p生效定位具体参数audit日志把磁盘写满规则过多、保留周期太长精简规则调整logrotate保留数扩大/var/log分区/tmp加了noexec后程序报错业务依赖在/tmp执行去掉noexec保留nosuid,nodev或让业务改用其他临时目录密码策略改了之后老用户登录提示密码过期PASS_MAX_DAYS生效属正常行为如需临时放行用chage单独调整关于SELinux和AppArmor这类强制访问控制MAC框架这里要单独提一句。它们的思路是在传统权限之外再加一层即使你有权限也不一定允许的限制安全性更高但配置复杂容易和业务冲突。我的建议是不要因为怕麻烦直接关掉至少要跑在permissive模式观察一段时间看日志里有哪些被拒绝的操作评估之后再决定是调整策略还是设为disabled。直接关掉等于放弃一整层防护实在可惜。如果要用排查拒绝事件用ausearch -m avc -ts recentSELinux或者dmesg | grep -i apparmorAppArmor。5.3 长期维护的几个习惯配置是一次性的安全是持续性的。做过一次加固不代表可以高枕无忧系统在变、业务在变、漏洞在变。我坚持的几个习惯分享给你。第一定期重新排查。每季度至少一次重新跑一遍SUID扫描、端口扫描、账号审计把新增的可疑项清掉。很多问题不是一次配置产生的是业务迭代过程中慢慢积累出来的。第二变更即检查。每次上线新服务、新端口、新账号顺手确认它有没有引入新的暴露面。把这一步塞进你的部署流程里比事后补救省事得多。第三关注补丁。系统组件和第三方软件的漏洞是绕不过去的及时打补丁是最朴素也最有效的防护。至少建立一套补丁管理的流程知道哪些机器在什么版本、什么时候该更新。第四别迷信单一手段。安全配置是纵深防御每一层都可能被绕过但多层叠加能大幅提高攻击成本。账户、网络、文件、审计每一层都做扎实比在某一个点上做到极致但其他点全放开要靠谱得多。最后再分享一个小技巧。我会给每台重要的服务器建一个安全基线文档把当前生效的关键配置SSH参数、防火墙规则、audit规则、sysctl关键值快照下来配上日期。这样任何时间点有人动了配置和基线一对比就能发现变化。这个习惯帮我抓出过好几次不知道为什么被改掉的配置比对着几百行配置文件发呆高效太多。安全这件事很多时候拼的不是技术多高深而是流程和习惯够不够扎实。