Ubuntu服务器拿到手之后,第一件事不是装应用,而是做安全基线配置。SSH作为远程管理的核心通道,内核参数作为系统底层的安全防线,这两块如果不加固,等于把大门敞开让人进。具体怎么做?SSH层面要改端口、禁root登录、限制用户、启用密钥认证、配置超时断开;内核层面要关闭IP转发、启用SYN Cookie、限制核心转储、加固网络栈参数。下面我把每一步的操作、原理、注意事项全部讲透。

一、SSH加固:从配置文件入手,逐条锁死攻击面

SSH的主配置文件在/etc/ssh/sshd_config,所有加固操作都围绕这个文件展开。先备份再改,这是铁律。

sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
sudo vim /etc/ssh/sshd_config

1. 更换默认端口

默认22端口是全球扫描机器人的第一目标,改成一个高位非标准端口能过滤掉90%以上的自动化攻击。但注意不要用太常见的端口如8080、8443,选一个20000-60000之间的随机端口。

Port 22847

改完之后,防火墙要同步放行新端口,否则自己也连不上。

sudo ufw allow 22847/tcp
sudo ufw delete allow 22/tcp

2. 禁止root直接登录

root账户是所有攻击者的终极目标,直接禁止root通过SSH登录,强迫使用普通用户登录后再提权。这一步能大幅降低暴力破解的成功率。

PermitRootLogin no

如果确实需要root远程操作,可以用sudo替代,或者通过ssh -t普通用户@主机 "sudo 命令"的方式实现。

3. 限制可登录用户

不是所有系统用户都需要SSH访问权限,明确指定哪些用户可以登录,其他用户一律拒绝。

AllowUsers deploy_user admin_user

如果团队人多,可以按组来限制:

AllowGroups ssh_access

4. 强制使用密钥认证,关闭密码登录

这是SSH加固中最关键的一步。密码可以被穷举,密钥几乎不可能被暴力破解。先在本地生成密钥对,再把公钥部署到服务器。

ssh-keygen -t ed25519 -C "your_email@example.com"
ssh-copy-id -p 22847 deploy_user@your_server_ip

确认密钥登录正常后,关闭密码认证:

PasswordAuthentication no
PubkeyAuthentication yes
ChallengeResponseAuthentication no

注意:在关闭密码登录之前,务必确认密钥已经能正常登录,否则会把自己锁在外面。

5. 配置空闲超时和最大认证尝试次数

防止已建立的连接长期挂着被利用,也防止暴力破解无限尝试。

ClientAliveInterval 300
ClientAliveCountMax 2
MaxAuthTries 3
LoginGraceTime 30

ClientAliveInterval 300表示每300秒服务器向客户端发一次心跳,ClientAliveCountMax 2表示两次没回应就断开。MaxAuthTries 3表示只允许3次认证失败就踢掉连接。

6. 禁用空密码和不安全的算法

PermitEmptyPasswords no
KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com
HostKeyAlgorithms ssh-ed25519

改完配置后重启SSH服务生效:

sudo systemctl restart sshd

7. 配合fail2ban做动态防护

fail2ban能监控SSH登录日志,自动封禁多次失败的IP。安装并配置:

sudo apt install fail2ban -y
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

编辑jail.local,加入SSH防护规则:

[sshd]
enabled = true
port = 22847
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600
findtime = 600

maxretry 3表示3次失败就封禁,bantime 3600表示封禁1小时。重启fail2ban:

sudo systemctl restart fail2ban

二、内核参数调优:从sysctl到安全模块,筑牢底层防线

内核参数控制着网络行为、内存管理、进程限制等底层机制。Ubuntu通过sysctl工具管理这些参数,配置文件在/etc/sysctl.conf和/etc/sysctl.d/目录下。建议新建一个专用文件,方便管理。

sudo vim /etc/sysctl.d/99-security-hardening.conf

1. 网络栈加固:防扫描、防洪水、防欺骗

网络层是攻击的第一战场,以下参数必须配置:

# 关闭IP转发,防止服务器被当作跳板
net.ipv4.ip_forward = 0
net.ipv6.conf.all.forwarding = 0

# 启用SYN Cookie,防御SYN洪水攻击
net.ipv4.tcp_syncookies = 1

# 防止ICMP重定向攻击
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0

# 忽略ICMP广播请求,防止Smurf攻击
net.ipv4.icmp_echo_ignore_broadcasts = 1

# 开启源地址验证,防止IP欺骗
net.ipv4.conf.all.rp_filter = 1

# 减少TIME_WAIT连接的超时时间
net.ipv4.tcp_fin_timeout = 15

# 限制SYN队列长度,防止队列溢出
net.ipv4.tcp_max_syn_backlog = 4096

# 开启TCP timestamps保护(RFC 1323)
net.ipv4.tcp_timestamps = 1

这些参数的逻辑很清晰:ip_forward=0防止你的机器被利用做中间人;syncookies=1让系统在高负载下也能正常响应合法连接;rp_filter=1确保进来的包源地址是真实的。每一条都有明确的防御目标。

2. 内存与进程安全:防溢出、防提权

# 限制核心转储文件大小,防止敏感信息泄露
kernel.core_pattern = |/usr/share/apport/apport %p %s %c %d %P
fs.suid_dumpable = 0

# 限制dmesg访问,防止内核信息泄露
kernel.dmesg_restrict = 1

# 开启ASLR随机化,增加缓冲区溢出难度
kernel.randomize_va_space = 2

# 限制单个进程可打开的文件数
fs.file-max = 65535

# 限制可创建的进程数
kernel.pid_max = 65535

kernel.randomize_va_space=2是全随机化,意味着每次程序运行时内存地址都不同,攻击者很难预测目标地址。fs.suid_dumpable=0意味着即使程序崩溃也不会生成包含敏感数据的core文件。

3. 加载内核安全模块:AppArmor强制访问控制

Ubuntu默认启用AppArmor,它是基于路径的强制访问控制系统,能限制程序只能访问被允许的文件和资源。确认状态:

sudo aa-status

如果显示有程序处于complain模式,可以切换到enforce模式:

sudo aa-enforce /usr/sbin/sshd
sudo aa-enforce /usr/sbin/nginx

对于自定义的服务,建议编写专属的AppArmor配置文件放在/etc/apparmor.d/目录下,限制其文件系统访问权限。

4. 使内核参数立即生效

编辑完sysctl文件后,不需要重启,直接加载:

sudo sysctl --system

用sysctl -a | grep 参数名可以验证每个参数是否已生效。

三、进阶加固:容易被忽略但极其重要的细节

1. 定期更新系统和SSH版本

安全基线不是一次性工作。Ubuntu的安全更新要及时打:

sudo apt update
sudo apt upgrade -y
sudo apt install unattended-upgrades -y

unattended-upgrades可以自动安装安全补丁,建议配置为只自动装安全更新。

sudo dpkg-reconfigure -plow unattended-upgrades

2. 审计与日志监控

加固之后要能看到谁在尝试攻击。安装auditd做系统审计:

sudo apt install auditd -y
sudo systemctl enable auditd
sudo systemctl start auditd

添加SSH登录监控规则:

sudo auditctl -w /var/log/auth.log -p wa -k ssh_login
sudo auditctl -w /etc/ssh/sshd_config -p wa -k ssh_config_change

用ausearch -k ssh_login可以查看所有SSH登录事件,包括成功和失败的。

3. 禁用不需要的服务和端口

每多开一个服务就多一个攻击面。用ss或netstat查看当前监听端口:

sudo ss -tlnp

只保留必要的端口(SSH、HTTP/HTTPS等),其余全部关闭。用ufw做默认拒绝策略:

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw enable

4. 定期轮换SSH密钥

即使使用了密钥认证,也建议每3-6个月更换一次。旧密钥要从authorized_keys中删除,防止离职人员或被盗密钥继续访问。

四、总结与实操建议

Ubuntu安全基线配置的核心逻辑是"最小权限+纵深防御"。SSH层面通过端口变更、密钥认证、登录限制、动态封禁四层防护把远程访问锁死;内核层面通过网络栈加固、内存保护、强制访问控制三层机制把底层防线筑牢。两块配合起来,基本能抵御绝大多数自动化扫描和常见攻击手法。

实操中有几个坑要注意:第一,改SSH配置前一定先开一个备用终端会话,防止配置错误导致自己连不上;第二,防火墙规则要在改SSH端口之前先放行新端口,顺序不能反;第三,sysctl参数不要盲目照搬网上的配置,要根据自己服务器的业务场景调整,比如高并发Web服务器的tcp_max_syn_backlog可以设得更高。安全加固不是越严越好,而是在安全和可用性之间找到平衡点。

最后强调一点:安全基线只是起点,不是终点。持续的补丁更新、日志分析、入侵检测才是长期安全运营的核心。把基线配置脚本化、自动化,纳入部署流程,才能真正做到每次上线都是安全的。