资讯详情

SSH、limits、systemd、logrotate、crontab:运维必懂配置文件实战解析

📅 2026/10/11 16:13:24 | 华诺云谱 👁 阅读
SSH、limits、systemd、logrotate、crontab:运维必懂配置文件实战解析
这个系列聊到第二篇。上一篇讲的主要是系统初始化阶段那些“开机就得对”的配置比如挂载表、主机名、环境变量之类。今天想换个角度专门挑几个日常运维里出场率最高、也最容易让新手翻车的“重要配置文件”来拆一遍——SSH 的sshd_config、资源限制limits.conf、systemd 服务单元、日志轮转logrotate还有定时任务crontab。这几个文件你可能天天见但真到排查问题的时候能不能快速定位、能不能改完不出事往往就决定了一次故障处理是半小时还是大半夜。写给谁看刚入门一两年、开始独立接触服务器和线上业务的初级运维。内容不追求大而全每个文件只讲“你一定要知道的那几件事”以及对应的踩坑案例。如果你已经能熟练处理这些可以直接跳过这一篇去看系列的后续。1. 为什么我劝初级运维把“配置文件”当突破口先说个比较普遍的现象。很多刚做运维的朋友热衷于背命令、记工具ps、grep、awk、netstat用得很溜但一遇到“某个服务行为不对”或者“系统出了怪问题”第一反应是到处搜资料很少会先想到去翻对应的配置文件。这不是态度问题是潜意识里觉得配置文件“只是些参数”看不出技术含量。但实际运维工作里绝大部分线上问题最后都落在某一个配置项上连不上是sshd_config的监听端口或防火墙策略服务一高并发就崩是文件句柄限制重启后没起来是 systemd 单元文件写错磁盘被写满大半是日志轮转没配好定时任务不跑是 cron 环境变量问题。换句话说配置文件的背后是系统所有行为的“开关”。谁能把这些开关的位置、作用、修改后果搞清楚谁就拥有了独立排查问题的底气。而且配置文件有一个好处它的知识是“可积累”的。你今天搞懂limits.conf以后换一家公司、换一套架构这个经验照样能用底层逻辑不会变。相比之下工具命令更新迭代快今天这个监控软件明天那个编排平台换个环境又要重学。所以我一直觉得初级运维最值得投入时间的就是把这些基础配置文件吃透。它们不起眼但性价比极高。这一篇我按“高频故障场景”来组织每章先用一句话点出它解决的痛点再讲关键配置项最后给一个真实排障链路。你可以把它当成一张“自查清单”来用遇到对应问题直接翻到那一章。2. SSH连接不顺、总被爆破先审一审 /etc/ssh/sshd_configSSH 大概是运维接触最多的远程管理方式但sshd_config这个文件很多人是“能不动就不动”因为怕改完把自己锁在外面。这种谨慎是对的但正因为它涉及安全你才更应该主动去理解里面的关键项而不是等出了问题再来看。2.1 这几个参数决定你的服务器“能否安全地被人连上”/etc/ssh/sshd_config里参数很多初级运维先盯住这几个就够用了它们是安全基线和连接体验的核心# 修改端口默认 22建议改成高位端口 Port 2222 # 禁止 root 直接登录必须用普通用户 su 切换 PermitRootLogin no # 关闭密码登录强制用密钥否则密码爆破挡不住 PasswordAuthentication no PubkeyAuthentication yes # 不解析客户端 DNS否则登录可能慢好几秒 UseDNS no # 限制登录尝试次数 MaxAuthTries 3 # 白名单只允许指定用户通过 SSH 登录 AllowUsers ops deploy每个参数背后都是一类真实事故。Port改成非默认值不能完全防住扫描但能把大多数无差别爆破挡在外面属于成本极低的安全手段。PermitRootLogin no配合sudo是安全审计的基础不然 root 密码一旦泄露攻击者拿到的是完整权限。PasswordAuthentication no这个改动要慎重它意味着你必须先把公钥部署好否则改完自己就进不去了。UseDNS no是个容易被忽略的小点。如果sshd开启了反向 DNS 解析而客户端 IP 的反查超时你就可能出现“输密码之后等十几秒才连上”的体验。把它关掉登录速度立竿见影。AllowUsers是白名单机制适合团队人员固定、账号较少的场景可以精确控制谁能登录。2.2 改这个文件最容易翻车的两个操作第一是改完直接重启 sshd。正确的做法是先保留至少一个已经建立的连接窗口再执行sshd -t做语法检查最后用reload而不是restart。# 语法检查没有任何输出且返回码为 0 才说明语法没问题 sshd -t # 平滑重载配置不断已有连接 systemctl reload sshd # 或者 service sshd reloadreload和restart的区别值得多说一句。restart会切断所有现存 SSH 连接如果你在改完配置的同时又因为防火墙规则变化或端口没放行新连接上不来、旧连接也被断了那就只能去机房或者带外管理界面救是非常狼狈的场景。reload会让 sshd 重新读取配置但不中断现有会话所以它才是改配置场景下的首选。只有改了Port这种监听参数时已建立的连接仍然是老端口不会断新连接才走新端口。第二是改配置前不备份。我也犯过这种懒觉得“就改一行能出什么事”直到有一次手滑写错了一个参数回滚的时候对着原文件凭记忆半天想不起来原来是什么。现在我的习惯是改任何配置先留一份带日期的副本cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak.$(date %F)这个习惯成本几乎为零但在紧急回滚时能救命。尤其是 sshd 这种一旦验证失败就进不去的文件备份就是你的后悔药。2.3 从“连不上”到“被爆破”的排查视角如果 SSH 登录变得很慢、或者你怀疑有人在爆破第一站去看认证日志部分系统在/var/log/secure部分系统在/var/log/auth.log# 查看最近 100 条认证记录 tail -n 100 /var/log/secure # 统计尝试登录失败最多的来源 IP grep Failed password /var/log/secure | awk {print $(NF-3)} | sort | uniq -c | sort -nr | head -20我处理过的一个场景是某台服务器连续几天出现大量Failed password日志刷得飞快。检查发现PasswordAuthentication yes还开着而且 root 可以直连攻击者正对着 root 用户名做字典尝试。处理方式是先确认密钥登录正常再关掉密码认证、禁止 root 直连、配置MaxAuthTries同时在前面加了一层 fail2ban 做动态封禁。改完后再看日志爆破量基本清零。这里想强调的是配置文件的每一行改动都不是孤立的。关密码登录之前必须确认所有同事的公钥都已经部署限制 root 直连之前必须确认大家的账号有 sudo 权限。顺序错了安全加固就会变成一次“自己为难自己”的事故。3. 高并发下老报“Too many open files”问题多半在 /etc/security/limits.conf如果说 sshd_config 是“连接安全”的关卡那limits.conf就是“服务能撑多大压力”的底层限制。很多服务刚上线时好好的流量一上来就崩报错里出现too many open files十有八九是这里没配好。3.1 文件句柄是什么为什么默认 1024 不够用文件句柄官方叫文件描述符fd你可以理解成进程和内核之间的一种“令牌”。进程每打开一个文件、建立一个 TCP 连接、创建 socket都要占一个 fd。Linux 对单个进程能持有的 fd 数量有限制这个限制就是ulimit -n显示的值。问题在于很多系统的默认值是 1024。对日常命令行操作来说够用了但一个稍微有点并发的服务就完全不够。比如一个 Nginx worker 进程每来一个客户端连接就占一个 fd如果它同时处理 2000 个连接1024 的限制直接卡死。对 Java 应用来说更明显Tomcat或微服务进程的 fd 不仅包含网络连接还包括日志文件、内存映射文件等各种资源很容易突破默认限制。所以高并发场景下调整文件句柄限制几乎是必做项。这不是“性能调优”而是“让服务能正常跑起来”的基础配置。3.2 正确修改姿势limits.conf、用户级别和 systemd 的坑limits.conf的核心格式是四列# domain type item value * soft nofile 65535 * hard nofile 65535domain可以是用户名、组名用 开头、*通配符等typesoft是软限制进程可以自行调高但不超过 hardhard是硬上限普通用户无法超过它itemnofile表示文件句柄数量还有nproc进程数、core核心转储大小等value数值一般设65535或更高。soft和hard都建议写上而且最好设成同一个值。只设soft不设hard某些服务在运行中尝试调高 fd 时会被硬限制挡回来只设hard进程当前会话里看到的软限制可能还是旧值。改完limits.conf之后有个特别容易踩的坑重新登录终端后执行ulimit -n确实变成 65535 了但 systemd 管理的服务仍然显示 1024。原因是 systemd 服务在启动时并不继承/etc/security/limits.conf的 PAM 配置它有自己的一套资源限制声明。所以对 systemd 服务要直接改单元文件加一行[Service] LimitNOFILE65535验证方式也要分开。终端会话用ulimit -n看已运行服务用下面这个命令看它的真实限制# 查看某个进程实际的资源限制 cat /proc/PID/limits # 输出里的 Max open files 才是它真正生效的值3.3 一个典型故障排查服务起来了连接一多就崩我之前处理过的一个模拟项目 X是个 Java 微服务平时一切正常一到促销流量就频繁报连接失败。应用日志里周期性地出现java.io.IOException: Too many open files但没有进程崩溃只是新的请求处理不了。排查过程很简单但当时的经验教训很深先看应用日志确认报错关键词是Too many open files用lsof -p PID | wc -l统计进程当前打开的 fd 数确实已经到了几千甚至上万用cat /proc/PID/limits查看进程真实的Max open files发现还是 1024查系统的/etc/security/limits.conf确实已经改过 65535但服务不生效最后定位到 systemd 单元文件缺LimitNOFILE加上并重启后解决。这个案例里最值得说的就是第 4 步和第 5 步的断层。很多人改了limits.conf就觉得高枕无忧了实际上对现代主流 Linux 发行版来说服务只要走 systemd 管理资源限制就必须在 unit 文件里单独指定。记住一句话终端里ulimit -n看到的值和你的线上服务进程真正生效的值可能完全是两个数字。排查时永远以/proc/PID/limits为准。4. 服务“重启后没起来”你的 systemd 单元文件写对了吗现在几乎所有主流发行版都用 systemd 管理系统服务。不管你用没用过日常操作里一定见过systemctl restart xxx。但很多初级运维只是把 systemd 当成一个“启动服务的工具”出了问题不知道去哪看更不知道服务起不来的根因往往就写在一个 unit 文件里。4.1 单元文件的最小可用结构systemd 的单元文件通常放在/etc/systemd/system/下一个最小可用的服务单元长这样[Unit] DescriptionMy Demo Service Afternetwork-online.target Wantsnetwork-online.target [Service] Typesimple Userops Groupops WorkingDirectory/data/app EnvironmentJAVA_HOME/usr/local/java ExecStart/data/app/bin/start.sh Restartalways RestartSec5 LimitNOFILE65535 [Install] WantedBymulti-user.target第一块[Unit]是描述与依赖关系。After表示在网络就绪后再启动Wants表示一个软依赖网络要是没起来就尽量等但不会像Requires那样失败就强制不启动。对新手来说Afternetwork-online.target和Wantsnetwork-online.target是绝大多数服务的标配能省掉“启动时连不上网络”的坑。[Service]是核心。ExecStart是启动命令这里必须是绝对路径。User和Group指定以哪个身份跑这个特别重要用 root 跑服务一旦被攻破就是权限全失用专用用户跑能限制影响面。WorkingDirectory是工作目录很多脚本启动失败是因为找不到相对路径下的文件就是这个没设置。Environment可以用来注入环境变量尤其适合需要自定义JAVA_HOME之类的场景。Restartalways表示进程异常退出后自动拉起是保证“服务挂了能自己回来”的关键。RestartSec是重启前等待的秒数给系统一点缓冲避免疯狂重启。LimitNOFILE就是上一章说的资源限制在 systemd 服务里它必须写在这里。4.2 为什么新服务我建议用 systemd 而不是 rc.local有些老环境习惯往/etc/rc.local里塞启动命令。但对新写的服务我强烈建议用 systemd 单元文件。原因很简单rc.local是在系统启动的最后阶段执行一段脚本它没有依赖管理、没有进程守护、没有日志收集脚本里服务如果中途退出了系统不会帮你拉起来出了问题也没地方看标准输出。systemd 帮你把这些都补齐了。服务自动拉起只是基本操作统一日志管理才是真正的效率提升。journalctl -u myservice能直接看服务的标准输出和错误日志不用再去翻以前的 nohup 文件。权限控制也更好可以给每个服务指定独立用户配合ProtectSystem之类的安全参数还能限制服务的文件访问范围。所以我的建议是只要发行版支持 systemd新服务一律写单元文件只有遇到老旧的init脚本环境才不得不用rc.local兜底。4.3 改完单元文件之后的三板斧改完 unit 文件最忌讳的是直接systemctl restart然后发现改的没生效。systemd 会缓存部分配置改完必须通知它重新加载# 1. 重新加载 systemd 配置 systemctl daemon-reload # 2. 设置开机自启并立即启动 systemctl enable --now myservice # 3. 查看状态和日志 systemctl status myservice journalctl -u myservice -n 50如果服务启动失败systemctl status会显示错误码和最后几行日志journalctl -u myservice -n 50则是完整的启动日志。常见问题无非几种ExecStart路径写错了或者启动脚本没有执行权限chmod x指定的User在系统里不存在WorkingDirectory目录不存在Type写错比如实际是常驻前台进程却写成了Typeforkingsystemd 一直等不到主进程退出就会判定启动超时。遇到这类问题不要慌逐项对着单元文件检查再用journalctl看具体报错基本都能快速定位。我曾经见过有人把ExecStart/data/start.sh写成ExecStart/data/start.sh 结果服务起来后 systemd 还是认为它不存在问题就出在“不需要在命令里手动加后台符号”Typesimple本身就是前台运行的意思。5. 磁盘被日志塞满别只想到删日志先看 /etc/logrotate.conf日志文件是所有服务器都会持续增长的文件类型。很多初级运维遇到磁盘告警第一反应是“删日志”但删了这次下次还会满。真正该做的是检查logrotate配置让日志有计划地轮转、压缩和清理。5.1 为什么不能一直让日志往一个文件里写从原理上说应用不断往同一个日志文件追加内容文件会无限膨胀。带来的问题不只是磁盘空间日志文件太大grep排查时也会越搜越慢老日志没有归档出问题想回溯历史却发现早已被覆盖或者无从下手。logrotate 的思路是按周期每天/每周或按大小把当前日志文件“滚”一下改名、压缩、保留若干份、删除最老的。它本身不产生日志只负责管理日志文件的“生命周期”。系统一般会通过 cron 每日触发一次/usr/sbin/logrotate所以你的配置要写在它认得到的位置。5.2 常用配置项逐个拆解logrotate 的配置分散在两个地方主配置/etc/logrotate.conf和/etc/logrotate.d/目录下的片段。日常新增配置应该放在/etc/logrotate.d/下不要直接改主配置这样便于管理也方便回滚。下面是一个针对 Nginx 日志的典型配置/data/nginx/logs/access.log { daily rotate 7 compress delaycompress missingok notifempty copytruncate dateext }逐项拆解daily每天轮转一次。也可以写weekly、monthly或者用size 100M按大小触发rotate 7最多保留 7 份归档超过的删除控制磁盘占用的核心参数compress归档后用 gzip 压缩节省空间delaycompress当天刚归档的文件不立即压缩方便调试时直接看到下一轮再压缩missingok日志文件不存在时不报错适合日志被分离或偶发性写入的场景notifempty日志为空就不轮转避免产生一堆空归档copytruncate先复制当前日志内容再把原文件截断。这个选项对 Nginx 这类不方便随意停服的应用很友好代价是可能丢失极少量正在写入的日志dateext归档名里带上日期比如access.log-20250612一眼能查到某天的日志。配置写完后先用调试模式确认语法没问题再强制跑一次看看效果# 调试模式只打印会执行的操作不实际改动 logrotate -d /etc/logrotate.d/nginx # 强制轮转 logrotate -f /etc/logrotate.d/nginx5.3 实战日志删了磁盘却没释放有一个坑处理过的朋友一定记得日志文件很大直接rm -f access.log再df -h一看磁盘空间还是满的。原因在于运行中的 Nginx 进程仍然持有那个已被删除文件的文件句柄数据块没有被真正释放空间要等进程释放 fd 才能收回。这种情况下最怕“删完再手动 touch 一个新文件”的操作因为旧句柄没释放日志又会写进那个看不见的已删除文件里磁盘继续增长你还会误以为删错了。处理方法有两个对支持平滑重载的服务执行systemctl reload nginx让进程重新打开新的日志文件并释放旧 fd或者在 logrotate 配置里用copytruncate从机制上避免“进程持有句柄”的问题。排查这种问题可以借助lsof | grep deleted能看到哪些进程握着已删除的文件。这个命令对“空间明明该释放了却还占着”的场景非常有效比盯着df干着急强得多。6. 定时任务不执行先分清 /etc/crontab、/etc/cron.d/ 和 crontab -e定时任务大概是初级运维最早接触、也最容易“莫名其妙不执行”的功能。明明脚本手动跑得好好的放进 crontab 就是没反应。要排查这个问题先得搞清楚系统里几套 cron 写法的差异。6.1 三种定时任务写法的区别cron 任务有几种常见的配置入口很多人混着用一出事就懵写法适用场景是否带用户字段说明crontab -e普通用户级任务不带默认当前用户实际写入/var/spool/cron/用户名/etc/crontab系统级任务带第 6 列是执行用户格式是六段分 时 日 月 周 用户 命令/etc/cron.d/下的文件软件包或运维自定义带第 6 列是执行用户适合放独立任务文件文件名不能含.初学者最容易踩的是字段数量对不上。crontab -e里写五段即可分 时 日 月 周后面直接跟命令。但/etc/crontab和/etc/cron.d/里的条目必须要多写一个用户字段。比如# /etc/cron.d/sync 示例每天 3 点 17 分以 ops 用户执行 17 3 * * * ops /data/scripts/sync.sh /tmp/sync.log 21如果你按这个格式把任务写进了crontab -ecron 会把ops当成命令去执行系统日志里就会报 command not found任务自然不跑。6.2 脚本手动执行 OKcron 就是不执行的经典坑这个坑几乎每个人都遇到过。手动在终端里执行/data/scripts/sync.sh一切正常放到 crontab 里就是静默失败。根因通常是环境变量差异。cron 执行任务时使用的是非登录、非交互的 shellPATH 非常精简一般只包含/usr/bin:/bin这种基础路径平时你手动能用的/usr/local/bin/python、/usr/local/mysql/bin/mysql这些它通通找不到。解决方式有三种命令里写绝对路径比如/usr/local/bin/python /data/scripts/sync.py在脚本开头强制设置 PATH例如export PATH/usr/local/bin:/usr/bin:/bin:$PATH在 crontab 文件开头设置全局环境变量。另外一个更隐蔽的问题是 cron 不会加载你的.bashrc、.profile等个人环境文件所以脚本里依赖的那些自定义变量、别名在 cron 里通通不存在。这也是为什么排查 cron 问题时我建议先把脚本的输出重定向到文件看它到底报什么错# 这样写至少能看到执行报错而不是石沉大海 17 3 * * * ops /data/scripts/sync.sh /tmp/sync.log 21系统层面也有排查入口。大多数发行版会把 cron 的执行记录写在/var/log/cron里任务有没有被调度、实际执行命令是什么都可以在这里看到。比如出现COMMAND FAILED或用户不对、路径不对一眼就能发现。6.3 上线前的小建议定时任务上线我建议先做两个小动作。第一手动跑一遍脚本确认没问题再故意设置一个“两分钟后执行”的时间看 cron 能不能正确拉起第二给可能执行时间较长、又怕重复触发的任务加上锁# 用 flock 防止同一个脚本上一次没跑完下一次又开始 */5 * * * * ops /usr/bin/flock -xn /tmp/sync.lock /data/scripts/sync.sh /tmp/sync.log 21-x是排他锁-n是拿不到锁就直接放弃。这样哪怕是耗时超过周期的任务也不会互相重叠执行。另外调度时间尽量避开整点和每 5 分钟的边界打散到 3 分、17 分这种随机时间可以避免一批任务扎堆执行导致系统瞬时负载升高。7. 最后分享一个让我少熬夜的改配置习惯这些年处理过不少故障回头总结很多“熬夜修复”的根子其实不在技术难度而在改配置时缺少一个小习惯。后来我给自己定了一条规则任何生产环境的配置改动先备份、再验证、后回滚无忧。具体到每一步就是改之前cp一份带日期的副本或者直接用版本管理记录改完后马上用对应的语法检查命令确认比如sshd -t、nginx -t、logrotate -d然后小步变更一次只改一个目标不要同时改三四个参数否则出了问题根本分不清是谁导致的最后一定要验证效果用工具确认新配置真正生效了而不是只看配置文件里写了什么。这个习惯本身没有任何高深的地方但它能让你从“改完配置心里没底”变成“改完配置知道下一步会发生什么”。对一个初级运维来说这比多记一百条命令都管用。配置文件是死的人解决问题的方法是活的把这几类高频文件吃透再配上一套稳妥的改动流程线上环境会温柔很多。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑