尧图精选

Linux服务器安全加固实战:防火墙、权限管理与入侵检测全攻略

🕒 发布时间:2026/10/2 5:08:13 📁 来源:尧图网络
这话题我在工位上跟同事聊过无数次了。不管是新上线的云服务器还是机房里的物理机凡是业务跑在Linux上的安全加固这事早晚都得面对。很多人觉得加固就是“装个防火墙、改个SSH端口、加个密码策略”真这么简单的话那些被勒索、被挖矿、被删库的案例就不会年年都有了。这三个月我集中做了一批服务器的整体安全加固把防火墙、权限管理、入侵检测这三块完整梳理了一遍踩了坑也填了坑把整个过程和心得写下来给做运维、做研发、甚至只是自己在云上租了台机器的朋友一条能直接照着做的路线。这篇文章解决的是一类很具体的问题你不是没有安全意识而是不知道从哪下手也不知道做完之后有没有效果。我会把加固思路、命令、配置、排查方法都拆开讲清楚适合刚入门的小白也适合已经有了几年经验但没系统梳理过安全体系的运维。1. 先从攻击面讲起Linux加固到底在防什么1.1 常见入侵路径盘点很多人的第一反应是“我的服务器没什么重要东西谁会来打”。但现实里扫描整个网段找弱口令的脚本从来没停过只要你的IP暴露在公网上基本上一小时内就会收到扫描记录。攻击者最常走的路径其实就那么几条SSH暴力破解这是占比最高的入口。用root账号试密码试dict里的弱口令一旦成功就是最高权限。服务漏洞Web服务、数据库、中间件存在已知CVE比如某些版本的Tomcat、Redis、Nginx组件漏洞。应用层漏洞代码注入、文件上传、路径穿越这些往往导致直接拿到服务器权限。账号泄露与内部滥用共享账号、离职员工账号未清理、开发人员用运维权限干别的。配置脆弱性root允许远程登录、默认端口全部暴露、防火墙规则形同虚设、日志不保留。我在实际加固过程中发现一个规律真正让人头疼的往往不是那种0day高精尖攻击而是最基础的弱口令和配置疏漏。安全加固本质上就是把攻击者需要用到的“桥”一座座拆掉能拆多少拆多少。1.2 分层防御的思路与加固优先级如果把服务器比作一栋写字楼防火墙就是大楼门口的门禁系统权限管理是进入楼内后你的门卡能刷开哪些门入侵检测则是走廊里的摄像头和各种报警器。三道防线各管一段缺一不可。分层防御的典型结构层级对应措施作用网络层防火墙、安全组、入侵防御控制谁能访问哪些端口系统层SSH加固、PAM策略、用户权限收敛控制登录方式和用户权限应用层Web防火墙、Tomcat/Redis安全配置阻挡应用漏洞利用数据层文件权限、不可变属性、备份保护数据不被篡改和破坏我个人的建议顺序是先接管入口再做权限收敛最后补检测能力。为什么要这个顺序因为优先级是“先挡外面的再管内部的最后是发现问题”。如果一开始就装了一堆检测工具但入口还是裸奔的检测到入侵也只是事后报警意义差了很多。实际操作中我也碰到过一种情况运维同事在改防火墙默认策略时把自己SSH断开了结果只能跑机房插显示器。所以加固前先确认所有配置没人动过或者至少有控制台/物理访问兜底再开始动手。2. 权限管理把最小权限原则落实到每一条命令2.1 用户、sudo与PAM谁能进、进来能做什么权限管理这块我基本是从三个维度来做的账号、提权、认证策略。先说账号。系统装好以后默认会有很多服务账号比如bin、daemon、adm、lp、mail等这些大多数情况下用不到但建议先查一遍再决定怎么处理。重点排查/etc/passwd里是否存在真实用户尤其是有登录Shell的账号。检查命令很简单awk -F: $3 1000 {print $1, $3, $7} /etc/passwd正常服务器上这个列表应该非常短。如果有共享账号、离职人员的账号直接锁定或者删除。锁定操作用passwd -l 用户名这比直接删除要更安全万一后面发现这个账号还在被用还能解封调查。然后是sudo提权。千万不要给所有人全量sudo权限更不能图省事给某个人加一个username ALL(ALL) NOPASSWD: ALL就完事。我在生产环境里见过开发账号带着无密码sudo权限跑了好几年出事之后查日志根本分不清是谁执行的命令。比较合理的做法是# 使用visudo编辑不要直接改文件 # 赋予某个组sudo权限 %deploy ALL(ALL) ALL # 只允许执行特定命令 deploy01 ALL(ALL) /usr/bin/systemctl restart nginx, /usr/bin/rsync这里有个关键点sudo的粒度越细审计价值越高。你可以在/var/log/secure里看到每个sudo命令的执行记录如果某天排查问题这段记录比什么都管用。接着说PAM认证策略。密码策略是很多人忽略的部分默认的密码可能永远不过期、没有复杂度和失败锁定。以主流发行版为例可以在/etc/security/pwquality.conf里配置minlen 12 dcredit -1 ucredit -1 lcredit -1 ocredit -1 difok 3这四个credit参数分别要求密码里必须包含数字、大写字母、小写字母、特殊字符负号表示至少出现一个。密码最短长度建议不低于12位别迷信8位现在挖矿程序跑字典的速度8位纯数字基本是秒破。登录失败锁定通过faillock来配。新建/etc/security/faillock.conf或者通过PAM配置关键参数是deny 5连续5次失败锁定、unlock_time 900锁定15分钟、even_deny_root 1root也锁定。这个配置对SSH暴力破解有直接拦截效果但我一般还会配合后面的fail2ban一起用前者管本地认证后者管网络层封禁。注意修改PAM配置之前先备份原文件。PAM的加载顺序非常敏感配置写错可能导致所有人包括root都无法登录。我的习惯是先开一个root会话不要关然后修改配置做测试确认没问题再关闭旧会话。2.2 文件权限与特殊权限位最容易忽略的“后门”文件权限这块大家都会看rwx但真正容易被忽略的是SUID、SGID和Sticky Bit这三个特殊权限位。SUID位最危险。一个文件如果设置了SUID意味着任何用户执行它时都会以文件属主的身份运行。如果属主是root就相当于任何人都能通过这个程序获得root身份执行。经典的渗透手法就是上传一个SUID shell或者利用系统里自带的SUID程序提权。我每次加固都会全盘扫描一下find / -perm -4000 -type f 2/dev/null # 同样把2000SGID和6000一起查 find / -perm -6000 -type f 2/dev/null查完之后逐个确认这些命令是不是真的需要SUID/SGID。大部分情况下像passwd、su、sudo这些系统命令是必须保留的但如果你发现一些冷门路径下的二进制文件带SUID位尤其是不在系统标准目录里的那就很可疑。去掉权限位的命令是chmod u-s /path/to/fileSticky Bit相对友好一些它主要用于/tmp、/var/tmp等共享目录。设置了Sticky Bit之后目录里的文件只有属主能删除即使是root以外的人有写权限也不能删别人的文件。这就是为什么/tmp目录权限是1777而不是777。一般人不会特地去改但我见过有的管理员觉得“777权限更方便”把/tmp改没了Sticky位结果一个用户就能删掉其他用户临时文件甚至在共享目录里放恶意脚本诱导别人执行。umask也顺手提一下。umask决定了新建文件和目录的默认权限建议在/etc/profile或/etc/bashrc里设置umask 022或更严的027。022意味着新文件是644、新目录是755027则会把组和其他人的写权限去掉对多用户服务器更稳妥。2.3 不可变属性与ACL最后一道防篡改防线权限管理做到前面那一步基本能挡住绝大多数误操作和普通提权。但root用户本身还是至高无上的一旦系统被拿下了root/etc/passwd、/etc/shadow、/etc/ssh/sshd_config这些文件是首要篡改目标。这时候就要用到文件系统的不可变属性chattr i /etc/passwd chattr i /etc/shadow chattr i /etc/ssh/sshd_config chattr i /etc/sudoers chattr i /etc/rc.local加了i属性的文件哪怕是root也没有权限修改、删除甚至不能创建硬链接。这对于防篡改来说非常有效我见过攻击者拿到root之后想往/etc/rc.local里写入持久化后门结果发现chmod和vim都报错那感觉确实很痛快。查看某个文件是否被设置了不可变属性用lsattrlsattr /etc/passwd # 输出中间有i标记就是被锁定了 ----i--------- /etc/passwd但这里有个大坑必须先说给系统关键文件加了i之后所有基于脚本的自动化配置管理工具比如Ansible、puppet、甚至自己写的定时维护脚本在更新这些文件时会全部失败。我踩过一次给/etc/hosts加了i后面改DNS映射怎么都写不进去排查半天才发现是加固脚本干的。所以加锁之前务必确认没有别的自动化流程依赖这些文件真要解锁时用chattr -i去掉属性再改改完再加回去。ACL访问控制列表是在传统权限之上更精细的控制手段。比如一个web项目目录/data/www属于www用户但一个运维账号需要通过SSH进去调整文件常规做法可能直接改属主或者给other加权限这都不够安全。用ACL就能精确到某个用户setfacl -m u:ops:rwx /data/www # 查看ACL权限 getfacl /data/www # 移除ACL setfacl -x u:ops /data/wwwACL的存在让“最小权限”可以落实到具体人而不是粗放的组和other。不过注意ACL设置之后文件权限位里的号会标记出来备份和恢复时要用getfacl -R和setfacl -R --restore否则恢复文件后ACL会丢。3. 防火墙策略从默认放行到默认拒绝3.1 先搞清楚选型iptables、firewalld还是nftables聊防火墙之前得先放下一个争论到底用iptables、firewalld还是nftables。我的态度很简单你手上是哪个发行版就优先用它的原生管理工具不要两头混着配。三者的关系用通俗的话说iptables是最经典的netfilter命令行工具规则直接脚本化非常灵活但规则多了之后可读性很差。firewalld是RHEL/CentOS 7开始默认引入的管理工具引入了zone的概念把端口和服务按区域归类。日常使用比裸iptables友好得多。nftables是netfilter的新一代框架语法更简洁性能更好Debian 11以后的版本逐步在向nftables迁移。维度iptablesfirewalldnftables适用发行版所有RHEL系为主新版本Debian/RHEL配置方式命令行持久化文件zoneservice/port脚本文件学习曲线中等平缓先陡后平规则可读性较差较好好但如果系统里同时配置了firewalld和iptables服务而且两个都在跑很容易出现规则互相冲突的情况。我的经验是用firewalld就只通过firewalld命令管理底层它自己会调用iptables/nftables不要手动去改iptables规则否则reload之后手动规则就没了这个坑后面细说。3.2 实战从默认放行改成最小开放策略大多数Linux发行版默认防火墙规则非常宽松基本上只有“开放”和“不开放”的区分甚至有些云镜像默认firewalld都没有启动。安全加固的第一步就是先明确一个原则默认拒绝最小开放。RHEL系的操作序列大概是这样的# 确认firewalld运行状态 systemctl status firewalld # 查看当前默认zone和已开放的端口 firewall-cmd --get-default-zone firewall-cmd --list-all # 设置默认拒绝把默认zone的未显式允许的服务全部拒掉 # 发布: 将公开网卡绑定到public zone firewall-cmd --set-default-zonepublic # 只放行SSH firewall-cmd --permanent --add-servicessh # 允许回环流量这是必须的 firewall-cmd --permanent --add-rich-rulerule familyipv4 source address127.0.0.1 accept # 重新加载生效 firewall-cmd --reload这里要单独讲一下--reload和--complete-reload的区别。--reload是平滑加载不会中断现有连接适合日常改规则--complete-reload会临时中断所有连接重新加载全部规则一般在规则严重混乱时才用。日常操作不要乱用--complete-reload生产环境一个中断可能就是事故。对于用iptables的老系统对应的策略是# 先备份现有规则救命操作 iptables-save /root/iptables.rules.bak # 清空自定义链规则 iptables -F # 设置默认策略INPUT链默认拒绝 iptables -P INPUT DROP # 允许回环 iptables -A INPUT -i lo -j ACCEPT # 允许已建立的连接及关联连接 iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT # 放行SSH iptables -A INPUT -p tcp --dport 22 -j ACCEPT # 持久化规则 service iptables save # 或者 iptables-save /etc/sysconfig/iptables很多朋友在设置iptables -P INPUT DROP之后立刻SSH断连原因就是没有提前加那一条ESTABLISHED,RELATED允许规则。SSH新建立连接时客户端发来的数据包会被当成INPUT链的NEW状态处理如果默认策略是拒绝那就直接断了。所以顺序很重要先允许回环再允许已建立的连接最后再设置默认DROP顺序反了会出问题。3.3 黑白名单与端口管理细节最小开放策略做完之后防火墙的精细化管理才算刚开始。实际工作中我们往往需要限制访问来源、临时封禁某个IP、或者在特定场景下允许某个管理端口只对办公网开放。这些场景在firewalld里用rich rule处理最方便。比如我只允许办公网段192.168.30.0/24访问MySQL的3306端口firewall-cmd --permanent --add-rich-rulerule familyipv4 source address192.168.30.0/24 port protocoltcp port3306 accept firewall-cmd --reload如果某个IP持续发起暴力破解也可以临时封禁firewall-cmd --permanent --add-rich-rulerule familyipv4 source address203.0.113.7 reject firewall-cmd --reloadreject和drop的区别很多人不清楚drop是直接丢弃数据包客户端会卡在那里等超时扫描方感觉主机“不存在”reject是直接回一个拒绝响应客户端立刻知道访问不通。对防暴力破解来说drop的迷惑效果更好因为攻击者不确定是主机下线了还是端口换了。对内部误封源IP来说reject更容易让用户立即发现问题。还有一个必须强调的细节firewalld的--permanent加--reload组合才是永久有效性。如果只加了--permanent不reload本次会话不生效如果只用不带--permanent的规则reload之后立刻消失。很多新手配完规则发现重启后没了基本都是这个原因。关于“防火墙关闭有影响吗”这个问题我看到很多人问这里统一回答裸奔运行的系统其风险取决于暴露面。如果机器完全在内网隔离环境关闭防火墙的短期风险尚可承受但只要有任何外部访问路径关闭防火墙就等于放任所有端口对新连接开放。真实环境里我见过关闭防火墙后被植入挖矿程序的案例排查时第一件事就是看主机上多出来的外连进程代价非常大。所以别说“感觉没啥影响”没出事儿只是没到时候。Docker环境下还有一个容易踩的坑Docker启动时会写入自己的iptables规则而且这些规则优先级比常规规则高。很多人发现防火墙明明限制了某个端口但Docker容器里的服务照样能从外部访问原因就在这里。如果你用Docker跑业务要么在Docker层面做网络隔离比如用bridge网络不映射端口要么用iptables的DOCKER-USER链来管理不要试图用firewalld直接封Docker映射的端口那基本封不住。4. 入侵检测与日志审计如何发现“已经发生的事”4.1 日志体系Linux留痕的第一现场防火墙和权限管理做得再好也不能保证百分之百不被突破。所以最后一道环节是检测——尽早发现异常才能在攻击者搞出更大破坏之前止损。而检测的根源就是日志。Linux的日志文件分布在/var/log下重点盯这几个/var/log/secureRHEL系//var/log/auth.logDebian系所有认证和sudo记录都在这查看SSH登录、sudo执行、su切换。/var/log/messages系统整体运行日志。/var/log/btmp失败的登录记录lastb命令读取。/var/log/wtmp成功登录记录last命令读取。/var/log/cron计划任务执行记录。检查SSH爆破最直接的就是统计Failed password的数量以及来源IP的分布grep Failed password /var/log/secure | awk {print $(NF-3)} | sort | uniq -c | sort -nr | head -20如果某个IP的失败次数在短时间内达到几十上百基本可以判定是扫描器或暴力破解后续交给fail2ban自动封禁。另外建议把核心服务的日志接入集中日志平台比如ELK或Loki。单机日志会轮转、会被攻击者清理集中日志至少能保证攻击者清除了本地痕迹之后你还有一份独立证据。我在生产环境里吃过这个亏被入侵后本地/var/log/secure被人为清空只能靠那时候已经开始同步的远程日志去还原入侵时间线。4.2 fail2ban实战给暴力破解装上自动反击fail2ban的原理不复杂它轮询应用的日志文件匹配到异常特征比如多次登录失败之后调用防火墙规则把攻击源IP封掉一段时间。相当于给你的服务器装了一个自动识别和主动封禁的“门禁保安”。安装和启用非常快# Debian/Ubuntu apt install fail2ban -y # RHEL/CentOS yum install fail2ban -y配置上我建议不要直接改主配置文件/etc/fail2ban/jail.conf而是新建/etc/fail2ban/jail.local覆盖需要的部分。原因很简单升级软件时主配置文件可能会被覆盖而local文件是独立保留的。基本配置长这样[DEFAULT] bantime 3600 findtime 600 maxretry 5 ignoreip 127.0.0.1/8 ::1 192.168.30.0/24 [sshd] enabled true port ssh logpath /var/log/secure这几个参数的含义要搞清楚别照抄findtime统计窗口也就是多长时间内的失败尝试会被计入。maxretry在统计窗口内最多允许失败几次。bantime超过阈值后被封禁的秒数。生产环境我建议至少3600秒极端环境下可以设为负值表示永久封禁但永久封禁有风险可能把正常用户误封进不来所以别轻易用永久。配置完重启并确认生效systemctl restart fail2ban # 查看当前封禁列表 fail2ban-client status sshd实测下来fail2ban对公网暴露的SSH端口效果立竿见影。我见过一台新机器部署完fail2ban之后第一次24小时内就封了几十个不同的尝试IP。它不一定能防住高级攻击但对付无差别扫描已经足够了。ignoreip那行是白名单一定要把自己的办公网IP和运维跳板机IP加进去否则你自己在外网配置服务器手滑输错几次密码IP被封掉了那才是真正尴尬的时刻。4.3 文件完整性校验与系统后门排查fail2ban防的是网络层的暴力破解但假如攻击者已经进来一次并且植入了后门靠日志很难发现。这时候需要从文件层去做完整性校验。我常用的工具是AIDEAdvanced Intrusion Detection Environment。思路很朴素给系统关键文件建立一个哈希基线数据库之后定期比对这个数据库任何文件变动都会被指出来。初始化基线yum install aide -y # 首次初始化生成基线数据库 aide --init # 生成的文件在/var/lib/aide/aide.db.new.gz替换成正式库 mv /var/lib/aide/aide.db.new.gz /var/lib/aide/aide.db.gz之后每次检查就是aide --check输出里会列出所有“被添加、被删除、被修改”的文件你只需要关注那些不在预期变更列表里的条目。比如/usr/bin下新出现一个奇怪的文件或者/etc/ssh/sshd_config被改动了都值得立刻查。AIDE的短板是它只能对比文件状态不能检测运行中的进程。这时候我会配合rkhunter来做辅助扫描rkhunter --check --skips-keypress会检查rootkit特征、异常文件属性、内核模块等。注意这东西的误报率不低跑出来的结果别急着删文件手动确认一下再说。更核心的手工排查手段绝对不能丢检查启动项systemctl list-unit-files | grep enabled看有没有不认识的service被设为开机启动。检查计划任务crontab -l以及/etc/cron.d/、/var/spool/cron/下有没有可疑脚本。检查SSH公钥看看/root/.ssh/authorized_keys和所有用户家目录的~/.ssh/authorized_keys有没有多了不认识的公钥攻击者一旦植入公钥就能随时免密登录。检查网络连接ss -tunap列出所有外连重点看有没有进程连接到可疑的陌生IP。配合lsof -i可以查得更加细。有一次我排查“服务器莫名CPU满”的问题top看到一个叫kworkerd的进程在疯狂跑名字看着像内核模块实际上是伪装成系统进程的挖矿程序。它的持久化埋在/etc/cron.d/里每10分钟去某个域名下拉一次脚本执行。这就是典型的“检测滞后”案例如果不是刚好人在现场盯着可能要等很久才会发现。所以一套能自动跑的检测脚本很重要我最终把AIDE检查放在了每周一的定时任务里加上fail2ban的实时封禁才敢说这台服务器“基本可控”。5. 常见问题与排查实录5.1 改完SSH端口连不上八成是防火墙或SELinux改SSH端口是加固的常规操作但也是最容易翻车的一步。很多人改了/etc/ssh/sshd_config里的Port、重启了sshd然后本地连接直接超时。我总结下来翻车原因无非三种。第一种是防火墙没放行新端口这个排查最快先看ss -tlnp确认新端口处于监听状态再查防火墙规则里有没有放行这个端口没有就加上。第二种是SELinux没有同步放行RHEL系系统需要执行semanage port -a -t ssh_port_t -p tcp 22022否则SELinux会直接拦掉sshd对非标准端口的监听。第三种是云服务器的安全组没有同步放行很多人在系统层改完就忽略了云厂商控制台里的安全组规则两头不一致导致连接失败。这里给一个救命建议改SSH配置前先开着另一个登录会话确认改完之后能用新端口登录一次再断开旧会话。如果连不上至少还有一个会话可以兜底回滚。5.2 配置sudoers把自己锁死了怎么办visudo写错语法是一个经典事故。比如漏了行尾的空格、把ALL(ALL)的括号写丢了或者给普通用户配置了不存在的命令路径下一次sudo直接报语法错误连root的sudo也一起失效因为sudo在加载配置文件时发现错误会拒绝执行。如果遇到这个问题第一反应不要慌直接切到物理控制台或者在能拿到root权限的会话里先用root的本机登录如果允许root直接登录然后修复/etc/sudoers。如果没有root登录权限但机器上有一个已知密码的普通用户可以尝试pkexec visudo它会弹出图形/文本认证界面输入该用户密码后以root身份执行visudo。更稳妥的做法是养成习惯visudo退出前先visudo -c做一次语法检查输出/etc/sudoers parsed OK再放心退出。这条命令花不了两秒钟能省去一次救援的事故时间。5.3 fail2ban把自己或者正常用户封了怎么办fail2ban误封通常有两种场景。一种是把自己的办公网出口IP封了原因是这个网段里有人做过暴力尝试或者你自己的IP被重复登录失败触发。另一种是白名单写错了ignoreip里写的IP跟实际出口IP对不上。解封命令要记住# 解封某个IP fail2ban-client set sshd unbanip 你被封的IP如果连自己是不是被封了都不确定先查fail2ban-client status sshd看banned IP列表再查系统日志确认触发原因。确认是误封之后立刻把当前出口IP加入ignoreip然后重启fail2ban。我在多个办公网络场景里都碰到过“公司出口NAT”的问题办公室里几十个人共用一个公网出口只要有一个人的密码被爆破整个办公网的IP都会被封。这种情况下必须在ignoreip里把办公网出口IP无条件加上。5.4 文件加了chattri之后连root都改不了这个问题几乎每个用过chattr的人都会遇到。当时是为了防篡改给/etc/passwd加了i后来系统要加一个用户useradd怎么执行都报“cannot open /etc/passwd”连root都没办法。解决方案是去掉不可变属性再改chattr -i /etc/passwd /etc/shadow # 执行需要的操作 useradd ... # 改完再加回去 chattr i /etc/passwd /etc/shadow这个坑的教训是不要一把锁锁死所有东西。合理的做法是区分哪些文件几乎永远不会变比如/etc/rc.local、/etc/sudoers、哪些文件偶尔还是要调整比如/etc/passwd、/etc/shadow。准备一份带注释的chattr清单锁了什么文件、什么时候加的、改的时候怎么解锁都记下来。不然过了三个月你自己都不记得哪些文件加了锁排查问题时会很痛苦。5.5 防火墙规则重启后消失了规则重启后“消失”先说结论它通常不是消失是你根本没把它持久化。firewalld的--permanent规则本身就会写入配置文件只要reload或者重启firewalld服务都会重新加载不用额外处理。但如果有人直接用iptables命令添加临时规则没有执行iptables-savefirewalld服务一重启这些规则就全部没了。混合使用iptables和firewalld是这类问题的高发原因。解决办法也很直接要么统一从firewalld管理规则推荐要么当你确认要用手动iptables规则时执行iptables-save /etc/sysconfig/iptables chkconfig iptables on并且确认firewalld没有在运行避免两套机制互相覆盖。运维环境里最怕的不是规则复杂而是两套管理工具交替使用且没有记录排查问题时根本说不清规则是谁加进去的。最后再分享一点经验这几套加固方案做下来我最深的体会是安全加固不是“一次性项目”而是一个持续维护的习惯。你可以在一个周末给服务器做完所有配置但防火墙规则会随着业务变化而调整、用户权限会随着人员变动而修改、入侵检测的基线也会随着系统更新而变化。真正有意义的是建立一套“配置之后能维护、维护之后能追溯、追溯之后能响应”的流程。哪怕只是一个简单的每周巡检脚本、一本记录所有加固操作的笔记长期跑下来价值都比任何一次性的完美配置大得多。如果这篇文章能让你少踩一次SSH断连或sudo锁死的坑那就不算白写了。
上一篇/下一篇内容由系统自动关联 返回资讯列表 →