- 适用环境: Ubuntu 22.04 / 24.04 (公网生产服务器)。
- 前置条件: 刚重装完系统,当前正以默认账号(
root或ubuntu)通过默认 22 端口登录。 - 规范约定: 假设你的日常操作用户名(非 root)为
einscat,自定义 SSH 端口为22999。
第一阶段:基础环境与防崩溃机制
1. 系统更新(基础免疫) 打上所有系统补丁,清除无用包。
sudo apt update && sudo apt upgrade -y && sudo apt autoremove -y
2. 时间同步 (NTP) 防止日志分析混乱和基于时间的一次性密码 (TOTP) 失效。
sudo timedatectl set-timezone Asia/Shanghai
sudo timedatectl set-ntp on
timedatectl show # 检查状态
3. 增加 Swap 分区 (防 OOM 崩溃) 为有限的内存提供缓冲,防止高负载时系统直接杀掉数据库或 Web 服务。
# 创建 2G 的 swap 文件
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
# 写入 fstab 实现开机自动挂载
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
第二阶段:账户安全与权限回收
重装系统后的第一件事是收回系统的控制权,严禁直接使用 root 或 ubuntu 进行日常业务。
1. 创建日常管理员账户
# 创建用户 einscat (系统会提示设置密码,设置一个强密码用于 sudo 提权)
sudo adduser einscat
# 赋予管理员权限
sudo usermod -aG sudo einscat
# 切换到新用户进行后续操作
su - einscat
2. 继承 SSH 密钥实现免密登录
sudo mkdir -p /home/einscat/.ssh
sudo cp /home/ubuntu/.ssh/authorized_keys /home/einscat/.ssh/
sudo chown -R einscat:einscat /home/einscat/.ssh
sudo chmod 700 /home/einscat/.ssh
sudo chmod 600 /home/einscat/.ssh/authorized_keys
⚠️ 测试登录: 不要关闭当前窗口!新开一个终端,尝试用
ssh -i [密钥] einscat@[IP]登录。确认成功后再进行后续高危操作。
3. 强制 SSH 安全策略 (关键)
这是黑客入侵最主要的途径。我们将禁用密码登录,仅允许密钥登录,并修改端口。
# 1. 配置 SSH 密钥 (在你的本地电脑上操作)
# 如果你还没有密钥对,请生成:
# 本地生成密钥 (如果是 Windows 使用 PowerShell 或 CMD)
ssh-keygen -t ed25519 -C "your_email@example.com" -f ~/.ssh/your_custom_key
# 2. 将公钥发送到服务器的 admin_user 账户下
ssh-copy-id -i ~/.ssh/your_custom_key.pub admin_user@<服务器IP>
第三阶段:网络防火墙与 SSH 隐蔽 (高危防锁死区)
必须严格按顺序执行:先配云厂商安全组 -> 再开系统防火墙 -> 最后改 SSH 配置。
1. 外部大门:配置云厂商安全组 登录云控制台,在安全组入站规则中,放行 TCP 22999、TCP 80、TCP 443 端口。
2. 内部防盗门:配置 UFW 防火墙
sudo ufw default deny incoming
sudo ufw default allow outgoing
# 核心:必须先放行新 SSH 端口
sudo ufw allow 22999/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status verbose # 确认 22999 状态为 ALLOW IN
3. 破解 Ubuntu 默认的 SSH Socket 限制 必须禁用系统底层的 Socket 机制,否则自定义端口无效且面临高并发暴破导致 CPU 耗尽的风险。
sudo systemctl disable --now ssh.socket
sudo systemctl enable --now ssh.service
4. 锁定 SSH 核心配置
sudo vim /etc/ssh/sshd_config
修改为以下安全状态(去掉前面的 #):
# 修改默认端口 (选一个 1024-65535 之间的非常用端口,例如 22999)
Port 22999
PermitRootLogin no
PasswordAuthentication no
AllowUsers einscat # 仅允许 admin_user 和 ubuntu 用户登录 (可选,更严格)
5. 重启并进行生死测试
sudo systemctl restart ssh
sudo ss -tulpn | grep ssh # 确认已监听 22999 端口
🚨 再次警告: 不要关闭当前终端。在新终端用
ssh -p 22999 einscat@[IP]测试登录。成功后,在防火墙和安全组中删掉旧的 22 端口规则。
第四阶段:自动化防御与审计追溯
1. 防暴破神器 (Fail2Ban) 自动封禁恶意扫描的 IP。
创建一个本地配置文件(不要直接改 jail.conf):
sudo apt install fail2ban -y
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo vim /etc/fail2ban/jail.local
找到 [sshd] 部分,确保启用并指向正确的端口:
[sshd]
enabled = true
port = 22999 # 填写你的实际 SSH 端口
logpath = %(sshd_log)s
backend = %(sshd_backend)s
maxretry = 3 # 尝试 3 次失败就封禁
bantime = 1d # 封禁 1 天 (支持 m/h/d)
- 向下滚动找到
[sshd]部分,确保enabled = true。 - 你可以修改
bantime(封禁时间),例如改为1d(一天)。
启动:sudo systemctl restart fail2ban
2. 开启自动安全更新
sudo apt install unattended-upgrades -y
# 启用自动更新配置向导,在弹出的界面中选择 **Yes**,系统就会自动每天检查并安装安全更新。
sudo dpkg-reconfigure -plow unattended-upgrades # 选 Yes
3. 锁定关键内核预加载文件 (防 Rootkit)
# 锁定 ld.so.preload (防止 Rootkit 劫持)
sudo touch /etc/ld.so.preload
sudo chattr +i /etc/ld.so.preload
# 如果需要修改该文件,需使用 chattr -i 解锁
4. 优化历史命令记录
cat << 'EOF' >> ~/.bashrc
# 记录命令执行的时间
export HISTTIMEFORMAT="%F %T "
# 增加历史记录容量
export HISTSIZE=10000
export HISTFILESIZE=20000
# 防止重复记录和空格开头的命令记录(保护隐私)
export HISTCONTROL=ignoreboth
EOF
source ~/.bashrc
第五阶段:生产环境常见开发配置规范
1. Docker 权限配置 (免 Sudo)
将当前用户加入 docker 组,避免日常操作滥用 root 权限。
sudo usermod -aG docker einscat
newgrp docker # 当前窗口立即生效
docker ps # 测试验证
2. /opt 目录部署项目代码规范
/opt 归属 root,直接 clone 会报错。标准部署流程如下(以部署 my-app 为例):
# 1. 提权创建项目目录
sudo mkdir -p /opt/my-app
# 2. 移交目录所有权给你的账号
sudo chown -R einscat:einscat /opt/my-app
# 3. 免 sudo 直接克隆代码
git clone <你的git地址> /opt/my-app
3. Docker 挂载目录权限报错处理
*针对日志:
Could not open file '/var/log/mysql/error.log' ... Permission denied*
当使用 Docker 运行 MySQL 等服务并挂载本地宿主机目录时,极易出现无权写入的问题。
原因: 宿主机目录归属 root 或 einscat,但容器内的 MySQL 进程通常以 uid 999 运行。
解决规范: 手动修正宿主机被挂载目录的权限。
# 假设你的挂载目录是 /opt/mysql/logs
sudo mkdir -p /opt/mysql/logs
# 将宿主机目录所有者改为容器内 MySQL 默认的 999 用户
sudo chown -R 999:999 /opt/mysql/logs
🎁 附:服务器自动化初始化脚本 (Bash Script)
为了避免每次重装系统都要手动敲上述基础命令,这里提供一份自动化的 Bash 脚本。
使用方法:
使用默认账号登录后,创建一个文件 init.sh,赋予执行权限 chmod +x init.sh,然后执行 sudo ./init.sh。
#!/bin/bash
# ====================================================
# Ubuntu 生产服务器一键安全初始化脚本
# 执行前请确保已经手动配置好新用户的 SSH 公钥免密登录!
# ====================================================
# --- 全局变量配置区 ---
NEW_USER="einscat" # 你的日常操作用户名
SSH_PORT="22999" # 新 SSH 端口
TIMEZONE="Asia/Shanghai" # 时区
SWAP_SIZE="2G" # Swap 大小
echo "🚀 开始执行服务器自动化初始化..."
# 1. 系统更新
echo ">> 更新系统软件包..."
apt update && DEBIAN_FRONTEND=noninteractive apt upgrade -y -q
# 2. 时区配置
echo ">> 配置时间同步..."
timedatectl set-timezone "$TIMEZONE"
timedatectl set-ntp on
# 3. Swap 配置
if [ ! -f /swapfile ]; then
echo ">> 创建 $SWAP_SIZE 的 Swap 分区..."
fallocate -l $SWAP_SIZE /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
echo '/swapfile none swap sw 0 0' >> /etc/fstab
fi
# 4. SSH 核心机制修复与配置
echo ">> 修复 Ubuntu ssh.socket 机制并修改 SSH 端口..."
systemctl disable --now ssh.socket
systemctl enable --now ssh.service
sed -i "s/^#\?Port .*/Port $SSH_PORT/" /etc/ssh/sshd_config
sed -i "s/^#\?PermitRootLogin .*/PermitRootLogin no/" /etc/ssh/sshd_config
sed -i "s/^#\?PasswordAuthentication .*/PasswordAuthentication no/" /etc/ssh/sshd_config
# 5. UFW 防火墙配置
echo ">> 配置 UFW 防火墙..."
ufw --force reset
ufw default deny incoming
ufw default allow outgoing
ufw allow $SSH_PORT/tcp
ufw allow 80/tcp
ufw allow 443/tcp
ufw --force enable
# 6. 安全工具与内核锁定
echo ">> 安装并配置 Fail2ban..."
apt install fail2ban unattended-upgrades -y
cat << EOF > /etc/fail2ban/jail.local
[sshd]
enabled = true
port = $SSH_PORT
logpath = %(sshd_log)s
backend = %(sshd_backend)s
maxretry = 3
bantime = 1d
EOF
systemctl restart fail2ban
systemctl restart ssh
echo ">> 锁定防篡改关键文件..."
touch /etc/ld.so.preload
chattr +i /etc/ld.so.preload
echo "✅ 初始化完成!"
echo "⚠️ 你的 SSH 端口已改为 $SSH_PORT。"
echo "⚠️ 请确保云厂商安全组已经放行了 $SSH_PORT 端口。"
echo "⚠️ 请不要断开当前连接,开启一个新终端验证能否使用 $NEW_USER 和端口 $SSH_PORT 成功登录!"