title: 一键安装脚本Netbox date: 2024-12-02T14:00:00+08:00
系统环境: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