NetBox_install.sh 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171
  1. #!/bin/bash
  2. # NetBox 一键安装脚本
  3. # 适用于 CentOS 9 Stream
  4. # 作者:Claude
  5. # 版本:1.0.1
  6. # 严格模式
  7. set -euo pipefail
  8. IFS=$'\n\t'
  9. # 定义变量
  10. BASE_DIR="/home"
  11. NETBOX_DIR="$BASE_DIR/netbox"
  12. VENV_DIR="$BASE_DIR/venv"
  13. NETBOX_CONFIG_DIR="$NETBOX_DIR/netbox/netbox"
  14. LOG_FILE="$BASE_DIR/netbox_install.log"
  15. DB_NAME="netbox"
  16. DB_USER="netbox"
  17. DB_PASS="your_secure_password"
  18. # 配置日志
  19. exec 1> >(tee -a "$LOG_FILE") 2>&1
  20. echo "开始安装 NetBox - $(date)"
  21. # 错误处理
  22. error_handler() {
  23. local line_no=$1
  24. echo "错误发生在第 ${line_no} 行"
  25. exit 1
  26. }
  27. trap 'error_handler ${LINENO}' ERR
  28. # 清理函数
  29. cleanup_services() {
  30. echo "清理现有服务和数据..."
  31. echo "停止服务..."
  32. sudo systemctl stop netbox nginx redis postgresql || true
  33. echo "清理运行时目录..."
  34. sudo rm -rf /var/run/netbox/* || true
  35. echo "清理 PostgreSQL 数据..."
  36. if [ -d "/var/lib/pgsql/data" ]; then
  37. sudo -u postgres dropdb netbox || true
  38. sudo -u postgres dropuser netbox || true
  39. fi
  40. echo "清理 NetBox 目录..."
  41. sudo rm -rf "$NETBOX_DIR" || true
  42. echo "清理 Python 虚拟环境..."
  43. sudo rm -rf "$VENV_DIR" || true
  44. echo "清理日志文件..."
  45. sudo rm -f /var/log/netbox*.log || true
  46. echo "清理 Redis 数据"
  47. sudo systemctl stop redis
  48. sudo rm -rf /var/lib/redis/* || true
  49. echo "清理 nginx 配置"
  50. sudo rm -f /etc/nginx/conf.d/netbox.conf || true
  51. echo "清理系统服务配置"
  52. sudo rm -f /etc/systemd/system/netbox.service || true
  53. echo "重新加载系统服务"
  54. sudo systemctl daemon-reload
  55. echo "清理完成"
  56. }
  57. # 检查依赖
  58. check_dependencies() {
  59. echo "检查并安装系统依赖..."
  60. # 添加必要的仓库
  61. sudo dnf install -y epel-release
  62. sudo dnf config-manager --set-enabled crb
  63. # 更新系统
  64. sudo dnf update -y
  65. # 安装开发工具组
  66. sudo dnf groupinstall -y "Development Tools"
  67. # 安装 SELinux 相关依赖
  68. echo "安装 SELinux 依赖..."
  69. sudo dnf install -y \
  70. policycoreutils-python-utils \
  71. python3-policycoreutils \
  72. python3-libselinux \
  73. python3-libsemanage \
  74. python3-setools \
  75. setroubleshoot-server \
  76. setools-console
  77. # 安装其他必要依赖
  78. echo "安装其他系统依赖..."
  79. sudo dnf install -y \
  80. python3.12 \
  81. python3.12-pip \
  82. python3.12-devel \
  83. postgresql-server \
  84. postgresql-contrib \
  85. postgresql-devel \
  86. nginx \
  87. redis \
  88. git \
  89. gcc \
  90. libpq-devel \
  91. libffi-devel \
  92. openssl-devel \
  93. libxml2-devel \
  94. libxslt-devel \
  95. libjpeg-devel \
  96. zlib-devel
  97. # 修改 Python 3.12 设置部分
  98. if [ -f "/usr/bin/python3.12" ]; then
  99. sudo alternatives --install /usr/bin/python3 python3 /usr/bin/python3.12 1
  100. sudo alternatives --set python3 /usr/bin/python3.12 || {
  101. echo "警告:无法设置 Python 3.12 为默认版本,但将继续安装..."
  102. }
  103. else
  104. echo "警告:未找到 Python 3.12,将使用系统默认的 Python 版本..."
  105. fi
  106. echo "系统依赖安装完成"
  107. }
  108. # 配置 PostgreSQL
  109. setup_database() {
  110. echo "配置 PostgreSQL 数据库..."
  111. # 确保 PostgreSQL 数据目录存在
  112. if [ ! -d "/var/lib/pgsql/data" ]; then
  113. sudo mkdir -p /var/lib/pgsql/data
  114. sudo chown postgres:postgres /var/lib/pgsql/data
  115. fi
  116. # 确 PostgreSQL 已初始化
  117. if [ ! -f /var/lib/pgsql/data/PG_VERSION ]; then
  118. echo "初始化 PostgreSQL 数据库..."
  119. # 使用 -E UTF8 显式指定编码,并使用 postgres 用户执行命令
  120. sudo -u postgres /usr/bin/postgresql-setup --initdb
  121. # 等待初始化完成
  122. sleep 5
  123. fi
  124. # 确保 PostgreSQL 服务已启动
  125. if ! systemctl is-active --quiet postgresql; then
  126. echo "启动 PostgreSQL 服务..."
  127. sudo systemctl start postgresql
  128. # 予服务足够的启动时间
  129. sleep 10
  130. fi
  131. # 验证 PostgreSQL 是否正在运行
  132. if ! pg_isready -q; then
  133. echo "错误:PostgreSQL 服务未能正确启动"
  134. sudo systemctl status postgresql
  135. exit 1
  136. fi
  137. # 修改 PostgreSQL 认证配置
  138. echo "配置 PostgreSQL 认证方式..."
  139. sudo cp /var/lib/pgsql/data/pg_hba.conf /var/lib/pgsql/data/pg_hba.conf.bak
  140. # 使用更安全的方式修改 pg_hba.conf
  141. sudo tee /var/lib/pgsql/data/pg_hba.conf > /dev/null <<EOF
  142. # TYPE DATABASE USER ADDRESS METHOD
  143. local all postgres trust
  144. local all all trust
  145. host all all 127.0.0.1/32 trust
  146. host all all ::1/128 trust
  147. EOF
  148. # 重启 PostgreSQL 服务以应用新配置
  149. sudo systemctl restart postgresql
  150. # 等待服务完全启动
  151. echo "等待 PostgreSQL 重新启动..."
  152. sleep 10
  153. # 再次验证服务状态
  154. if ! pg_isready -q; then
  155. echo "错误:PostgreSQL 服务重启后未能正确运行"
  156. sudo systemctl status postgresql
  157. exit 1
  158. fi
  159. # 设置 postgres 用户密码 (使用 trust 认证,无需密码)
  160. echo "设置 postgres 用户密码..."
  161. sudo -u postgres psql -c "ALTER USER postgres WITH PASSWORD 'postgres';"
  162. # 创建数据库和用户
  163. echo "创建数据库和用户..."
  164. sudo -u postgres psql <<EOF
  165. DROP DATABASE IF EXISTS $DB_NAME;
  166. DROP USER IF EXISTS $DB_USER;
  167. CREATE DATABASE $DB_NAME;
  168. CREATE USER $DB_USER WITH PASSWORD '$DB_PASS';
  169. ALTER ROLE $DB_USER SET client_encoding TO 'utf8';
  170. ALTER ROLE $DB_USER SET default_transaction_isolation TO 'read committed';
  171. ALTER ROLE $DB_USER SET timezone TO 'UTC';
  172. GRANT ALL PRIVILEGES ON DATABASE $DB_NAME TO $DB_USER;
  173. \c $DB_NAME
  174. GRANT ALL ON SCHEMA public TO $DB_USER;
  175. EOF
  176. # 修改回 md5 认证
  177. sudo sed -i 's/trust/md5/g' /var/lib/pgsql/data/pg_hba.conf
  178. # 重启 PostgreSQL 使新配置生效
  179. sudo systemctl restart postgresql
  180. echo "数据库配置完成"
  181. }
  182. # 安装 NetBox
  183. install_netbox() {
  184. echo "安装 NetBox..."
  185. # 确保基础目录存在
  186. sudo mkdir -p "$BASE_DIR"
  187. # 克隆最新的 NetBox 代码
  188. if [ ! -d "$NETBOX_DIR" ]; then
  189. git clone https://github.com/netbox-community/netbox.git "$NETBOX_DIR"
  190. fi
  191. # 确保配置目录存在
  192. sudo mkdir -p "$NETBOX_CONFIG_DIR"
  193. # 创建并激活虚拟环境
  194. python3.12 -m venv "$VENV_DIR"
  195. source "$VENV_DIR/bin/activate"
  196. # 升级包管理工具
  197. pip install --upgrade pip wheel setuptools
  198. # 安装 gunicorn
  199. pip install gunicorn
  200. # 安装 NetBox 依赖
  201. cd "$NETBOX_DIR"
  202. pip install -r requirements.txt
  203. # 设置目录权限
  204. sudo chown -R netbox:netbox "$NETBOX_DIR"
  205. sudo chown -R netbox:netbox "$VENV_DIR"
  206. sudo chmod -R 755 "$NETBOX_DIR"
  207. sudo chmod -R 755 "$VENV_DIR"
  208. # 确保 gunicorn 可执行
  209. sudo chmod +x "$VENV_DIR/bin/gunicorn"
  210. sudo chmod +x "$VENV_DIR/bin/python"
  211. }
  212. # 配置 NetBox
  213. configure_netbox() {
  214. echo "配置 NetBox..."
  215. # 配置文件路径
  216. CONFIG_FILE="$NETBOX_CONFIG_DIR/configuration.py"
  217. EXAMPLE_CONFIG="$NETBOX_CONFIG_DIR/configuration.example.py"
  218. # 确保配置目录存在
  219. sudo mkdir -p "$NETBOX_CONFIG_DIR"
  220. # 如果找不到示例配置文件,尝试其他位置
  221. if [ ! -f "$EXAMPLE_CONFIG" ]; then
  222. ALTERNATE_PATHS=(
  223. "$NETBOX_DIR/netbox/configuration.example.py"
  224. "$NETBOX_DIR/configuration.example.py"
  225. "$NETBOX_CONFIG_DIR/configuration.example.py"
  226. )
  227. for path in "${ALTERNATE_PATHS[@]}"; do
  228. if [ -f "$path" ]; then
  229. EXAMPLE_CONFIG="$path"
  230. echo "找到示例配置文件:$EXAMPLE_CONFIG"
  231. break
  232. fi
  233. done
  234. fi
  235. if [ ! -f "$CONFIG_FILE" ]; then
  236. echo "正在创建配置文件..."
  237. # 直接创建配置文件,而不是复制示例文件
  238. sudo tee "$CONFIG_FILE" > /dev/null <<EOF
  239. import os
  240. import platform
  241. # 生成随机密钥
  242. SECRET_KEY = '$(python3 -c "import secrets; print(secrets.token_urlsafe(50))")'
  243. # 数据库配置
  244. DATABASE = {
  245. 'NAME': '$DB_NAME',
  246. 'USER': '$DB_USER',
  247. 'PASSWORD': '$DB_PASS',
  248. 'HOST': 'localhost',
  249. 'PORT': '5432',
  250. 'CONN_MAX_AGE': 300,
  251. }
  252. # Redis 配置
  253. REDIS = {
  254. 'tasks': {
  255. 'HOST': 'localhost',
  256. 'PORT': 6379,
  257. 'PASSWORD': '',
  258. 'DATABASE': 0,
  259. 'SSL': False,
  260. },
  261. 'caching': {
  262. 'HOST': 'localhost',
  263. 'PORT': 6379,
  264. 'PASSWORD': '',
  265. 'DATABASE': 1,
  266. 'SSL': False,
  267. }
  268. }
  269. # 允许所有主机访问
  270. ALLOWED_HOSTS = ['*']
  271. # 设置时区
  272. TIME_ZONE = 'Asia/Shanghai'
  273. EOF
  274. fi
  275. # 设置配置文件权限
  276. sudo chown -R netbox:netbox "$NETBOX_CONFIG_DIR"
  277. sudo chmod -R 755 "$NETBOX_CONFIG_DIR"
  278. # 激活虚拟环境
  279. source "$VENV_DIR/bin/activate"
  280. # 执行数据库迁移
  281. echo "执行数据库迁移..."
  282. cd "$NETBOX_DIR/netbox"
  283. python3 manage.py migrate
  284. # 创建超级用户
  285. echo "创建超级用户..."
  286. DJANGO_SUPERUSER_USERNAME=admin \
  287. DJANGO_SUPERUSER_EMAIL=admin@example.com \
  288. DJANGO_SUPERUSER_PASSWORD=admin \
  289. python3 manage.py createsuperuser --noinput || {
  290. echo "警告:创建超级用户失败,可能已存在。继续安装..."
  291. }
  292. # 收集静态文件
  293. echo "收集静态文件..."
  294. python3 manage.py collectstatic --no-input
  295. # 验证数据库连接
  296. echo "验证数据库连接..."
  297. python3 manage.py check || {
  298. echo "警告:数据库检查失败,请检查配置..."
  299. return 1
  300. }
  301. }
  302. # 配置系统服务
  303. setup_services() {
  304. echo "配置系统服务..."
  305. # 创建 netbox 用户和组
  306. sudo useradd -r -s /bin/false netbox || true
  307. # 创建并设置必要的目录权限
  308. sudo mkdir -p /var/run/netbox
  309. sudo mkdir -p /var/log/netbox
  310. sudo chown -R netbox:netbox /var/run/netbox
  311. sudo chown -R netbox:netbox /var/log/netbox
  312. sudo chmod 755 /var/run/netbox
  313. sudo chmod 755 /var/log/netbox
  314. # 设置目录权限
  315. sudo chown -R netbox:netbox "$NETBOX_DIR"
  316. sudo chown -R netbox:netbox "$VENV_DIR"
  317. sudo chmod -R 755 "$NETBOX_DIR"
  318. sudo chmod -R 755 "$VENV_DIR"
  319. # 确保 gunicorn 和 python 可执行
  320. sudo chmod +x "$VENV_DIR/bin/gunicorn"
  321. sudo chmod +x "$VENV_DIR/bin/python"
  322. # 配置 Gunicorn 服务
  323. sudo tee /etc/systemd/system/netbox.service <<EOF
  324. [Unit]
  325. Description=NetBox WSGI Service
  326. Documentation=https://netbox.readthedocs.io/
  327. After=network.target postgresql.service redis.service
  328. Wants=postgresql.service redis.service
  329. [Service]
  330. Type=simple
  331. User=netbox
  332. Group=netbox
  333. RuntimeDirectory=netbox
  334. PIDFile=/var/run/netbox/netbox.pid
  335. WorkingDirectory=$NETBOX_DIR/netbox
  336. Environment="PATH=$VENV_DIR/bin:/usr/local/bin:/usr/bin:/bin"
  337. Environment="PYTHONPATH=$NETBOX_DIR/netbox"
  338. Environment="HOME=/home/netbox"
  339. Environment="USER=netbox"
  340. ExecStart=/usr/bin/env $VENV_DIR/bin/gunicorn \\
  341. --pid /var/run/netbox/netbox.pid \\
  342. --bind 127.0.0.1:8001 \\
  343. --workers 4 \\
  344. --timeout 300 \\
  345. --access-logfile /var/log/netbox/access.log \\
  346. --error-logfile /var/log/netbox/error.log \\
  347. netbox.wsgi:application
  348. Restart=always
  349. RestartSec=30
  350. [Install]
  351. WantedBy=multi-user.target
  352. EOF
  353. # 重新加载服务
  354. sudo systemctl daemon-reload
  355. sudo systemctl enable --now redis postgresql nginx netbox
  356. # 等待服务启动
  357. echo "等待服务启动..."
  358. sleep 10
  359. # 检查服务状态和日志
  360. echo "检查服务状态..."
  361. sudo systemctl status netbox --no-pager
  362. if ! systemctl is-active --quiet netbox; then
  363. echo "NetBox 服务启动失败,检查日志..."
  364. sudo journalctl -u netbox --no-pager | tail -n 50
  365. sudo cat /var/log/netbox/error.log || true
  366. fi
  367. # 配置 Nginx
  368. echo "配置 Nginx..."
  369. # 删除所有默认配置
  370. sudo rm -f /etc/nginx/conf.d/*.conf
  371. sudo tee /etc/nginx/conf.d/netbox.conf <<EOF
  372. server {
  373. listen 80 default_server;
  374. listen [::]:80 default_server;
  375. server_name _;
  376. client_max_body_size 25m;
  377. # 修正静态文件路径
  378. location /static/ {
  379. alias $NETBOX_DIR/netbox/static/;
  380. access_log off;
  381. expires 30d;
  382. }
  383. location / {
  384. proxy_pass http://127.0.0.1:8001;
  385. proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
  386. proxy_set_header X-Real-IP \$remote_addr;
  387. proxy_set_header Host \$http_host;
  388. proxy_set_header X-Forwarded-Proto \$scheme;
  389. proxy_redirect off;
  390. proxy_buffering off;
  391. }
  392. }
  393. EOF
  394. # 配置 SELinux(只在 SELinux 启用时执行)
  395. if [ "$(getenforce)" != "Disabled" ]; then
  396. echo "配置 SELinux 权限..."
  397. sudo setsebool -P httpd_can_network_connect 1
  398. sudo chcon -Rt httpd_sys_content_t "$NETBOX_DIR/netbox/static/" || true
  399. else
  400. echo "SELinux 已禁用,跳过 SELinux 配置"
  401. fi
  402. # 确保 nginx 用户有权限访问静态文件
  403. sudo chown -R nginx:nginx $NETBOX_DIR/netbox/static
  404. sudo chmod -R 755 $NETBOX_DIR/netbox/static
  405. # 测试 Nginx 配置
  406. sudo nginx -t
  407. # 重启 Nginx 服务
  408. sudo systemctl restart nginx
  409. }
  410. # 配置 Redis
  411. setup_redis() {
  412. echo "配置 Redis..."
  413. # 确保 Redis 已安装
  414. if ! command -v redis-server &> /dev/null; then
  415. echo "安装 Redis..."
  416. sudo dnf install -y redis
  417. fi
  418. # 备份并修改 Redis 配置
  419. if [ -f /etc/redis.conf ]; then
  420. sudo cp /etc/redis.conf /etc/redis.conf.bak
  421. # 修改 Redis 配置
  422. sudo tee /etc/redis.conf > /dev/null <<EOF
  423. bind 127.0.0.1
  424. port 6379
  425. daemonize yes
  426. supervised systemd
  427. dir /var/lib/redis
  428. pidfile /var/run/redis/redis.pid
  429. logfile /var/log/redis/redis.log
  430. EOF
  431. # 创建必要的目录
  432. sudo mkdir -p /var/log/redis
  433. sudo mkdir -p /var/run/redis
  434. # 设置权限
  435. sudo chown -R redis:redis /var/lib/redis
  436. sudo chown -R redis:redis /var/log/redis
  437. sudo chown -R redis:redis /var/run/redis
  438. sudo chmod 755 /var/lib/redis
  439. sudo chmod 755 /var/log/redis
  440. sudo chmod 755 /var/run/redis
  441. fi
  442. # 重启 Redis 服务
  443. sudo systemctl enable redis
  444. sudo systemctl restart redis
  445. # 等待 Redis 启动并验证
  446. echo "等待 Redis 启动..."
  447. for i in {1..30}; do
  448. if redis-cli ping &>/dev/null; then
  449. echo "Redis 已成功启动"
  450. break
  451. fi
  452. if [ $i -eq 30 ]; then
  453. echo "Redis 启动失败,请检查日志: sudo journalctl -u redis"
  454. exit 1
  455. fi
  456. sleep 1
  457. done
  458. }
  459. # 主函数
  460. main() {
  461. echo "开始安装 NetBox..."
  462. # 询问是否需要清理
  463. read -p "是否清理现有安装?(y/n) " -n 1 -r
  464. echo
  465. if [[ $REPLY =~ ^[Yy]$ ]]; then
  466. cleanup_services
  467. fi
  468. check_dependencies
  469. setup_redis
  470. setup_database
  471. install_netbox
  472. configure_netbox
  473. setup_services
  474. echo "NetBox 安装成功完成!"
  475. echo "请使用以下凭据访问 NetBox:"
  476. echo "URL: http://your-server-ip"
  477. echo "用户名: admin"
  478. echo "密码: admin"
  479. echo "请务必在首次登录后修改密码!"
  480. echo "注意:如果无法访问,请确保已配置防火墙允许 HTTP 访问(端口 80)"
  481. }
  482. # 执行主函数
  483. main#!/bin/bash
  484. # NetBox 一键安装脚本
  485. # 适用于 CentOS 9 Stream
  486. # 作者:Claude
  487. # 版本:1.0.1
  488. # 严格模式
  489. set -euo pipefail
  490. IFS=$'\n\t'
  491. # 定义变量
  492. BASE_DIR="/home"
  493. NETBOX_DIR="$BASE_DIR/netbox"
  494. VENV_DIR="$BASE_DIR/venv"
  495. NETBOX_CONFIG_DIR="$NETBOX_DIR/netbox/netbox"
  496. LOG_FILE="$BASE_DIR/netbox_install.log"
  497. DB_NAME="netbox"
  498. DB_USER="netbox"
  499. DB_PASS="your_secure_password"
  500. # 配置日志
  501. exec 1> >(tee -a "$LOG_FILE") 2>&1
  502. echo "开始安装 NetBox - $(date)"
  503. # 错误处理
  504. error_handler() {
  505. local line_no=$1
  506. echo "错误发生在第 ${line_no} 行"
  507. exit 1
  508. }
  509. trap 'error_handler ${LINENO}' ERR
  510. # 清理函数
  511. cleanup_services() {
  512. echo "清理现有服务和数据..."
  513. echo "停止服务..."
  514. sudo systemctl stop netbox nginx redis postgresql || true
  515. echo "清理运行时目录..."
  516. sudo rm -rf /var/run/netbox/* || true
  517. echo "清理 PostgreSQL 数据..."
  518. if [ -d "/var/lib/pgsql/data" ]; then
  519. sudo -u postgres dropdb netbox || true
  520. sudo -u postgres dropuser netbox || true
  521. fi
  522. echo "清理 NetBox 目录..."
  523. sudo rm -rf "$NETBOX_DIR" || true
  524. echo "清理 Python 虚拟环境..."
  525. sudo rm -rf "$VENV_DIR" || true
  526. echo "清理日志文件..."
  527. sudo rm -f /var/log/netbox*.log || true
  528. echo "清理 Redis 数据"
  529. sudo systemctl stop redis
  530. sudo rm -rf /var/lib/redis/* || true
  531. echo "清理 nginx 配置"
  532. sudo rm -f /etc/nginx/conf.d/netbox.conf || true
  533. echo "清理系统服务配置"
  534. sudo rm -f /etc/systemd/system/netbox.service || true
  535. echo "重新加载系统服务"
  536. sudo systemctl daemon-reload
  537. echo "清理完成"
  538. }
  539. # 检查依赖
  540. check_dependencies() {
  541. echo "检查并安装系统依赖..."
  542. # 添加必要的仓库
  543. sudo dnf install -y epel-release
  544. sudo dnf config-manager --set-enabled crb
  545. # 更新系统
  546. sudo dnf update -y
  547. # 安装开发工具组
  548. sudo dnf groupinstall -y "Development Tools"
  549. # 安装 SELinux 相关依赖
  550. echo "安装 SELinux 依赖..."
  551. sudo dnf install -y \
  552. policycoreutils-python-utils \
  553. python3-policycoreutils \
  554. python3-libselinux \
  555. python3-libsemanage \
  556. python3-setools \
  557. setroubleshoot-server \
  558. setools-console
  559. # 安装其他必要依赖
  560. echo "安装其他系统依赖..."
  561. sudo dnf install -y \
  562. python3.12 \
  563. python3.12-pip \
  564. python3.12-devel \
  565. postgresql-server \
  566. postgresql-contrib \
  567. postgresql-devel \
  568. nginx \
  569. redis \
  570. git \
  571. gcc \
  572. libpq-devel \
  573. libffi-devel \
  574. openssl-devel \
  575. libxml2-devel \
  576. libxslt-devel \
  577. libjpeg-devel \
  578. zlib-devel
  579. # 修改 Python 3.12 设置部分
  580. if [ -f "/usr/bin/python3.12" ]; then
  581. sudo alternatives --install /usr/bin/python3 python3 /usr/bin/python3.12 1
  582. sudo alternatives --set python3 /usr/bin/python3.12 || {
  583. echo "警告:无法设置 Python 3.12 为默认版本,但将继续安装..."
  584. }
  585. else
  586. echo "警告:未找到 Python 3.12,将使用系统默认的 Python 版本..."
  587. fi
  588. echo "系统依赖安装完成"
  589. }
  590. # 配置 PostgreSQL
  591. setup_database() {
  592. echo "配置 PostgreSQL 数据库..."
  593. # 确保 PostgreSQL 数据目录存在
  594. if [ ! -d "/var/lib/pgsql/data" ]; then
  595. sudo mkdir -p /var/lib/pgsql/data
  596. sudo chown postgres:postgres /var/lib/pgsql/data
  597. fi
  598. # 确 PostgreSQL 已初始化
  599. if [ ! -f /var/lib/pgsql/data/PG_VERSION ]; then
  600. echo "初始化 PostgreSQL 数据库..."
  601. # 使用 -E UTF8 显式指定编码,并使用 postgres 用户执行命令
  602. sudo -u postgres /usr/bin/postgresql-setup --initdb
  603. # 等待初始化完成
  604. sleep 5
  605. fi
  606. # 确保 PostgreSQL 服务已启动
  607. if ! systemctl is-active --quiet postgresql; then
  608. echo "启动 PostgreSQL 服务..."
  609. sudo systemctl start postgresql
  610. # 予服务足够的启动时间
  611. sleep 10
  612. fi
  613. # 验证 PostgreSQL 是否正在运行
  614. if ! pg_isready -q; then
  615. echo "错误:PostgreSQL 服务未能正确启动"
  616. sudo systemctl status postgresql
  617. exit 1
  618. fi
  619. # 修改 PostgreSQL 认证配置
  620. echo "配置 PostgreSQL 认证方式..."
  621. sudo cp /var/lib/pgsql/data/pg_hba.conf /var/lib/pgsql/data/pg_hba.conf.bak
  622. # 使用更安全的方式修改 pg_hba.conf
  623. sudo tee /var/lib/pgsql/data/pg_hba.conf > /dev/null <<EOF
  624. # TYPE DATABASE USER ADDRESS METHOD
  625. local all postgres trust
  626. local all all trust
  627. host all all 127.0.0.1/32 trust
  628. host all all ::1/128 trust
  629. EOF
  630. # 重启 PostgreSQL 服务以应用新配置
  631. sudo systemctl restart postgresql
  632. # 等待服务完全启动
  633. echo "等待 PostgreSQL 重新启动..."
  634. sleep 10
  635. # 再次验证服务状态
  636. if ! pg_isready -q; then
  637. echo "错误:PostgreSQL 服务重启后未能正确运行"
  638. sudo systemctl status postgresql
  639. exit 1
  640. fi
  641. # 设置 postgres 用户密码 (使用 trust 认证,无需密码)
  642. echo "设置 postgres 用户密码..."
  643. sudo -u postgres psql -c "ALTER USER postgres WITH PASSWORD 'postgres';"
  644. # 创建数据库和用户
  645. echo "创建数据库和用户..."
  646. sudo -u postgres psql <<EOF
  647. DROP DATABASE IF EXISTS $DB_NAME;
  648. DROP USER IF EXISTS $DB_USER;
  649. CREATE DATABASE $DB_NAME;
  650. CREATE USER $DB_USER WITH PASSWORD '$DB_PASS';
  651. ALTER ROLE $DB_USER SET client_encoding TO 'utf8';
  652. ALTER ROLE $DB_USER SET default_transaction_isolation TO 'read committed';
  653. ALTER ROLE $DB_USER SET timezone TO 'UTC';
  654. GRANT ALL PRIVILEGES ON DATABASE $DB_NAME TO $DB_USER;
  655. \c $DB_NAME
  656. GRANT ALL ON SCHEMA public TO $DB_USER;
  657. EOF
  658. # 修改回 md5 认证
  659. sudo sed -i 's/trust/md5/g' /var/lib/pgsql/data/pg_hba.conf
  660. # 重启 PostgreSQL 使新配置生效
  661. sudo systemctl restart postgresql
  662. echo "数据库配置完成"
  663. }
  664. # 安装 NetBox
  665. install_netbox() {
  666. echo "安装 NetBox..."
  667. # 确保基础目录存在
  668. sudo mkdir -p "$BASE_DIR"
  669. # 克隆最新的 NetBox 代码
  670. if [ ! -d "$NETBOX_DIR" ]; then
  671. git clone https://github.com/netbox-community/netbox.git "$NETBOX_DIR"
  672. fi
  673. # 确保配置目录存在
  674. sudo mkdir -p "$NETBOX_CONFIG_DIR"
  675. # 创建并激活虚拟环境
  676. python3.12 -m venv "$VENV_DIR"
  677. source "$VENV_DIR/bin/activate"
  678. # 升级包管理工具
  679. pip install --upgrade pip wheel setuptools
  680. # 安装 gunicorn
  681. pip install gunicorn
  682. # 安装 NetBox 依赖
  683. cd "$NETBOX_DIR"
  684. pip install -r requirements.txt
  685. # 设置目录权限
  686. sudo chown -R netbox:netbox "$NETBOX_DIR"
  687. sudo chown -R netbox:netbox "$VENV_DIR"
  688. sudo chmod -R 755 "$NETBOX_DIR"
  689. sudo chmod -R 755 "$VENV_DIR"
  690. # 确保 gunicorn 可执行
  691. sudo chmod +x "$VENV_DIR/bin/gunicorn"
  692. sudo chmod +x "$VENV_DIR/bin/python"
  693. }
  694. # 配置 NetBox
  695. configure_netbox() {
  696. echo "配置 NetBox..."
  697. # 配置文件路径
  698. CONFIG_FILE="$NETBOX_CONFIG_DIR/configuration.py"
  699. EXAMPLE_CONFIG="$NETBOX_CONFIG_DIR/configuration.example.py"
  700. # 确保配置目录存在
  701. sudo mkdir -p "$NETBOX_CONFIG_DIR"
  702. # 如果找不到示例配置文件,尝试其他位置
  703. if [ ! -f "$EXAMPLE_CONFIG" ]; then
  704. ALTERNATE_PATHS=(
  705. "$NETBOX_DIR/netbox/configuration.example.py"
  706. "$NETBOX_DIR/configuration.example.py"
  707. "$NETBOX_CONFIG_DIR/configuration.example.py"
  708. )
  709. for path in "${ALTERNATE_PATHS[@]}"; do
  710. if [ -f "$path" ]; then
  711. EXAMPLE_CONFIG="$path"
  712. echo "找到示例配置文件:$EXAMPLE_CONFIG"
  713. break
  714. fi
  715. done
  716. fi
  717. if [ ! -f "$CONFIG_FILE" ]; then
  718. echo "正在创建配置文件..."
  719. # 直接创建配置文件,而不是复制示例文件
  720. sudo tee "$CONFIG_FILE" > /dev/null <<EOF
  721. import os
  722. import platform
  723. # 生成随机密钥
  724. SECRET_KEY = '$(python3 -c "import secrets; print(secrets.token_urlsafe(50))")'
  725. # 数据库配置
  726. DATABASE = {
  727. 'NAME': '$DB_NAME',
  728. 'USER': '$DB_USER',
  729. 'PASSWORD': '$DB_PASS',
  730. 'HOST': 'localhost',
  731. 'PORT': '5432',
  732. 'CONN_MAX_AGE': 300,
  733. }
  734. # Redis 配置
  735. REDIS = {
  736. 'tasks': {
  737. 'HOST': 'localhost',
  738. 'PORT': 6379,
  739. 'PASSWORD': '',
  740. 'DATABASE': 0,
  741. 'SSL': False,
  742. },
  743. 'caching': {
  744. 'HOST': 'localhost',
  745. 'PORT': 6379,
  746. 'PASSWORD': '',
  747. 'DATABASE': 1,
  748. 'SSL': False,
  749. }
  750. }
  751. # 允许所有主机访问
  752. ALLOWED_HOSTS = ['*']
  753. # 设置时区
  754. TIME_ZONE = 'Asia/Shanghai'
  755. EOF
  756. fi
  757. # 设置配置文件权限
  758. sudo chown -R netbox:netbox "$NETBOX_CONFIG_DIR"
  759. sudo chmod -R 755 "$NETBOX_CONFIG_DIR"
  760. # 激活虚拟环境
  761. source "$VENV_DIR/bin/activate"
  762. # 执行数据库迁移
  763. echo "执行数据库迁移..."
  764. cd "$NETBOX_DIR/netbox"
  765. python3 manage.py migrate
  766. # 创建超级用户
  767. echo "创建超级用户..."
  768. DJANGO_SUPERUSER_USERNAME=admin \
  769. DJANGO_SUPERUSER_EMAIL=admin@example.com \
  770. DJANGO_SUPERUSER_PASSWORD=admin \
  771. python3 manage.py createsuperuser --noinput || {
  772. echo "警告:创建超级用户失败,可能已存在。继续安装..."
  773. }
  774. # 收集静态文件
  775. echo "收集静态文件..."
  776. python3 manage.py collectstatic --no-input
  777. # 验证数据库连接
  778. echo "验证数据库连接..."
  779. python3 manage.py check || {
  780. echo "警告:数据库检查失败,请检查配置..."
  781. return 1
  782. }
  783. }
  784. # 配置系统服务
  785. setup_services() {
  786. echo "配置系统服务..."
  787. # 创建 netbox 用户和组
  788. sudo useradd -r -s /bin/false netbox || true
  789. # 创建并设置必要的目录权限
  790. sudo mkdir -p /var/run/netbox
  791. sudo mkdir -p /var/log/netbox
  792. sudo chown -R netbox:netbox /var/run/netbox
  793. sudo chown -R netbox:netbox /var/log/netbox
  794. sudo chmod 755 /var/run/netbox
  795. sudo chmod 755 /var/log/netbox
  796. # 设置目录权限
  797. sudo chown -R netbox:netbox "$NETBOX_DIR"
  798. sudo chown -R netbox:netbox "$VENV_DIR"
  799. sudo chmod -R 755 "$NETBOX_DIR"
  800. sudo chmod -R 755 "$VENV_DIR"
  801. # 确保 gunicorn 和 python 可执行
  802. sudo chmod +x "$VENV_DIR/bin/gunicorn"
  803. sudo chmod +x "$VENV_DIR/bin/python"
  804. # 配置 Gunicorn 服务
  805. sudo tee /etc/systemd/system/netbox.service <<EOF
  806. [Unit]
  807. Description=NetBox WSGI Service
  808. Documentation=https://netbox.readthedocs.io/
  809. After=network.target postgresql.service redis.service
  810. Wants=postgresql.service redis.service
  811. [Service]
  812. Type=simple
  813. User=netbox
  814. Group=netbox
  815. RuntimeDirectory=netbox
  816. PIDFile=/var/run/netbox/netbox.pid
  817. WorkingDirectory=$NETBOX_DIR/netbox
  818. Environment="PATH=$VENV_DIR/bin:/usr/local/bin:/usr/bin:/bin"
  819. Environment="PYTHONPATH=$NETBOX_DIR/netbox"
  820. Environment="HOME=/home/netbox"
  821. Environment="USER=netbox"
  822. ExecStart=/usr/bin/env $VENV_DIR/bin/gunicorn \\
  823. --pid /var/run/netbox/netbox.pid \\
  824. --bind 127.0.0.1:8001 \\
  825. --workers 4 \\
  826. --timeout 300 \\
  827. --access-logfile /var/log/netbox/access.log \\
  828. --error-logfile /var/log/netbox/error.log \\
  829. netbox.wsgi:application
  830. Restart=always
  831. RestartSec=30
  832. [Install]
  833. WantedBy=multi-user.target
  834. EOF
  835. # 重新加载服务
  836. sudo systemctl daemon-reload
  837. sudo systemctl enable --now redis postgresql nginx netbox
  838. # 等待服务启动
  839. echo "等待服务启动..."
  840. sleep 10
  841. # 检查服务状态和日志
  842. echo "检查服务状态..."
  843. sudo systemctl status netbox --no-pager
  844. if ! systemctl is-active --quiet netbox; then
  845. echo "NetBox 服务启动失败,检查日志..."
  846. sudo journalctl -u netbox --no-pager | tail -n 50
  847. sudo cat /var/log/netbox/error.log || true
  848. fi
  849. # 配置 Nginx
  850. echo "配置 Nginx..."
  851. # 删除所有默认配置
  852. sudo rm -f /etc/nginx/conf.d/*.conf
  853. sudo tee /etc/nginx/conf.d/netbox.conf <<EOF
  854. server {
  855. listen 80 default_server;
  856. listen [::]:80 default_server;
  857. server_name _;
  858. client_max_body_size 25m;
  859. # 修正静态文件路径
  860. location /static/ {
  861. alias $NETBOX_DIR/netbox/static/;
  862. access_log off;
  863. expires 30d;
  864. }
  865. location / {
  866. proxy_pass http://127.0.0.1:8001;
  867. proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
  868. proxy_set_header X-Real-IP \$remote_addr;
  869. proxy_set_header Host \$http_host;
  870. proxy_set_header X-Forwarded-Proto \$scheme;
  871. proxy_redirect off;
  872. proxy_buffering off;
  873. }
  874. }
  875. EOF
  876. # 配置 SELinux(只在 SELinux 启用时执行)
  877. if [ "$(getenforce)" != "Disabled" ]; then
  878. echo "配置 SELinux 权限..."
  879. sudo setsebool -P httpd_can_network_connect 1
  880. sudo chcon -Rt httpd_sys_content_t "$NETBOX_DIR/netbox/static/" || true
  881. else
  882. echo "SELinux 已禁用,跳过 SELinux 配置"
  883. fi
  884. # 确保 nginx 用户有权限访问静态文件
  885. sudo chown -R nginx:nginx $NETBOX_DIR/netbox/static
  886. sudo chmod -R 755 $NETBOX_DIR/netbox/static
  887. # 测试 Nginx 配置
  888. sudo nginx -t
  889. # 重启 Nginx 服务
  890. sudo systemctl restart nginx
  891. }
  892. # 配置 Redis
  893. setup_redis() {
  894. echo "配置 Redis..."
  895. # 确保 Redis 已安装
  896. if ! command -v redis-server &> /dev/null; then
  897. echo "安装 Redis..."
  898. sudo dnf install -y redis
  899. fi
  900. # 备份并修改 Redis 配置
  901. if [ -f /etc/redis.conf ]; then
  902. sudo cp /etc/redis.conf /etc/redis.conf.bak
  903. # 修改 Redis 配置
  904. sudo tee /etc/redis.conf > /dev/null <<EOF
  905. bind 127.0.0.1
  906. port 6379
  907. daemonize yes
  908. supervised systemd
  909. dir /var/lib/redis
  910. pidfile /var/run/redis/redis.pid
  911. logfile /var/log/redis/redis.log
  912. EOF
  913. # 创建必要的目录
  914. sudo mkdir -p /var/log/redis
  915. sudo mkdir -p /var/run/redis
  916. # 设置权限
  917. sudo chown -R redis:redis /var/lib/redis
  918. sudo chown -R redis:redis /var/log/redis
  919. sudo chown -R redis:redis /var/run/redis
  920. sudo chmod 755 /var/lib/redis
  921. sudo chmod 755 /var/log/redis
  922. sudo chmod 755 /var/run/redis
  923. fi
  924. # 重启 Redis 服务
  925. sudo systemctl enable redis
  926. sudo systemctl restart redis
  927. # 等待 Redis 启动并验证
  928. echo "等待 Redis 启动..."
  929. for i in {1..30}; do
  930. if redis-cli ping &>/dev/null; then
  931. echo "Redis 已成功启动"
  932. break
  933. fi
  934. if [ $i -eq 30 ]; then
  935. echo "Redis 启动失败,请检查日志: sudo journalctl -u redis"
  936. exit 1
  937. fi
  938. sleep 1
  939. done
  940. }
  941. # 主函数
  942. main() {
  943. echo "开始安装 NetBox..."
  944. # 询问是否需要清理
  945. read -p "是否清理现有安装?(y/n) " -n 1 -r
  946. echo
  947. if [[ $REPLY =~ ^[Yy]$ ]]; then
  948. cleanup_services
  949. fi
  950. check_dependencies
  951. setup_redis
  952. setup_database
  953. install_netbox
  954. configure_netbox
  955. setup_services
  956. echo "NetBox 安装成功完成!"
  957. echo "请使用以下凭据访问 NetBox:"
  958. echo "URL: http://your-server-ip"
  959. echo "用户名: admin"
  960. echo "密码: admin"
  961. echo "请务必在首次登录后修改密码!"
  962. echo "注意:如果无法访问,请确保已配置防火墙允许 HTTP 访问(端口 80)"
  963. }
  964. # 执行主函数
  965. main