Logo
活死人の行知路

🚀 Ubuntu 服务器初始化与安全规范 (SOP)


📅 | 📝 836 字
#linux #ubuntu
  • 适用环境: Ubuntu 22.04 / 24.04 (公网生产服务器)。
  • 前置条件: 刚重装完系统,当前正以默认账号(rootubuntu)通过默认 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

第二阶段:账户安全与权限回收

重装系统后的第一件事是收回系统的控制权,严禁直接使用 rootubuntu 进行日常业务。

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 22999TCP 80TCP 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 成功登录!"