Browse Source

scripts and base

merge-requests/1/head
Steven Foerster 6 years ago
parent
commit
c97ce52398
  1. 169
      base.yml
  2. 8
      scripts/conf/15-iptables.conf
  3. 2
      scripts/conf/20auto-upgrades
  4. 36
      scripts/conf/50unattended-upgrades
  5. 3
      scripts/conf/cockpit.conf
  6. 246
      scripts/install.sh
  7. 8
      scripts/route_domains.txt
  8. 37
      scripts/services/Mistborn-base.service
  9. 23
      scripts/services/Mistborn-bitwarden.service
  10. 21
      scripts/services/Mistborn-homeassistant.service
  11. 21
      scripts/services/Mistborn-jellyfin.service
  12. 21
      scripts/services/Mistborn-nextcloud.service
  13. 21
      scripts/services/Mistborn-onlyoffice.service
  14. 21
      scripts/services/Mistborn-raspap.service
  15. 23
      scripts/services/Mistborn-rocketchat.service
  16. 25
      scripts/services/Mistborn-syncthing.service
  17. 23
      scripts/services/Mistborn-tor.service
  18. 4
      scripts/services/raspap/install.sh
  19. 29
      scripts/subinstallers/cockpit.sh
  20. 70
      scripts/subinstallers/docker.sh
  21. 63
      scripts/subinstallers/gen_prod_env.sh
  22. 119
      scripts/subinstallers/iptables.sh
  23. 22
      scripts/subinstallers/wireguard.sh

169
base.yml

@ -0,0 +1,169 @@ @@ -0,0 +1,169 @@
version: '3'
volumes:
production_postgres_data: {}
production_postgres_data_backups: {}
production_traefik: {}
services:
django: &django
image: cyber5k/mistborn:latest
container_name: mistborn_production_django
depends_on:
- postgres
- redis
labels:
- "traefik.enable=true"
- "traefik.port=5000"
env_file:
- ./.envs/.production/.django
- ./.envs/.production/.postgres
volumes:
- ../mistborn_volumes/base/media:/mistborn-media
- ../mistborn_volumes/base/private_media:/mistborn-private-media
command: /start
postgres:
build:
context: .
dockerfile: ./compose/production/postgres/Dockerfile
image: mistborn_production_postgres
container_name: mistborn_production_postgres
volumes:
- production_postgres_data:/var/lib/postgresql/data
- production_postgres_data_backups:/backups
env_file:
- ./.envs/.production/.postgres
traefik:
build:
context: .
dockerfile: ./compose/production/traefik/Dockerfile
image: mistborn_production_traefik
container_name: mistborn_production_traefik
depends_on:
- django
volumes:
- production_traefik:/etc/traefik/acme
- /var/run/docker.sock:/var/run/docker.sock:ro
ports:
- "0.0.0.0:80:80/tcp"
redis:
image: redis:5.0
container_name: mistborn_production_redis
celeryworker:
image: cyber5k/mistborn:latest
container_name: mistborn_production_celeryworker
volumes:
- ../mistborn_volumes/base/media:/mistborn-media
- ../mistborn_volumes/base/private_media:/mistborn-private-media
env_file:
- ./.envs/.production/.django
- ./.envs/.production/.postgres
- ./.envs/.production/.pihole
networks:
default:
dns_net:
ipv4_address: 10.2.1.3
dns:
- 10.2.1.2
depends_on:
- traefik
- pihole
command: /start-celeryworker
celeryworker-low-priority:
image: cyber5k/mistborn:latest
container_name: mistborn_production_celeryworker_low_priority
volumes:
- ../mistborn_volumes/base/media:/mistborn-media
- ../mistborn_volumes/base/private_media:/mistborn-private-media
env_file:
- ./.envs/.production/.django
- ./.envs/.production/.postgres
- ./.envs/.production/.pihole
networks:
default:
dns_net:
ipv4_address: 10.2.1.4
dns:
- 10.2.1.2
depends_on:
- traefik
- pihole
command: /start-celeryworker-low-priority
celerybeat:
image: cyber5k/mistborn:latest
container_name: mistborn_production_celerybeat
env_file:
- ./.envs/.production/.django
- ./.envs/.production/.postgres
command: /start-celerybeat
flower:
image: cyber5k/mistborn:latest
container_name: mistborn_production_flower
ports:
- "5555:5555/tcp"
command: /start-flower
pihole:
container_name: mistborn_production_pihole
image: pihole/pihole:latest
ports:
- "53:53/tcp"
- "53:53/udp"
labels:
- "traefik.enable=true"
environment:
- ServerIP=10.2.0.3
- DNS1='10.2.0.2#5054' # docs say port 5054, was 54; use network_mode: host to see which port is used
- DNS2=''
- IPv6='false'
- DNSMASQ_LISTENING=all
# TZ: 'America/New York'
# Volumes store your data between container upgrades
env_file:
- ./.envs/.production/.pihole
volumes:
- ../mistborn_volumes/base/pihole/etc-pihole:/etc/pihole/
- ../mistborn_volumes/base/pihole/etc-dnsmasqd:/etc/dnsmasq.d/
dns:
- 127.0.0.1
networks:
default:
pihole_net:
ipv4_address: 10.2.0.3
dns_net:
ipv4_address: 10.2.1.2
restart: unless-stopped
dnscrypt-proxy:
container_name: mistborn_production_dnscrypt_proxy
image: djaydev/dnscrypt-proxy
environment:
- DNSCRYPT_LISTEN_PORT=5054
# resolvers: https://download.dnscrypt.info/dnscrypt-resolvers/v2/public-resolvers.md
#- DNSCRYPT_SERVER_NAMES=['scaleway-fr','google','yandex','cloudflare']
- DNSCRYPT_SERVER_NAMES=['cloudflare','dnswarden-doh1','dnswarden-doh2','dnswarden-doh3','securedns-doh','adguard-dns-doh']
networks:
pihole_net:
ipv4_address: 10.2.0.2
restart: unless-stopped
networks:
pihole_net:
driver: bridge
ipam:
config:
- subnet: 10.2.0.0/29
dns_net:
driver: bridge
ipam:
config:
- subnet: 10.2.1.0/24

8
scripts/conf/15-iptables.conf

@ -0,0 +1,8 @@ @@ -0,0 +1,8 @@
# Log kernel iptables dropped messages to iptables.log
$template MyTemplate,"%$day%-%timegenerated:1:3:date-rfc3164%-%$year% %timegenerated:12:19:date-rfc3339% %HOSTNAME% %syslogtag% %msg%\n"
:msg,contains,"[IPTables-Dropped]:" /var/log/iptables.log;MyTemplate #RSYSLOG_FileFormat
# Uncomment the following to stop logging anything that matches the last rule.
# Doing this will stop logging kernel generated UFW log messages to the file
# normally containing kern.* messages (eg, /var/log/kern.log)
#& stop

2
scripts/conf/20auto-upgrades

@ -0,0 +1,2 @@ @@ -0,0 +1,2 @@
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";

36
scripts/conf/50unattended-upgrades

@ -0,0 +1,36 @@ @@ -0,0 +1,36 @@
// Automatically upgrade packages from these (origin, archive) pairs
Unattended-Upgrade::Allowed-Origins {
// ${distro_id} and ${distro_codename} will be automatically expanded
"${distro_id} stable";
"${distro_id} ${distro_codename}-security";
// Autoupdate Nginx
"nginx:${distro_codename}";
// Autoupdate WireGuard
"LP-PPA-wireguard-wireguard:${distro_codename}";
};
// List of packages to not update
Unattended-Upgrade::Package-Blacklist {
};
// Do automatic removal of new unused dependencies after the upgrade
// (equivalent to apt-get autoremove)
Unattended-Upgrade::Remove-Unused-Dependencies "true";
// Automatically reboot *WITHOUT CONFIRMATION* if a
// the file /var/run/reboot-required is found after the upgrade
Unattended-Upgrade::Automatic-Reboot "true";
// If automatic reboot is enabled and needed, reboot at the specific
// time instead of immediately
// Default: "now"
Unattended-Upgrade::Automatic-Reboot-Time "00:00";
// Avoid conffile dpkg prompt by *always* leaving the modified configuration in
// place and putting the new package configuration in a .dpkg-dist file
Dpkg::Options {
"--force-confdef";
"--force-confold";
};

3
scripts/conf/cockpit.conf

@ -0,0 +1,3 @@ @@ -0,0 +1,3 @@
[WebService]
ProtocolHeader = X-Forwarded-Proto
AllowUnencrypted=true

246
scripts/install.sh

@ -0,0 +1,246 @@ @@ -0,0 +1,246 @@
#!/bin/bash
set -e
## ensure run as nonroot user
#if [ "$EUID" -eq 0 ]; then
MISTBORN_USER="mistborn"
if [ $(whoami) != "$MISTBORN_USER" ]; then
echo "Creating user: $MISTBORN_USER"
sudo useradd -s /bin/bash -d /home/$MISTBORN_USER -m -G sudo $MISTBORN_USER 2>/dev/null || true
SCRIPTPATH="$( cd "$(dirname "$0")" ; pwd -P )"
#echo "SCRIPTPATH: $SCRIPTPATH"
FILENAME=$(basename -- "$0")
#echo "FILENAME: $FILENAME"
FULLPATH="$SCRIPTPATH/$FILENAME"
#echo "FULLPATH: $FULLPATH"
# SUDO
case `sudo grep -e "^$MISTBORN_USER.*" /etc/sudoers >/dev/null; echo $?` in
0)
echo "$MISTBORN_USER already in sudoers"
;;
1)
echo "Adding $MISTBORN_USER to sudoers"
sudo bash -c "echo '$MISTBORN_USER ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers"
;;
*)
echo "There was a problem checking sudoers"
;;
esac
# get git branch if one exists (default to master)
pushd .
cd $SCRIPTPATH
GIT_BRANCH=$(git symbolic-ref --short HEAD || echo "master")
popd
sudo cp $FULLPATH /home/$MISTBORN_USER
sudo chown $MISTBORN_USER:$MISTBORN_USER /home/$MISTBORN_USER/$FILENAME
sudo SSH_CLIENT="$SSH_CLIENT" MISTBORN_DEFAULT_PASSWORD="$MISTBORN_DEFAULT_PASSWORD" GIT_BRANCH="$GIT_BRANCH" -i -u $MISTBORN_USER bash -c "/home/$MISTBORN_USER/$FILENAME" # self-referential call
exit 0
fi
echo "Running as $USER"
# banner
echo -e " ____ _ ____ _ __"
echo -e " / ___| _| |__ ___ _ __ | ___|| |/ /"
echo -e "| | | | | | '_ \ / _ \ '__| |___ \| ' /"
echo -e "| |__| |_| | |_) | __/ | ___) | . \ "
echo -e " \____\__, |_.__/ \___|_| |____/|_|\_\ "
echo -e " |___/"
echo -e " __ __ _ _ _"
echo -e "| \/ (_)___| |_| |__ ___ _ __ _ __"
echo -e "| |\/| | / __| __| '_ \ / _ \| '__| '_ \ "
echo -e "| | | | \__ \ |_| |_) | (_) | | | | | |"
echo -e "|_| |_|_|___/\__|_.__/ \___/|_| |_| |_|"
echo -e ""
# Get OS info
# Determine OS platform
UNAME=$(uname | tr "[:upper:]" "[:lower:]")
DISTRO=""
# If Linux, try to determine specific distribution
if [ "$UNAME" == "linux" ]; then
# use /etc/os-release to get distro
DISTRO=$(cat /etc/os-release | awk -F= '/^ID=/{print $2}')
fi
echo "UNAME: $UNAME"
echo "DISTRO: $DISTRO"
# INPUT default admin password
if [ -z "${MISTBORN_DEFAULT_PASSWORD}" ]; then
read -p "(Mistborn) Set default admin password: " -s MISTBORN_DEFAULT_PASSWORD
echo
else
echo "MISTBORN_DEFAULT_PASSWORD is already set"
fi
# SSH keys
if [ ! -f ~/.ssh/id_rsa ]; then
echo "Generating SSH keypair for $USER"
ssh-keygen -t rsa -b 4096 -N "" -m pem -f ~/.ssh/id_rsa -q
# Authorized keys
echo "from=\"172.16.0.0/12,192.168.0.0/16,10.0.0.0/8\" $(cat ~/.ssh/id_rsa.pub)" > ~/.ssh/authorized_keys
else
echo "SSH key exists for $USER"
fi
sudo rm -rf /opt/mistborn 2>/dev/null || true
# clone to /opt and change directory
echo "Cloning $GIT_BRANCH branch from mistborn repo"
sudo git clone https://gitlab.com/cyber5k/mistborn.git -b $GIT_BRANCH /opt/mistborn
sudo chown -R $USER:$USER /opt/mistborn
pushd .
cd /opt/mistborn
git submodule update --init --recursive
# iptables
echo "Setting up firewall (iptables)"
if [ ! -f "/etc/iptables/rules.v4" ]; then
echo "Setting iptables rules..."
./scripts/subinstallers/iptables.sh
else
echo "iptables rules exist. Leaving alone."
fi
# SSH Server
sudo apt-get install -y openssh-server
sudo sed -i 's/#PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config
sudo sed -i 's/PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config
sudo sed -i 's/#PermitRootLogin.*/PermitRootLogin prohibit-password/' /etc/ssh/sshd_config
sudo sed -i 's/PermitRootLogin.*/PermitRootLogin prohibit-password/' /etc/ssh/sshd_config
sudo systemctl restart ssh
# Additional tools fail2ban
sudo apt-get install -y dnsutils fail2ban
# Install kernel headers
if [ "$DISTRO" == "ubuntu" ] || [ "$DISTRO" == "debian" ]; then
sudo apt install -y linux-headers-$(uname -r)
elif [ "$DISTRO" == "raspbian" ]; then
sudo apt-get install -y raspberrypi-kernel-headers
fi
# Wireugard
source ./scripts/subinstallers/wireguard.sh
# Docker
source ./scripts/subinstallers/docker.sh
# Unattended upgrades
sudo apt-get install -y unattended-upgrades
# Cockpit
source ./scripts/subinstallers/cockpit.sh
# Mistborn
# final setup vars
iface=$(ip -o -4 route show to default | egrep -o 'dev [^ ]*' | awk '{print $2}')
IPV4_PUBLIC=$(ip -o -4 route show default | egrep -o 'dev [^ ]*' | awk '{print $2}' | xargs ip -4 addr show | grep 'inet ' | awk '{print $2}' | grep -o "^[0-9.]*" | tr -cd '\11\12\15\40-\176' | head -1) # tail -1 to get last
# clean
if [ -f "/etc/systemd/system/Mistborn-base.service" ]; then
sudo systemctl stop Mistborn*.service 2>/dev/null || true
sudo systemctl disable Mistborn*.service 2>/dev/null || true
fi
sudo docker volume rm -f mistborn_production_postgres_data 2>/dev/null || true
sudo docker volume rm -f mistborn_production_postgres_data_backups 2>/dev/null || true
sudo docker volume rm -f mistborn_production_traefik 2>/dev/null || true
# generate production .env file
if [ ! -d ./.envs/.production ]; then
./scripts/subinstallers/gen_prod_env.sh "$MISTBORN_DEFAULT_PASSWORD"
fi
# unattended upgrades
sudo cp ./scripts/conf/20auto-upgrades /etc/apt/apt.conf.d/
sudo cp ./scripts/conf/50unattended-upgrades /etc/apt/apt.conf.d/
sudo systemctl stop unattended-upgrades
sudo systemctl daemon-reload
sudo systemctl restart unattended-upgrades
# setup Mistborn services
# install and start base services
# default interface
sudo cp ./scripts/services/Mistborn* /etc/systemd/system/
sudo find /etc/systemd/system/ -type f -name 'Mistborn*' | xargs sudo sed -i "s/User=.*/User=$USER/"
sudo find /etc/systemd/system/ -type f -name 'Mistborn*' | xargs sudo sed -i "s/ root:root / $USER:$USER /"
sudo find /etc/systemd/system/ -type f -name 'Mistborn*' | xargs sudo sed -i "s/DIFACE/$iface/"
if [ "$DISTRO" == "debian" ] || [ "$DISTRO" == "raspbian" ]; then
# remove systemd-resolved lines
sudo sed -i '/.*systemd-resolved/d' /etc/systemd/system/Mistborn-base.service
fi
# set default password (hashed form will write over)
mkdir -p ./mistborn/users/files
echo $MISTBORN_DEFAULT_PASSWORD > ./mistborn/users/files/default_pw
# volumes init with ssh
#mkdir -p ./compose/production/ssh/
#cp -r ~/.ssh/* ./compose/production/ssh/
# setup local volumes for pihole
sudo mkdir -p ../mistborn_volumes/
sudo chown -R root:root ../mistborn_volumes/
sudo mkdir -p ../mistborn_volumes/base/pihole/etc-pihole
sudo mkdir -p ../mistborn_volumes/base/pihole/etc-dnsmasqd
echo "addn-hosts=/etc/pihole/lan.list" | sudo tee ../mistborn_volumes/base/pihole/etc-dnsmasqd/02-lan.conf
sudo touch ../mistborn_volumes/base/pihole/etc-pihole/lan.list
sudo mkdir -p ../mistborn_volumes/extra
# Traefik final setup (cockpit)
sudo sed -i "s/IPV4_PUBLIC/$IPV4_PUBLIC/" ./compose/production/traefik/traefik.toml
# Download docker images while DNS is operable
sudo docker-compose -f base.yml pull 2>/dev/null || true
sudo docker-compose -f base.yml build
# DNS
sudo systemctl stop systemd-resolved 2>/dev/null || true
sudo systemctl disable systemd-resolved 2>/dev/null || true
# array of dns entries to add (not not already present)
declare -a dnslist=("pihole.mistborn" \
"home.mistborn" \
"hass.mistborn" \
"syncthing.mistborn" \
"chat.mistborn" \
"tor.mistborn" \
"nextcloud.mistborn" \
"onlyoffice.mistborn" \
"bitwarden.mistborn" \
"jellyfin.mistborn" \
"raspap.mistborn" \
"cockpit.mistborn")
for dnsname in "${dnslist[@]}"
do
sudo grep -qF "$dnsname" ../mistborn_volumes/base/pihole/etc-pihole/lan.list \
&& echo "$dnsname already in DNS" \
|| echo "$IPV4_PUBLIC $dnsname" | sudo tee -a ../mistborn_volumes/base/pihole/etc-pihole/lan.list
done
# ResolvConf (OpenResolv installed with Wireguard)
sudo sed -i "s/#name_servers.*/name_servers=$IPV4_PUBLIC/" /etc/resolvconf.conf
sudo sed -i "s/name_servers.*/name_servers=$IPV4_PUBLIC/" /etc/resolvconf.conf
#sudo sed -i "s/#name_servers.*/name_servers=127.0.0.1/" /etc/resolvconf.conf
sudo resolvconf -u 1>/dev/null 2>&1
echo "backup up original volumes folder"
sudo mkdir -p ../mistborn_backup
sudo tar -czf ../mistborn_backup/mistborn_volumes_backup.tar.gz ../mistborn_volumes 1>/dev/null 2>&1
# start base service
sudo systemctl enable Mistborn-base.service
sudo systemctl start Mistborn-base.service
popd

8
scripts/route_domains.txt

@ -0,0 +1,8 @@ @@ -0,0 +1,8 @@
netflix.com
nflxext.com
nflximg.com
nflxvideo.net
nflxso.net
amazonaws.com
hulu.com
whatismyipaddress.com

37
scripts/services/Mistborn-base.service

@ -0,0 +1,37 @@ @@ -0,0 +1,37 @@
[Unit]
Description=Mistborn Base
Requires=docker.service
After=docker.service
[Service]
Restart=always
User=root
Group=docker
PermissionsStartOnly=true
# Shutdown container (if running) when unit is stopped
ExecStartPre=/usr/local/bin/docker-compose -f /opt/mistborn/base.yml down
ExecStartPre=/bin/chown -R root:root /opt/mistborn_volumes/
ExecStartPre=/usr/local/bin/docker-compose -f /opt/mistborn/base.yml build
ExecStartPre=/bin/systemctl stop systemd-resolved
ExecStartPre=/sbin/iptables -I DOCKER-USER -i DIFACE -p udp --dport 53 -j MISTBORN_LOG_DROP
ExecStartPre=/sbin/iptables -I DOCKER-USER -i DIFACE -p tcp --dport 53 -j MISTBORN_LOG_DROP
ExecStartPre=/sbin/iptables -I DOCKER-USER -i DIFACE -p tcp --dport 80 -j MISTBORN_LOG_DROP
ExecStartPre=/sbin/iptables -I DOCKER-USER -i DIFACE -p tcp --dport 5555 -j MISTBORN_LOG_DROP
ExecStartPre=/sbin/iptables -A OUTPUT -o DIFACE -p udp --dport 53 -j MISTBORN_LOG_DROP
ExecStartPre=/sbin/ip6tables -A OUTPUT -p udp --dport 53 -j MISTBORN_LOG_DROP
ExecStartPre=/sbin/resolvconf -u
# Start container when unit is started
ExecStart=/usr/local/bin/docker-compose -f /opt/mistborn/base.yml up
# Stop container when unit is stopped
ExecStop=/usr/local/bin/docker-compose -f /opt/mistborn/base.yml down
# Post stop
ExecStopPost=/sbin/iptables -D DOCKER-USER -i DIFACE -p udp --dport 53 -j MISTBORN_LOG_DROP
ExecStopPost=/sbin/iptables -D DOCKER-USER -i DIFACE -p tcp --dport 53 -j MISTBORN_LOG_DROP
ExecStopPost=/sbin/iptables -D DOCKER-USER -i DIFACE -p tcp --dport 80 -j MISTBORN_LOG_DROP
ExecStopPost=/sbin/iptables -D DOCKER-USER -i DIFACE -p tcp --dport 5555 -j MISTBORN_LOG_DROP
ExecStopPost=/sbin/iptables -D OUTPUT -o DIFACE -p udp --dport 53 -j MISTBORN_LOG_DROP
ExecStopPost=/sbin/ip6tables -D OUTPUT -p udp --dport 53 -j MISTBORN_LOG_DROP
ExecStopPost=/bin/systemctl start systemd-resolved
[Install]
WantedBy=multi-user.target

23
scripts/services/Mistborn-bitwarden.service

@ -0,0 +1,23 @@ @@ -0,0 +1,23 @@
[Unit]
Description=Mistborn Bitwarden Service
Requires=Mistborn-base.service
After=Mistborn-base.service
[Service]
Restart=always
User=root
Group=docker
PermissionsStartOnly=true
# Shutdown container (if running) when unit is stopped
ExecStartPre=/usr/local/bin/docker-compose -f /opt/mistborn/extra/bitwarden.yml down
ExecStartPre=/bin/chown -R --from=root:root root:root /opt/mistborn_volumes/
ExecStartPre=/sbin/iptables -I DOCKER-USER -i DIFACE -p tcp --dport 3012 -j MISTBORN_LOG_DROP
# Start container when unit is started
ExecStart=/usr/local/bin/docker-compose -f /opt/mistborn/extra/bitwarden.yml up --build
# Stop container when unit is stopped
ExecStop=/usr/local/bin/docker-compose -f /opt/mistborn/extra/bitwarden.yml down
# Post stop
ExecStopPost=/sbin/iptables -D DOCKER-USER -i DIFACE -p tcp --dport 3012 -j MISTBORN_LOG_DROP
[Install]
WantedBy=multi-user.target

21
scripts/services/Mistborn-homeassistant.service

@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
[Unit]
Description=Mistborn Home Assistant
Requires=Mistborn-base.service
After=Mistborn-base.service
[Service]
Restart=always
User=root
Group=docker
PermissionsStartOnly=true
# Shutdown container (if running) when unit is stopped
ExecStartPre=/usr/local/bin/docker-compose -f /opt/mistborn/extra/homeassistant.yml down
ExecStartPre=/bin/chown -R --from=root:root root:root /opt/mistborn_volumes/
# Start container when unit is started
ExecStart=/usr/local/bin/docker-compose -f /opt/mistborn/extra/homeassistant.yml up --build
# Stop container when unit is stopped
ExecStop=/usr/local/bin/docker-compose -f /opt/mistborn/extra/homeassistant.yml down
# Post stop
[Install]
WantedBy=multi-user.target

21
scripts/services/Mistborn-jellyfin.service

@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
[Unit]
Description=Mistborn Jellyfin Service
Requires=Mistborn-nextcloud.service
After=Mistborn-nextcloud.service
[Service]
Restart=always
User=root
Group=docker
PermissionsStartOnly=true
# Shutdown container (if running) when unit is stopped
ExecStartPre=/usr/local/bin/docker-compose -f /opt/mistborn/extra/jellyfin.yml down
ExecStartPre=/bin/chown -R --from=root:root root:root /opt/mistborn_volumes/
# Start container when unit is started
ExecStart=/usr/local/bin/docker-compose -f /opt/mistborn/extra/jellyfin.yml up --build
# Stop container when unit is stopped
ExecStop=/usr/local/bin/docker-compose -f /opt/mistborn/extra/jellyfin.yml down
# Post stop
[Install]
WantedBy=multi-user.target

21
scripts/services/Mistborn-nextcloud.service

@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
[Unit]
Description=Mistborn Nextcloud Service
Requires=Mistborn-base.service
After=Mistborn-base.service
[Service]
Restart=always
User=root
Group=docker
PermissionsStartOnly=true
# Shutdown container (if running) when unit is stopped
ExecStartPre=/usr/local/bin/docker-compose -f /opt/mistborn/extra/nextcloud.yml down
ExecStartPre=/bin/chown -R --from=root:root root:root /opt/mistborn_volumes/
# Start container when unit is started
ExecStart=/usr/local/bin/docker-compose -f /opt/mistborn/extra/nextcloud.yml up --build
# Stop container when unit is stopped
ExecStop=/usr/local/bin/docker-compose -f /opt/mistborn/extra/nextcloud.yml down
# Post stop
[Install]
WantedBy=multi-user.target

21
scripts/services/Mistborn-onlyoffice.service

@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
[Unit]
Description=Mistborn OnlyOffice Service
Requires=Mistborn-base.service
After=Mistborn-base.service
[Service]
Restart=always
User=root
Group=docker
PermissionsStartOnly=true
# Shutdown container (if running) when unit is stopped
ExecStartPre=/usr/local/bin/docker-compose -f /opt/mistborn/extra/onlyoffice.yml down
ExecStartPre=/bin/chown -R --from=root:root root:root /opt/mistborn_volumes/
# Start container when unit is started
ExecStart=/usr/local/bin/docker-compose -f /opt/mistborn/extra/onlyoffice.yml up --build
# Stop container when unit is stopped
ExecStop=/usr/local/bin/docker-compose -f /opt/mistborn/extra/onlyoffice.yml down
# Post stop
[Install]
WantedBy=multi-user.target

21
scripts/services/Mistborn-raspap.service

@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
[Unit]
Description=Mistborn RaspAP Service
Requires=Mistborn-base.service
After=Mistborn-base.service
[Service]
Restart=always
User=root
Group=docker
PermissionsStartOnly=true
# Shutdown container (if running) when unit is stopped
ExecStartPre=/usr/local/bin/docker-compose -f /opt/mistborn/extra/raspap.yml down
ExecStartPre=/bin/chown -R --from=root:root root:root /opt/mistborn_volumes/
# Start container when unit is started
ExecStart=/usr/local/bin/docker-compose -f /opt/mistborn/extra/raspap.yml up --build
# Stop container when unit is stopped
ExecStop=/usr/local/bin/docker-compose -f /opt/mistborn/extra/raspap.yml down
# Post stop
[Install]
WantedBy=multi-user.target

23
scripts/services/Mistborn-rocketchat.service

@ -0,0 +1,23 @@ @@ -0,0 +1,23 @@
[Unit]
Description=Mistborn Rocket Chat Service
Requires=Mistborn-base.service
After=Mistborn-base.service
[Service]
Restart=always
User=root
Group=docker
PermissionsStartOnly=true
# Shutdown container (if running) when unit is stopped
ExecStartPre=/usr/local/bin/docker-compose -f /opt/mistborn/extra/rocketchat.yml down
ExecStartPre=/bin/chown -R --from=root:root root:root /opt/mistborn_volumes/
ExecStartPre=/sbin/iptables -I DOCKER-USER -i DIFACE -p tcp --dport 3001 -j MISTBORN_LOG_DROP
# Start container when unit is started
ExecStart=/usr/local/bin/docker-compose -f /opt/mistborn/extra/rocketchat.yml up --build
# Stop container when unit is stopped
ExecStop=/usr/local/bin/docker-compose -f /opt/mistborn/extra/rocketchat.yml down
# Post stop
ExecStopPost=/sbin/iptables -D DOCKER-USER -i DIFACE -p tcp --dport 3001 -j MISTBORN_LOG_DROP
[Install]
WantedBy=multi-user.target

25
scripts/services/Mistborn-syncthing.service

@ -0,0 +1,25 @@ @@ -0,0 +1,25 @@
[Unit]
Description=Mistborn Syncthing Service
Requires=Mistborn-base.service
After=Mistborn-base.service
[Service]
Restart=always
User=root
Group=docker
PermissionsStartOnly=true
# Shutdown container (if running) when unit is stopped
ExecStartPre=/usr/local/bin/docker-compose -f /opt/mistborn/extra/syncthing.yml down
ExecStartPre=/bin/chown -R --from=root:root root:root /opt/mistborn_volumes/
ExecStartPre=/sbin/iptables -I DOCKER-USER -i DIFACE -p udp --dport 21027 -j MISTBORN_LOG_DROP
ExecStartPre=/sbin/iptables -I DOCKER-USER -i DIFACE -p tcp --dport 22000 -j MISTBORN_LOG_DROP
# Start container when unit is started
ExecStart=/usr/local/bin/docker-compose -f /opt/mistborn/extra/syncthing.yml up --build
# Stop container when unit is stopped
ExecStop=/usr/local/bin/docker-compose -f /opt/mistborn/extra/syncthing.yml down
# Post stop
ExecStopPost=/sbin/iptables -D DOCKER-USER -i DIFACE -p udp --dport 21027 -j MISTBORN_LOG_DROP
ExecStopPost=/sbin/iptables -D DOCKER-USER -i DIFACE -p tcp --dport 22000 -j MISTBORN_LOG_DROP
[Install]
WantedBy=multi-user.target

23
scripts/services/Mistborn-tor.service

@ -0,0 +1,23 @@ @@ -0,0 +1,23 @@
[Unit]
Description=Mistborn Tor Service
Requires=Mistborn-base.service
After=Mistborn-base.service
[Service]
Restart=always
User=root
Group=docker
PermissionsStartOnly=true
# Shutdown container (if running) when unit is stopped
ExecStartPre=/usr/local/bin/docker-compose -f /opt/mistborn/extra/tor.yml down
ExecStartPre=/bin/chown -R --from=root:root root:root /opt/mistborn_volumes/
ExecStartPre=/sbin/iptables -I DOCKER-USER -i DIFACE -p tcp --dport 9150 -j MISTBORN_LOG_DROP
# Start container when unit is started
ExecStart=/usr/local/bin/docker-compose -f /opt/mistborn/extra/tor.yml up --build
# Stop container when unit is stopped
ExecStop=/usr/local/bin/docker-compose -f /opt/mistborn/extra/tor.yml down
# Post stop
ExecStopPost=/sbin/iptables -D DOCKER-USER -i DIFACE -p tcp --dport 9150 -j MISTBORN_LOG_DROP
[Install]
WantedBy=multi-user.target

4
scripts/services/raspap/install.sh

@ -0,0 +1,4 @@ @@ -0,0 +1,4 @@
#!/bin/bash
# install on gateway
sudo apt-get install -y hostapd vnstat

29
scripts/subinstallers/cockpit.sh

@ -0,0 +1,29 @@ @@ -0,0 +1,29 @@
#!/bin/bash
# Cockpit
echo "Installing Cockpit"
if [ "$DISTRO" == "ubuntu" ]; then
echo "Ubuntu backports enabled by default"
sudo apt-get install -y cockpit cockpit-docker
elif [ "$DISTRO" == "debian" ]; then
sudo grep -qF "buster-backports" /etc/apt/sources.list.d/backports.list \
&& echo "buster-backports already in sources" \
|| echo 'deb http://deb.debian.org/debian buster-backports main' | sudo tee -a /etc/apt/sources.list.d/backports.list
sudo apt-get install -y cockpit cockpit-docker
elif [ "$DISTRO" == "raspbian" ]; then
echo "Raspbian repos contain cockpit"
sudo apt-get install -y cockpit cockpit-docker
fi
sudo cp ./scripts/conf/cockpit.conf /etc/cockpit/cockpit.conf
sudo systemctl restart cockpit.socket
# create system cockpit user
echo "Creating cockpit user"
sudo useradd -s /bin/bash -d /home/cockpit -m -G sudo -p $(openssl passwd -1 "$MISTBORN_DEFAULT_PASSWORD") cockpit || true

70
scripts/subinstallers/docker.sh

@ -0,0 +1,70 @@ @@ -0,0 +1,70 @@
#!/bin/bash
# Docker
# dependencies
echo "Installing Docker dependencies"
sudo apt-get install -y \
apt-transport-https \
ca-certificates \
curl \
gnupg-agent \
software-properties-common
# Docker repo key
echo "Adding docker repository key"
if [ "$DISTRO" == "ubuntu" ]; then
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
elif [ "$DISTRO" == "debian" ]; then
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add -
elif [ "$DISTRO" == "raspbian" ]; then
curl -fsSL https://download.docker.com/linux/$(. /etc/os-release; echo "$ID")/gpg | sudo apt-key add -
fi
# Docker repo to source list
echo "Adding docker to sources list"
if [ "$DISTRO" == "ubuntu" ]; then
sudo add-apt-repository -y \
"deb https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
elif [ "$DISTRO" == "debian" ]; then
sudo add-apt-repository -y \
"deb https://download.docker.com/linux/debian \
$(lsb_release -cs) \
stable"
elif [ "$DISTRO" == "raspbian" ]; then
echo "deb [arch=armhf] https://download.docker.com/linux/$(. /etc/os-release; echo "$ID") \
$(lsb_release -cs) stable" | \
sudo tee /etc/apt/sources.list.d/docker.list
fi
# install Docker
echo "Installing docker"
sudo apt-get update
if [ "$DISTRO" == "ubuntu" ] || [ "$DISTRO" == "debian" ]; then
sudo apt-get install -y docker-ce docker-ce-cli containerd.io
elif [ "$DISTRO" == "raspbian" ]; then
sudo apt install -y --no-install-recommends \
docker-ce \
cgroupfs-mount
fi
# Docker group
sudo usermod -aG docker $USER
# Docker Compose
echo "Installing Docker Compose"
#if [ "$DISTRO" == "ubuntu" ] || [ "$DISTRO" == "debian" ]; then
# sudo curl -L "https://github.com/docker/compose/releases/download/1.24.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# sudo chmod +x /usr/local/bin/docker-compose
#elif [ "$DISTRO" == "raspbian" ]; then
# Install required packages
sudo apt update
sudo apt install -y python python3-pip libffi-dev python-backports.ssl-match-hostname
# Install Docker Compose from pip
# This might take a while
sudo pip3 install docker-compose
#fi

63
scripts/subinstallers/gen_prod_env.sh

@ -0,0 +1,63 @@ @@ -0,0 +1,63 @@
#!/bin/sh
# generate production .env file for Django
mkdir -p ./.envs/.production
DJANGO_PROD_FILE="./.envs/.production/.django"
DJANGO_SECRET_KEY=$(python3 -c "import secrets; import string; print(f''.join([secrets.choice(string.ascii_letters+string.digits) for x in range(50)]))")
#CELERY_FLOWER_PASSWORD=$(python3 -c "import secrets; import string; print(f''.join([secrets.choice(string.ascii_letters+string.digits) for x in range(32)]))")
CELERY_FLOWER_PASSWORD="$1"
echo "DJANGO_SETTINGS_MODULE=config.settings.production" > $DJANGO_PROD_FILE
echo "DJANGO_SECRET_KEY=$DJANGO_SECRET_KEY" >> $DJANGO_PROD_FILE
echo "DJANGO_ADMIN_URL=admin/" >> $DJANGO_PROD_FILE
echo "USE_DOCKER=yes" >> $DJANGO_PROD_FILE
echo "REDIS_URL=redis://redis:6379/0" >> $DJANGO_PROD_FILE
echo "CELERY_FLOWER_USER=prod" >> $DJANGO_PROD_FILE
echo "CELERY_FLOWER_PASSWORD=$CELERY_FLOWER_PASSWORD" >> $DJANGO_PROD_FILE
echo "#MAILGUN_API_KEY=" >> $DJANGO_PROD_FILE
echo "#MAILGUN_API_URL=" >> $DJANGO_PROD_FILE
echo "#SENTRY_DNS=" >> $DJANGO_PROD_FILE
# generate production .env file for postgresql
POSTGRES_PROD_FILE="./.envs/.production/.postgres"
POSTGRES_PASSWORD=$(python3 -c "import secrets; import string; print(f''.join([secrets.choice(string.ascii_letters+string.digits) for x in range(32)]))")
echo "POSTGRES_HOST=postgres" > $POSTGRES_PROD_FILE
echo "POSTGRES_PORT=5432" >> $POSTGRES_PROD_FILE
echo "POSTGRES_DB=mistborn" >> $POSTGRES_PROD_FILE
echo "POSTGRES_USER=prod" >> $POSTGRES_PROD_FILE
echo "POSTGRES_PASSWORD=$POSTGRES_PASSWORD" >> $POSTGRES_PROD_FILE
# generate production .env file for pihole
PIHOLE_PROD_FILE="./.envs/.production/.pihole"
#WEBPASSWORD=$(python3 -c "import secrets; import string; print(f''.join([secrets.choice(string.ascii_letters+string.digits) for x in range(32)]))")
WEBPASSWORD="$1"
echo "TZ=\"America/New York\"" > $PIHOLE_PROD_FILE
echo "WEBPASSWORD=$WEBPASSWORD" >> $PIHOLE_PROD_FILE
# generate rocketchat .env files
ROCKETCHAT_PROD_FILE="./.envs/.production/.rocketchat"
#ROCKETCHAT_PASSWORD=$(python3 -c "import secrets; import string; print(f''.join([secrets.choice(string.ascii_letters+string.digits) for x in range(32)]))")
ROCKETCHAT_PASSWORD="$1"
echo "ROCKETCHAT_USER=bot" > $ROCKETCHAT_PROD_FILE
echo "ROCKETCHAT_ROOM=GENERAL" >> $ROCKETCHAT_PROD_FILE
echo "BOT_NAME=bot" >> $ROCKETCHAT_PROD_FILE
echo "ROCKETCHAT_PASSWORD=$ROCKETCHAT_PASSWORD" >> $ROCKETCHAT_PROD_FILE
# generate nextcloud .env files
NEXTCLOUD_PROD_FILE="./.envs/.production/.nextcloud"
#NEXTCLOUD_PASSWORD=$(python3 -c "import secrets; import string; print(f''.join([secrets.choice(string.ascii_letters+string.digits) for x in range(32)]))")
NEXTCLOUD_PASSWORD="$1"
echo "NEXTCLOUD_ADMIN_USER=mistborn" > $NEXTCLOUD_PROD_FILE
echo "NEXTCLOUD_ADMIN_PASSWORD=$NEXTCLOUD_PASSWORD" >> $NEXTCLOUD_PROD_FILE
echo "NEXTCLOUD_TRUSTED_DOMAINS=nextcloud.mistborn" >> $NEXTCLOUD_PROD_FILE
# generate onlyoffice .env files
ONLYOFFICE_PROD_FILE="./.envs/.production/.onlyoffice"
JWT_SECRET="$1"
echo "JWT_ENABLED=true" > $ONLYOFFICE_PROD_FILE
echo "JWT_SECRET=$JWT_SECRET" >> $ONLYOFFICE_PROD_FILE
# generate bitwarden .env files
BITWARDEN_PROD_FILE="./.envs/.production/.bitwarden"
echo "WEBSOCKET_ENABLED=true" > $BITWARDEN_PROD_FILE
echo "SIGNUPS_ALLOWED=true" >> $BITWARDEN_PROD_FILE

119
scripts/subinstallers/iptables.sh

@ -0,0 +1,119 @@ @@ -0,0 +1,119 @@
#!/bin/bash
set -e
echo "stop iptables wrappers"
if [ "$DISTRO" == "ubuntu" ]; then
# Disable UFW
sudo systemctl stop ufw || true
sudo systemctl disable ufw || true
fi
# default interface
iface=$(ip -o -4 route show to default | egrep -o 'dev [^ ]*' | awk '{print $2}')
# real public interface
riface=$(ip -o -4 route get 1.1.1.1 | egrep -o 'dev [^ ]*' | awk '{print $2}')
# resetting iptables
sudo iptables -F
sudo iptables -t nat -F
sudo iptables -X MISTBORN_LOG_DROP 2>/dev/null || true
sudo iptables -X MISTBORN_WIREGUARD_INPUT 2>/dev/null || true
sudo iptables -X MISTBORN_WIREGUARD_FORWARD 2>/dev/null || true
sudo iptables -X MISTBORN_DOCKER_INPUT 2>/dev/null || true
# iptables: log and drop chain
sudo iptables -N MISTBORN_LOG_DROP
sudo iptables -A MISTBORN_LOG_DROP -m limit --limit 2/min -j LOG --log-prefix "[IPTables-Dropped]: " --log-level 4
sudo iptables -A MISTBORN_LOG_DROP -j DROP
# wireguard rules chains
sudo iptables -N MISTBORN_WIREGUARD_INPUT
sudo iptables -N MISTBORN_WIREGUARD_FORWARD
# iptables
echo "Setting iptables rules"
sudo iptables -P INPUT ACCEPT
sudo iptables -I INPUT -i lo -j ACCEPT
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
fi
# docker rules
sudo iptables -N MISTBORN_DOCKER_INPUT
sudo iptables -A MISTBORN_DOCKER_INPUT -i br-+ -j ACCEPT
#sudo iptables -A INPUT ! -i $iface -s 172.16.0.0/12 -j ACCEPT
# last rules
sudo iptables -A INPUT -j MISTBORN_DOCKER_INPUT
sudo iptables -A INPUT -j MISTBORN_WIREGUARD_INPUT
sudo iptables -A INPUT -j MISTBORN_LOG_DROP
sudo iptables -A FORWARD -j MISTBORN_WIREGUARD_FORWARD
sudo iptables -P INPUT DROP
sudo iptables -P FORWARD DROP
sudo iptables -P OUTPUT ACCEPT
#if [ "$iface" == "$riface" ]; then
sudo iptables -t nat -I POSTROUTING -o $iface -j MASQUERADE
#else
# sudo iptables -t nat -I POSTROUTING -o $iface -j MASQUERADE
# sudo iptables -t nat -I POSTROUTING -o $riface -j MASQUERADE
#fi
# resetting ip6tables rules
sudo ip6tables -F
sudo ip6tables -t nat -F
sudo ip6tables -X MISTBORN_LOG_DROP 2>/dev/null || true
# ip6tables: log and drop chain
sudo ip6tables -N MISTBORN_LOG_DROP
sudo ip6tables -A MISTBORN_LOG_DROP -m limit --limit 6/min -j LOG --log-prefix "[IPTables-Dropped]: " --log-level 4
sudo ip6tables -A MISTBORN_LOG_DROP -j DROP
# ip6tables
echo "Setting ip6tables rules"
sudo ip6tables -P INPUT ACCEPT
sudo ip6tables -I INPUT -i lo -j ACCEPT
sudo ip6tables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo ip6tables -A INPUT -j MISTBORN_LOG_DROP
sudo ip6tables -P INPUT DROP
sudo ip6tables -P FORWARD DROP
sudo ip6tables -P OUTPUT ACCEPT
# initial load update package list
sudo apt-get update
# iptables-persistent
if [ ! "$(dpkg-query -l iptables-persistent)" ]; then
echo "Installing iptables-persistent"
# answer variables
echo iptables-persistent iptables-persistent/autosave_v4 boolean true | sudo debconf-set-selections
echo iptables-persistent iptables-persistent/autosave_v6 boolean true | sudo debconf-set-selections
# install
sudo apt-get install -y iptables-persistent ipset
else
echo "Saving iptables rules"
sudo bash -c "iptables-save > /etc/iptables/rules.v4"
echo "Saving ip6tables rules"
sudo bash -c "ip6tables-save > /etc/iptables/rules.v6"
fi
# IP forwarding
sudo sed -i 's/.*net.ipv4.ip_forward.*/net.ipv4.ip_forward=1/' /etc/sysctl.conf
sudo sysctl -p /etc/sysctl.conf
# rsyslog to create /var/log/iptables.log
sudo cp ./scripts/conf/15-iptables.conf /etc/rsyslog.d/
sudo chown root:root /etc/rsyslog.d/15-iptables.conf
sudo systemctl restart rsyslog

22
scripts/subinstallers/wireguard.sh

@ -0,0 +1,22 @@ @@ -0,0 +1,22 @@
#!/bin/bash
# Wireguard
if [ "$DISTRO" == "raspbian" ]; then
echo "Adding Wireguard repo keys"
sudo apt-get install -y dirmngr
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 8B48AD6246925553
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 7638D0442B90D010
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 04EE7237B7D453EC
fi
echo "Installing Wireguard"
if [ "$DISTRO" == "ubuntu" ]; then
# Ubuntu
sudo add-apt-repository -y ppa:wireguard/wireguard
elif [ "$DISTRO" == "debian" ] || [ "$DISTRO" == "raspbian" ]; then
# Debian
sudo bash -c 'echo "deb http://deb.debian.org/debian/ unstable main" > /etc/apt/sources.list.d/unstable.list'
sudo bash -c "printf 'Package: *\nPin: release a=unstable\nPin-Priority: 90\n' > /etc/apt/preferences.d/limit-unstable"
fi
sudo apt-get update
sudo apt-get install -y openresolv wireguard
Loading…
Cancel
Save