| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379 |
- #!/bin/bash
- # ============================================================
- # 生产服务器初始化脚本
- #
- # 功能:
- # - 系统更新
- # - Docker 安装
- # - 防火墙配置 (ufw)
- # - SSH 加固
- # - 用户创建
- # - 目录结构创建
- #
- # 用法: sudo ./server-setup.sh
- # ============================================================
- set -euo pipefail
-
- # ==================== 配置 ====================
- DEPLOY_USER="${DEPLOY_USER:-deploy}"
- APP_DIR="${APP_DIR:-/opt/water-management}"
- BACKUP_DIR="${BACKUP_DIR:-/opt/water-management/backups}"
- LOG_DIR="${LOG_DIR:-/opt/water-management/logs}"
-
- # ==================== 函数 ====================
-
- log() {
- echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
- }
-
- check_root() {
- if [ "$(id -u)" -ne 0 ]; then
- log "❌ 请以 root 用户或 sudo 执行此脚本"
- exit 1
- fi
- }
-
- # ==================== 系统更新 ====================
- update_system() {
- log "📦 更新系统包..."
-
- if command -v apt-get &>/dev/null; then
- apt-get update -y
- apt-get upgrade -y
- apt-get install -y \
- curl \
- wget \
- git \
- unzip \
- software-properties-common \
- apt-transport-https \
- ca-certificates \
- gnupg \
- lsb-release \
- htop \
- iotop \
- jq \
- openssl \
- fail2ban \
- ufw
- elif command -v yum &>/dev/null; then
- yum update -y
- yum install -y \
- curl \
- wget \
- git \
- unzip \
- yum-utils \
- htop \
- iotop \
- jq \
- openssl \
- fail2ban \
- firewalld
- else
- log "⚠️ 未知的包管理器,请手动安装依赖"
- fi
-
- log "✅ 系统更新完成"
- }
-
- # ==================== Docker 安装 ====================
- install_docker() {
- if command -v docker &>/dev/null; then
- log "✅ Docker 已安装: $(docker --version)"
- return 0
- fi
-
- log "🐳 安装 Docker..."
-
- # 使用官方安装脚本
- curl -fsSL https://get.docker.com | sh
-
- # 启动 Docker
- systemctl enable docker
- systemctl start docker
-
- # 配置 Docker 镜像加速(中国大陆)
- mkdir -p /etc/docker
- cat > /etc/docker/daemon.json <<EOF
- {
- "registry-mirrors": [
- "https://docker.mirrors.ustc.edu.cn",
- "https://hub-mirror.c.163.com"
- ],
- "log-driver": "json-file",
- "log-opts": {
- "max-size": "50m",
- "max-file": "3"
- },
- "storage-driver": "overlay2",
- "live-restore": true,
- "default-ulimits": {
- "nofile": {
- "Name": "nofile",
- "Hard": 65535,
- "Soft": 65535
- }
- }
- }
- EOF
-
- systemctl restart docker
-
- # 安装 Docker Compose
- COMPOSE_VERSION=$(curl -s https://api.github.com/repos/docker/compose/releases/latest | grep -oP '"tag_name": "\K(.*)(?=")')
- curl -L "https://github.com/docker/compose/releases/download/${COMPOSE_VERSION}/docker-compose-$(uname -s)-$(uname -m)" \
- -o /usr/local/bin/docker-compose
- chmod +x /usr/local/bin/docker-compose
- ln -sf /usr/local/bin/docker-compose /usr/bin/docker-compose
-
- log "✅ Docker 安装完成: $(docker --version)"
- log "✅ Docker Compose 安装完成: $(docker-compose --version)"
- }
-
- # ==================== 防火墙配置 ====================
- setup_firewall() {
- log "🔥 配置防火墙..."
-
- if command -v ufw &>/dev/null; then
- # Ubuntu/Debian - UFW
- ufw default deny incoming
- ufw default allow outgoing
-
- # SSH
- ufw allow 22/tcp comment "SSH"
- ufw limit 22/tcp
-
- # HTTP/HTTPS
- ufw allow 80/tcp comment "HTTP"
- ufw allow 443/tcp comment "HTTPS"
-
- # MQTT (物联网设备接入)
- ufw allow 1883/tcp comment "MQTT"
-
- # 内部服务端口(仅允许内网访问,按实际 IP 段调整)
- # ufw allow from 10.0.0.0/8 to any port 8080
- # ufw allow from 10.0.0.0/8 to any port 8848
-
- ufw --force enable
- log "✅ UFW 防火墙已启用"
-
- elif command -v firewall-cmd &>/dev/null; then
- # CentOS/RHEL - firewalld
- systemctl enable firewalld
- systemctl start firewalld
-
- firewall-cmd --permanent --add-service=ssh
- firewall-cmd --permanent --add-service=http
- firewall-cmd --permanent --add-service=https
- firewall-cmd --permanent --add-port=1883/tcp
- firewall-cmd --reload
-
- log "✅ firewalld 防火墙已配置"
- fi
- }
-
- # ==================== SSH 加固 ====================
- harden_ssh() {
- log "🔒 SSH 加固..."
-
- local sshd_config="/etc/ssh/sshd_config"
-
- # 备份原配置
- cp "$sshd_config" "${sshd_config}.bak.$(date +%Y%m%d)"
-
- # 禁用 root 密码登录
- sed -i 's/^#*PermitRootLogin.*/PermitRootLogin prohibit-password/' "$sshd_config"
-
- # 禁用空密码
- sed -i 's/^#*PermitEmptyPasswords.*/PermitEmptyPasswords no/' "$sshd_config"
-
- # 启用公钥认证
- sed -i 's/^#*PubkeyAuthentication.*/PubkeyAuthentication yes/' "$sshd_config"
-
- # 禁用密码登录(确保已配置公钥后启用)
- # sed -i 's/^#*PasswordAuthentication.*/PasswordAuthentication no/' "$sshd_config"
-
- # 限制最大认证尝试
- sed -i 's/^#*MaxAuthTries.*/MaxAuthTries 3/' "$sshd_config"
-
- # 客户端存活检测
- sed -i 's/^#*ClientAliveInterval.*/ClientAliveInterval 300/' "$sshd_config"
- sed -i 's/^#*ClientAliveCountMax.*/ClientAliveCountMax 2/' "$sshd_config"
-
- systemctl restart sshd
-
- log "✅ SSH 加固完成"
- }
-
- # ==================== Fail2Ban 配置 ====================
- setup_fail2ban() {
- log "🛡️ 配置 Fail2Ban..."
-
- cat > /etc/fail2ban/jail.local <<EOF
- [DEFAULT]
- bantime = 3600
- findtime = 600
- maxretry = 5
- backend = systemd
-
- [sshd]
- enabled = true
- port = ssh
- filter = sshd
- logpath = /var/log/auth.log
- maxretry = 3
- bantime = 86400
- EOF
-
- systemctl enable fail2ban
- systemctl restart fail2ban
-
- log "✅ Fail2Ban 已配置"
- }
-
- # ==================== 创建部署用户 ====================
- create_deploy_user() {
- log "👤 创建部署用户: ${DEPLOY_USER}"
-
- if id "$DEPLOY_USER" &>/dev/null; then
- log "✅ 用户已存在: ${DEPLOY_USER}"
- else
- useradd -m -s /bin/bash "$DEPLOY_USER"
- usermod -aG docker "$DEPLOY_USER"
- log "✅ 用户已创建: ${DEPLOY_USER}"
- fi
-
- # 配置 sudo 权限(免密码执行 docker 命令)
- cat > "/etc/sudoers.d/${DEPLOY_USER}" <<EOF
- ${DEPLOY_USER} ALL=(ALL) NOPASSWD: /usr/bin/docker, /usr/bin/docker-compose, /usr/local/bin/docker-compose
- EOF
- chmod 440 "/etc/sudoers.d/${DEPLOY_USER}"
-
- # 创建 SSH 目录
- local user_home
- user_home=$(eval echo "~${DEPLOY_USER}")
- mkdir -p "${user_home}/.ssh"
- chmod 700 "${user_home}/.ssh"
- chown -R "${DEPLOY_USER}:${DEPLOY_USER}" "${user_home}/.ssh"
-
- log "✅ 部署用户配置完成"
- log "⚠️ 请将公钥添加到 ${user_home}/.ssh/authorized_keys"
- }
-
- # ==================== 创建目录结构 ====================
- create_directories() {
- log "📁 创建应用目录结构..."
-
- mkdir -p "${APP_DIR}"
- mkdir -p "${APP_DIR}/config"
- mkdir -p "${APP_DIR}/config/postgres"
- mkdir -p "${APP_DIR}/config/nginx"
- mkdir -p "${APP_DIR}/config/certs"
- mkdir -p "${BACKUP_DIR}/daily"
- mkdir -p "${BACKUP_DIR}/weekly"
- mkdir -p "${BACKUP_DIR}/monthly"
- mkdir -p "${LOG_DIR}"
-
- chown -R "${DEPLOY_USER}:${DEPLOY_USER}" "${APP_DIR}"
-
- log "✅ 目录结构创建完成"
- }
-
- # ==================== 内核优化 ====================
- optimize_kernel() {
- log "⚙️ 内核参数优化..."
-
- cat > /etc/sysctl.d/99-water-management.conf <<EOF
- # TCP 优化
- net.core.somaxconn = 65535
- net.ipv4.tcp_max_syn_backlog = 65535
- net.ipv4.tcp_syncookies = 1
- net.ipv4.tcp_tw_reuse = 1
- net.ipv4.ip_local_port_range = 1024 65535
-
- # 文件描述符
- fs.file-max = 655350
- fs.inotify.max_user_watches = 524288
-
- # 内存优化
- vm.swappiness = 10
- vm.dirty_ratio = 15
- vm.dirty_background_ratio = 5
-
- # 网络优化
- net.ipv4.tcp_keepalive_time = 600
- net.ipv4.tcp_keepalive_intvl = 30
- net.ipv4.tcp_keepalive_probes = 3
- EOF
-
- sysctl -p /etc/sysctl.d/99-water-management.conf
-
- # 文件描述符限制
- cat > /etc/security/limits.d/99-water-management.conf <<EOF
- * soft nofile 65535
- * hard nofile 65535
- * soft nproc 65535
- * hard nproc 65535
- ${DEPLOY_USER} soft nofile 65535
- ${DEPLOY_USER} hard nofile 65535
- EOF
-
- log "✅ 内核优化完成"
- }
-
- # ==================== 配置定时任务 ====================
- setup_cron() {
- log "⏰ 配置定时任务..."
-
- local cron_file="/etc/cron.d/water-management"
-
- cat > "$cron_file" <<EOF
- # 数据库备份 - 每天凌晨 2 点
- 0 2 * * * ${DEPLOY_USER} ${APP_DIR}/deploy/production/backup/backup-db.sh >> ${LOG_DIR}/backup.log 2>&1
-
- # 证书续期 - 每天凌晨 3 点
- 0 3 * * * root ${APP_DIR}/deploy/production/nginx/certbot-renew.sh >> ${LOG_DIR}/certbot-renew.log 2>&1
-
- # 日志清理 - 每天凌晨 4 点
- 0 4 * * * ${DEPLOY_USER} find ${LOG_DIR} -name "*.log" -mtime +30 -delete 2>/dev/null || true
-
- # 磁盘监控 - 每小时
- 0 * * * * ${DEPLOY_USER} df -h | awk 'NR>1 && +\$5>90 {print "⚠️ 磁盘告警: "\$0}' | mail -s "磁盘告警" root 2>/dev/null || true
- EOF
-
- chmod 644 "$cron_file"
-
- log "✅ 定时任务配置完成"
- }
-
- # ==================== 主流程 ====================
-
- log "========================================="
- log " 生产服务器初始化"
- log "========================================="
-
- check_root
- update_system
- install_docker
- setup_firewall
- harden_ssh
- setup_fail2ban
- create_deploy_user
- create_directories
- optimize_kernel
- setup_cron
-
- log "========================================="
- log " ✅ 服务器初始化完成!"
- log "========================================="
- log ""
- log "后续步骤:"
- log "1. 将 SSH 公钥添加到 /home/${DEPLOY_USER}/.ssh/authorized_keys"
- log "2. 配置 .env 环境变量文件: ${APP_DIR}/.env"
- log "3. 配置域名 DNS 解析"
- log "4. 申请 Let's Encrypt 证书"
- log "5. 部署应用: docker compose -f docker-compose.yml -f deploy/production/docker-compose.override.yml up -d"
- log "6. 启动监控栈: docker compose -f deploy/production/monitoring/docker-compose.monitoring.yml up -d"
- log "7. 启动日志栈: docker compose -f deploy/production/logging/docker-compose.logging.yml up -d"
- log ""
|