netboxのセットアップ(dockerでない)

はじめに

netbox.readthedocs.io

DigitalOceanが考案したOSSのIPAM/DCIM Webアプリケーションです。 ブラウザでぽちぽち資産管理ができるようになります。 物理構成と照らし合わせて忠実に管理できるのが特徴です。

IPアドレスや接続情報を物理的な構成に即して管理できますが、 モニタリング等はしてくれません。

ソフトウェア構成は下記の通りです。

Function Component
HTTP service nginx or Apache
WSGI service gunicorn or uWSGI
Application Django/Python
Database PostgreSQL 9.6+
Task queuing Redis/django-rq
Live device access NAPALM

netboxはDockerイメージが手供されていますが、今回は敢えて使わず、愚直にセットアップしてみました。環境は下記です。

$ cat /etc/redhat-release
CentOS Linux release 7.8.2003 (Core)

netboxのセットアップ

netbox本体を含む上記のコンポーネントをインストールします。

PostgreSQL

netboxはPostgreSQL 9.6以上が必要ですが、現状、デフォルトのリポジトリだと9.2が最新のため、外部リポジトリから9.6をインストールします。

# yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm
# yum install -y postgresql96 postgresql96-server postgresql96-devel
# /usr/pgsql-9.6/bin/postgresql96-setup initdb

パスワードベース認証を受け付けるよう、下記ファイルのindentmd5に書き換えます。

対象ファイル: /var/lib/pgsql/9.6/data/var/lib/pgsql/9.6/data/pg_hba.conf

変更前

# TYPE  DATABASE        USER                ADDRESS                 METHOD

# "local" is for Unix domain socket connections     only
local   all                 all                                     peer
# IPv4 local connections:
host    all             all             127.0.0.    1/32            ident
# IPv6 local connections:
host    all             all             ::1/    128                 ident

変更後

# TYPE  DATABASE        USER                ADDRESS                 METHOD

# "local" is for Unix domain socket connections     only
local   all                 all                                     peer
# IPv4 local connections:
host    all             all             127.0.0.    1/32            md5
# IPv6 local connections:
host    all             all             ::1/    128                 md5

PostgreSQLを起動し、自動起動も有効にします。

# systemctl start postgresql-9.6
# systemctl enable postgresql-9.6

netbox用のDBを用意します。

# sudo -u postgres psql
psql (9.6.18)
Type "help" for help.

postgres=# CREATE DATABASE netbox;
CREATE DATABASE
postgres=# CREATE USER netbox WITH PASSWORD '任意のパスワード';
CREATE ROLE
postgres=# GRANT ALL PRIVILEGES ON DATABASE netbox TO netbox;
GRANT
postgres=# \q

設定したパスワードで正しく認証されることを確認します。

# psql -U netbox -W -h localhost netbox
Password for user netbox: (パスワードを入力)
psql (9.6.18)        
Type "help" for help.

netbox=> \q

Redis

RedisはインメモリのKVSで、netboxはキャッシングとキューイングに使用します。

# yum install -y epel-release
# yum install -y redis
# systemctl start redis
# systemctl enable redis
# redis-cli ping
PONG

netbox本体

netbox本体をインストールする前に、pythonや、必要な依存ライブラリをインストールします。

# yum install -y gcc python36 python36-devel python36-setuptools libxml2-devel libxslt-devel libffi-devel openssl-devel redhat-rpm-config
# easy_install-3.6 pip

netbox本体をダウンロードします。今回はgit cloneしました。

# yum install -y git
# git config --global user.name hoge
# git config --global user.email hoge@example.com
# git clone -b master https://github.com/netbox-community/netbox.git /opt/netbox

WSGIとHTTPサービスを動作させるために、netboxユーザを作成します。

# groupadd --system netbox
# adduser --system --gid netbox netbox
# chown --recursive netbox /opt/netbox/netbox/media/

netboxが必要なパッケージがベースシステムと衝突しないように、Python仮想環境を拵えます。

# python3 -m venv /opt/netbox/venv
# cd /opt/netbox/
# source venv/bin/activate
(venv) # pip3 install --upgrade pip
(venv) # pip3 install -r requirements.txt

必須ではありませんが、NAPALMをインストールすることで、netboxから REST API経由でデバイスデータを取得できます。 また、local_requirements.txtにパッケージを記載しておくと、upgrade時に 一緒に更新してくれます。

(venv) # pip3 install napalm
(venv) # pwd
/opt/netbox
(venv) # echo napalm >> local_requirements.txt
(venv) # cat local_requirements.txt
napalm

ひな型からconfiguration.pyを作成し、必要な値を設定します。

(venv) # cd netbox/netbox/
(venv) # pwd
/opt/netbox/netbox/netbox
(venv) # cp configuration.example.py configuration.py

今回設定したのは下記です。順番に見ていきます。

  • ALLOWED_HOSTS
  • DATABASEの諸々
  • SECRET_KEY
  • TIME_ZONE

ALLOWED_HOSTS

netboxにアクセスできるノードのホスト名かIPアドレスを定義します。 VirtualBox上の仮想マシンに構築しているので、ガバガバにします。

ALLOWED_HOSTS = ['*']

※0.0.0.0だと駄目みたいです。下記のエラーが出力されました。

[01/Jul/2020 20:06:51] "GET / HTTP/###1" 400 143
[01/Jul/2020 20:06:51] "GET /favicon.ico HTTP/###1" 400 143

github.com

DATABASEの諸々

PostgreSQL用の各種情報を定義します。

DATABASE = {
'NAME': 'netbox',               # Database name
'USER': 'netbox',               # PostgreSQL username
'PASSWORD': 'パスワード',       # PostgreSQL password
'HOST': 'localhost',            # Database server
'PORT': '',                     # Database port (leave blank for default)
'CONN_MAX_AGE': 300,            # Max database connection age
}

SECRET_KEY

cookieの暗号化やパスワードリセットに使うキーを設定します。

SECRET_KEY = 'ランダムな50文字の文字列'

数字、記号を含むランダムな50文字以上の文字列である必要があります。 下記のスクリプトを実行することで要件を満たす文字列を生成できます。

# /opt/netbox/netbox/generate_secret_key.py 
ランダムな50文字の文字列

TIME_ZONE

デフォルトがUTCなので、Asia/Tokyoに変更します。

# Time zone (default: UTC)
TIME_ZONE = 'Asia/Tokyo'

configuration.pyの編集は以上です。

続いて、PostgreSQLにnetbox用のスキーマをインストールします。

(venv) # cd /opt/netbox/netbox/
(venv) # python3 manage.py migrate
(venv) # python3 manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, circuits, contenttypes, dcim, extras, ipam, secrets, sessions, taggit, tenancy, users,     virtualization    
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
(以下省略)

netboxには事前作成されたユーザが存在しないため、管理者用のユーザを作成します。

(venv) # python3 manage.py createsuperuser
Username (leave blank to use 'root'): (Enter押下)
Email address: (Enter押下)
Password: (任意のパスワード入力)
Password (again): (任意のパスワード入力)
Superuser created successfully.

Djangoで使用する静的ファイルを集約します。

(venv) # python3 manage.py collectstatic --no-input

976 static files copied to '/opt/netbox/netbox/static'.

netboxのインスタンスが動作する状態になっているので、インスタンスを立ち上げて、 接続確認してみます。

(venv) # python3 manage.py runserver 0.0.0.0:8000 --insecure
Performing system checks...

System check identified no issues (0 silenced).
July 01, 2020 - 01:08:54
Django version 3.0.7, using settings 'netbox.settings'
Starting development server at http://0.0.0.0:8000/
Quit the server with CONTROL-C.

上記の状態でnetboxにブラウザでアクセスし、ホーム画面が表示されることを確認します。 今回の場合はVirtualBoxでホストの8000からゲストの8000にフォワーディングしていたので、 http://127.0.0.1:8000/で繋がりました。 終わったらCtrl + Cで抜けます。

※netboxのホーム画面が表示されない場合、手順が誤っている可能性があります。切り分けの煩雑化を避けるため、後続の手順に進む前に、トラブルシューティングすることをお勧めします。

ssl通信のため、いわゆるオレオレ証明書を作成します。フィールドは全部空Enterで作りました。ちなみに、これ以降はvenv抜けて良いはずなのですが、抜けるの忘れててそのまま続行したため、プロンプトの表記も残しています。

(venv) # mkdir /etc/ssl/private
(venv) # openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \
> -keyout /etc/ssl/private/netbox.key \
> -out /etc/ssl/certs/netbox.crt

nginx

nginxをインストールしてnetbox用に設定します。 公式に習ってバーチャルホストっぽく設定します。

(venv) # yum -y install nginx
(venv) # mkdir /etc/nginx/sites-available
(venv) # cp /opt/netbox/contrib/nginx.conf /etc/nginx/sites-available/netbox
(venv) # mkdir /etc/nginx/sites-enabled
(venv) # cd /etc/nginx/sites-enabled/
(venv) # ln -s /etc/nginx/sites-available/netbox /etc/nginx/sites-enabled/netbox

sites-enabled配下に作ったconfigを参照するよう、includeディレクティブを追記します。

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '     
                      '"$http_user_agent" "$http_x_forwarded_for"';   

    (中略)

    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include       
    # for more information.
    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;   # ここを追記

nginxを起動して、自動起動も有効にします。

(venv) # systemctl start nginx
(venv) # systemctl enable nginx

Gunicorn

アップグレードでファイルが上書きされないよう、コピーしておきます。

(venv) # cd /opt/netbox
(venv) # cp contrib/gunicorn.py /opt/netbox/gunicorn.py

systemd

netboxサービスをデーモン化します。

(venv) # pwd 
/opt/netbox
(venv) # cp contrib/*.service /etc/systemd/system/
(venv) # systemctl daemon-reload
(venv) # systemctl start netbox netbox-rq
(venv) # systemctl enable netbox netbox-rq
(venv) # cp contrib/gunicorn.py /opt/netbox/gunicorn.py
● netbox.service - NetBox WSGI Service
   Loaded: loaded (/etc/systemd/system/netbox.service; enabled; vendor preset: disabled)
   Active: active (running) since Wed 2020-07-01 22:49:05 JST; 5s ago
     Docs: https://netbox.readthedocs.io/en/stable/
 Main PID: 3924 (gunicorn)
   CGroup: /system.slice/netbox.service
           ├─3924 /opt/netbox/venv/bin/python3 /opt/netbox/venv/bin/gunicorn --pid /var/tmp/netbox.pid --pythonpath /opt/netbox/netbox --co...
           ├─3927 /opt/netbox/venv/bin/python3 /opt/netbox/venv/bin/gunicorn --pid /var/tmp/netbox.pid --pythonpath /opt/netbox/netbox --co...
           ├─3929 /opt/netbox/venv/bin/python3 /opt/netbox/venv/bin/gunicorn --pid /var/tmp/netbox.pid --pythonpath /opt/netbox/netbox --co...
           ├─3930 /opt/netbox/venv/bin/python3 /opt/netbox/venv/bin/gunicorn --pid /var/tmp/netbox.pid --pythonpath /opt/netbox/netbox --co...
           ├─3931 /opt/netbox/venv/bin/python3 /opt/netbox/venv/bin/gunicorn --pid /var/tmp/netbox.pid --pythonpath /opt/netbox/netbox --co...
           └─3935 /opt/netbox/venv/bin/python3 /opt/netbox/venv/bin/gunicorn --pid /var/tmp/netbox.pid --pythonpath /opt/netbox/netbox --co...

サービスが正常に起動したら、ブラウザからnetboxの443ポートにアクセスすれば、netboxのホーム画面が表示されるはずです。

おわりに

意外とやること多かった印象です。本当はインストールしてAnsibleと連携させるまで記事にしようと思っていたのですが、また今度にします。