智慧水务管理系统 - 精河县供水工程综合管理平台

server-setup.sh 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  1. #!/bin/bash
  2. # ============================================================
  3. # 生产服务器初始化脚本
  4. #
  5. # 功能:
  6. # - 系统更新
  7. # - Docker 安装
  8. # - 防火墙配置 (ufw)
  9. # - SSH 加固
  10. # - 用户创建
  11. # - 目录结构创建
  12. #
  13. # 用法: sudo ./server-setup.sh
  14. # ============================================================
  15. set -euo pipefail
  16. # ==================== 配置 ====================
  17. DEPLOY_USER="${DEPLOY_USER:-deploy}"
  18. APP_DIR="${APP_DIR:-/opt/water-management}"
  19. BACKUP_DIR="${BACKUP_DIR:-/opt/water-management/backups}"
  20. LOG_DIR="${LOG_DIR:-/opt/water-management/logs}"
  21. # ==================== 函数 ====================
  22. log() {
  23. echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
  24. }
  25. check_root() {
  26. if [ "$(id -u)" -ne 0 ]; then
  27. log "❌ 请以 root 用户或 sudo 执行此脚本"
  28. exit 1
  29. fi
  30. }
  31. # ==================== 系统更新 ====================
  32. update_system() {
  33. log "📦 更新系统包..."
  34. if command -v apt-get &>/dev/null; then
  35. apt-get update -y
  36. apt-get upgrade -y
  37. apt-get install -y \
  38. curl \
  39. wget \
  40. git \
  41. unzip \
  42. software-properties-common \
  43. apt-transport-https \
  44. ca-certificates \
  45. gnupg \
  46. lsb-release \
  47. htop \
  48. iotop \
  49. jq \
  50. openssl \
  51. fail2ban \
  52. ufw
  53. elif command -v yum &>/dev/null; then
  54. yum update -y
  55. yum install -y \
  56. curl \
  57. wget \
  58. git \
  59. unzip \
  60. yum-utils \
  61. htop \
  62. iotop \
  63. jq \
  64. openssl \
  65. fail2ban \
  66. firewalld
  67. else
  68. log "⚠️ 未知的包管理器,请手动安装依赖"
  69. fi
  70. log "✅ 系统更新完成"
  71. }
  72. # ==================== Docker 安装 ====================
  73. install_docker() {
  74. if command -v docker &>/dev/null; then
  75. log "✅ Docker 已安装: $(docker --version)"
  76. return 0
  77. fi
  78. log "🐳 安装 Docker..."
  79. # 使用官方安装脚本
  80. curl -fsSL https://get.docker.com | sh
  81. # 启动 Docker
  82. systemctl enable docker
  83. systemctl start docker
  84. # 配置 Docker 镜像加速(中国大陆)
  85. mkdir -p /etc/docker
  86. cat > /etc/docker/daemon.json <<EOF
  87. {
  88. "registry-mirrors": [
  89. "https://docker.mirrors.ustc.edu.cn",
  90. "https://hub-mirror.c.163.com"
  91. ],
  92. "log-driver": "json-file",
  93. "log-opts": {
  94. "max-size": "50m",
  95. "max-file": "3"
  96. },
  97. "storage-driver": "overlay2",
  98. "live-restore": true,
  99. "default-ulimits": {
  100. "nofile": {
  101. "Name": "nofile",
  102. "Hard": 65535,
  103. "Soft": 65535
  104. }
  105. }
  106. }
  107. EOF
  108. systemctl restart docker
  109. # 安装 Docker Compose
  110. COMPOSE_VERSION=$(curl -s https://api.github.com/repos/docker/compose/releases/latest | grep -oP '"tag_name": "\K(.*)(?=")')
  111. curl -L "https://github.com/docker/compose/releases/download/${COMPOSE_VERSION}/docker-compose-$(uname -s)-$(uname -m)" \
  112. -o /usr/local/bin/docker-compose
  113. chmod +x /usr/local/bin/docker-compose
  114. ln -sf /usr/local/bin/docker-compose /usr/bin/docker-compose
  115. log "✅ Docker 安装完成: $(docker --version)"
  116. log "✅ Docker Compose 安装完成: $(docker-compose --version)"
  117. }
  118. # ==================== 防火墙配置 ====================
  119. setup_firewall() {
  120. log "🔥 配置防火墙..."
  121. if command -v ufw &>/dev/null; then
  122. # Ubuntu/Debian - UFW
  123. ufw default deny incoming
  124. ufw default allow outgoing
  125. # SSH
  126. ufw allow 22/tcp comment "SSH"
  127. ufw limit 22/tcp
  128. # HTTP/HTTPS
  129. ufw allow 80/tcp comment "HTTP"
  130. ufw allow 443/tcp comment "HTTPS"
  131. # MQTT (物联网设备接入)
  132. ufw allow 1883/tcp comment "MQTT"
  133. # 内部服务端口(仅允许内网访问,按实际 IP 段调整)
  134. # ufw allow from 10.0.0.0/8 to any port 8080
  135. # ufw allow from 10.0.0.0/8 to any port 8848
  136. ufw --force enable
  137. log "✅ UFW 防火墙已启用"
  138. elif command -v firewall-cmd &>/dev/null; then
  139. # CentOS/RHEL - firewalld
  140. systemctl enable firewalld
  141. systemctl start firewalld
  142. firewall-cmd --permanent --add-service=ssh
  143. firewall-cmd --permanent --add-service=http
  144. firewall-cmd --permanent --add-service=https
  145. firewall-cmd --permanent --add-port=1883/tcp
  146. firewall-cmd --reload
  147. log "✅ firewalld 防火墙已配置"
  148. fi
  149. }
  150. # ==================== SSH 加固 ====================
  151. harden_ssh() {
  152. log "🔒 SSH 加固..."
  153. local sshd_config="/etc/ssh/sshd_config"
  154. # 备份原配置
  155. cp "$sshd_config" "${sshd_config}.bak.$(date +%Y%m%d)"
  156. # 禁用 root 密码登录
  157. sed -i 's/^#*PermitRootLogin.*/PermitRootLogin prohibit-password/' "$sshd_config"
  158. # 禁用空密码
  159. sed -i 's/^#*PermitEmptyPasswords.*/PermitEmptyPasswords no/' "$sshd_config"
  160. # 启用公钥认证
  161. sed -i 's/^#*PubkeyAuthentication.*/PubkeyAuthentication yes/' "$sshd_config"
  162. # 禁用密码登录(确保已配置公钥后启用)
  163. # sed -i 's/^#*PasswordAuthentication.*/PasswordAuthentication no/' "$sshd_config"
  164. # 限制最大认证尝试
  165. sed -i 's/^#*MaxAuthTries.*/MaxAuthTries 3/' "$sshd_config"
  166. # 客户端存活检测
  167. sed -i 's/^#*ClientAliveInterval.*/ClientAliveInterval 300/' "$sshd_config"
  168. sed -i 's/^#*ClientAliveCountMax.*/ClientAliveCountMax 2/' "$sshd_config"
  169. systemctl restart sshd
  170. log "✅ SSH 加固完成"
  171. }
  172. # ==================== Fail2Ban 配置 ====================
  173. setup_fail2ban() {
  174. log "🛡️ 配置 Fail2Ban..."
  175. cat > /etc/fail2ban/jail.local <<EOF
  176. [DEFAULT]
  177. bantime = 3600
  178. findtime = 600
  179. maxretry = 5
  180. backend = systemd
  181. [sshd]
  182. enabled = true
  183. port = ssh
  184. filter = sshd
  185. logpath = /var/log/auth.log
  186. maxretry = 3
  187. bantime = 86400
  188. EOF
  189. systemctl enable fail2ban
  190. systemctl restart fail2ban
  191. log "✅ Fail2Ban 已配置"
  192. }
  193. # ==================== 创建部署用户 ====================
  194. create_deploy_user() {
  195. log "👤 创建部署用户: ${DEPLOY_USER}"
  196. if id "$DEPLOY_USER" &>/dev/null; then
  197. log "✅ 用户已存在: ${DEPLOY_USER}"
  198. else
  199. useradd -m -s /bin/bash "$DEPLOY_USER"
  200. usermod -aG docker "$DEPLOY_USER"
  201. log "✅ 用户已创建: ${DEPLOY_USER}"
  202. fi
  203. # 配置 sudo 权限(免密码执行 docker 命令)
  204. cat > "/etc/sudoers.d/${DEPLOY_USER}" <<EOF
  205. ${DEPLOY_USER} ALL=(ALL) NOPASSWD: /usr/bin/docker, /usr/bin/docker-compose, /usr/local/bin/docker-compose
  206. EOF
  207. chmod 440 "/etc/sudoers.d/${DEPLOY_USER}"
  208. # 创建 SSH 目录
  209. local user_home
  210. user_home=$(eval echo "~${DEPLOY_USER}")
  211. mkdir -p "${user_home}/.ssh"
  212. chmod 700 "${user_home}/.ssh"
  213. chown -R "${DEPLOY_USER}:${DEPLOY_USER}" "${user_home}/.ssh"
  214. log "✅ 部署用户配置完成"
  215. log "⚠️ 请将公钥添加到 ${user_home}/.ssh/authorized_keys"
  216. }
  217. # ==================== 创建目录结构 ====================
  218. create_directories() {
  219. log "📁 创建应用目录结构..."
  220. mkdir -p "${APP_DIR}"
  221. mkdir -p "${APP_DIR}/config"
  222. mkdir -p "${APP_DIR}/config/postgres"
  223. mkdir -p "${APP_DIR}/config/nginx"
  224. mkdir -p "${APP_DIR}/config/certs"
  225. mkdir -p "${BACKUP_DIR}/daily"
  226. mkdir -p "${BACKUP_DIR}/weekly"
  227. mkdir -p "${BACKUP_DIR}/monthly"
  228. mkdir -p "${LOG_DIR}"
  229. chown -R "${DEPLOY_USER}:${DEPLOY_USER}" "${APP_DIR}"
  230. log "✅ 目录结构创建完成"
  231. }
  232. # ==================== 内核优化 ====================
  233. optimize_kernel() {
  234. log "⚙️ 内核参数优化..."
  235. cat > /etc/sysctl.d/99-water-management.conf <<EOF
  236. # TCP 优化
  237. net.core.somaxconn = 65535
  238. net.ipv4.tcp_max_syn_backlog = 65535
  239. net.ipv4.tcp_syncookies = 1
  240. net.ipv4.tcp_tw_reuse = 1
  241. net.ipv4.ip_local_port_range = 1024 65535
  242. # 文件描述符
  243. fs.file-max = 655350
  244. fs.inotify.max_user_watches = 524288
  245. # 内存优化
  246. vm.swappiness = 10
  247. vm.dirty_ratio = 15
  248. vm.dirty_background_ratio = 5
  249. # 网络优化
  250. net.ipv4.tcp_keepalive_time = 600
  251. net.ipv4.tcp_keepalive_intvl = 30
  252. net.ipv4.tcp_keepalive_probes = 3
  253. EOF
  254. sysctl -p /etc/sysctl.d/99-water-management.conf
  255. # 文件描述符限制
  256. cat > /etc/security/limits.d/99-water-management.conf <<EOF
  257. * soft nofile 65535
  258. * hard nofile 65535
  259. * soft nproc 65535
  260. * hard nproc 65535
  261. ${DEPLOY_USER} soft nofile 65535
  262. ${DEPLOY_USER} hard nofile 65535
  263. EOF
  264. log "✅ 内核优化完成"
  265. }
  266. # ==================== 配置定时任务 ====================
  267. setup_cron() {
  268. log "⏰ 配置定时任务..."
  269. local cron_file="/etc/cron.d/water-management"
  270. cat > "$cron_file" <<EOF
  271. # 数据库备份 - 每天凌晨 2 点
  272. 0 2 * * * ${DEPLOY_USER} ${APP_DIR}/deploy/production/backup/backup-db.sh >> ${LOG_DIR}/backup.log 2>&1
  273. # 证书续期 - 每天凌晨 3 点
  274. 0 3 * * * root ${APP_DIR}/deploy/production/nginx/certbot-renew.sh >> ${LOG_DIR}/certbot-renew.log 2>&1
  275. # 日志清理 - 每天凌晨 4 点
  276. 0 4 * * * ${DEPLOY_USER} find ${LOG_DIR} -name "*.log" -mtime +30 -delete 2>/dev/null || true
  277. # 磁盘监控 - 每小时
  278. 0 * * * * ${DEPLOY_USER} df -h | awk 'NR>1 && +\$5>90 {print "⚠️ 磁盘告警: "\$0}' | mail -s "磁盘告警" root 2>/dev/null || true
  279. EOF
  280. chmod 644 "$cron_file"
  281. log "✅ 定时任务配置完成"
  282. }
  283. # ==================== 主流程 ====================
  284. log "========================================="
  285. log " 生产服务器初始化"
  286. log "========================================="
  287. check_root
  288. update_system
  289. install_docker
  290. setup_firewall
  291. harden_ssh
  292. setup_fail2ban
  293. create_deploy_user
  294. create_directories
  295. optimize_kernel
  296. setup_cron
  297. log "========================================="
  298. log " ✅ 服务器初始化完成!"
  299. log "========================================="
  300. log ""
  301. log "后续步骤:"
  302. log "1. 将 SSH 公钥添加到 /home/${DEPLOY_USER}/.ssh/authorized_keys"
  303. log "2. 配置 .env 环境变量文件: ${APP_DIR}/.env"
  304. log "3. 配置域名 DNS 解析"
  305. log "4. 申请 Let's Encrypt 证书"
  306. log "5. 部署应用: docker compose -f docker-compose.yml -f deploy/production/docker-compose.override.yml up -d"
  307. log "6. 启动监控栈: docker compose -f deploy/production/monitoring/docker-compose.monitoring.yml up -d"
  308. log "7. 启动日志栈: docker compose -f deploy/production/logging/docker-compose.logging.yml up -d"
  309. log ""