Browse Source

Resolve "Multifactor Authentication"

merge-requests/39/merge
Steven Foerster 5 years ago
parent
commit
09cfda0e37
  1. 35
      README.md
  2. 66
      compose/production/traefik/traefik.toml.template
  3. 6
      scripts/env/setup.sh
  4. 1
      scripts/install.sh
  5. 2
      scripts/subinstallers/gen_prod_env.sh
  6. 3
      scripts/subinstallers/iptables.sh
  7. 4
      scripts/update.sh

35
README.md

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
# Mistborn
A secure platform for easily standing up and managing your own cloud services: including firewall, ad-blocking, and Wireguard VPN access
A secure platform for easily standing up and managing your own cloud services: including firewall, ad-blocking, and multi-factor Wireguard VPN access
# Table of Contents
[[_TOC_]]
@ -13,6 +13,7 @@ Ideal for teams who: @@ -13,6 +13,7 @@ Ideal for teams who:
- hate internet ads
- need to be protected from malicious internet domains
- need to collaborate securely
- need multi-factor authentication for Wireguard
- want to retain sole ownership of their data
- want to easily grant and revoke access to people and devices via a simple web interface
- want secure internet access wherever they are
@ -214,6 +215,30 @@ Mistborn makes extra services available. @@ -214,6 +215,30 @@ Mistborn makes extra services available.
Mistborn functions as a network firewall and provides metrics on blocked probes from the internet.
![Mistborn Metrics](https://gitlab.com/cyber5k/public/-/raw/master/graphics/home.mistborn_metrics.png)*Mistborn Firewall Metrics*
# Authentication
There are multiple ways to authenticate and use the system.
![Mistborn Multi Factor Authentication - Authenticator App Setup](https://gitlab.com/cyber5k/public/-/raw/master/graphics/mfa_qr.png)*Mistborn Multi Factor Authentication - Authenticator App Setup*
## Profile: Wireguard Authentication
Mistborn always authenticates with Wireguard. You must have a valid Wireguard configuration file associated with the correct internal IP address. A classic Mistborn profile (Wireguard Only) will allow you to access the internet and all services hosted by Mistborn once you have connected via Wireguard. Note: individual services may require passwords or additional authentication.
## Profile: Multi Factor Authentication (MFA)
In addition to Wireguard, you may create a Mistborn profile enabling multi-factor authentication (MFA). You must first connect to Mistborn via Wireguard. Then all internet traffic will route you to the Mistborn webserver where you must first setup and thereafter authenticate with an app (Google Authenticator, Authy, etc.). You must go to [http://home.mistborn](http://home.mistborn) to complete the authentication process.
![Mistborn Multi Factor Authentication](https://gitlab.com/cyber5k/public/-/raw/master/graphics/mfa1.png)*Mistborn Multi Factor Authentication Prompt*
### MFA Internet Access
Internet access is blocked via iptables until authentication is completed for an MFA profile. You must go to [http://home.mistborn](http://home.mistborn) to complete the authentication process. Click "Sign Out" to re-block internet access until authentication completes again.
![Mistborn Multi Factor Authentication - Token Prompt](https://gitlab.com/cyber5k/public/-/raw/master/graphics/mfa_token_enter.png)*Mistborn Multi Factor Authentication - Token Prompt*
### MFA Mistborn Service Access
Mistborn service access is blocked via traefik until Mistborn authentication is complete. You will not be able to access the web pages for pihole, cockpit, or any extra services until authentication is complete for an MFA profile. Attempting to visit one of these pages will redirect you to [http://home.mistborn](http://home.mistborn) where you must complete the authentication process. Click "Sign Out" to re-block access until authentication completes again.
### Notes
- **Sessions**: Traefik checks the authenticated sessions on the server side to determine whether to allow access to the Mistborn service web pages. If an open session exists for your Mistborn IP address then access will be granted. You may close all sessions by clicking "Sign Out" on the Mistborn home page. Expired sessions are regularly cleaned by the Mistborn system (celery periodic task).
# Mistborn Subdomains
Mistborn uses the following domains (that can be reached by all Wireguard clients):
@ -389,6 +414,14 @@ DNS = 10.2.3.1 @@ -389,6 +414,14 @@ DNS = 10.2.3.1
```
Close the config and restart the client Wireguard process.
## Troubleshooting Raspberry Pi OS (Raspbian)
Be sure to always reboot after updating the kernel. When the kernel is updated the kernel modules are deleted (for the currently running kernel) and you will have issues with any function requiring kernel modules (e.g. `iptables` or `wireguard`).
**Note**: The Raspberry Pi OS 64-bit BETA (versions from May 2020 and prior) have a bug where the os-release info indicates that it is Debian. Mistborn proceeds to install as though it were Debian. Since it's not Debian there are errors.
## Troubleshooting Debian 10
Run updates and restart before installing Mistborn (`sudo apt-get update && sudo apt-get -y dist-upgrade && sudo shutdown -r now`). Some older Linux kernels will prevent newer Wireguard versions from installing.
# Technical and Security Insights
These are some notes regarding the technical design and implementations of Mistborn. Feel free to contact me for additional details.

66
compose/production/traefik/traefik.toml.template

@ -96,6 +96,12 @@ defaultEntryPoints = ["http", "https"] @@ -96,6 +96,12 @@ defaultEntryPoints = ["http", "https"]
[frontends.pihole]
backend = "pihole"
passHostHeader = true
[frontends.pihole.auth]
[frontends.pihole.auth.forward]
address = "https://home.mistborn/auth/"
trustForwardHeader = false
[frontends.pihole.auth.forward.tls]
insecureSkipVerify = true
[frontends.pihole.headers]
HostsProxyHeaders = ['X-CSRFToken']
[frontends.pihole.routes.dr1]
@ -104,6 +110,12 @@ defaultEntryPoints = ["http", "https"] @@ -104,6 +110,12 @@ defaultEntryPoints = ["http", "https"]
[frontends.homeassistant]
backend = "homeassistant"
passHostHeader = true
[frontends.homeassistant.auth]
[frontends.homeassistant.auth.forward]
address = "https://home.mistborn/auth/"
trustForwardHeader = false
[frontends.homeassistant.auth.forward.tls]
insecureSkipVerify = true
[frontends.homeassistant.headers]
HostsProxyHeaders = ['X-CSRFToken']
[frontends.homeassistant.routes.dr1]
@ -112,6 +124,12 @@ defaultEntryPoints = ["http", "https"] @@ -112,6 +124,12 @@ defaultEntryPoints = ["http", "https"]
[frontends.syncthing]
backend = "syncthing"
passHostHeader = true
[frontends.syncthing.auth]
[frontends.syncthing.auth.forward]
address = "https://home.mistborn/auth/"
trustForwardHeader = false
[frontends.syncthing.auth.forward.tls]
insecureSkipVerify = true
[frontends.syncthing.headers]
HostsProxyHeaders = ['X-CSRFToken']
[frontends.syncthing.routes.dr1]
@ -120,6 +138,12 @@ defaultEntryPoints = ["http", "https"] @@ -120,6 +138,12 @@ defaultEntryPoints = ["http", "https"]
[frontends.rocketchat]
backend = "rocketchat"
passHostHeader = true
[frontends.rocketchat.auth]
[frontends.rocketchat.auth.forward]
address = "https://home.mistborn/auth/"
trustForwardHeader = false
[frontends.rocketchat.auth.forward.tls]
insecureSkipVerify = true
[frontends.rocketchat.headers]
HostsProxyHeaders = ['X-CSRFToken']
[frontends.rocketchat.routes.dr1]
@ -128,6 +152,12 @@ defaultEntryPoints = ["http", "https"] @@ -128,6 +152,12 @@ defaultEntryPoints = ["http", "https"]
[frontends.nextcloud]
backend = "nextcloud"
passHostHeader = true
[frontends.nextcloud.auth]
[frontends.nextcloud.auth.forward]
address = "https://home.mistborn/auth/"
trustForwardHeader = false
[frontends.nextcloud.auth.forward.tls]
insecureSkipVerify = true
[frontends.nextcloud.headers]
HostsProxyHeaders = ['X-CSRFToken']
[frontends.nextcloud.routes.dr1]
@ -136,6 +166,12 @@ defaultEntryPoints = ["http", "https"] @@ -136,6 +166,12 @@ defaultEntryPoints = ["http", "https"]
[frontends.onlyoffice]
backend = "onlyoffice"
passHostHeader = true
[frontends.onlyoffice.auth]
[frontends.onlyoffice.auth.forward]
address = "https://home.mistborn/auth/"
trustForwardHeader = false
[frontends.onlyoffice.auth.forward.tls]
insecureSkipVerify = true
[frontends.onlyoffice.headers]
HostsProxyHeaders = ['X-CSRFToken']
[frontends.onlyoffice.routes.dr1]
@ -144,6 +180,12 @@ defaultEntryPoints = ["http", "https"] @@ -144,6 +180,12 @@ defaultEntryPoints = ["http", "https"]
[frontends.bitwarden]
backend = "bitwarden"
passHostHeader = true
[frontends.bitwarden.auth]
[frontends.bitwarden.auth.forward]
address = "https://home.mistborn/auth/"
trustForwardHeader = false
[frontends.bitwarden.auth.forward.tls]
insecureSkipVerify = true
[frontends.bitwarden.headers]
HostsProxyHeaders = ['X-CSRFToken']
[frontends.bitwarden.routes.dr1]
@ -152,6 +194,12 @@ defaultEntryPoints = ["http", "https"] @@ -152,6 +194,12 @@ defaultEntryPoints = ["http", "https"]
[frontends.jellyfin]
backend = "jellyfin"
passHostHeader = true
[frontends.jellyfin.auth]
[frontends.jellyfin.auth.forward]
address = "https://home.mistborn/auth/"
trustForwardHeader = false
[frontends.jellyfin.auth.forward.tls]
insecureSkipVerify = true
[frontends.jellyfin.headers]
HostsProxyHeaders = ['X-CSRFToken']
[frontends.jellyfin.routes.dr1]
@ -160,6 +208,12 @@ defaultEntryPoints = ["http", "https"] @@ -160,6 +208,12 @@ defaultEntryPoints = ["http", "https"]
[frontends.jitsi]
backend = "jitsi"
passHostHeader = true
[frontends.jitsi.auth]
[frontends.jitsi.auth.forward]
address = "https://home.mistborn/auth/"
trustForwardHeader = false
[frontends.jitsi.auth.forward.tls]
insecureSkipVerify = true
[frontends.jitsi.headers]
HostsProxyHeaders = ['X-CSRFToken']
[frontends.jitsi.routes.dr1]
@ -168,6 +222,12 @@ defaultEntryPoints = ["http", "https"] @@ -168,6 +222,12 @@ defaultEntryPoints = ["http", "https"]
[frontends.raspap]
backend = "raspap"
passHostHeader = true
[frontends.raspap.auth]
[frontends.raspap.auth.forward]
address = "https://home.mistborn/auth/"
trustForwardHeader = false
[frontends.raspap.auth.forward.tls]
insecureSkipVerify = true
[frontends.raspap.headers]
HostsProxyHeaders = ['X-CSRFToken']
[frontends.raspap.routes.dr1]
@ -176,6 +236,12 @@ defaultEntryPoints = ["http", "https"] @@ -176,6 +236,12 @@ defaultEntryPoints = ["http", "https"]
[frontends.cockpit]
backend = "cockpit"
passHostHeader = true
[frontends.cockpit.auth]
[frontends.cockpit.auth.forward]
address = "https://home.mistborn/auth/"
trustForwardHeader = false
[frontends.cockpit.auth.forward.tls]
insecureSkipVerify = true
[frontends.cockpit.headers]
HostsProxyHeaders = ['X-CSRFToken']
[frontends.cockpit.routes.dr1]

6
scripts/env/setup.sh vendored

@ -4,10 +4,10 @@ VAR_FILE=/opt/mistborn/.env @@ -4,10 +4,10 @@ VAR_FILE=/opt/mistborn/.env
source /opt/mistborn/scripts/subinstallers/platform.sh
MISTBORN_DNS_BIND_IP="0.0.0.0"
if [ "$DISTRO" == "ubuntu" ] && [ "$VERSION_ID" == "20.04" ]; then
MISTBORN_DNS_BIND_IP="10.2.3.1"
fi
#if [ "$DISTRO" == "ubuntu" ] && [ "$VERSION_ID" == "20.04" ]; then
# MISTBORN_DNS_BIND_IP="10.2.3.1"
#fi
echo "MISTBORN_DNS_BIND_IP=${MISTBORN_DNS_BIND_IP}" | sudo tee ${VAR_FILE}
sudo chown mistborn:mistborn ${VAR_FILE}

1
scripts/install.sh

@ -206,6 +206,7 @@ sudo mkdir -p ../mistborn_volumes/extra @@ -206,6 +206,7 @@ sudo mkdir -p ../mistborn_volumes/extra
# Traefik final setup (cockpit)
cp ./compose/production/traefik/traefik.toml.template ./compose/production/traefik/traefik.toml
# setup tls certs
source ./scripts/subinstallers/openssl.sh
sudo rm -rf ../mistborn_volumes/base/tls

2
scripts/subinstallers/gen_prod_env.sh

@ -20,6 +20,8 @@ echo "#MAILGUN_API_KEY=" >> $DJANGO_PROD_FILE @@ -20,6 +20,8 @@ echo "#MAILGUN_API_KEY=" >> $DJANGO_PROD_FILE
echo "#MAILGUN_API_URL=" >> $DJANGO_PROD_FILE
echo "#SENTRY_DNS=" >> $DJANGO_PROD_FILE
echo "MISTBORN_INSTALL_COCKPIT=$MISTBORN_INSTALL_COCKPIT" >> $DJANGO_PROD_FILE
echo "MISTBORN_PORTAL_IP=10.2.3.1" >> $DJANGO_PROD_FILE
echo "MISTBORN_PORTAL_PORT=5000" >> $DJANGO_PROD_FILE
# generate production .env file for postgresql
POSTGRES_PROD_FILE="./.envs/.production/.postgres"

3
scripts/subinstallers/iptables.sh

@ -46,7 +46,8 @@ sudo iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT @@ -46,7 +46,8 @@ sudo iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
# if installing over SSH, add SSH rule
if [ ! -z "${SSH_CLIENT}" ]; then
SSH_SRC=$(echo $SSH_CLIENT | awk '{print $1}')
sudo iptables -A INPUT -p tcp -s $SSH_SRC --dport 22 -j ACCEPT
SSH_PRT=$(echo $SSH_CLIENT | awk '{print $3}')
sudo iptables -A INPUT -p tcp -s $SSH_SRC --dport $SSH_PRT -j ACCEPT
fi
# docker rules

4
scripts/update.sh

@ -10,11 +10,15 @@ sudo git -C /opt/mistborn submodule update --init --recursive @@ -10,11 +10,15 @@ sudo git -C /opt/mistborn submodule update --init --recursive
# ensure mistborn-cli is installed
sudo pip3 install -e /opt/mistborn/modules/mistborn-cli
# handle updates to Mistborn systemd scripts
iface=$(ip -o -4 route show to default | egrep -o 'dev [^ ]*' | awk 'NR==1{print $2}')
sudo cp /opt/mistborn/scripts/services/Mistborn* /etc/systemd/system/
sudo find /etc/systemd/system/ -type f -name 'Mistborn*' | xargs sudo sed -i "s/User=root/User=mistborn/"
sudo find /etc/systemd/system/ -type f -name 'Mistborn*' | xargs sudo sed -i "s/DIFACE/$iface/"
# handle updates to traefik
sudo cp /opt/mistborn/compose/production/traefik/traefik.toml.template /opt/mistborn/compose/production/traefik/traefik.toml
sudo systemctl daemon-reload
sudo systemctl enable Mistborn-setup.service
sudo systemctl restart Mistborn-setup.service

Loading…
Cancel
Save