一键安装脚本Netbox.md 16 KB


title: 一键安装脚本Netbox date: 2024-12-02T14:00:00+08:00

lastmod: 2024-12-02T14:01:01+08:00

一键安装脚本Netbox

  系统环境:Centos9

  文件路径:home

#!/bin/bash

# NetBox 一键安装脚本
# 适用于 CentOS 9 Stream
# 作者:Claude
# 版本:1.0.1

# 严格模式
set -euo pipefail
IFS=$'\n\t'

# 定义变量
BASE_DIR="/home"
NETBOX_DIR="$BASE_DIR/netbox"
VENV_DIR="$BASE_DIR/venv"
NETBOX_CONFIG_DIR="$NETBOX_DIR/netbox/netbox"
LOG_FILE="$BASE_DIR/netbox_install.log"
DB_NAME="netbox"
DB_USER="netbox"
DB_PASS="your_secure_password"

# 配置日志
exec 1> >(tee -a "$LOG_FILE") 2>&1
echo "开始安装 NetBox - $(date)"

# 错误处理
error_handler() {
    local line_no=$1
    echo "错误发生在第 ${line_no} 行"
    exit 1
}
trap 'error_handler ${LINENO}' ERR

# 清理函数
cleanup_services() {
    echo "清理现有服务和数据..."
  
    echo "停止服务..."
    sudo systemctl stop netbox nginx redis postgresql || true
  
    echo "清理运行时目录..."
    sudo rm -rf /var/run/netbox/* || true
  
    echo "清理 PostgreSQL 数据..."
    if [ -d "/var/lib/pgsql/data" ]; then
        sudo -u postgres dropdb netbox || true
        sudo -u postgres dropuser netbox || true
    fi
  
    echo "清理 NetBox 目录..."
    sudo rm -rf "$NETBOX_DIR" || true
  
    echo "清理 Python 虚拟环境..."
    sudo rm -rf "$VENV_DIR" || true
  
    echo "清理日志文件..."
    sudo rm -f /var/log/netbox*.log || true
  
    echo "清理 Redis 数据"
    sudo systemctl stop redis
    sudo rm -rf /var/lib/redis/* || true
  
    echo "清理 nginx 配置"
    sudo rm -f /etc/nginx/conf.d/netbox.conf || true
  
    echo "清理系统服务配置"
    sudo rm -f /etc/systemd/system/netbox.service || true
  
    echo "重新加载系统服务"
    sudo systemctl daemon-reload
  
    echo "清理完成"
}

# 检查依赖
check_dependencies() {
    echo "检查并安装系统依赖..."
  
    # 添加必要的仓库
    sudo dnf install -y epel-release
    sudo dnf config-manager --set-enabled crb
  
    # 更新系统
    sudo dnf update -y
  
    # 安装开发工具组
    sudo dnf groupinstall -y "Development Tools"
  
    # 安装 SELinux 相关依赖
    echo "安装 SELinux 依赖..."
    sudo dnf install -y \
        policycoreutils-python-utils \
        python3-policycoreutils \
        python3-libselinux \
        python3-libsemanage \
        python3-setools \
        setroubleshoot-server \
        setools-console
  
    # 安装其他必要依赖
    echo "安装其他系统依赖..."
    sudo dnf install -y \
        python3.12 \
        python3.12-pip \
        python3.12-devel \
        postgresql-server \
        postgresql-contrib \
        postgresql-devel \
        nginx \
        redis \
        git \
        gcc \
        libpq-devel \
        libffi-devel \
        openssl-devel \
        libxml2-devel \
        libxslt-devel \
        libjpeg-devel \
        zlib-devel
      
    # 修改 Python 3.12 设置部分
    if [ -f "/usr/bin/python3.12" ]; then
        sudo alternatives --install /usr/bin/python3 python3 /usr/bin/python3.12 1
        sudo alternatives --set python3 /usr/bin/python3.12 || {
            echo "警告:无法设置 Python 3.12 为默认版本,但将继续安装..."
        }
    else
        echo "警告:未找到 Python 3.12,将使用系统默认的 Python 版本..."
    fi
  
    echo "系统依赖安装完成"
}

# 配置 PostgreSQL
setup_database() {
    echo "配置 PostgreSQL 数据库..."
  
    # 确保 PostgreSQL 数据目录存在
    if [ ! -d "/var/lib/pgsql/data" ]; then
        sudo mkdir -p /var/lib/pgsql/data
        sudo chown postgres:postgres /var/lib/pgsql/data
    fi
  
    # 确 PostgreSQL 已初始化
    if [ ! -f /var/lib/pgsql/data/PG_VERSION ]; then
        echo "初始化 PostgreSQL 数据库..."
        # 使用 -E UTF8 显式指定编码,并使用 postgres 用户执行命令
        sudo -u postgres /usr/bin/postgresql-setup --initdb
      
        # 等待初始化完成
        sleep 5
    fi
  
    # 确保 PostgreSQL 服务已启动
    if ! systemctl is-active --quiet postgresql; then
        echo "启动 PostgreSQL 服务..."
        sudo systemctl start postgresql
        # 予服务足够的启动时间
        sleep 10
    fi
  
    # 验证 PostgreSQL 是否正在运行
    if ! pg_isready -q; then
        echo "错误:PostgreSQL 服务未能正确启动"
        sudo systemctl status postgresql
        exit 1
    fi
  
    # 修改 PostgreSQL 认证配置
    echo "配置 PostgreSQL 认证方式..."
    sudo cp /var/lib/pgsql/data/pg_hba.conf /var/lib/pgsql/data/pg_hba.conf.bak
  
    # 使用更安全的方式修改 pg_hba.conf
    sudo tee /var/lib/pgsql/data/pg_hba.conf > /dev/null <<EOF
# TYPE  DATABASE        USER            ADDRESS                 METHOD
local   all            postgres                                trust
local   all            all                                     trust
host    all            all             127.0.0.1/32           trust
host    all            all             ::1/128                 trust
EOF

    # 重启 PostgreSQL 服务以应用新配置
    sudo systemctl restart postgresql
  
    # 等待服务完全启动
    echo "等待 PostgreSQL 重新启动..."
    sleep 10
  
    # 再次验证服务状态
    if ! pg_isready -q; then
        echo "错误:PostgreSQL 服务重启后未能正确运行"
        sudo systemctl status postgresql
        exit 1
    fi
  
    # 设置 postgres 用户密码 (使用 trust 认证,无需密码)
    echo "设置 postgres 用户密码..."
    sudo -u postgres psql -c "ALTER USER postgres WITH PASSWORD 'postgres';"
  
    # 创建数据库和用户
    echo "创建数据库和用户..."
    sudo -u postgres psql <<EOF
DROP DATABASE IF EXISTS $DB_NAME;
DROP USER IF EXISTS $DB_USER;
CREATE DATABASE $DB_NAME;
CREATE USER $DB_USER WITH PASSWORD '$DB_PASS';
ALTER ROLE $DB_USER SET client_encoding TO 'utf8';
ALTER ROLE $DB_USER SET default_transaction_isolation TO 'read committed';
ALTER ROLE $DB_USER SET timezone TO 'UTC';
GRANT ALL PRIVILEGES ON DATABASE $DB_NAME TO $DB_USER;
\c $DB_NAME
GRANT ALL ON SCHEMA public TO $DB_USER;
EOF
  
    # 修改回 md5 认证
    sudo sed -i 's/trust/md5/g' /var/lib/pgsql/data/pg_hba.conf
  
    # 重启 PostgreSQL 使新配置生效
    sudo systemctl restart postgresql
  
    echo "数据库配置完成"
}

# 安装 NetBox
install_netbox() {
    echo "安装 NetBox..."
  
    # 确保基础目录存在
    sudo mkdir -p "$BASE_DIR"
  
    # 克隆最新的 NetBox 代码
    if [ ! -d "$NETBOX_DIR" ]; then
        git clone https://github.com/netbox-community/netbox.git "$NETBOX_DIR"
    fi
  
    # 确保配置目录存在
    sudo mkdir -p "$NETBOX_CONFIG_DIR"
  
    # 创建并激活虚拟环境
    python3.12 -m venv "$VENV_DIR"
    source "$VENV_DIR/bin/activate"
  
    # 升级包管理工具
    pip install --upgrade pip wheel setuptools

    # 安装 gunicorn
    pip install gunicorn
  
    # 安装 NetBox 依赖
    cd "$NETBOX_DIR"
    pip install -r requirements.txt

    # 设置目录权限
    sudo chown -R netbox:netbox "$NETBOX_DIR"
    sudo chown -R netbox:netbox "$VENV_DIR"
    sudo chmod -R 755 "$NETBOX_DIR"
    sudo chmod -R 755 "$VENV_DIR"
  
    # 确保 gunicorn 可执行
    sudo chmod +x "$VENV_DIR/bin/gunicorn"
    sudo chmod +x "$VENV_DIR/bin/python"
}

# 配置 NetBox
configure_netbox() {
    echo "配置 NetBox..."
  
    # 配置文件路径
    CONFIG_FILE="$NETBOX_CONFIG_DIR/configuration.py"
    EXAMPLE_CONFIG="$NETBOX_CONFIG_DIR/configuration.example.py"
  
    # 确保配置目录存在
    sudo mkdir -p "$NETBOX_CONFIG_DIR"
  
    # 如果找不到示例配置文件,尝试其他位置
    if [ ! -f "$EXAMPLE_CONFIG" ]; then
        ALTERNATE_PATHS=(
            "$NETBOX_DIR/netbox/configuration.example.py"
            "$NETBOX_DIR/configuration.example.py"
            "$NETBOX_CONFIG_DIR/configuration.example.py"
        )
      
        for path in "${ALTERNATE_PATHS[@]}"; do
            if [ -f "$path" ]; then
                EXAMPLE_CONFIG="$path"
                echo "找到示例配置文件:$EXAMPLE_CONFIG"
                break
            fi
        done
    fi
  
    if [ ! -f "$CONFIG_FILE" ]; then
        echo "正在创建配置文件..."
        # 直接创建配置文件,而不是复制示例文件
        sudo tee "$CONFIG_FILE" > /dev/null <<EOF
import os
import platform

# 生成随机密钥
SECRET_KEY = '$(python3 -c "import secrets; print(secrets.token_urlsafe(50))")'

# 数据库配置
DATABASE = {
    'NAME': '$DB_NAME',
    'USER': '$DB_USER',
    'PASSWORD': '$DB_PASS',
    'HOST': 'localhost',
    'PORT': '5432',
    'CONN_MAX_AGE': 300,
}

# Redis 配置
REDIS = {
    'tasks': {
        'HOST': 'localhost',
        'PORT': 6379,
        'PASSWORD': '',
        'DATABASE': 0,
        'SSL': False,
    },
    'caching': {
        'HOST': 'localhost',
        'PORT': 6379,
        'PASSWORD': '',
        'DATABASE': 1,
        'SSL': False,
    }
}

# 允许所有主机访问
ALLOWED_HOSTS = ['*']

# 设置时区
TIME_ZONE = 'Asia/Shanghai'
EOF
    fi
  
    # 设置配置文件权限
    sudo chown -R netbox:netbox "$NETBOX_CONFIG_DIR"
    sudo chmod -R 755 "$NETBOX_CONFIG_DIR"
  
    # 激活虚拟环境
    source "$VENV_DIR/bin/activate"
  
    # 执行数据库迁移
    echo "执行数据库迁移..."
    cd "$NETBOX_DIR/netbox"
    python3 manage.py migrate
  
    # 创建超级用户
    echo "创建超级用户..."
    DJANGO_SUPERUSER_USERNAME=admin \
    DJANGO_SUPERUSER_EMAIL=admin@example.com \
    DJANGO_SUPERUSER_PASSWORD=admin \
    python3 manage.py createsuperuser --noinput || {
        echo "警告:创建超级用户失败,可能已存在。继续安装..."
    }
  
    # 收集静态文件
    echo "收集静态文件..."
    python3 manage.py collectstatic --no-input
  
    # 验证数据库连接
    echo "验证数据库连接..."
    python3 manage.py check || {
        echo "警告:数据库检查失败,请检查配置..."
        return 1
    }
}

# 配置系统服务
setup_services() {
    echo "配置系统服务..."
  
    # 创建 netbox 用户和组
    sudo useradd -r -s /bin/false netbox || true
  
    # 创建并设置必要的目录权限
    sudo mkdir -p /var/run/netbox
    sudo mkdir -p /var/log/netbox
    sudo chown -R netbox:netbox /var/run/netbox
    sudo chown -R netbox:netbox /var/log/netbox
    sudo chmod 755 /var/run/netbox
    sudo chmod 755 /var/log/netbox
  
    # 设置目录权限
    sudo chown -R netbox:netbox "$NETBOX_DIR"
    sudo chown -R netbox:netbox "$VENV_DIR"
    sudo chmod -R 755 "$NETBOX_DIR"
    sudo chmod -R 755 "$VENV_DIR"
  
    # 确保 gunicorn 和 python 可执行
    sudo chmod +x "$VENV_DIR/bin/gunicorn"
    sudo chmod +x "$VENV_DIR/bin/python"
  
    # 配置 Gunicorn 服务
    sudo tee /etc/systemd/system/netbox.service <<EOF
[Unit]
Description=NetBox WSGI Service
Documentation=https://netbox.readthedocs.io/
After=network.target postgresql.service redis.service
Wants=postgresql.service redis.service

[Service]
Type=simple
User=netbox
Group=netbox
RuntimeDirectory=netbox
PIDFile=/var/run/netbox/netbox.pid
WorkingDirectory=$NETBOX_DIR/netbox
Environment="PATH=$VENV_DIR/bin:/usr/local/bin:/usr/bin:/bin"
Environment="PYTHONPATH=$NETBOX_DIR/netbox"
Environment="HOME=/home/netbox"
Environment="USER=netbox"
ExecStart=/usr/bin/env $VENV_DIR/bin/gunicorn \\
    --pid /var/run/netbox/netbox.pid \\
    --bind 127.0.0.1:8001 \\
    --workers 4 \\
    --timeout 300 \\
    --access-logfile /var/log/netbox/access.log \\
    --error-logfile /var/log/netbox/error.log \\
    netbox.wsgi:application
Restart=always
RestartSec=30

[Install]
WantedBy=multi-user.target
EOF

    # 重新加载服务
    sudo systemctl daemon-reload
    sudo systemctl enable --now redis postgresql nginx netbox
  
    # 等待服务启动
    echo "等待服务启动..."
    sleep 10
  
    # 检查服务状态和日志
    echo "检查服务状态..."
    sudo systemctl status netbox --no-pager
  
    if ! systemctl is-active --quiet netbox; then
        echo "NetBox 服务启动失败,检查日志..."
        sudo journalctl -u netbox --no-pager | tail -n 50
        sudo cat /var/log/netbox/error.log || true
    fi
  
    # 配置 Nginx
    echo "配置 Nginx..."
  
    # 删除所有默认配置
    sudo rm -f /etc/nginx/conf.d/*.conf
  
    sudo tee /etc/nginx/conf.d/netbox.conf <<EOF
server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name _;

    client_max_body_size 25m;

    # 修正静态文件路径
    location /static/ {
        alias $NETBOX_DIR/netbox/static/;
        access_log off;
        expires 30d;
    }

    location / {
        proxy_pass http://127.0.0.1:8001;
        proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
        proxy_set_header X-Real-IP \$remote_addr;
        proxy_set_header Host \$http_host;
        proxy_set_header X-Forwarded-Proto \$scheme;
        proxy_redirect off;
        proxy_buffering off;
    }
}
EOF

    # 配置 SELinux(只在 SELinux 启用时执行)
    if [ "$(getenforce)" != "Disabled" ]; then
        echo "配置 SELinux 权限..."
        sudo setsebool -P httpd_can_network_connect 1
        sudo chcon -Rt httpd_sys_content_t "$NETBOX_DIR/netbox/static/" || true
    else
        echo "SELinux 已禁用,跳过 SELinux 配置"
    fi

    # 确保 nginx 用户有权限访问静态文件
    sudo chown -R nginx:nginx $NETBOX_DIR/netbox/static
    sudo chmod -R 755 $NETBOX_DIR/netbox/static

    # 测试 Nginx 配置
    sudo nginx -t

    # 重启 Nginx 服务
    sudo systemctl restart nginx
}

# 配置 Redis
setup_redis() {
    echo "配置 Redis..."
  
    # 确保 Redis 已安装
    if ! command -v redis-server &> /dev/null; then
        echo "安装 Redis..."
        sudo dnf install -y redis
    fi
  
    # 备份并修改 Redis 配置
    if [ -f /etc/redis.conf ]; then
        sudo cp /etc/redis.conf /etc/redis.conf.bak
      
        # 修改 Redis 配置
        sudo tee /etc/redis.conf > /dev/null <<EOF
bind 127.0.0.1
port 6379
daemonize yes
supervised systemd
dir /var/lib/redis
pidfile /var/run/redis/redis.pid
logfile /var/log/redis/redis.log
EOF
      
        # 创建必要的目录
        sudo mkdir -p /var/log/redis
        sudo mkdir -p /var/run/redis
      
        # 设置权限
        sudo chown -R redis:redis /var/lib/redis
        sudo chown -R redis:redis /var/log/redis
        sudo chown -R redis:redis /var/run/redis
        sudo chmod 755 /var/lib/redis
        sudo chmod 755 /var/log/redis
        sudo chmod 755 /var/run/redis
    fi
  
    # 重启 Redis 服务
    sudo systemctl enable redis
    sudo systemctl restart redis
  
    # 等待 Redis 启动并验证
    echo "等待 Redis 启动..."
    for i in {1..30}; do
        if redis-cli ping &>/dev/null; then
            echo "Redis 已成功启动"
            break
        fi
        if [ $i -eq 30 ]; then
            echo "Redis 启动失败,请检查日志: sudo journalctl -u redis"
            exit 1
        fi
        sleep 1
    done
}

# 主函数
main() {
    echo "开始安装 NetBox..."
  
    # 询问是否需要清理
    read -p "是否清理现有安装?(y/n) " -n 1 -r
    echo
    if [[ $REPLY =~ ^[Yy]$ ]]; then
        cleanup_services
    fi
  
    check_dependencies
    setup_redis
    setup_database
    install_netbox
    configure_netbox
    setup_services
  
    echo "NetBox 安装成功完成!"
    echo "请使用以下凭据访问 NetBox:"
    echo "URL: http://your-server-ip"
    echo "用户名: admin"
    echo "密码: admin"
    echo "请务必在首次登录后修改密码!"
    echo "注意:如果无法访问,请确保已配置防火墙允许 HTTP 访问(端口 80)"
}

# 执行主函数
main