前言:为什么家庭服务器安全很重要

将家庭服务器暴露在互联网上的那一刻,全世界的机器人和黑客就开始扫描你的服务器。这不是夸张。实际上,新服务器一上线,几分钟内就能在日志中看到SSH暴力破解攻击开始了。如果你在上一篇完成了网络和DDNS设置,现在是时候学习如何安全地保护服务器了。

安全看起来很难很复杂,但只要遵守基本原则,就可以阻止大多数攻击。本篇将逐一介绍家庭服务器运营者必须了解的安全设置。

1. UFW防火墙设置

1.1 什么是防火墙?

防火墙是控制进出服务器的网络流量的安全系统。简单来说,就是决定"谁可以通过哪扇门进入"。在Ubuntu中,使用UFW(Uncomplicated Firewall)工具可以比iptables更容易地管理防火墙。

1.2 UFW安装和基本设置

大多数Ubuntu版本已经预装了UFW。检查是否安装,如果没有则安装。

# 检查并安装UFW
sudo apt update
sudo apt install ufw

# 检查UFW状态
sudo ufw status

开始时应该是非活动状态。在激活之前,必须先允许SSH访问。否则,防火墙激活的那一刻你就会被踢出服务器。

# 设置默认策略:阻止所有入站连接,允许出站连接
sudo ufw default deny incoming
sudo ufw default allow outgoing

# 允许SSH(重要!)
sudo ufw allow ssh
# 或按端口号指定
sudo ufw allow 22/tcp

# 允许Web服务器端口
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

# 激活UFW
sudo ufw enable

1.3 按服务允许端口

根据运行的服务,需要打开必要的端口。

# 允许特定端口
sudo ufw allow 8080/tcp    # 备用Web端口
sudo ufw allow 32400/tcp   # Plex媒体服务器

# 允许端口范围
sudo ufw allow 6000:6010/tcp

# 只允许特定IP访问
sudo ufw allow from 192.168.1.0/24 to any port 22

# 阻止特定IP
sudo ufw deny from 123.45.67.89

# 查看规则
sudo ufw status numbered

# 删除特定规则(按编号)
sudo ufw delete 3
注意:如果你正在远程管理服务器,请特别注意不要阻止SSH端口。如果不小心阻止了,就需要物理访问服务器。

2. 使用fail2ban防御暴力破解攻击

2.1 什么是fail2ban?

fail2ban是一个监控日志文件的工具,当检测到异常访问尝试(如重复登录失败)时,会自动阻止该IP。对防止SSH暴力破解攻击非常有效。

2.2 fail2ban安装和设置

# 安装fail2ban
sudo apt install fail2ban

# 启动服务并设置自动启动
sudo systemctl start fail2ban
sudo systemctl enable fail2ban

fail2ban的配置在/etc/fail2ban/目录中。建议不要直接修改默认配置文件,而是创建local文件使用。

# 创建本地配置文件
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.local

2.3 jail.local详细设置

让我们来看看主要设置选项。

[DEFAULT]
# 阻止时间(秒,-1为永久阻止)
bantime = 3600

# 监控登录尝试的时间范围
findtime = 600

# 允许的失败次数
maxretry = 5

# 排除阻止的IP(添加自己的IP)
ignoreip = 127.0.0.1/8 ::1 192.168.1.0/24

# 阻止时邮件通知(可选)
# action = %(action_mwl)s
# destemail = your@email.com
# sender = fail2ban@yourdomain.com

[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 86400

# Nginx相关jail
[nginx-http-auth]
enabled = true
port = http,https
filter = nginx-http-auth
logpath = /var/log/nginx/error.log
maxretry = 5

[nginx-botsearch]
enabled = true
port = http,https
filter = nginx-botsearch
logpath = /var/log/nginx/access.log
maxretry = 2

更改设置后需要重启fail2ban。

# 应用设置
sudo systemctl restart fail2ban

# 查看当前阻止状态
sudo fail2ban-client status
sudo fail2ban-client status sshd

# 手动解除特定IP阻止
sudo fail2ban-client set sshd unbanip 123.45.67.89

3. SSH安全加固

3.1 更改SSH端口

更改默认SSH端口(22)可以避免大部分自动化机器人攻击。虽然不是完美的安全措施,但可以明显感觉到攻击日志减少。

# 编辑SSH配置文件
sudo nano /etc/ssh/sshd_config

# 找到以下行并修改(取消注释并更改端口号)
Port 2222

在更改端口之前,务必先在UFW中允许新端口。

# 允许新SSH端口
sudo ufw allow 2222/tcp

# 重启SSH服务
sudo systemctl restart sshd

# 现在使用新端口连接
ssh -p 2222 username@server_ip

3.2 仅允许SSH密钥认证

SSH密钥认证比密码认证安全得多。强烈建议设置密钥认证并禁用密码登录。

# 在客户端(本机)生成SSH密钥
ssh-keygen -t ed25519 -C "your_email@example.com"

# 将生成的公钥复制到服务器
ssh-copy-id -p 2222 username@server_ip

# 或手动复制
cat ~/.ssh/id_ed25519.pub | ssh -p 2222 username@server_ip "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"

确认密钥认证正常工作后,禁用密码认证。

# 编辑SSH配置文件
sudo nano /etc/ssh/sshd_config

# 找到以下设置并修改
PasswordAuthentication no
PubkeyAuthentication yes
PermitRootLogin no
PermitEmptyPasswords no
ChallengeResponseAuthentication no

# 重启SSH
sudo systemctl restart sshd
重要:在禁用密码认证之前,务必确认SSH密钥可以正常连接。否则可能会完全被锁在服务器外面。

3.3 附加SSH安全设置

# 在/etc/ssh/sshd_config中添加设置
# 只允许特定用户SSH访问
AllowUsers username1 username2

# 连接等待时间限制
LoginGraceTime 30

# 最大认证尝试次数
MaxAuthTries 3

# 限制同时未认证连接数
MaxStartups 10:30:60

# 禁用X11转发(如果不需要)
X11Forwarding no

4. SSL/TLS证书(Let's Encrypt)

4.1 为什么需要HTTPS

HTTP通信未加密,可以在中间窃听数据。HTTPS使用SSL/TLS证书加密通信并保证服务器身份。使用Let's Encrypt可以免费获得受信任的证书。

4.2 Certbot安装和证书颁发

# 安装Certbot
sudo apt install certbot python3-certbot-nginx

# 使用Nginx时(自动配置)
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com

# 仅颁发证书(手动配置)
sudo certbot certonly --standalone -d yourdomain.com

# 确认证书颁发
sudo certbot certificates

4.3 证书自动续期

Let's Encrypt证书每90天需要续期一次。Certbot会设置自动续期的定时器。

# 检查自动续期定时器
sudo systemctl status certbot.timer

# 手动测试续期
sudo certbot renew --dry-run

# 通过cron直接设置自动续期(可选)
sudo crontab -e
# 添加以下行(每天凌晨3点尝试续期)
0 3 * * * /usr/bin/certbot renew --quiet

5. 反向代理与HTTPS

5.1 Nginx反向代理设置

使用反向代理可以在一台服务器上按域名或路径分流多个服务。而且可以在一个地方管理SSL证书,非常方便。

# /etc/nginx/sites-available/reverse-proxy
server {
    listen 80;
    server_name yourdomain.com;

    # 将HTTP重定向到HTTPS
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name yourdomain.com;

    # SSL证书设置
    ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;

    # SSL安全设置
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
    ssl_prefer_server_ciphers off;

    # HSTS头
    add_header Strict-Transport-Security "max-age=63072000" always;

    # 代理到主应用程序
    location / {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_cache_bypass $http_upgrade;
    }

    # 代理到API服务器
    location /api/ {
        proxy_pass http://localhost:8080/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}
# 激活配置
sudo ln -s /etc/nginx/sites-available/reverse-proxy /etc/nginx/sites-enabled/

# 测试配置并应用
sudo nginx -t
sudo systemctl reload nginx

6. 安全更新自动化

6.1 unattended-upgrades设置

错过安全更新可能会暴露于已知漏洞。使用Ubuntu的unattended-upgrades可以自动应用安全更新。

# 安装包
sudo apt install unattended-upgrades apt-listchanges

# 设置自动更新
sudo dpkg-reconfigure -plow unattended-upgrades

6.2 详细设置

# 编辑配置文件
sudo nano /etc/apt/apt.conf.d/50unattended-upgrades

主要设置选项:

// 自动更新的包源
Unattended-Upgrade::Allowed-Origins {
    "${distro_id}:${distro_codename}";
    "${distro_id}:${distro_codename}-security";
    "${distro_id}ESMApps:${distro_codename}-apps-security";
    "${distro_id}ESM:${distro_codename}-infra-security";
};

// 自动删除未使用的内核包
Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";

// 自动重启(必要时)
Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-Time "03:00";

// 邮件通知
Unattended-Upgrade::Mail "your@email.com";
Unattended-Upgrade::MailReport "on-change";

7. 入侵检测基础

7.1 日志监控

定期检查服务器日志可以及早发现异常迹象。

# 查看认证日志(SSH访问尝试)
sudo tail -f /var/log/auth.log

# 查看失败的登录尝试
sudo grep "Failed password" /var/log/auth.log | tail -20

# 查看成功的登录
sudo grep "Accepted" /var/log/auth.log | tail -20

# 查看系统日志
sudo journalctl -xe

# 最近登录记录
last
lastb  # 失败的登录

7.2 使用AIDE进行文件完整性检查

AIDE(Advanced Intrusion Detection Environment)是检测文件系统更改的工具。

# 安装AIDE
sudo apt install aide

# 创建初始数据库
sudo aideinit

# 应用数据库
sudo cp /var/lib/aide/aide.db.new /var/lib/aide/aide.db

# 运行完整性检查
sudo aide --check

# 通过cron设置定期检查
sudo crontab -e
# 每天凌晨4点检查
0 4 * * * /usr/bin/aide --check | mail -s "AIDE Report" your@email.com

7.3 使用rkhunter进行rootkit检查

# 安装rkhunter
sudo apt install rkhunter

# 更新数据库
sudo rkhunter --update

# 更新属性
sudo rkhunter --propupd

# 运行rootkit检查
sudo rkhunter --check

# 设置自动检查(cron)
sudo crontab -e
0 5 * * * /usr/bin/rkhunter --check --skip-keypress 2>&1 | mail -s "rkhunter Report" your@email.com

8. 安全检查清单

整理了家庭服务器安全检查清单。

项目 设置状态 重要程度
启用UFW防火墙 必需
设置SSH密钥认证 必需
禁用SSH密码认证 建议
安装并设置fail2ban 建议
更改SSH端口 可选
禁用root登录 建议
应用SSL/TLS证书 必需(Web服务)
自动安全更新 建议
定期检查日志 建议

结语

安全不是设置一次就结束的,而是需要持续管理的领域。只要按照本篇介绍的基本安全设置做好,就可以保护服务器免受大多数自动化攻击。

下一篇我们将学习服务器运营中不可或缺的备份策略和监控。即使安全做得再好,意外情况也可能发生,所以通过备份和监控为万一的情况做好准备才是明智的。

如果有问题或疑问,请在评论中留言。我们一起解决。