1. 项目概述为什么说“账号、登录、口令、端口”是Linux安全的四道门如果你刚接手一台Linux服务器或者准备把自己的VPS打造成一个更坚固的堡垒从哪里开始加固最有效我的经验是抛开那些复杂的安全框架和昂贵的商业软件先把最基础、最容易被忽视的四个点——账号、登录、口令、端口——给扎扎实实地管好。这就像给房子装防盗门你可能会装智能锁、监控但如果门本身是纸糊的或者钥匙就藏在门口的地垫下其他一切都是白搭。在真实的攻防对抗或安全审计中攻击者第一步往往就是“敲门”。他们会尝试默认账号、弱口令、未关闭的远程端口或者利用有缺陷的登录机制。我见过太多因为一个弱口令的测试账号或者一个默认开启的22端口被暴力破解导致整个服务器沦陷的案例。因此这个“核心实战”项目就是要带你把这四道门逐一加固把那些低级的、却足以致命的风险点给堵上。无论你是运维工程师、开发者还是个人站长这套组合拳都是你Linux安全入门的必修课也是构建纵深防御体系的第一块基石。2. 账号安全从清理“僵尸”到精细化权限管控账号是系统访问的起点。一个混乱的账号体系意味着攻击者有更多可乘之机。我们的目标不仅是删除无用账号更要建立清晰的账号管理和权限划分原则。2.1 账号清单审计与无用账号清理第一步你得知道自己系统里到底有多少“住户”。直接查看/etc/passwd文件是最基本的方法但信息比较杂乱。我习惯用几个组合命令来快速审计# 查看所有系统用户UID 1000和普通用户 awk -F: $3 1000 {print $1 (系统用户)} $3 1000 {print $1 (普通用户)} /etc/passwd # 查看最近登录过的用户 lastlog # 查看当前登录的用户及其来源 who -a重点排查以下几类“高危”账号默认测试或示例账号如test、guest、demo等。这些账号口令往往简单或为空。长期未登录的账号使用lastlog命令找出那些“上次登录时间”显示为**从未登录过**或时间非常久远的账号。这些可能是被遗忘的“僵尸账号”。UID为0的非root账号任何UID为0的用户都拥有root权限。除了root本身不应该有其他UID为0的账号。检查命令awk -F: ($3 0) {print $1} /etc/passwd。对于确认无用的账号坚决删除。但删除前务必确认该账号没有关联任何正在运行的服务或定时任务。一个鲁莽的userdel -r username可能会导致服务崩溃。我的操作流程是ps -u username查看该用户是否有进程在运行。crontab -u username -l查看该用户的定时任务。确认无误后再使用userdel -r username删除账号及其家目录。实操心得对于一时无法确定是否可删的账号比如某个老旧应用的服务账号一个更稳妥的做法是先禁用后观察。使用usermod -L username或passwd -l username锁定账号使其无法登录。观察一段时间如一两周确认系统所有功能正常后再行删除。2.2 超级用户权限的受控分配永远不要直接分享root密码。这是铁律。正确的做法是使用sudo机制进行细粒度的权限委派。首先精简wheel组或sudo组取决于发行版的成员。只有确需管理员权限的用户才应加入该组。检查命令grep ^wheel /etc/group或grep ^sudo /etc/group。其次也是更关键的一步是为特定用户或组配置精细化的sudo规则而不是简单地赋予所有sudo权限。直接编辑/etc/sudoers文件风险较高推荐使用visudo命令它会在保存前检查语法避免配置错误导致所有sudo功能失效。一个精细化配置的例子# 用户 alice 只能以root身份重启nginx服务且无需输入密码 alice ALL(root) NOPASSWD: /usr/bin/systemctl restart nginx # 组 developers 可以运行所有软件包管理命令 %developers ALL(ALL) /usr/bin/apt, /usr/bin/apt-get, /usr/bin/dpkg # 用户 bob 可以管理用户但不能修改root密码 bob ALL(ALL) /usr/sbin/useradd, /usr/sbin/userdel, /usr/sbin/usermod, /usr/bin/passwd, !/usr/bin/passwd root最后一行配置中的!表示“禁止”这是一个非常实用的技巧可以实现“允许大部分禁止小部分”的权限控制。注意事项NOPASSWD选项要慎用。虽然方便了自动化脚本但也降低了安全门槛。仅在对安全性要求不高、且需要频繁执行的内网自动化任务中考虑使用。2.3 服务账号的“降权”运行原则很多应用程序如Web服务器、数据库需要以非root身份运行。我们应遵循“最小权限原则”为这些服务创建专用的、权限受限的系统账号。例如为Nginx创建服务账号sudo useradd -r -s /sbin/nologin nginx参数解释-r创建系统账号UID较小通常不创建家目录。-s /sbin/nologin设置其登录shell为/sbin/nologin禁止该账号通过SSH等方式交互式登录这从根本上杜绝了通过该账号获得shell的风险。然后在Nginx的配置文件如nginx.conf中将user指令设置为nginx。这样即使Nginx服务存在漏洞被攻破攻击者获得的也只是一个权限极低的nginx账号身份难以进行横向移动或提权。3. 登录安全筑起身份验证的坚固防线控制了谁能进账号接下来就要管好“怎么进”登录。SSH是Linux远程管理的命脉也是攻击者最常攻击的入口。3.1 SSH服务配置深度优化默认的SSH配置过于“友好”我们需要让它变得“挑剔”且“坚固”。配置文件位于/etc/ssh/sshd_config修改后需重启服务sudo systemctl restart sshd。关键配置项解析与加固修改默认端口PortPort 2222 # 将22改为一个非知名端口如2222、3522等为什么这是最直接、最有效的“噪音过滤”手段。互联网上绝大多数针对22端口的自动化扫描脚本会因此失效。这并不能防止定向攻击但能减少99%的随机扫描和暴力破解尝试。注意修改后连接命令需指定端口ssh -p 2222 userhost。务必在修改前确保新端口在防火墙中是放行的并且保留一个当前活跃的SSH会话作为“逃生通道”以防配置错误导致无法连接。禁止root用户直接登录PermitRootLoginPermitRootLogin no为什么即使root口令很强直接暴露最高权限账户也是极危险的。强制攻击者先攻破一个普通用户再尝试提权增加了攻击难度和我们的预警时间。禁用密码认证启用密钥对认证PasswordAuthentication PubkeyAuthenticationPasswordAuthentication no PubkeyAuthentication yes为什么这是防御暴力破解的终极方案。密钥认证基于非对称加密私钥本地保存不通过网络传输理论上无法被暴力破解。彻底关闭密码认证后SSH暴力破解工具将完全失效。如何操作本地生成密钥对ssh-keygen -t ed25519 -C your_emailexample.com推荐ed25519算法更快更安全。将公钥~/.ssh/id_ed25519.pub内容上传到服务器的对应用户家目录下的~/.ssh/authorized_keys文件中。务必确保~/.ssh目录权限为700authorized_keys文件权限为600否则SSH会出于安全考虑拒绝使用密钥。使用更强的基础加密算法KexAlgorithms, Ciphers, MACs 禁用已知不安全的旧算法强制使用现代强算法。这是一个进阶配置能抵御针对弱加密算法的攻击。KexAlgorithms curve25519-sha256libssh.org,diffie-hellman-group-exchange-sha256 Ciphers chacha20-poly1305openssh.com,aes256-gcmopenssh.com,aes128-gcmopenssh.com,aes256-ctr,aes192-ctr,aes128-ctr MACs hmac-sha2-512-etmopenssh.com,hmac-sha2-256-etmopenssh.com,umac-128-etmopenssh.com3.2 双因子认证2FA增强对于安全要求极高的场景如生产环境跳板机仅靠密钥认证可能还不够。可以引入基于时间的一次性密码TOTP作为第二因素。即使私钥泄露没有动态口令也无法登录。常用工具是google-authenticator。安装后运行google-authenticator命令按照提示用手机App如Google Authenticator、Microsoft Authenticator扫描二维码然后在SSH配置中启用挑战应答认证ChallengeResponseAuthentication yes AuthenticationMethods publickey,keyboard-interactive:pam这样登录时就需要先通过密钥认证再输入手机App上显示的6位动态码。踩坑记录配置2FA后一定要为自己保留至少两个有效的验证方式如两台手机都绑定并保存好紧急救援码。我曾因手机丢失又没备份差点把自己锁在服务器外面。3.3 登录监控与入侵检测加固之后还需要有“眼睛”。/var/log/auth.logDebian/Ubuntu或/var/log/secureRHEL/CentOS记录了所有认证日志。实时监控失败登录sudo tail -f /var/log/auth.log | grep -i failed password统计攻击源IPsudo grep Failed password /var/log/auth.log | awk {print $11} | sort | uniq -c | sort -nr | head -20对于频繁攻击的IP可以手动加入防火墙黑名单或者使用fail2ban这类工具自动封禁。fail2ban会监控日志当某个IP在短时间内达到预设的失败次数阈值时自动调用防火墙规则如iptables将其封禁一段时间。4. 口令安全告别“弱口令”的全面策略口令是最后一道本地防线。即使SSH用了密钥本地登录、数据库、Web应用后台等依然依赖口令。4.1 系统级口令强度策略实施通过PAM可插拔认证模块强制所有用户使用强口令。编辑/etc/security/pwquality.conf或/etc/pam.d/common-password文件。一个严格的策略配置示例minlen 12 minclass 3 dcredit -1 ucredit -1 ocredit -1 lcredit -1 maxrepeat 2 reject_username yes enforce_for_root yesminlen12最小长度12位。minclass3密码中至少包含3种字符类别小写、大写、数字、符号。dcredit-1要求至少1位数字。ucredit、ocredit、lcredit同理分别对应大写、符号、小写。maxrepeat2同一字符最多连续出现2次。reject_usernameyes密码中不能包含用户名。enforce_for_rootyes此策略对root用户同样生效。设置后用户使用passwd修改密码时就必须符合此策略。4.2 定期口令更换与过期策略对于有合规要求的场景需要强制用户定期更换密码。通过/etc/login.defs和chage命令管理。在/etc/login.defs中设置默认策略PASS_MAX_DAYS 90 PASS_MIN_DAYS 7 PASS_WARN_AGE 14PASS_MAX_DAYS 90密码最长使用90天。PASS_MIN_DAYS 7密码修改后7天内不能再次修改。PASS_WARN_AGE 14密码过期前14天开始警告。查看特定用户密码策略chage -l username。 手动设置用户策略sudo chage -M 90 -m 7 -W 14 username。4.3 口令存储与哈希算法升级系统用户口令并非明文存储而是经过哈希处理后的字符串存放在/etc/shadow文件中。哈希算法的强度至关重要。检查当前系统默认的密码哈希算法sudo authselect current | grep password-hashing现代Linux发行版默认应使用sha512。如果你的系统还在使用陈旧的md5或des必须升级。升级所有现有用户的密码哈希到sha512是一个敏感操作。可以鼓励用户在下次登录时自行修改密码系统会自动用新算法存储。对于服务账号可以用openssl passwd -6-6代表sha512生成哈希值然后手动更新/etc/shadow文件但需格外小心。重要警告直接编辑/etc/shadow文件风险极高极易导致用户无法登录。非必要不手动操作。优先通过passwd命令或鼓励用户登录修改来触发哈希升级。5. 端口防护从暴露到隐匿的网络边界控制端口是网络服务的门户。开放不必要的端口就等于在城墙多开了一道无人看守的侧门。5.1 端口发现与服务识别在加固之前先搞清楚自己“家”里到底开了哪些“门”。不要只相信你自己的记忆或配置要从外部和内部两个视角进行扫描。外部视角模拟攻击者使用nmap从另一台机器扫描你的服务器公网IP。nmap -sS -p- -T4 你的服务器IP。-sS是SYN半开放扫描-p-扫描所有65535个端口-T4是速度级别。这个结果会告诉你在互联网上到底能访问到哪些服务。内部视角自查在服务器本机上使用ss推荐比netstat更高效或netstat命令。sudo ss -tulnp-tTCP端口。-uUDP端口。-l仅显示监听状态的端口。-n以数字形式显示地址和端口。-p显示占用端口的进程名和PID。仔细核对每一个监听端口问自己三个问题1. 这个服务是我需要的吗2. 它需要被公网访问吗3. 它是最新、安全的版本吗5.2 防火墙策略的精细化配置防火墙是你的网络守门人。我强烈推荐使用iptables的后继者nftables或者更易用的前端工具ufwUncomplicated Firewall。这里以ufw为例因为它语法简单适合快速上手。基础策略默认拒绝所有入站允许所有出站。sudo ufw default deny incoming sudo ufw default allow outgoing按需放行端口放行SSH假设你已改为2222端口sudo ufw allow 2222/tcp comment SSH Access放行HTTP/HTTPSsudo ufw allow 80,443/tcp comment Web Services放行特定IP访问特定端口如只允许办公室IP访问数据库sudo ufw allow from 192.168.1.100 to any port 3306 proto tcp comment MySQL for Admin PC启用并检查规则sudo ufw enable sudo ufw status numbered verbose # 查看带编号和注释的详细规则一个关键技巧速率限制。对于必须开放的服务如SSH可以启用速率限制来减缓暴力破解。sudo ufw limit 2222/tcp comment SSH rate limit这条规则会自动限制同一IP在短时间内新建连接的频率。5.3 服务绑定与访问控制列表ACL有时你希望一个服务如数据库、Redis只被本机或内部网络的其他服务器访问而不是整个互联网。仅靠防火墙可能不够精细需要在服务本身配置绑定地址。MySQL/MariaDB在配置文件/etc/mysql/mysql.conf.d/mysqld.cnf或/etc/my.cnf中找到bind-address项将其设置为127.0.0.1仅本地或内部网络IP如192.168.1.10而不是0.0.0.0。Redis默认绑定127.0.0.1是安全的但如果需要网络访问务必在redis.conf中设置bind 192.168.1.10指定IP并必须配置requirepass设置一个强密码。更进一步可以在服务层面配置ACL。例如Nginx可以配置allow和deny指令只允许特定IP段访问管理后台location。5.4 端口隐匿与敲门Port Knocking技术对于极度敏感的服务可以将其“隐藏”起来。端口敲门是一种有趣的技术服务端口默认关闭只有按照特定顺序“敲击”连接一系列预设的封闭端口后防火墙规则才会临时打开目标端口。例如使用knockd工具。配置一个敲门序列1000,2000,3000TCP。客户端需要依次快速连接这三个端口后服务器的防火墙才会临时开放SSH端口如2222给该客户端IP持续30秒。这极大地增加了攻击者发现和攻击目标端口的难度。但请注意这不是银弹它增加了管理复杂性且不适合高频率访问的场景。它更像是一个为特定管理通道增加的“秘密机关”。6. 实战整合构建一个最小化暴露的服务器配置示例让我们把以上所有点串联起来为一个全新的Ubuntu 22.04服务器制定一份初始安全加固清单。假设这是一台用于部署Web应用Nginx Python的服务器。第1步初始登录与账号设置使用云平台控制台或本地终端用提供的初始密钥或密码登录。立即修改root密码如果允许sudo passwd root设置一个超强密码并妥善保存即使后续禁用root登录也应设置。创建个人管理账号并加入sudo组sudo adduser yourusername sudo usermod -aG sudo yourusername切勿退出当前root或初始会话。新开一个终端用新创建的yourusername账号和密钥/密码尝试登录并执行sudo -i确认sudo权限正常。第2步SSH深度加固在新账号的会话中编辑SSH配置sudo vim /etc/ssh/sshd_config。应用以下关键修改Port 3522 PermitRootLogin no PasswordAuthentication no PubkeyAuthentication yes AllowUsers yourusername # 只允许特定用户登录多个用户用空格隔开将本地公钥~/.ssh/id_ed25519.pub内容追加到服务器上yourusername用户的家目录下~/.ssh/authorized_keys。设置正确的权限sudo chmod 700 ~/.ssh sudo chmod 600 ~/.ssh/authorized_keys在重启SSH前至关重要的一步在另一个终端窗口保持一个当前活跃的SSH连接不关闭作为“救援会话”。然后在新会话中测试新端口连接ssh -p 3522 -i ~/.ssh/your_private_key yourusername服务器IP。确认能成功登录后再回到“救援会话”重启SSH服务sudo systemctl restart sshd。用新端口和新账号成功登录后方可关闭旧的“救援会话”。第3步配置防火墙UFW设置默认策略并放行必要端口sudo ufw default deny incoming sudo ufw default allow outgoing sudo ufw allow 3522/tcp comment SSH on non-standard port sudo ufw allow 80,443/tcp comment HTTP/HTTPS # 如果数据库只需内网访问这里不放行3306等端口启用UFWsudo ufw enable。系统可能会提示影响当前的SSH连接因为默认策略是deny incoming。由于我们已经明确放行了3522端口所以输入y确认即可。第4步服务配置与口令策略为Nginx和你的Python应用如Gunicorn创建专属系统账号。sudo useradd -r -s /sbin/nologin nginx sudo useradd -r -s /sbin/nologin myapp在Nginx和Gunicorn配置文件中指定以对应用户运行。配置全局密码策略编辑/etc/security/pwquality.conf设置如前面所述的强密码规则。使用chage命令为你的yourusername账号设置密码过期策略。第5步部署监控与日志安装并配置fail2bansudo apt install fail2ban sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local编辑/etc/fail2ban/jail.local针对SSH端口进行监控注意端口号[sshd] enabled true port 3522 filter sshd logpath /var/log/auth.log maxretry 5 bantime 3600启动并设置开机自启sudo systemctl enable --now fail2ban。定期查看日志sudo tail -f /var/log/fail2ban.log和sudo tail -f /var/log/auth.log。完成以上步骤你的服务器就从“裸奔”状态变成了一个拥有坚固四道防线的堡垒。这只是一个起点安全是一个持续的过程需要结合漏洞扫描、定期更新、备份恢复等共同构成完整的防御体系。但毫无疑问把这四件事做好你已经挡住了绝大多数自动化攻击和初级攻击者为你的数据和业务赢得了至关重要的安全基础。