netbox 3.0.7 on OpenBSD 7

📆
🏷
,

Ever since dywis0r made me aware of netbox I was planning on getting my hands dirty with it. But only after looking loads of videos on the topic and after being `forced’ to use it at work has I been able to finally get enough momentum going to start the journey for myself.

At the beginning of it lay another topic I was successfully procrastinating since a very long time: a suffiently detailed network diagram which was both useful and pleasing to the eye. Being interested especially in isometric network diagrams I started working on that very foundation for better documentation of my home network. A journey which led me down a rabbit hole at which’s bottom I found inkscape to be the best tool available for my different needs. It’s not the most effective tool for drawing a network diagram but I had a nice produce after a steep learning curve. But this is another story.

Back to the topic at hand. After drawing the diagram and cleaning up my network from countless redesigns leaving artifacts of me learning and labbing at home I started on working on netbox. After some further research I found what I think to be a good starting point over at Jasper’s blog. I used it as a skeletton but wanted to

  1. use relayd(8) instead of nginx for redirecting static content elsewhere
  2. use httpd(8) instead of nginx to serve static content
  3. use rc(8) instead of supervisord

in large parts due to the software already laying around and the target system already had httpd running. The architecture will more or less look like this:

architecture overview
netbox running with httpd and relayd

Other than that you get same as with Jasper’s setup:

The following documents the steps needed to setup NetBox on OpenBSD. I am running NetBox on a PC Engines APU which holds up fairly well and I have since migrated my own setup from RackTables to NetBox, primarily because of the API functionality NetBox offers which allows for integration with SaltStack. But more on that some other time.

– Jasper Lievisse Adriaanse, Setting up NetBox on OpenBSD

Prerequisites - Installation and Setup

netbox needs a running postgres database server which I lacked, so this was my first actionable point, installing and setting up the database

# pkg_add postgresql-server && cat /usr/local/share/doc/pkg-readmes/postgresql-*
# su - _postgresql
$ mkdir /var/postgresql/netbox
$ initdb -D /var/postgresql/netbox -U postgres -A scram-sha-256 -E UTF8 -W
$ exit
# rcctl enable postgres
# rcctl start postgres

afterwards I followed Jasper’s blog for setting up the virtualenv for netbox and installing git (minus nginx and supervisor):

# pkg_info -Q py3-natsort py3-graphviz py3-pygfm py3-Pillow \
    py3-cryptodomex py3-ncclient py3-django-lts py3-psycopg2 \
    py3-paramiko py3-xmltodict py3-netaddr \
    py3-virtualenv py3-gunicorn redis git

again I followed Jasper by running netbox from within a virtualenv but adjusted the commands where neccessary:

# cd /var/www/
# git clone https://github.com/digitalocean/netbox
# cd netbox
# git checkout v3.0.7
# virtualenv --system-site-packages env
# . env/bin/activate
# pip3 install -r requirements.txt

Now just follow upstreams documentation for setting up netbox:

# su - _postgresql
$ psql -U postgres
postgres=# CREATE DATABASE netbox;
postgres=# CREATE USER netbox WITH PASSWORD 'changeme';
postgres=# GRANT ALL PRIVILEGES ON DATABASE netbox TO netbox;
postgres=# \q
$ exit
# rcctl enable redis
# rcctl start redis
# cp /var/www/netbox/netbox/netbox/configuration.{example.py,py}

then edit the following settings:

  • ALLOWED_HOSTS
  • DATABASE
  • REDIS
  • SECRET_KEY

and continue setting up gunicorn.

gunicorn and rc

At this point we deviate from both Jasper’s setup and the official documentation. Instead we run gunicorn as www (instead of netbox) and we do so using rc instead of supervisor. Lets start by creating the following script as /etc/rc.d/netbox

#!/bin/ksh
#
# netbox rc script.
# Frank Brodbeck <fab@clacks.xyz>

_BASEDIR=/var/www/netbox

daemon="${_BASEDIR}/env/bin/gunicorn"
daemon_flags="--name netbox --user=www --group=www --config=${_BASEDIR}/gunicorn.py" 
daemon_flags="${daemon_flags} --log-level=info --log-file=- netbox.wsgi"

. /etc/rc.d/rc.subr

pexp="${_BASEDIR}/env/bin/python3.8 ${daemon}${daemon_flags:+ ${daemon_flags}}"
rc_reload=YES
rc_bg=YES

rc_pre() {
        cat <<EOF>/var/run/netbox_start
APPDIR=${_BASEDIR}/netbox

cd \${APPDIR}
. ${_BASEDIR}/env/bin/activate
export PYTHONPATH=${_BASEDIR}/env/lib/python3.8/site-packages:${APPDIR}${PYTHONPATH:+:${PYTHONPATH}}
exec gunicorn ${daemon_flags}
EOF
        chmod u+x /var/run/netbox_start
}

rc_start() {
        ${rcexec} /var/run/netbox_start
}

rc_cmd $1

and finalize the gunicorn setup

# chown -R www /var/www/netbox/netbox/media
# cp /var/www/netbox/contrib/gunicorn.py /var/www/netbox/
# chmod 0555 /etc/rc.d/netbox
# rcctl enable netbox
# rcctl start netbox

rc_pre() will create a script at /var/run/netbox_start which can be adjusted and executed manually for debugging.

httpd setup for netbox

At this point gunicorn should be up and running to serve netbox. For reasons unknown to me, netbox decided to deliver certain content not from gunicorn but from a plain old httpd. netbox and Jasper provide examples for using nginx, I will show you how to setup httpd for the task:

server "netbox.office.lan" {
        listen on localhost port 80
        root "/netbox/netbox"
        log style combined
}

Just add the above snippet to your /etc/httpd.conf and you’r good to go:

# rcctl enable httpd
# rcctl start httpd

relayd setup for netbox

Both gunicorn and httpd are now up and running, waiting to serve their content to users. In order to divert traffic to the right piece we will setup relayd to distribute traffic accordingly:

# $OpenBSD: relayd.conf,v 1.5 2018/05/06 20:56:55 benno Exp $
#
# Macros

#
# Global Options
#
# interval 10
# timeout 1000
# prefork 5

#
# Each table will be mapped to a pf table.
#
table <netbox> { 127.0.0.1 }
table <netbox_gunicorn> { 127.0.0.1 }

http protocol netbox {
    match request header append "X-Forwarded-For" value "$REMOTE_ADDR"
    match request header append "X-Forwarded-By" \
        value "$SERVER_ADDR:$SERVER_PORT"
    match request header set "Connection" value "close"
    match request header "Host" value "netbox.office.lan" path "/static/*" tag netbox_static
    pass request tagged netbox_static forward to <netbox>

    # Various TCP options
    tcp { sack, backlog 128 }

    tls { ciphers "EECDH+AESGCM:EDH+AESGCM" }
        tls no session tickets
    tls keypair "netbox"
}

relay netbox {
        listen on 192.168.23.33 port https tls
        protocol netbox

        forward to <netbox_gunicorn> port 8001
        forward to <netbox> port 80
}

copy your TLS stuff and start the service

# cp cert /etc/ssl/netbox
# cp key /etc/ssl/private/netbox
# rcctl enable relayd
# rcctl start relayd

If everything went OK you show now be able to access your netbox installation :-)

--EOF