Last active
March 7, 2019 14:10
-
-
Save versionsix/620ed22ad0e7f25cd84937a7a6819f31 to your computer and use it in GitHub Desktop.
Install netbox in one go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# install: | |
# NETBOX_FQDN=netbox.example.com bash -c "$(curl -Lso- https://git.io/fhp1D)" | |
export DEBIAN_FRONTEND=noninteractive | |
systemctl restart systemd-timesyncd | |
ipv6="${ipv6:-$( wget -qO- -t1 -T2 ipv6.icanhazip.com)}" | |
ipv4="${ipv4:-$( wget -qO- -t1 -T2 ipv4.icanhazip.com)}" | |
ipv4_slug="$(echo $ipv4 | sed 's/\./-/g').nip.io" | |
random_dbpass=`date +%s | sha256sum | base64 | head -c 32` | |
random_nbpass=`date +%s | sha256sum | base64 | head -c 32` | |
NETBOX_POSTGRESS_PASS="${NETBOX_POSTGRESS_PASS:-$random_dbpass}" | |
NETBOX_FQDN="${NETBOX_FQDN:-$ipv4_slug}" | |
NETBOX_ADMIN_PASS="${NETBOX_ADMIN_PASS:-$random_nbpass}" | |
set -e -u -x | |
apt update | |
apt -yq upgrade | |
# dpkg --configure -a | |
# Prevent auto starting service | |
systemctl mask nginx | |
apt -yq install postgresql postgresql-contrib libpq-dev python3 python3-pip python3-dev python3-setuptools python3-wheel build-essential libxml2-dev libxslt1-dev libffi-dev graphviz libpq-dev libssl-dev zlib1g-dev jq redis-server nginx | |
NETBOX_TARGZ=$(curl -s https://api.github.com/repos/digitalocean/netbox/releases/latest | jq --raw-output '.tarball_url') | |
NETBOX_TAG=$(curl -s https://api.github.com/repos/digitalocean/netbox/releases/latest | jq --raw-output '.tag_name') | |
groupadd netbox || true | |
useradd -r -M -g netbox -g www-data netbox|| true | |
su -s /bin/sh postgres -c "cd && psql << EOF | |
\conninfo | |
CREATE DATABASE netbox; | |
CREATE USER netbox WITH PASSWORD '$NETBOX_POSTGRESS_PASS'; | |
GRANT ALL PRIVILEGES ON DATABASE netbox TO netbox; | |
EOF" | |
wget -O /opt/netbox-$NETBOX_TAG.tar.gz $NETBOX_TARGZ | |
mkdir -p /opt/netbox-$NETBOX_TAG | |
tar -xzf /opt/netbox-$NETBOX_TAG.tar.gz -C /opt/netbox-$NETBOX_TAG --strip 1 | |
chown -R netbox:www-data /opt/netbox-$NETBOX_TAG | |
ln -sf /opt/netbox-$NETBOX_TAG/ /opt/netbox | |
pushd /opt/netbox/ | |
pip3 install napalm django-rq gunicorn | |
pip3 install -r requirements.txt | |
# cp -n netbox/netbox/configuration.example.py netbox/netbox/configuration.py | |
# pushd /opt/netbox/netbox | |
# sed -i "s/SECRET_KEY = ''/SECRET_KEY = '$(python3 /opt/netbox/netbox/generate_secret_key.py)'/g" netbox/configuration.py | |
# (if [[ "$ipv4" != "" ]]; then echo ,"'$ipv4'"; fi)$(if [[ "$ipv6" != "" ]]; then echo ,"'$ipv6'"; fi) | |
cat <<EOF > /opt/netbox/netbox/netbox/configuration.py | |
######################### | |
# # | |
# Required settings # | |
# # | |
######################### | |
# This is a list of valid fully-qualified domain names (FQDNs) for the NetBox server. NetBox will not permit write | |
# access to the server via any other hostnames. The first FQDN in the list will be treated as the preferred name. | |
# | |
# Example: ALLOWED_HOSTS = ['netbox.example.com', 'netbox.internal.local'] | |
ALLOWED_HOSTS = ['127.0.0.1','localhost','$NETBOX_FQDN','$ipv4_slug'] | |
# PostgreSQL database configuration. | |
DATABASE = { | |
'NAME': 'netbox', # Database name | |
'USER': 'netbox', # PostgreSQL username | |
'PASSWORD': '$NETBOX_POSTGRESS_PASS', # PostgreSQL password | |
'HOST': 'localhost', # Database server | |
'PORT': '', # Database port (leave blank for default) | |
} | |
# This key is used for secure generation of random numbers and strings. It must never be exposed outside of this file. | |
# For optimal security, SECRET_KEY should be at least 50 characters in length and contain a mix of letters, numbers, and | |
# symbols. NetBox will not run without this defined. For more information, see | |
# https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-SECRET_KEY | |
SECRET_KEY = '$(python3 /opt/netbox/netbox/generate_secret_key.py)' | |
######################### | |
# # | |
# Optional settings # | |
# # | |
######################### | |
# Specify one or more name and email address tuples representing NetBox administrators. These people will be notified of | |
# application errors (assuming correct email settings are provided). | |
ADMINS = [ | |
# ['John Doe', 'jdoe@example.com'], | |
] | |
# Optionally display a persistent banner at the top and/or bottom of every page. HTML is allowed. To display the same | |
# content in both banners, define BANNER_TOP and set BANNER_BOTTOM = BANNER_TOP. | |
BANNER_TOP = '' | |
BANNER_BOTTOM = '' | |
# Text to include on the login page above the login form. HTML is allowed. | |
BANNER_LOGIN = '¯\_(ツ)_/¯' | |
# Base URL path if accessing NetBox within a directory. For example, if installed at http://example.com/netbox/, set: | |
# BASE_PATH = 'netbox/' | |
BASE_PATH = '' | |
# Maximum number of days to retain logged changes. Set to 0 to retain changes indefinitely. (Default: 90) | |
CHANGELOG_RETENTION = 90 | |
# API Cross-Origin Resource Sharing (CORS) settings. If CORS_ORIGIN_ALLOW_ALL is set to True, all origins will be | |
# allowed. Otherwise, define a list of allowed origins using either CORS_ORIGIN_WHITELIST or | |
# CORS_ORIGIN_REGEX_WHITELIST. For more information, see https://github.com/ottoyiu/django-cors-headers | |
CORS_ORIGIN_ALLOW_ALL = False | |
CORS_ORIGIN_WHITELIST = [ | |
# 'hostname.example.com', | |
] | |
CORS_ORIGIN_REGEX_WHITELIST = [ | |
# r'^(https?://)?(\w+\.)?example\.com$', | |
] | |
# Set to True to enable server debugging. WARNING: Debugging introduces a substantial performance penalty and may reveal | |
# sensitive information about your installation. Only enable debugging while performing testing. Never enable debugging | |
# on a production system. | |
DEBUG = False | |
# Email settings | |
EMAIL = { | |
'SERVER': 'localhost', | |
'PORT': 25, | |
'USERNAME': '', | |
'PASSWORD': '', | |
'TIMEOUT': 10, # seconds | |
'FROM_EMAIL': '', | |
} | |
# Enforcement of unique IP space can be toggled on a per-VRF basis. To enforce unique IP space within the global table | |
# (all prefixes and IP addresses not assigned to a VRF), set ENFORCE_GLOBAL_UNIQUE to True. | |
ENFORCE_GLOBAL_UNIQUE = False | |
# Enable custom logging. Please see the Django documentation for detailed guidance on configuring custom logs: | |
# https://docs.djangoproject.com/en/1.11/topics/logging/ | |
LOGGING = {} | |
# Setting this to True will permit only authenticated users to access any part of NetBox. By default, anonymous users | |
# are permitted to access most data in NetBox (excluding secrets) but not make any changes. | |
LOGIN_REQUIRED = True | |
# The length of time (in seconds) for which a user will remain logged into the web UI before being prompted to | |
# re-authenticate. (Default: 1209600 [14 days]) | |
LOGIN_TIMEOUT = None | |
# Setting this to True will display a "maintenance mode" banner at the top of every page. | |
MAINTENANCE_MODE = False | |
# An API consumer can request an arbitrary number of objects =by appending the "limit" parameter to the URL (e.g. | |
# "?limit=1000"). This setting defines the maximum limit. Setting it to 0 or None will allow an API consumer to request | |
# all objects by specifying "?limit=0". | |
MAX_PAGE_SIZE = 1000 | |
# The file path where uploaded media such as image attachments are stored. A trailing slash is not needed. Note that | |
# the default value of this setting is derived from the installed location. | |
# MEDIA_ROOT = '/opt/netbox/netbox/media' | |
# Credentials that NetBox will uses to authenticate to devices when connecting via NAPALM. | |
NAPALM_USERNAME = '' | |
NAPALM_PASSWORD = '' | |
# NAPALM timeout (in seconds). (Default: 30) | |
NAPALM_TIMEOUT = 30 | |
# NAPALM optional arguments (see http://napalm.readthedocs.io/en/latest/support/#optional-arguments). Arguments must | |
# be provided as a dictionary. | |
NAPALM_ARGS = {} | |
# Determine how many objects to display per page within a list. (Default: 50) | |
PAGINATE_COUNT = 50 | |
# When determining the primary IP address for a device, IPv6 is preferred over IPv4 by default. Set this to True to | |
# prefer IPv4 instead. | |
PREFER_IPV4 = False | |
# Redis database settings (optional). A Redis database is required only if the webhooks backend is enabled. | |
REDIS = { | |
'HOST': 'localhost', | |
'PORT': 6379, | |
'PASSWORD': '', | |
'DATABASE': 0, | |
'DEFAULT_TIMEOUT': 300, | |
} | |
# The file path where custom reports will be stored. A trailing slash is not needed. Note that the default value of | |
# this setting is derived from the installed location. | |
# REPORTS_ROOT = '/opt/netbox/netbox/reports' | |
# By default, NetBox will store session data in the database. Alternatively, a file path can be specified here to use | |
# local file storage instead. (This can be useful for enabling authentication on a standby instance with read-only | |
# database access.) Note that the user as which NetBox runs must have read and write permissions to this path. | |
SESSION_FILE_PATH = None | |
# Time zone (default: UTC) | |
TIME_ZONE = 'UTC' | |
# The webhooks backend is disabled by default. Set this to True to enable it. Note that this requires a Redis | |
# database be configured and accessible by NetBox. | |
WEBHOOKS_ENABLED = True | |
# Date/time formatting. See the following link for supported formats: | |
# https://docs.djangoproject.com/en/dev/ref/templates/builtins/#date | |
DATE_FORMAT = 'N j, Y' | |
SHORT_DATE_FORMAT = 'Y-m-d' | |
TIME_FORMAT = 'g:i a' | |
SHORT_TIME_FORMAT = 'H:i:s' | |
DATETIME_FORMAT = 'N j, Y g:i a' | |
SHORT_DATETIME_FORMAT = 'Y-m-d H:i' | |
EOF | |
python3 /opt/netbox/netbox/manage.py migrate | |
python3 /opt/netbox/netbox/manage.py collectstatic --no-input | |
python3 /opt/netbox/netbox/manage.py loaddata initial_data | |
# python3 /opt/netbox/netbox/manage.py runserver 0.0.0.0:8000 --insecure | |
echo "from django.contrib.auth import get_user_model; User = get_user_model(); User.objects.create_superuser('admin', 'admin@example.com', '$NETBOX_ADMIN_PASS')" | python3 /opt/netbox/netbox/manage.py shell | |
cat <<EOF > /etc/nginx/sites-available/netbox | |
server { | |
listen 80; | |
listen [::]:80; | |
server_name $NETBOX_FQDN; | |
client_max_body_size 25m; | |
location /static/ { | |
alias /opt/netbox/netbox/static/; | |
} | |
location / { | |
proxy_pass http://unix:/run/gunicorn.socket; | |
proxy_set_header X-Forwarded-Host \$server_name; | |
proxy_set_header X-Real-IP \$remote_addr; | |
proxy_set_header X-Forwarded-Proto \$scheme; | |
add_header P3P 'CP="ALL DSP COR PSAa PSDa OUR NOR ONL UNI COM NAV"'; | |
} | |
location /.well-known/acme-challenge/ { | |
alias /var/www/le_root/.well-known/acme-challenge/; | |
} | |
} | |
server { | |
#------- Start SSL config with http2 support ----# | |
listen 443 ssl http2; | |
listen [::]:443 ssl http2; | |
server_name $NETBOX_FQDN; | |
ssl_certificate /etc/nginx/certs/$NETBOX_FQDN.cert; | |
ssl_certificate_key /etc/nginx/certs/$NETBOX_FQDN.key; | |
ssl_session_timeout 30m; | |
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; | |
ssl_ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS; | |
ssl_session_cache shared:SSL:10m; | |
ssl_dhparam /etc/nginx/certs/dhparams.pem; | |
ssl_prefer_server_ciphers on; | |
## Improves TTFB by using a smaller SSL buffer than the nginx default | |
ssl_buffer_size 8k; | |
## Send header to tell the browser to prefer https to http traffic | |
add_header Strict-Transport-Security max-age=3600; | |
## SSL logs ## | |
access_log /var/log/nginx/ssl_access.log; | |
error_log /var/log/nginx/ssl_error.log; | |
#-------- END SSL config -------## | |
# Add rest of your config below like document path and more ## | |
client_max_body_size 25m; | |
location /static/ { | |
alias /opt/netbox/netbox/static/; | |
} | |
location / { | |
proxy_pass http://unix:/run/gunicorn.socket; | |
proxy_set_header Host \$host; | |
proxy_set_header X-Forwarded-Host \$server_name; | |
proxy_set_header X-Real-IP \$remote_addr; | |
proxy_set_header X-Forwarded-Proto \$scheme; | |
add_header P3P 'CP="ALL DSP COR PSAa PSDa OUR NOR ONL UNI COM NAV"'; | |
} | |
} | |
EOF | |
pushd /etc/nginx/sites-enabled/ | |
rm -rf default | |
ln -sf /etc/nginx/sites-available/netbox | |
popd | |
cat << 'EOF' > /etc/systemd/system/gunicorn.service | |
[Unit] | |
Description=gunicorn daemon | |
Requires=gunicorn.socket | |
After=network.target | |
[Service] | |
PIDFile=/run/gunicorn/pid | |
User=netbox | |
Group=www-data | |
RuntimeDirectory=gunicorn | |
WorkingDirectory=/opt/netbox/netbox/ | |
ExecStart=/usr/local/bin/gunicorn --pid /run/gunicorn/pid \ | |
--bind unix:/run/gunicorn.socket \ | |
--pythonpath /opt/netbox/netbox \ | |
--workers 2 \ | |
--user netbox netbox.wsgi | |
ExecReload=/bin/kill -s HUP $MAINPID | |
ExecStop=/bin/kill -s TERM $MAINPID | |
PrivateTmp=true | |
[Install] | |
WantedBy=multi-user.target | |
EOF | |
cat <<EOF > /etc/systemd/system/gunicorn.socket | |
[Unit] | |
Description=gunicorn socket | |
PartOf=gunicorn.service | |
[Socket] | |
ListenStream=/run/gunicorn.socket | |
SocketUser=netbox | |
SocketGroup=www-data | |
Writable=true | |
[Install] | |
WantedBy=sockets.target | |
EOF | |
cat <<EOF > /etc/tmpfiles.d/gunicorn.conf | |
#Type Path Mode User Group Age Argument | |
d /run/gunicorn 2775 netbox www-data - - | |
EOF | |
cat <<EOF > /etc/systemd/system/netbox-rqworker.service | |
[Unit] | |
Description=netbox-rqworker daemon | |
After=network.target | |
[Service] | |
User=www-data | |
Group=www-data | |
RuntimeDirectory=rqworker | |
WorkingDirectory=/opt/netbox/netbox/ | |
ExecStart=/usr/bin/python3 /opt/netbox/netbox/manage.py rqworker | |
[Install] | |
WantedBy=multi-user.target | |
EOF | |
mkdir -p /var/www/le_root/.well-known/acme-challenge | |
chown -R root:www-data /var/www/le_root | |
# Make self signed cert. | |
mkdir -p /etc/nginx/certs/ | |
dd if=/dev/urandom of=~/.rnd bs=256 count=1 | |
openssl dhparam -out /etc/nginx/certs/dhparams.pem -dsaparam 4096 | |
openssl req \ | |
-new \ | |
-newkey ec \ | |
-pkeyopt ec_paramgen_curve:prime256v1 \ | |
-days 18250 \ | |
-nodes \ | |
-x509 \ | |
-subj "/C=BE/ST=D/L=V/O=TM/CN=$NETBOX_FQDN" \ | |
-keyout /etc/nginx/certs/$NETBOX_FQDN.key \ | |
-out /etc/nginx/certs/$NETBOX_FQDN.cert | |
systemctl daemon-reload | |
ufw allow http | |
systemctl enable gunicorn.socket | |
systemctl enable --now gunicorn.service | |
systemctl enable --now netbox-rqworker.service | |
systemctl unmask nginx | |
systemctl enable --now nginx | |
# Install acme.sh | |
curl https://get.acme.sh | sh | |
cat <<EOF > /root/netbox_admin.txt | |
Domain: https://$NETBOX_FQDN | |
Admin login: admin | |
Admin password: $NETBOX_ADMIN_PASS | |
Admin api token: $(echo "print(Token.objects.create(user_id=1).key)" | python3 /opt/netbox/netbox/manage.py nbshell 2>&1 | gawk " />>>\s\w{40}/ {print \$2} ") | |
To enable the green padlock generate a letsencrypt cert. Append --test to try it first | |
acme.sh --issue --nginx -d $NETBOX_FQDN --fullchain-file /etc/nginx/certs/$NETBOX_FQDN.cert --key-file /etc/nginx/certs/$NETBOX_FQDN.key --reloadcmd "systemctl reload nginx" --test | |
EOF |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment