文章总结: 文章从实战角度系统阐述了Linux服务器安全加固的完整流程,涵盖SSH配置、防火墙设置、Fail2ban部署、用户权限管理、系统与数据库加固、Web服务安全及监控审计等关键环节。核心结论是安全需主动配置而非被动应对,通过禁用密码登录、修改默认端口、限制访问、启用自动封禁等可操作措施,能有效抵御大部分自动化攻击,并强调定期检查与更新的重要性。 综合评分: 85 文章分类: 安全建设,网络安全,渗透测试,实战经验,应急响应
linux安全加固:服务器被打之前和之后,我分别做了什么
原创
释然 释然
释然IT杂谈
2026年2月26日 08:18 上海
#
服务器挂在公网上,说白了就是把家门开着睡觉。你不知道什么时候有人进来,但你可以确定的是——一定有人在试。我见过太多人觉得”我这服务器没啥重要数据,没人盯着我”,然后某天发现机器在挖矿,或者带宽被打满了,账单直接炸。
所以这事不是可选项。
SSH,从这里开始
SSH 是被攻击最多的入口,没有之一。默认配置放在那里,基本等于在门口贴了张纸写着”欢迎进来”。
先把 root 登录关掉:
# /etc/ssh/sshd_config
PermitRootLogin no
然后是密码登录——这个必须禁掉。密码可以被暴力破解,密钥不行,这是本质区别。不过有个顺序问题,一定要先把密钥配好,再禁密码,别把自己锁外面了,这个坑我见人踩过不止一次。
# 本地生成密钥,ed25519 比老的 rsa 安全
ssh-keygen -t ed25519 -C "[email protected]"
# 传公钥上去
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server
传完再改配置:
# /etc/ssh/sshd_config
PasswordAuthentication no
PubkeyAuthentication yes
端口也改一下,22 这个端口每天被扫的次数,你看了日志真的会头皮发麻。改成非标准端口,能过滤掉绝大多数无脑扫描,不是说改了就绝对安全,但能省很多事。
Port 22222
还有一个容易被忽略的——限制哪些用户能登录:
AllowUsers deploy admin
把这些拼在一起,完整配置大概长这样:
Port 22222
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
AllowUsers deploy admin
MaxAuthTries 3
ClientAliveInterval 300
ClientAliveCountMax 2
X11Forwarding no
改完别急着重启,先测一下:
sshd -t
systemctl restart sshd
防火墙,默认拒绝一切
这块的核心逻辑就一句话:不需要的端口,一个都不开。很多人装完系统就直接用,防火墙规则乱七八糟,或者干脆没配。
Ubuntu 用 UFW,简单直接:
apt install ufw
ufw default deny incoming
ufw default allow outgoing
# 注意,先放行 SSH 再启用,顺序别搞反
ufw allow 22222/tcp
ufw allow 80/tcp
ufw allow 443/tcp
# 数据库端口只给特定 IP
ufw allow from 192.168.1.100 to any port 3306
ufw enable
ufw status verbose
CentOS 系用 firewalld:
systemctl start firewalld
systemctl enable firewalld
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
firewall-cmd --permanent --add-port=22222/tcp
# 精细控制,只允许某个 IP 访问 MySQL
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.100" port port="3306" protocol="tcp" accept'
firewall-cmd --reload
iptables 的话,老系统或者需要精细控制才用,规则写起来麻烦但灵活:
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp --dport 22222 -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
iptables-save > /etc/iptables.rules
echo "iptables-restore < /etc/iptables.rules" >> /etc/rc.local
Fail2ban,让暴力破解自动凉凉
光有防火墙还不够,Fail2ban 是用来对付那些一直在试密码的人的。原理很简单:盯着日志,某个 IP 短时间失败太多次,直接封。
apt install fail2ban
cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
基本配置,SSH 这块我建议封禁时间设长一点,24 小时不过分:
# /etc/fail2ban/jail.local
[DEFAULT]
bantime = 3600
findtime = 600
maxretry = 5
ignoreip = 127.0.0.1/8 192.168.1.0/24
[sshd]
enabled = true
port = 22222
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 86400
跑 Web 服务的话,Nginx 也加上:
[nginx-http-auth]
enabled = true
filter = nginx-http-auth
port = http,https
logpath = /var/log/nginx/error.log
[nginx-botsearch]
enabled = true
filter = nginx-botsearch
port = http,https
logpath = /var/log/nginx/access.log
maxretry = 2
还可以自定义过滤规则,专门针对那些乱扫 404 的爬虫:
# /etc/fail2ban/filter.d/nginx-cc.conf
[Definition]
failregex = ^<HOST> .* "(GET|POST).* HTTP.*" (404|444|403|400) .*$
ignoreregex =
[nginx-cc]
enabled = true
filter = nginx-cc
port = http,https
logpath = /var/log/nginx/access.log
maxretry = 100
findtime = 60
bantime = 3600
常用的管理命令记几个就行:
fail2ban-client status sshd # 看封了哪些 IP
fail2ban-client set sshd unbanip 1.2.3.4 # 解封,误封了自己用这个
fail2ban-client set sshd banip 1.2.3.4 # 手动封
tail -f /var/log/fail2ban.log
用户权限,别偷懒
最小权限原则,道理大家都懂,但真正做到的不多。
创建专用部署用户,别什么都用 root 跑:
useradd -m -s /bin/bash deploy
passwd deploy
usermod -aG sudo deploy
sudo 权限这块,我见过很多人直接给 NOPASSWD:ALL,图省事,但这跟直接用 root 没太大区别。稍微细化一下,只给需要的命令:
# /etc/sudoers.d/deploy
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart nginx
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart php8.2-fpm
deploy ALL=(ALL) NOPASSWD: /usr/bin/docker-compose *
文件权限别乱给,敏感文件 600 就够了:
chown -R www-data:www-data /var/www/html
chmod -R 755 /var/www/html
chmod 600 /var/www/html/.env
chmod 600 ~/.ssh/authorized_keys
系统层面的加固
装完系统默认跑着一堆没用的服务,关掉:
systemctl list-units --type=service --state=running # 先看看有什么
systemctl disable cups # 打印服务,服务器用不上
systemctl disable avahi-daemon
systemctl disable bluetooth
内核参数这块,改一下 sysctl.conf,能防一些常见的网络攻击:
# /etc/sysctl.conf
net.ipv4.ip_forward = 0
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.tcp_syncookies = 1 # 防 SYN 洪水,这个一定要开
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.icmp_echo_ignore_broadcasts = 1
net.ipv4.conf.all.log_martians = 1
sysctl -p
自动安全更新,Ubuntu 上装一下,至少安全补丁能自动打:
apt install unattended-upgrades
dpkg-reconfigure unattended-upgrades
# /etc/apt/apt.conf.d/50unattended-upgrades
Unattended-Upgrade::Allowed-Origins {
"${distro_id}:${distro_codename}-security";
};
Unattended-Upgrade::Automatic-Reboot "false";
Unattended-Upgrade::Mail "[email protected]";
数据库,这块别马虎
MySQL 装完跑一下这个,按提示操作,能解决大部分默认配置的问题:
mysql_secure_installation
业务账号单独建,不要用 root 跑应用,权限给够用的就行:
CREATE USER'app'@'localhost'IDENTIFIEDBY'strong_password';
GRANTSELECT, INSERT, UPDATE, DELETEON myapp.* TO'app'@'localhost';
FLUSHPRIVILEGES;
-- root 禁止远程登录
DELETEFROM mysql.user WHEREUser='root'AND Host NOTIN ('localhost', '127.0.0.1', '::1');
FLUSHPRIVILEGES;
Redis 这个,坦白说很多人装完就忘了,默认没密码还绑在 0.0.0.0,暴露在公网上是真的危险:
# /etc/redis/redis.conf
bind 127.0.0.1
requirepass your_strong_password
rename-command FLUSHDB ""
rename-command FLUSHALL ""
rename-command CONFIG ""
rename-command KEYS ""
Nginx 和 PHP 的安全配置
Nginx 加几个安全头,顺手的事:
server_tokens off; # 别让人知道你的版本号
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Content-Security-Policy "default-src 'self'" always;
# .git、.env 这些文件绝对不能暴露
location ~ /\.(git|env|htaccess) {
deny all;
}
location ~ \.(sql|bak|log)$ {
deny all;
}
PHP 这边,禁掉危险函数,关掉错误显示:
disable_functions = exec,passthru,shell_exec,system,proc_open,popen
expose_php = Off
upload_max_filesize = 10M
max_file_uploads = 5
session.cookie_httponly = 1
session.cookie_secure = 1
session.use_strict_mode = 1
display_errors = Off
log_errors = On
error_log = /var/log/php/error.log
审计和监控,别等出事了再看
grep "Failed password" /var/log/auth.log | tail -20
grep "sudo" /var/log/auth.log | tail -20
文件完整性检查,AIDE 装上,定期跑一下,看有没有文件被动过:
apt install aide
aideinit
aide --check
一键安全检查脚本,加到 crontab 里每天跑一次,有问题早发现:
#!/bin/bash
echo"=== 安全检查报告 ==="
echo"1. SSH 配置"
grep -E "^(PermitRootLogin|PasswordAuthentication|Port)" /etc/ssh/sshd_config
echo"2. 开放端口"
ss -tulpn | grep LISTEN
echo"3. 最近登录失败"
grep "Failed password" /var/log/auth.log 2>/dev/null | tail -5
echo"4. 当前登录用户"
who
echo"5. 磁盘使用"
df -h | grep -E "^/dev"
echo"6. 内存使用"
free -h
echo"7. 待更新包"
apt list --upgradable 2>/dev/null | head -10
echo"8. Fail2ban 状态"
fail2ban-client status 2>/dev/null || echo"Fail2ban 未安装"
最后说一句,安全这事不是配完就完了。定期检查,关注漏洞公告,补丁出来及时打。很多安全事故说到底不是技术问题,是懒。
改个 SSH 端口、禁掉密码登录、装个 Fail2ban,这几步做完,能挡掉绝大多数自动化攻击。剩下的,就是保持习惯。
- EOF –
另外我给大家整理了一些技术资料有需要直接下载即可
链接:https://pan.quark.cn/s/7063628fb0be
需要什么资料也可在评论区留言
或者添加小编咨询
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:释然IT杂谈 释然 释然《linux安全加固:服务器被打之前和之后,我分别做了什么》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。









评论