一、先说几个真实踩过的坑
去年给一家电商公司搭集群,服务器选的是Ubuntu 22.04 LTS,结果上线第三天,运维突然报警:CPU占用率飙到98%,网站打不开了。排查半天发现是apt自动更新把内核升了,导致旧版Nginx模块编译失败。更离谱的是,他们之前还有台服务器,开机后发现root密码是空的——因为安装时选了”自动设置空密码”。
这些坑不是吓唬你,是企业上云最常见的几个雷区。今天我把从镜像选择到安全加固的全流程,结合实战经验,给你一个完整指南。
二、镜像选择:别选错的第一步
2.1 官方镜像 vs 云服务商定制镜像
很多人直接选云厂商给的”优化版”镜像,觉得省事。但我建议先用官方原始镜像,理由很简单:
- 官方镜像是纯Ubuntu,组件干净,出问题好定位
- 云厂商定制镜像里装了一堆他们的监控Agent、备份工具,有些会静默后台运行,占用资源
- 官方镜像升级路径清晰,你清楚知道自己在装什么
验证方法:
# 登录后先看看系统里到底有什么
dpkg -l | grep -E "(aliyun|aws|tencent|huawei)"
# 如果有输出,说明是定制镜像,有额外组件
2.2 确认版本号
22.04有多个变体,选错会直接影响后续部署:
| 版本 | 特点 | 适用场景 |
|---|---|---|
| Ubuntu Server 22.04 LTS | 最小化安装,只有基础组件 | 生产服务器首选 |
| Ubuntu Desktop 22.04 | 带GUI,占用资源多 | 不推荐用于服务器 |
| Ubuntu Minimal | 比Server还精简 | 容器宿主机 |
| Ubuntu Cloud Image | 预装cloud-init | 云平台自动部署 |
# 查看当前版本
cat /etc/os-release
# 期望看到:VERSION="22.04.x LTS"
三、首次登录:别忽视的安全第一步
3.1 SSH密钥登录(强烈建议)
密码登录有被暴力破解的风险,企业服务器必须用密钥:
# 本地机器生成密钥(如果还没有)
ssh-keygen -t ed25519 -C "your@email.com"
# 把公钥复制到服务器
ssh-copy-id root@your-server-ip
# 或者手动粘贴
cat ~/.ssh/id_ed25519.pub | ssh root@your-server-ip "mkdir -p ~/.ssh && echo '' >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
3.2 禁用密码登录
编辑SSH配置:
sudo nano /etc/ssh/sshd_config
确保以下几行存在且生效:
PasswordAuthentication no
PermitRootLogin prohibit-password
PubkeyAuthentication yes
ChallengeResponseAuthentication no
然后重启SSH服务:
sudo systemctl restart sshd
注意:改之前先开一个备用终端窗口,防止改错后锁在外面。
3.3 修改默认端口(可选但推荐)
# 在sshd_config里改端口
Port 2222 # 换成你选的高端口
# 记得在防火墙里放行
sudo ufw allow 2222/tcp
四、系统更新:别被自动更新坑了
4.1 禁用自动更新
Ubuntu默认会启用unattended-upgrades,这在生产环境经常惹麻烦:
# 查看自动更新状态
systemctl status unattended-upgrades
# 停用并禁用
sudo systemctl stop unattended-upgrades
sudo systemctl disable unattended-upgrades
# 禁用apt自动配置
echo 'APT::Periodic::Update-Package-Lists "0";' | sudo tee /etc/apt/apt.conf.d/20auto-upgrades
echo 'APT::Periodic::Unattended-Upgrade "0";' | sudo tee -a /etc/apt/apt.conf.d/20auto-upgrades
4.2 手动更新策略
企业建议:
- 测试环境:每周手动更新一次,观察兼容性
- 生产环境:每月固定时间窗口更新,提前备份
- 紧急安全更新:关注Ubuntu Security Notices,针对CVE手动评估
# 安全的更新流程
sudo apt update
sudo apt upgrade --dry-run # 先看看要装什么
sudo apt upgrade # 确认没问题再执行
sudo apt autoremove # 清理旧包
五、防火墙配置:UFW是标配
5.1 基础配置
# 安装UFW(如果还没装)
sudo apt install ufw -y
# 默认策略:拒绝入站,允许出站
sudo ufw default deny incoming
sudo ufw default allow outgoing
# 放行必要端口(根据你的服务调整)
sudo ufw allow 2222/tcp # SSH(如果改了端口)
sudo ufw allow 80/tcp # HTTP
sudo ufw allow 443/tcp # HTTPS
sudo ufw allow 3306/tcp # MySQL(如果是内网访问,建议加限制)
sudo ufw allow from 192.168.1.0/24 # 只允许内网访问数据库
# 启用防火墙
sudo ufw enable
5.2 常见误区:忘了放行某些端口
很多新手部署完服务发现连不上,排查半天发现是防火墙没开。建议部署前先列好所有需要的端口,一次性配置好:
# 查看所有放行的规则
sudo ufw status verbose
# 删除规则
sudo ufw delete allow 80/tcp
六、用户权限:root不是万能的
6.1 创建普通用户
# 创建用户
sudo adduser deploy
# 或者指定home目录
sudo adduser --home /home/appuser --shell /bin/bash appuser
# 加入sudo组
sudo usermod -aG sudo deploy
6.2 限制root登录
除了前面说的禁用root密码登录,还可以直接禁止root SSH登录:
# 在sshd_config里
PermitRootLogin no
然后用普通用户登录后用sudo提权:
sudo -i
# 或者执行单条命令
sudo apt update
6.3 配置sudoers安全策略
# 编辑sudoers(用visudo,防止语法错误锁死)
sudo visudo
添加限制:
# 允许deploy用户执行特定命令
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart nginx, /usr/bin/docker ps
# 禁止执行危险命令
%sudo ALL=!/bin/bash, !/bin/sh, !/usr/bin/su
七、服务部署实战:以Nginx+MySQL+Python为例
7.1 Nginx部署
# 安装
sudo apt install nginx -y
# 配置文件位置
sudo nano /etc/nginx/nginx.conf
关键安全配置:
# 隐藏版本信息
server_tokens off;
# 限制请求大小(防大文件攻击)
client_max_body_size 10m;
# 添加安全头
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 "no-referrer-when-downgrade" always;
server {
listen 80;
server_name your-domain.com;
# 强制HTTPS
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name your-domain.com;
ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your-domain.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;
root /var/www/your-domain.com;
index index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
}
7.2 MySQL安全配置
# 安装
sudo apt install mysql-server -y
# 运行安全脚本
sudo mysql_secure_installation
交互式配置:
VALIDATE PASSWORD COMPONENT? Y
Set root password? Y
Remove anonymous users? Y
Disallow root login remotely? Y
Remove test database? Y
Reload privilege tables now? Y
# 创建数据库和用户(不要用root)
sudo mysql -u root -p
CREATE DATABASE app_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'app_user'@'localhost' IDENTIFIED BY 'Str0ngP@ssw0rd!';
GRANT ALL PRIVILEGES ON app_db.* TO 'app_user'@'localhost';
FLUSH PRIVILEGES;
EXIT;
# 限制MySQL只监听本地(如果不是分布式部署)
sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf
# 确保这行存在
bind-address = 127.0.0.1
sudo systemctl restart mysql
7.3 Python应用部署
# 安装Python和必要工具
sudo apt install python3 python3-pip python3-venv -y
# 创建虚拟环境
cd /opt
sudo mkdir -p your-app
cd your-app
python3 -m venv venv
source venv/bin/activate
# 安装依赖
pip install -r requirements.txt
# 用systemd管理服务
sudo nano /etc/systemd/system/your-app.service
[Unit]
Description=Your Python Application
After=network.target
[Service]
User=appuser
Group=www-data
WorkingDirectory=/opt/your-app
ExecStart=/opt/your-app/venv/bin/gunicorn --workers 4 --bind 127.0.0.1:8000 app:app
Restart=always
RestartSec=5
# 安全限制
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/opt/your-app/logs
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable your-app
sudo systemctl start your-app
# 查看状态
sudo systemctl status your-app
八、日志监控:出问题能快速定位
8.1 系统日志
# 查看系统日志
sudo journalctl -u your-app -f
sudo journalctl -u nginx -f
sudo journalctl -u mysql -f
# 查看认证日志(排查暴力破解)
sudo tail -f /var/log/auth.log
# 查看安全日志
sudo tail -f /var/log/syslog
8.2 安装fail2ban(防暴力破解)
sudo apt install fail2ban -y
# 创建配置
sudo nano /etc/fail2ban/jail.local
[DEFAULT]
bantime = 3600
findtime = 600
maxretry = 5
banaction = ufw
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 86400
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
# 查看封禁状态
sudo fail2ban-client status sshd
8.3 磁盘监控
# 安装监控工具
sudo apt install htop iotop nethogs -y
# 查看磁盘使用
df -h
du -sh /var/log/*
# 查看内存使用
free -h
# 监控网络流量
sudo nethogs
九、备份策略:别等丢了才后悔
9.1 系统备份
# 使用rsync做增量备份
BACKUP_DIR="/backup/$(date +%Y%m%d)"
mkdir -p $BACKUP_DIR
# 备份配置文件
sudo rsync -av /etc/ $BACKUP_DIR/etc/
# 备份网站数据
rsync -av /var/www/ $BACKUP_DIR/www/
# 备份数据库
sudo mysqldump -u app_user -p app_db > $BACKUP_DIR/app_db.sql
# 压缩备份
tar -czf $BACKUP_DIR.tar.gz $BACKUP_DIR
rm -rf $BACKUP_DIR
9.2 自动备份脚本
sudo nano /usr/local/bin/backup.sh
#!/bin/bash
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="/backup/$DATE"
RETENTION_DAYS=30
mkdir -p $BACKUP_DIR/etc
mkdir -p $BACKUP_DIR/www
mkdir -p $BACKUP_DIR/db
# 备份配置
rsync -av /etc/ $BACKUP_DIR/etc/
# 备份数据
rsync -av /var/www/ $BACKUP_DIR/www/
# 备份数据库
sudo mysqldump -u app_user -p'YourPassword' app_db > $BACKUP_DIR/db/app_db.sql
# 压缩
tar -czf /backup/backup_$DATE.tar.gz -C /backup $DATE
rm -rf $BACKUP_DIR
# 清理旧备份
find /backup -name "backup_*.tar.gz" -mtime +$RETENTION_DAYS -delete
echo "Backup completed: $DATE"
sudo chmod +x /usr/local/bin/backup.sh
# 设置定时任务
sudo crontab -e
添加:
0 2 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1
十、安全加固清单:上线前必做
10.1 核心检查项
# 1. 检查开放端口
sudo netstat -tlnp
# 或
sudo ss -tlnp
# 2. 检查自动启动服务
systemctl list-unit-files --type=service | grep enabled
# 3. 检查sudoers配置
sudo visudo -c
# 4. 检查SSH配置
sudo sshd -t
sudo grep -E "(PasswordAuth|PermitRoot|PubkeyAuth)" /etc/ssh/sshd_config
# 5. 检查防火墙规则
sudo ufw status verbose
# 6. 检查是否有多余用户
cat /etc/passwd | grep -E "/bin/(bash|sh)"
# 7. 检查关键目录权限
ls -la /etc/shadow
ls -la /etc/passwd
ls -la /root/
10.2 加固脚本(一键执行)
sudo nano /usr/local/bin/harden.sh
”`bash #!/bin/bash set -e
echo “=== Ubuntu 22.04 Security Hardening ===”
1. 更新系统
echo “[1⁄10] Updating system…” apt update && apt upgrade -y
2. 禁用不需要的服务
echo “[2⁄10] Disabling unnecessary services…” systemctl stop telnet.socket systemctl disable telnet.socket systemctl stop cups systemctl disable cups
3. 配置防火墙
echo “[3⁄10] Configuring firewall…” ufw default deny incoming ufw default allow outgoing ufw –force enable
4. 安装安全工具
echo “[4⁄10] Installing security tools…” apt install -y fail2ban ufw apt-listbugs
5. 配置SSH安全
echo “[5⁄10] Hardening SSH…” sed -i ’s/^#PasswordAuthentication./PasswordAuthentication no/’ /etc/ssh/sshd_config sed -i ’s/^#PermitRootLogin./PermitRootLogin prohibit-password/’ /etc/ssh/sshd_config systemctl restart sshd
6. 配置自动安全更新(仅安全补丁)
echo “[6⁄10] Configuring security auto-updates…” apt install -y unattended-upgrades dpkg-reconfigure -f noninteractive unattended-upgrades
7. 设置文件系统权限
echo “[7⁄10] Setting file permissions…” chmod 600 /etc/shadow chmod 640 /etc/passwd chmod 700 /root
8. 配置sysctl安全参数
echo “[8⁄10] Configuring sysctl…” cat >> /etc/sysctl.d/99-hardening.conf << ‘EOF’ net.ipv4.conf.all.rp_filter = 1 net.ipv4.conf.default.rp_filter = 1 net.ipv4.conf.all.accept_redirects = 0 net.ipv4.conf.default.accept_redirects = 0 net.ipv4.conf.all.send_redirects = 0 net.ipv4.conf.default.send_redirects = 0 net.ipv4.icmp_echo_ignore_broadcasts = 1 net.ipv4.icmp_ignore_bogus_error_responses = 1 net.ipv6.conf.all.accept_redirects = 0 net.ipv6.conf.default.accept_redirects = 0 kernel.kptr_restrict = 2 kernel.unprivileged_bpf_disabled =