版本比较
标识
- 该行被添加。
- 该行被删除。
- 格式已经改变。
简介
NetBox 是专为网络运维人员管理数据中心资产而打造的开源工具。和 iTop (iTop 是完全基于 ITIL 的工具,CMDB 仅是其中的部分功能)相比,它的功能更聚焦,对应的功能更简洁,并且原生提供了自定义设备组件配置的功能(iTop 需要自定义,当然也更灵活)
中小型规模的使用 NetBox,规模较大且管理要求高的还是推荐 iTop。
与通用CMDB不同,NetBox策划了一个专门满足网络工程师和运营商需求的数据模型。它提供了精心设计的各种对象类型,以最好地满足基础架构设计和文档的需求。这些涵盖了网络技术的所有方面,从 IP 地址管理到布线再到覆盖层等等:
- 分层地区、数据中心和物理位置
- 机架、设备和设备组件
- 线路连接和无线连接管理
- 供电跟踪
- 虚拟线路和提供商
- 虚拟机和群集
- IP 网段、汇聚和地址
- VRF 和 RT
- FHRP组(VRRP,HSRP等)
- AS 编号
- VLAN 和作用域 VLAN 组
- L2VPN 虚拟网络
- 租户分配
联系人管理
架构图
安装步骤
安装环境介绍
- 使用Rocky Linux 9.2 (关闭SE Linux和防火墙)(也适用于RHEL 9系列及其衍生发行版)
- 使用Python 3.9
- 使用PostgreSQL 15
- 使用Redis 6
- NetBox版本:3.5.6
- 硬件配置:建议4C8G以上,100G存储空间。
关闭 Selinux 和防火墙
代码块 | ||
---|---|---|
| ||
systemctl disable --now firewalld sed -i 's/^SELINUX=enforcing$/SELINUX=disabled/' /etc/selinux/config && setenforce 0 dnf install tree vim bash-completion -y # 安装一些工具 |
安装和配置数据库
更具体的数据库安装配置操作可以参考:PGSQL 安装配置指南 https://wiki.waringid.me/x/RAES
代码块 | ||
---|---|---|
| ||
dnf module install postgresql:15 -y
# 指定安装15版本
postgresql-setup --initdb
# 初始化数据库
vim /var/lib/pgsql/data/pg_hba.conf
# "local" is for Unix domain socket connections only
local all all peer
# IPv4 local connections:
host all all 127.0.0.1/32 scram-sha-256
# IPv6 local connections:
host all all ::1/128 scram-sha-256
# 将主机连接的加密方式将ident改为scram-sha-256即可。
systemctl enable --now postgresql
# 启动并设置开机启动
systemctl status postgresql
ss -an | grep 5432
# 查看是否正常启动 |
修改密码并创建数据库
代码块 |
---|
sudo -u postgres psql # 登录到PostgreSQL shell ALTER USER postgres WITH PASSWORD 'waringid.com'; # 运行查询,为默认的PostgreSQL用户“postgres”设置新密码。 CREATE DATABASE netboxdb; # 创建数据库 quit # 退出 |
PS: 优化配置生成器:https://pgtune.leopard.in.ua/
安装和配置 Redis
Redis 更详细的配置可以参照:redis 常用操作指令 https://wiki.waringid.me/x/pgMS
代码块 | ||
---|---|---|
| ||
dnf install redis -y vim /etc/redis/redis.conf requirepass waringid.com # 打开配置文件,找到被注释的requirepass行,修改密码为waringid.com。保存文件并退出 |
代码块 |
---|
systemctl enable --now redis # 配置启动并开机启动 systemctl status redis ss -an | grep 6379 # 验证启动 redis-cli 127.0.0.1:6379> AUTH waringid.com OK 127.0.0.1:6379> ping PONG 127.0.0.1:6379> exit # 输入密码登录验证是否正常 |
前期环境配置
代码块 | ||
---|---|---|
| ||
dnf install gcc libxml2-devel libxslt-devel libffi-devel libpq-devel openssl-devel redhat-rpm-config git -y
# 安装环境,系统默认有Python3.9
useradd -r -d /opt/netbox -s /usr/sbin/nologin netbox
# 创建netbox用户
mkdir -p /opt/netbox; cd /opt/netbox
# 创建netbox所属权限的文件,作为安装主文件夹。并CD过去。
git clone -b master --depth 1 https://github.com/netbox-community/netbox.git .
# 下载最新源代码,如果网络不允许,可以手动下载,上传到服务器。
chown -R netbox:netbox /opt/netbox
cd /opt/netbox/netbox/netbox
# 配置netbox文件夹权限所属。
tree -L 3 /opt/
/opt/
└── netbox
├── base_requirements.txt
├── CHANGELOG.md
├── contrib
│ ├── apache.conf
│ ├── gunicorn.py
│ ├── netbox-housekeeping.service
│ ├── netbox-housekeeping.sh
│ ├── netbox-housekeeping.timer
│ ├── netbox-rq.service
│ ├── netbox.service
│ ├── nginx.conf
│ ├── openapi2.json
│ └── openapi2.yaml
├── CONTRIBUTING.md
├── docs
│ ├── administration
│ ├── configuration
│ ├── customization
│ ├── development
│ ├── extra.css
│ ├── features
│ ├── getting-started
│ ├── index.md
│ ├── installation
│ ├── integrations
│ ├── introduction.md
│ ├── media
│ ├── models
│ ├── netbox_logo.png
│ ├── netbox_logo.svg
│ ├── plugins
│ ├── reference
│ ├── release-notes
│ └── _theme
├── LICENSE.txt
├── mkdocs.yml
├── netbox
│ ├── circuits
│ ├── core
│ ├── dcim
│ ├── extras
│ ├── generate_secret_key.py
│ ├── ipam
│ ├── manage.py
│ ├── media
│ ├── netbox
│ ├── project-static
│ ├── reports
│ ├── scripts
│ ├── templates
│ ├── tenancy
│ ├── users
│ ├── utilities
│ ├── virtualization
│ └── wireless
├── NOTICE
├── pyproject.toml
├── README.md
├── requirements.txt
├── scripts
│ ├── git-hooks
│ └── verify-bundles.sh
├── SECURITY.md
└── upgrade.sh
# 查看当前目录结构 |
生成并配置密钥
代码块 |
---|
cd /opt/netbox/netbox/netbox # 确保进入到此目录 sudo -u netbox cp configuration_example.py configuration.py # 创建配置文件,指定用户权限 sudo -u netbox python3 ../generate_secret_key.py # 生成密钥,生成的密钥示例:SOGo0)YKa^RMGs&b=4p1AtnB-5nZq(!N#2-cah$q972DPCf&%F sudo -u netbox vim configuration.py SECRET_KEY = 'SOGo0)YKa^RMGs&b=4p1AtnB-5nZq(!N#2-cah$q972DPCf&%F' # 打开配置文件,将生成的密钥写入进去。 |
配置数据库连接
代码块 |
---|
cd /opt/netbox/netbox/netbox
sudo -u netbox vim configuration.py
ALLOWED_HOSTS = ["*"]
# 代表可以通过任意域名访问Netbox
DATABASE = {
'ENGINE': 'django.db.backends.postgresql', # Database engine
'NAME': 'netboxdb', # 配置数据库名字
'USER': 'postgres', # 数据库用户
'PASSWORD': 'Songxwn.com', # 数据库用户密码
'HOST': 'localhost', # Database server
'PORT': '', # Database port (leave blank for default)
'CONN_MAX_AGE': 300, # Max database connection age
}
REDIS = {
'tasks': {
'HOST': 'localhost',
'PORT': 6379,
'USERNAME': '',
'PASSWORD': 'waringid.com', #配置数据库密码
'DATABASE': 0,
'SSL': False,
},
'caching': {
'HOST': 'localhost',
'PORT': 6379,
'USERNAME': '',
'PASSWORD': 'Songxwn.com', #配置数据库密码
'DATABASE': 1,
'SSL': False,
}
}
SECRET_KEY = 'SOGo0)YKa^RMGs&b=4p1AtnB-5nZq(!N#2-cah$q972DPCf&%F'
# 加密密钥
ENABLE_LOCALIZATION = True
# 开启本地化,让一些选项中文。
TIME_ZONE = 'Asia/Shanghai'
# 配置时区
PAGINATE_COUNT = 60
# 配置查看的时候默认分页数量 |
初始化数据库和环境
代码块 |
---|
sed -i 'pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple' /opt/netbox/upgrade.sh # 配置安装环境的时候,使用清华源的pypi。(可不配置) sudo -u netbox /opt/netbox/upgrade.sh # 执行安装,需要较久时间。 Completed. Removing expired user sessions (python3 netbox/manage.py clearsessions)... Clearing the cache (python3 netbox/manage.py clearcache)... Cache has been cleared. Upgrade complete! Don't forget to restart the NetBox services: > sudo systemctl restart netbox netbox-rq # 出现以上字符代表成功。 |
创建管理员账户
代码块 |
---|
source /opt/netbox/venv/bin/activate
# 进入虚拟环境
cd /opt/netbox/netbox
python3 manage.py createsuperuser
Username (leave blank to use 'root'): admin
Email address: me@songxwn.com
Password:
Password (again):
Superuser created successfully.
# 创建管理员 admin,输入邮箱和两遍密码。 |
配置每天的清理任务
代码块 |
---|
sudo ln -s /opt/netbox/contrib/netbox-housekeeping.sh /etc/cron.daily/netbox-housekeeping |
配置Gunicorn WSGI
Gunicorn 是一个 Python 的 WSGI HTTP 服务器。
代码块 |
---|
sudo -u netbox cp /opt/netbox/contrib/gunicorn.py /opt/netbox/gunicorn.py # 复制创建配置文件 sudo -u netbox vim /opt/netbox/gunicorn.py # 可修改配置文件,更改监听端口,默认8001 cp -v /opt/netbox/contrib/*.service /etc/systemd/system/ # 复制到系统服务 systemctl daemon-reload # 重新加载系统服务 systemctl enable --now netbox netbox-rq # 配置启动并开机启动 systemctl status netbox systemctl status netbox-rq # 查看状态 |
配置 nginx 反向代理
代码块 |
---|
dnf install nginx -y # 安装Nginx vim /etc/nginx/conf.d/netbox.conf # 创建配置文件,注意修改netbox.waringid.com 为自己的域名。反向代理到8001端口 server { listen 80; # CHANGE THIS TO YOUR SERVER'S NAME server_name netbox.waringid.com; client_max_body_size 25m; fastcgi_connect_timeout 1200s; fastcgi_send_timeout 1200s; fastcgi_read_timeout 1200s; fastcgi_buffer_size 64k; fastcgi_buffers 4 64k; fastcgi_busy_buffers_size 128k; fastcgi_temp_file_write_size 256k; location /static/ { alias /opt/netbox/netbox/static/; } location / { proxy_pass http://127.0.0.1:8001; proxy_set_header X-Forwarded-Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-Proto $scheme; proxy_connect_timeout 600; proxy_send_timeout 600; proxy_read_timeout 600; send_timeout 600; } } systemctl enable --now nginx # 配置启动并开机启动 systemctl status nginx # 查看状态 |
菜单汉化
文件路径:vim /opt/netbox/netbox/netbox/navigation/menu.py
代码块 | ||
---|---|---|
| ||
from django.utils.translation import gettext as _ from netbox.registry import registry from . import * # # Nav menus # ORGANIZATION_MENU = Menu( label=_('组织机构'), icon_class='mdi mdi-domain', groups=( MenuGroup( label=_('机房'), items=( get_model_item('dcim', 'site', _('数据中心')), get_model_item('dcim', 'region', _('地区')), get_model_item('dcim', 'sitegroup', _('数据中心组')), get_model_item('dcim', 'location', _('具体地点')), ), ), MenuGroup( label=_('机架'), items=( get_model_item('dcim', 'rack', _('机柜')), get_model_item('dcim', 'rackrole', _('机柜角色')), get_model_item('dcim', 'rackreservation', _('预留')), MenuItem( link='dcim:rack_elevation_list', link_text=_('立面图'), permissions=['dcim.view_rack'] ), ), ), MenuGroup( label=_('租凭'), items=( get_model_item('tenancy', 'tenant', _('租户')), get_model_item('tenancy', 'tenantgroup', _('租户组')), ), ), MenuGroup( label=_('联系方式'), items=( get_model_item('tenancy', 'contact', _('联系人')), get_model_item('tenancy', 'contactgroup', _('联系人组')), get_model_item('tenancy', 'contactrole', _('联系人角色')), get_model_item('tenancy', 'contactassignment', _('联系方式分配'), actions=[]), ), ), ), ) DEVICES_MENU = Menu( label=_('设备'), icon_class='mdi mdi-server', groups=( MenuGroup( label=_('Devices'), items=( get_model_item('dcim', 'device', _('设备')), get_model_item('dcim', 'module', _('模块组件')), get_model_item('dcim', 'devicerole', _('设备角色')), get_model_item('dcim', 'platform', _('平台')), get_model_item('dcim', 'virtualchassis', _('虚拟机箱')), get_model_item('dcim', 'virtualdevicecontext', _('Virtual Device Contexts')), ), ), MenuGroup( label=_('类型'), items=( get_model_item('dcim', 'devicetype', _('设备型号')), get_model_item('dcim', 'moduletype', _('模块类型')), get_model_item('dcim', 'manufacturer', _('制造商')), ), ), MenuGroup( label=_('设备组件'), items=( get_model_item('dcim', 'interface', _('接口')), get_model_item('dcim', 'frontport', _('前端口')), get_model_item('dcim', 'rearport', _('后端口')), get_model_item('dcim', 'consoleport', _('Console 端口')), get_model_item('dcim', 'consoleserverport', _('Console 服务器端口')), get_model_item('dcim', 'powerport', _('电力接口')), get_model_item('dcim', 'poweroutlet', _('电源插座PDU')), get_model_item('dcim', 'modulebay', _('模块组件托架')), get_model_item('dcim', 'devicebay', _('设备托架')), get_model_item('dcim', 'inventoryitem', _('库存物品')), get_model_item('dcim', 'inventoryitemrole', _('库存项目角色')), ), ), ), ) CONNECTIONS_MENU = Menu( label=_('连接'), icon_class='mdi mdi-connection', groups=( MenuGroup( label=_('Connections'), items=( get_model_item('dcim', 'cable', _('线缆'), actions=['import']), get_model_item('wireless', 'wirelesslink', _('无线连接')), MenuItem( link='dcim:interface_connections_list', link_text=_('接口连接'), permissions=['dcim.view_interface'] ), MenuItem( link='dcim:console_connections_list', link_text=_('Console 连接'), permissions=['dcim.view_consoleport'] ), MenuItem( link='dcim:power_connections_list', link_text=_('电源连接'), permissions=['dcim.view_powerport'] ), ), ), ), ) WIRELESS_MENU = Menu( label=_('无线'), icon_class='mdi mdi-wifi', groups=( MenuGroup( label=_('Wireless'), items=( get_model_item('wireless', 'wirelesslan', _('无线局域网')), get_model_item('wireless', 'wirelesslangroup', _('无线局域网组')), ), ), ), ) IPAM_MENU = Menu( label=_('IP地址管理'), icon_class='mdi mdi-counter', groups=( MenuGroup( label=_('IP Addresses'), items=( get_model_item('ipam', 'ipaddress', _('IP 地址')), get_model_item('ipam', 'iprange', _('IP 范围')), ), ), MenuGroup( label=_('Prefixes'), items=( get_model_item('ipam', 'prefix', _('IP网段')), get_model_item('ipam', 'role', _('网段和VLAN 角色')), ), ), MenuGroup( label=_('ASNs'), items=( get_model_item('ipam', 'asnrange', _('ASN Ranges')), get_model_item('ipam', 'asn', _('ASNs')), ), ), MenuGroup( label=_('Aggregates'), items=( get_model_item('ipam', 'aggregate', _('Aggregates')), get_model_item('ipam', 'rir', _('RIRs')), ), ), MenuGroup( label=_('VRFs'), items=( get_model_item('ipam', 'vrf', _('VRFs')), get_model_item('ipam', 'routetarget', _('Route Targets')), ), ), MenuGroup( label=_('VLANs'), items=( get_model_item('ipam', 'vlan', _('VLANs')), get_model_item('ipam', 'vlangroup', _('VLAN Groups')), ), ), MenuGroup( label=_('Other'), items=( get_model_item('ipam', 'fhrpgroup', _('FHRP Groups')), get_model_item('ipam', 'servicetemplate', _('Service Templates')), get_model_item('ipam', 'service', _('Services')), ), ), ), ) OVERLAY_MENU = Menu( label=_('网络虚拟化Overlay'), icon_class='mdi mdi-graph-outline', groups=( MenuGroup( label='L2VPNs', items=( get_model_item('ipam', 'l2vpn', _('L2VPNs')), get_model_item('ipam', 'l2vpntermination', _('Terminations')), ), ), ), ) VIRTUALIZATION_MENU = Menu( label=_('裸金属虚拟化'), icon_class='mdi mdi-monitor', groups=( MenuGroup( label=_('Virtual Machines'), items=( get_model_item('virtualization', 'virtualmachine', _('虚拟机')), get_model_item('virtualization', 'vminterface', _('虚拟机接口')), ), ), MenuGroup( label=_('Clusters'), items=( get_model_item('virtualization', 'cluster', _('虚拟化集群')), get_model_item('virtualization', 'clustertype', _('虚拟化集群类型')), get_model_item('virtualization', 'clustergroup', _('集群组')), ), ), ), ) CIRCUITS_MENU = Menu( label=_('线路'), icon_class='mdi mdi-transit-connection-variant', groups=( MenuGroup( label=_('Circuits'), items=( get_model_item('circuits', 'circuit', _('线路')), get_model_item('circuits', 'circuittype', _('线路类型')), ), ), MenuGroup( label=_('Providers'), items=( get_model_item('circuits', 'provider', _('供应商')), get_model_item('circuits', 'provideraccount', _('供应商账号')), get_model_item('circuits', 'providernetwork', _('供应商网络')), ), ), ), ) POWER_MENU = Menu( label=_('电力'), icon_class='mdi mdi-flash', groups=( MenuGroup( label=_('Power'), items=( get_model_item('dcim', 'powerfeed', _('电源线')), get_model_item('dcim', 'powerpanel', _('电源插座')), ), ), ), ) PROVISIONING_MENU = Menu( label=_('设备配置'), icon_class='mdi mdi-file-document-multiple-outline', groups=( MenuGroup( label=_('Configurations'), items=( get_model_item('extras', 'configcontext', _('Config Contexts'), actions=['add']), get_model_item('extras', 'configtemplate', _('Config Templates'), actions=['add']), ), ), ), ) CUSTOMIZATION_MENU = Menu( label=_('自定义'), icon_class='mdi mdi-toolbox-outline', groups=( MenuGroup( label=_('Customization'), items=( get_model_item('extras', 'customfield', _('自定义字段')), get_model_item('extras', 'customlink', _('自定义链接')), get_model_item('extras', 'exporttemplate', _('自定义验证')), get_model_item('extras', 'savedfilter', _('已保存的筛选条件')), get_model_item('extras', 'tag', 'Tags'), get_model_item('extras', 'imageattachment', _('图片附件'), actions=()), ), ), MenuGroup( label=_('Reports & Scripts'), items=( MenuItem( link='extras:report_list', link_text=_('报告'), permissions=['extras.view_report'], buttons=get_model_buttons('extras', "reportmodule", actions=['add']) ), MenuItem( link='extras:script_list', link_text=_('脚本'), permissions=['extras.view_script'], buttons=get_model_buttons('extras', "scriptmodule", actions=['add']) ), ), ), ), ) OPERATIONS_MENU = Menu( label=_('运营'), icon_class='mdi mdi-cogs', groups=( MenuGroup( label=_('Integrations'), items=( get_model_item('core', 'datasource', _('Data Sources')), get_model_item('extras', 'webhook', _('Webhooks')), ), ), MenuGroup( label=_('Jobs'), items=( MenuItem( link='core:job_list', link_text=_('Jobs'), permissions=['core.view_job'], ), ), ), MenuGroup( label=_('Logging'), items=( get_model_item('extras', 'journalentry', _('日记列表'), actions=['import']), get_model_item('extras', 'objectchange', _('操作日志'), actions=[]), ), ), ), ) MENUS = [ ORGANIZATION_MENU, DEVICES_MENU, CONNECTIONS_MENU, WIRELESS_MENU, IPAM_MENU, OVERLAY_MENU, VIRTUALIZATION_MENU, CIRCUITS_MENU, POWER_MENU, PROVISIONING_MENU, CUSTOMIZATION_MENU, OPERATIONS_MENU, ] # # Add plugin menus # for menu in registry['plugins']['menus']: MENUS.append(menu) if registry['plugins']['menu_items']: # Build the default plugins menu groups = [ MenuGroup(label=label, items=items) for label, items in registry['plugins']['menu_items'].items() ] plugins_menu = Menu( label=_("Plugins"), icon_class="mdi mdi-puzzle", groups=groups ) MENUS.append(plugins_menu) |
NetBox CSV导出中文乱码问题
NetBox 在导出CSV的时候,会是使用UTF-8编码,而不是UTF-8-SIG编码。
这样会导致导出的文件,在微软的Excel打开中会乱码。(使用Notepad ++不会)
思路
直接修改Netbox 虚拟环境的 django_tables2 库的默认编码,这样只要不升级或重装此库就不会失效。
修改
代码块 |
---|
vim /opt/netbox/venv/lib/python3.9/site-packages/django_tables2/export/export.py # 修改库文件,路径看自己的实际情况。 FORMATS = { CSV: "text/csv; charset=utf-8-sig", JSON: "application/json", LATEX: "text/plain", ODS: "application/vnd.oasis.opendocument.spreadsheet", TSV: "text/tsv; charset=utf-8", XLS: "application/vnd.ms-excel", XLSX: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", YAML: "text/yaml; charset=utf-8", } 在第37行,直接修改为utf-8-sig,然后重启NetBox即可。 systemctl restart netbox netbox-rq |
参考
目录 |
---|