diff --git a/bin/dumpcerts b/bin/dumpcerts new file mode 100755 index 0000000..f417985 --- /dev/null +++ b/bin/dumpcerts @@ -0,0 +1,29 @@ +#!/bin/bash +# +# Dump Traefik certs and install into containers that need them + +if ! command -v traefik-certs-dumper &> /dev/null; then + failcheck "FAILED - traefik-certs-dumper tool not installed" +fi + +traefik-certs-dumper file --version v2 --source /federated/apps/traefik/data/letsencrypt/acme.json --dest /federated/certs &> /dev/null + +# Install into PostgreSQL container +cp /federated/apps/certs/certs/$DOMAIN.crt /federated/apps/postgresql/data/var/lib/postgresql/server.crt +cp /federated/apps/certs/private/$DOMAIN.key /federated/apps/postgresql/data/var/lib/postgresql/server.key +chown 999 /federated/apps/postgresql/data/var/lib/postgresql/server.crt /federated/apps/postgresql/data/var/lib/postgresql/server.key +chmod 600 /federated/apps/postgresql/data/var/lib/postgresql/server.crt /federated/apps/postgresql/data/var/lib/postgresql/server.key + +# Install into LDAP container +cp /federated/apps/certs/certs/$DOMAIN.crt /federated/apps/certs/private/$DOMAIN.key /federated/apps/ldap/data/certs/ + +# Install into Mail container +cp /federated/apps/certs/certs/$DOMAIN.crt /federated/apps/certs/private/$DOMAIN.key /federated/apps/mail/data/root/certs/ + +# Install into Collabora container +cp /federated/apps/certs/certs/$DOMAIN.crt /federated/apps/certs/private/$DOMAIN.key /federated/apps/collabora/data/root/certs/ +chown 104 /federated/apps/collabora/data/root/certs/* + +# Install into Matrix container +cp /federated/apps/certs/certs/$DOMAIN.crt /federated/apps/certs/private/$DOMAIN.key /federated/apps/matrix/data/matrix/ +chmod 644 /federated/apps/matrix/data/matrix/$DOMAIN.crt /federated/apps/matrix/data/matrix/$DOMAIN.key diff --git a/bin/install-federated b/bin/install-federated index d30811a..05445a1 100755 --- a/bin/install-federated +++ b/bin/install-federated @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/bash -x # # Federated installation script @@ -34,8 +34,13 @@ get_config() { . /federated/lib/proxy.sh . /federated/lib/wireguard.sh . /federated/lib/baserow.sh + . /federated/lib/calcom.sh . /federated/lib/gitea.sh . /federated/lib/caddy.sh + . /federated/lib/pdns-mysql.sh + . /federated/lib/pdns.sh + . /federated/lib/pdnsadmin.sh + . /federated/lib/pdns-static.sh COUNTRIES=("AF" "AL" "DZ" "AS" "AD" "AO" "AI" "AQ" "AG" "AR" "AM" "AW" "AU" "AT" "AZ" "BS" "BH" "BD" "BB" "BY" "BE" "BZ" "BJ" "BM" "BT" "BO" "BO" "BA" "BW" "BV" "BR" "IO" "BN" "BN" "BG" "BF" "BI" "KH" "CM" "CA" "CV" "KY" "CF" "TD" "CL" "CN" "CX" "CC" "CO" "KM" "CG" "CD" "CK" "CR" "CI" "CI" "HR" "CU" "CY" "CZ" "DK" "DJ" "DM" "DO" "EC" "EG" "SV" "GQ" "ER" "EE" "ET" "FK" "FO" "FJ" "FI" "FR" "GF" "PF" "TF" "GA" "GM" "GE" "DE" "GH" "GI" "GR" "GL" "GD" "GP" "GU" "GT" "GG" "GN" "GW" "GY" "HT" "HM" "VA" "HN" "HK" "HU" "IS" "IN" "ID" "IR" "IQ" "IE" "IM" "IL" "IT" "JM" "JP" "JE" "JO" "KZ" "KE" "KI" "KP" "KR" "KR" "KW" "KG" "LA" "LV" "LB" "LS" "LR" "LY" "LY" "LI" "LT" "LU" "MO" "MK" "MG" "MW" "MY" "MV" "ML" "MT" "MH" "MQ" "MR" "MU" "YT" "MX" "FM" "MD" "MC" "MN" "ME" "MS" "MA" "MZ" "MM" "MM" "NA" "NR" "NP" "NL" "AN" "NC" "NZ" "NI" "NE" "NG" "NU" "NF" "MP" "NO" "OM" "PK" "PW" "PS" "PA" "PG" "PY" "PE" "PH" "PN" "PL" "PT" "PR" "QA" "RE" "RO" "RU" "RU" "RW" "SH" "KN" "LC" "PM" "VC" "VC" "VC" "WS" "SM" "ST" "SA" "SN" "RS" "SC" "SL" "SG" "SK" "SI" "SB" "SO" "ZA" "GS" "SS" "ES" "LK" "SD" "SR" "SJ" "SZ" "SE" "CH" "SY" "TW" "TW" "TJ" "TZ" "TH" "TL" "TG" "TK" "TO" "TT" "TN" "TR" "TM" "TC" "TV" "UG" "UA" "AE" "GB" "US" "UM" "UY" "UZ" "VU" "VE" "VE" "VN" "VN" "VG" "VI" "WF" "EH" "YE" "ZM" "ZW") @@ -53,6 +58,19 @@ get_config() { else failcheck "/federated/bin/.env doesn't exist" fi + + # Setup DOMAIN variable for domain or subdomain + DOMAIN_ARRAY=(${DOMAIN//./ }) + if [ "${#DOMAIN_ARRAY[@]}" -eq "2" ]; then + DOMAIN_FIRST=${DOMAIN_ARRAY[0]} + DOMAIN_LAST=${DOMAIN_ARRAY[1]} + elif [ "${#DOMAIN_ARRAY[@]}" -eq "3" ]; then + DOMAIN_FIRST=${DOMAIN_ARRAY[0]} + DOMAIN_MIDDLE=${DOMAIN_ARRAY[1]} + DOMAIN_LAST=${DOMAIN_ARRAY[2]} + else + failcheck "$DOMAIN is not a valid domain.com or sub.domain.com" + fi } while getopts d OPTION; do @@ -77,11 +95,13 @@ check_ports config_network # Configure and start each federated service -for i in dns postgresql ldap mail collabora proxy nextcloud matrix element listmonk vaultwarden panel wireguard jitsi baserow gitea caddy; do +#for i in pdnsmysql pdns pdnsadmin traefik postgresql ldap mail collabora nextcloud matrix element listmonk vaultwarden panel wireguard jitsi baserow gitea caddy; do +for i in "${SERVICES[@]}"; do config_$i start_$i done +# Add cron jobs for backup, upgrade, dumpcerts add_cron # Print out federated environment details diff --git a/bin/start b/bin/start index 6ad7e16..ae7b002 100755 --- a/bin/start +++ b/bin/start @@ -1,9 +1,11 @@ #!/bin/bash # # Federated Start Script +. /federated/lib/functions.sh usage() { - echo "$0: all|dns|postgresql|ldap|mail|collabora|nextcloud|matrix|element|jitsi|listmonk|vaultwarden|panel|proxy|wireguard|connector|baserow|calcom|gitea|caddy" + printf -v SERVICES_JOINED '%s|' "${SERVICES[@]}" + echo "$0: ${SERVICES_JOINED%|}" exit 2 } startservice() { @@ -11,7 +13,7 @@ startservice() { cd /federated/apps/$SERVICE && docker-compose -f docker-compose.yml -p $SERVICE up -d } startservice_all() { - for i in dns postgresql ldap mail collabora nextcloud matrix element jitsi listmonk vaultwarden panel proxy wireguard connector baserow calcom gitea caddy; do + for i in "${SERVICES[@]}"; do echo "* Starting $i.." cd /federated/apps/$i && docker-compose -f docker-compose.yml -p $i up -d done @@ -20,8 +22,9 @@ startservice_all() { [ $# != 1 ] && usage SERVICE=$1 -case "$SERVICE" in - all) startservice_all;; - dns|postgresql|ldap|mail|collabora|nextcloud|matrix|element|jitsi|listmonk|vaultwarden|panel|proxy|wireguard|connector|baserow|calcom|gitea|caddy) startservice;; - *) usage;; -esac +[ "$SERVICE" = "all" ] && startservice_all +if printf '%s\0' "${SERVICES[@]}" | grep -Fxqz -- "$SERVICE"; then + startservice +else + usage +fi diff --git a/bin/stop b/bin/stop index 5159f88..6eae973 100755 --- a/bin/stop +++ b/bin/stop @@ -1,9 +1,11 @@ #!/bin/bash # # Federated Stop Script +. /federated/lib/functions.sh usage() { - echo "$0: all|dns|postgresql|ldap|mail|collabora|nextcloud|matrix|element|jitsi|listmonk|vaultwarden|panel|proxy|wireguard|connector|baserow|calcom|gitea|caddy" + printf -v SERVICES_JOINED '%s|' "${SERVICES[@]}" + echo "$0: ${SERVICES_JOINED%|}" exit 2 } stopservice() { @@ -11,7 +13,7 @@ stopservice() { cd /federated/apps/$SERVICE && docker-compose -f docker-compose.yml -p $SERVICE down } stopservice_all() { - for i in dns postgresql ldap mail collabora nextcloud matrix element jitsi listmonk vaultwarden panel proxy wireguard connector baserow calcom gitea caddy; do + for i in "${SERVICES[@]}"; do echo "* Stopping $i.." cd /federated/apps/$i && docker-compose -f docker-compose.yml -p $i down done @@ -20,8 +22,9 @@ stopservice_all() { [ $# != 1 ] && usage SERVICE=$1 -case "$SERVICE" in - all) stopservice_all;; - dns|postgresql|ldap|mail|collabora|nextcloud|matrix|element|jitsi|listmonk|vaultwarden|panel|proxy|wireguard|connector|baserow|calcom|gitea|caddy) stopservice;; - *) usage;; -esac +[ "$SERVICE" = "all" ] && stopservice_all +if printf '%s\0' "${SERVICES[@]}" | grep -Fxqz -- "$SERVICE"; then + stopservice +else + usage +fi diff --git a/lib/baserow.sh b/lib/baserow.sh index c5ebd67..f914b50 100644 --- a/lib/baserow.sh +++ b/lib/baserow.sh @@ -34,6 +34,11 @@ services: - ./.env volumes: - ./data/baserow/data:/baserow/data + labels: + - "traefik.enable=true" + - "traefik.http.routers.baserow.rule=Host(\`baserow.$DOMAIN\`)" + - "traefik.http.routers.baserow.entrypoints=websecure" + - "traefik.http.routers.baserow.tls.certresolver=letsencrypt" networks: federated: @@ -59,9 +64,6 @@ EMAIL_SMTP_PORT=587 EMAIL_SMTP_USER=admin EMAIL_SMTP_PASSWORD=$ADMINPASS EMAIL_SMTP_USE_TLS=True -VIRTUAL_PROTO=http -VIRTUAL_PORT=80 -VIRTUAL_HOST=baserow.$DOMAIN EOF chmod 600 /federated/apps/baserow/.env diff --git a/lib/caddy.sh b/lib/caddy.sh index 71902e6..a9e1b4a 100644 --- a/lib/caddy.sh +++ b/lib/caddy.sh @@ -40,6 +40,11 @@ services: - ./data/srv:/srv - ./data/etc/caddy/Caddyfile:/etc/caddy/Caddyfile - ./data/data:/data + labels: + - "traefik.enable=true" + - "traefik.http.routers.pdnsadmin.rule=Host(\`www.$DOMAIN\`,\`blog.$DOMAIN\`,\`documentation.$DOMAIN\`)" + - "traefik.http.routers.pdnsadmin.entrypoints=websecure" + - "traefik.http.routers.pdnsadmin.tls.certresolver=letsencrypt" networks: federated: @@ -48,9 +53,6 @@ EOF cat > /federated/apps/caddy/.env < /dev/null - cp -rf /federated/apps/dns/data/etc/letsencrypt/archive/$DOMAIN/*.pem /federated/apps/collabora/data/root/certs/ + cp /federated/apps/certs/certs/$DOMAIN.crt /federated/apps/certs/private/$DOMAIN.key /federated/apps/collabora/data/root/certs/ chown 104 /federated/apps/collabora/data/root/certs/* fi @@ -38,13 +38,17 @@ services: - "9980:9980" volumes: - ./data/root:/root - - ./data/root/certs/fullchain1.pem:/etc/coolwsd/cert.pem - - ./data/root/certs/privkey1.pem:/etc/coolwsd/key.pem - - ./data/root/certs/chain1.pem:/etc/coolwsd/ca-chain.cert.pem + - ./data/root/certs/$DOMAIN.crt:/etc/coolwsd/cert.pem + - ./data/root/certs/$DOMAIN.key:/etc/coolwsd/key.pem env_file: - ./.env cap_add: - MKNOD + labels: + - "traefik.enable=true" + - "traefik.http.routers.pdnsadmin.rule=Host(\`collabora.$DOMAIN\`)" + - "traefik.http.routers.pdnsadmin.entrypoints=websecure" + - "traefik.http.routers.pdnsadmin.tls.certresolver=letsencrypt" networks: federated: @@ -53,9 +57,6 @@ EOF cat > /federated/apps/collabora/.env <1 | grep acme-dns | awk '{ print $3 }'` echo "Got CNAME record: $CNAME_RECORD" echo "$CNAME_RECORD" > /etc/bind/.cnamerecord - echo -e "_acme-challenge\tIN\tCNAME\t$CNAME_RECORD" >> /etc/bind/zones/$DOMAIN + echo -e "_acme-challenge.customer2\tIN\tCNAME\t$CNAME_RECORD" >> /etc/bind/zones/$DOMAIN # Reload Bind configuration without restarting the container or process named -f -g & @@ -91,6 +91,7 @@ if [ ! -e /etc/bind/.firstdone ]; then touch /etc/bind/.firstdone echo "[federated]: FAILED generating certificates for $DOMAIN" echo "[federated]: Check that you have DNS setup properly" + wait -n exit 2; fi @@ -116,6 +117,7 @@ elif [ -e /etc/bind/.firstdone ] && [ -e /etc/bind/.failedcert ]; then touch /etc/bind/.failedcert echo "[federated]: FAILED generating certificates for $DOMAIN" echo "[federated]: Check that you have DNS setup properly" + wait -n exit 2; fi wait -n @@ -177,24 +179,6 @@ ns1 IN A $EXTERNALIP ns2 IN A $EXTERNALIP mail IN A $EXTERNALIP www IN A $EXTERNALIP -computer IN A $EXTERNALIP -panel IN A $EXTERNALIP -nextcloud IN A $EXTERNALIP -collabora IN A $EXTERNALIP -jitsi IN A $EXTERNALIP -matrix IN A $EXTERNALIP -element IN A $EXTERNALIP -listmonk IN A $EXTERNALIP -vaultwarden IN A $EXTERNALIP -vpn IN A $EXTERNALIP -connector IN A $EXTERNALIP -baserow IN A $EXTERNALIP -gitea IN A $EXTERNALIP -blog IN A $EXTERNALIP -documentation IN A $EXTERNALIP -* IN A $EXTERNALIP -$DOMAIN. IN A $EXTERNALIP -$DOMAIN. IN CNAME www.$DOMAIN EOF cat > /federated/apps/dns/data/etc/bind/zones/$DOMAIN.rev < /federated/apps/element/.env </dev/null; echo "30 23 * * * /federated/bin/backuptool -b all >> /federated/logs/backup.log 2>&1") | sort -u | crontab - - (crontab -l 2>/dev/null; echo "0 2 * * * /federated/bin/upgrade >> /federated/logs/upgrade.log 2>&1") | sort -u | crontab - + (crontab -l 2>/dev/null; echo "30 23 * * * date >> /federated/logs/backup.log && /federated/bin/backuptool -b all >> /federated/logs/backup.log 2>&1") | sort -u | crontab - + (crontab -l 2>/dev/null; echo "0 2 * * * date >> /federated/logs/upgrade.log && /federated/bin/upgrade >> /federated/logs/upgrade.log 2>&1") | sort -u | crontab - + (crontab -l 2>/dev/null; echo "0 3 * * * date >> /federated/logs/dumpcerts.log && /federated/bin/dumpcerts >> /federated/logs/dumpcerts.log 2>&1") | sort -u | crontab - } install_federated() { [ -d "/federated" ] && fail "Directory /federated already exists. Already installed?" @@ -199,6 +200,10 @@ Baserow: Easy Database. Replacement for Airtable. Build amazing, easy to create on-line databases to be used by your team. https://baserow.$DOMAIN +Cal.com: Easy scheduling. Create easy links so that others can easily +schedule time on your calendar without the annoying back-and-forth. +https://calcom.$DOMAIN + All documentation for users can be found at https://documentation.federated.computer/users. EOF @@ -239,8 +244,12 @@ check_docker() { [ $? -ne 0 ] && failcheck "Couldn't run sudo apt install docker packages" # Install extra packages - sudo apt-get install duplicity python3-b2sdk uuid -y &> /dev/null + sudo apt-get install duplicity python3-b2sdk uuid apache2-utils -y &> /dev/null [ $? -ne 0 ] && failcheck "Couldn't run sudo apt install extra packages" + + # Install Traefik certs dumper + curl -sfL https://raw.githubusercontent.com/ldez/traefik-certs-dumper/master/godownloader.sh | bash -s -- -b $(go env GOPATH 2>/dev/null)/bin v2.8.1 &> /dev/null + [ $? -ne 0 ] && failcheck "Couldn't install traefik certs dumper" fi kill -9 $SPINPID &> /dev/null echo -ne "done." @@ -289,8 +298,9 @@ check_ports() { [ $? -ne 0 ] && failcheck "Failed running systemctl stop systemd-resolved" # Put nameserver entries so will exist on reboot - echo "nameserver 8.8.8.8" > /etc/resolvconf/resolv.conf.d/tail - echo "nameserver 8.8.8.8" > /run/resolvconf/resolv.conf + rm /etc/resolv.conf + echo "nameserver 1.1.1.1" >> /etc/resolv/resolv.conf + echo "nameserver 1.0.0.1" >> /etc/resolv/resolv.conf kill -9 $SPINPID &> /dev/null echo -ne "done." diff --git a/lib/gitea.sh b/lib/gitea.sh index a19b950..3956933 100644 --- a/lib/gitea.sh +++ b/lib/gitea.sh @@ -11,9 +11,6 @@ config_gitea() { if [ ! -d "/federated/apps/gitea" ]; then mkdir -p /federated/apps/gitea/data/data - mkdir -p /federated/apps/gitea/data/data/git/.ssh - touch /federated/apps/gitea/data/data/git/.ssh/authorized_keys - chmod 600 /federated/apps/gitea/data/data/git/.ssh/authorized_keys fi DOMAIN_ARRAY=(${DOMAIN//./ }) @@ -38,27 +35,26 @@ services: - "blog.$DOMAIN:$EXTERNALIP" - "documentation.$DOMAIN:$EXTERNALIP" ports: - - "2222:22" + - 22:22 env_file: - ./.env volumes: - ./data/data:/data - - ./data/data/git/.ssh:/data/git/.ssh - /etc/timezone:/etc/timezone:ro - /etc/localtime:/etc/localtime:ro + labels: + - "traefik.enable=true" + - "traefik.http.routers.pdnsadmin.rule=Host(\`gitea.$DOMAIN\`)" + - "traefik.http.routers.pdnsadmin.entrypoints=websecure" + - "traefik.http.routers.pdnsadmin.tls.certresolver=letsencrypt" networks: federated: external: true EOF -#GITEA_SECRET="RbzalooGM4BbQug6wvRaklR7NeN0GRSA" - cat > /federated/apps/gitea/.env < /dev/null mkdir -p /federated/apps/ldap/data/certs &> /dev/null mkdir -p /federated/apps/ldap/data/root &> /dev/null - cp -rf /federated/apps/dns/data/etc/letsencrypt/archive/$DOMAIN/*.pem /federated/apps/ldap/data/certs/ + cp /federated/apps/certs/certs/$DOMAIN.crt /federated/apps/certs/private/$DOMAIN.key /federated/apps/ldap/data/certs/ fi DOMAIN_ARRAY=(${DOMAIN//./ }) @@ -63,9 +63,9 @@ LDAP_ADMIN_PASSWORD_FILE=/run/secrets/federated_ldap_password LDAP_RFC2307BIS_SCHEMA=true LDAP_REMOVE_CONFIG_AFTER_SETUP=true LDAP_TLS=true -LDAP_TLS_CRT_FILENAME=fullchain1.pem -LDAP_TLS_KEY_FILENAME=privkey1.pem -LDAP_TLS_CA_CRT_FILENAME=chain1.pem +LDAP_TLS_CRT_FILENAME=$DOMAIN.crt +LDAP_TLS_KEY_FILENAME=$DOMAIN.key +#LDAP_TLS_CA_CRT_FILENAME=chain1.pem LDAP_TLS_VERIFY_CLIENT=try EOF chmod 600 /federated/apps/ldap/.env diff --git a/lib/listmonk.sh b/lib/listmonk.sh index 75d207a..2de012f 100644 --- a/lib/listmonk.sh +++ b/lib/listmonk.sh @@ -36,6 +36,11 @@ services: volumes: - ./data/listmonk/config.toml:/listmonk/config.toml - ./data/listmonk/static:/listmonk/static + labels: + - "traefik.enable=true" + - "traefik.http.routers.listmonk.rule=Host(\`listmonk.$DOMAIN\`)" + - "traefik.http.routers.listmonk.entrypoints=websecure" + - "traefik.http.routers.listmonk.tls.certresolver=letsencrypt" networks: federated: @@ -44,9 +49,6 @@ EOF cat > /federated/apps/listmonk/.env < /dev/null mkdir -p /federated/apps/mail/data/var/log/mail &> /dev/null mkdir -p /federated/apps/mail/data/tmp/docker-mailserver &> /dev/null - cp -rf /federated/apps/dns/data/etc/letsencrypt/archive/$DOMAIN/*.pem /federated/apps/mail/data/root/certs/ + cp /federated/apps/certs/certs/$DOMAIN.crt /federated/apps/certs/private/$DOMAIN.key /federated/apps/mail/data/root/certs/ fi DOMAIN_ARRAY=(${DOMAIN//./ }) @@ -72,8 +72,8 @@ DMS_DEBUG=0 LOG_LEVEL=debug ENABLE_LDAP=1 SSL_TYPE=manual -SSL_CERT_PATH=/root/certs/fullchain1.pem -SSL_KEY_PATH=/root/certs/privkey1.pem +SSL_CERT_PATH=/root/certs/$DOMAIN.crt +SSL_KEY_PATH=/root/certs/$DOMAIN.key LDAP_START_TLS=yes DOVECOT_TLS=yes SASLAUTHD_LDAP_START_TLS=yes @@ -103,8 +103,7 @@ EOF chmod 600 /federated/apps/mail/.env cat > /federated/apps/mail/data/tmp/docker-mailserver/postfix-main.cf <<'EOF' -smtpd_sender_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unknown_sender_domain, reject_sender_login_mismatch, reject_unknown_reverse_client_hostname, reject_unknown_client_hostname -smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination, check_policy_service unix:private/policyd-spf, reject_unauth_pipelining, reject_invalid_helo_hostname, reject_non_fqdn_helo_hostname, reject_unknown_recipient_domain, check_policy_service inet:127.0.0.1:10023, reject_rhsbl_helo dbl.spamhaus.org, reject_rhsbl_reverse_client dbl.spamhaus.org, reject_rhsbl_sender dbl.spamhaus.org, reject_rbl_client zen.spamhaus.org +smtpd_sender_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unknown_sender_domain, reject_sender_login_mismatch smtpd_sender_login_maps = ldap:/etc/postfix/ldap-aliases.cf EOF @@ -124,7 +123,7 @@ start_mail() { [ $? -ne 0 ] && fail "Couldn't insert DKIM record into /federated/apps/dns container" # Insert the DMARC DNS TXT entry into /federated/apps/dns container - echo "_dmarc.$DOMAIN. IN TXT \"v=DMARC1; p=quarantine; rua=mailto:admin@$DOMAIN; ruf=mailto:admin@$DOMAIN; sp=none; ri=86400\"" >> /federated/apps/dns/data/etc/bind/zones/$DOMAIN + echo "_dmarc.$DOMAIN. IN TXT \"v=DMARC1; p=none; rua=mailto:admin@$DOMAIN; ruf=mailto:admin@$DOMAIN; sp=none; ri=86400\"" >> /federated/apps/dns/data/etc/bind/zones/$DOMAIN [ $? -ne 0 ] && fail "Couldn't insert DMARC record into /federated/apps/dns container" # Reload DNS configuration in /federated/apps/dns container diff --git a/lib/matrix.sh b/lib/matrix.sh index b867462..5620e3b 100644 --- a/lib/matrix.sh +++ b/lib/matrix.sh @@ -11,8 +11,8 @@ config_matrix() { if [ ! -d "/federated/apps/matrix" ]; then mkdir -p /federated/apps/matrix/data/matrix &> /dev/null - cp -rf /federated/apps/dns/data/etc/letsencrypt/archive/$DOMAIN/*.pem /federated/apps/matrix/data/matrix - chmod 644 /federated/apps/matrix/data/matrix/*.pem + cp /federated/apps/certs/certs/$DOMAIN.crt /federated/apps/certs/private/$DOMAIN.key /federated/apps/matrix/data/matrix/ + chmod 644 /federated/apps/matrix/data/matrix/$DOMAIN.crt /federated/apps/matrix/data/matrix/$DOMAIN.key fi DOMAIN_ARRAY=(${DOMAIN//./ }) @@ -36,6 +36,11 @@ services: - ./data/matrix:/data env_file: - ./.env + labels: + - "traefik.enable=true" + - "traefik.http.routers.listmonk.rule=Host(\`matrix.$DOMAIN\`)" + - "traefik.http.routers.listmonk.entrypoints=websecure" + - "traefik.http.routers.listmonk.tls.certresolver=letsencrypt" networks: federated: @@ -44,9 +49,6 @@ EOF cat > /federated/apps/matrix/.env < /dev/null diff --git a/lib/nextcloud.sh b/lib/nextcloud.sh index 517d22b..7245721 100644 --- a/lib/nextcloud.sh +++ b/lib/nextcloud.sh @@ -50,6 +50,11 @@ services: secrets: - federated_psql_password - federated_nextcloud_password + labels: + - "traefik.enable=true" + - "traefik.http.routers.listmonk.rule=Host(\`nextcloud.$DOMAIN\`)" + - "traefik.http.routers.listmonk.entrypoints=websecure" + - "traefik.http.routers.listmonk.tls.certresolver=letsencrypt" secrets: federated_psql_password: @@ -68,9 +73,6 @@ chmod 600 /federated/apps/nextcloud/.postgresql.secret /federated/apps/nextcloud cat > /federated/apps/nextcloud/.env < /federated/apps/panel/.env < /federated/apps/pdns/docker-compose.yml < /federated/apps/pdns/.env < /federated/apps/pdns/data/root/createrecords.sh < /dev/null +echo -ne "done." +} +start_pdns() { + # Start service with command to make sure it's up before proceeding + start_service "pdns" "nc -z 172.99.0.9 8081 &> /dev/null" + + # Run createrecords.sh inside baserow container + docker exec -it pdns /root/createrecords.sh + [ $? -ne 0 ] && fail "Couldn't run createrecords.sh in /federated/apps/pdns container" + + kill -9 $SPINPID &> /dev/null + echo -ne "done." +} diff --git a/lib/pdnsadmin.sh b/lib/pdnsadmin.sh new file mode 100644 index 0000000..de09d1d --- /dev/null +++ b/lib/pdnsadmin.sh @@ -0,0 +1,104 @@ +#!/bin/bash +# +# PowerDNS Admin Service + +PATH=$HOME/.docker/cli-plugins:/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin + +config_pdnsadmin() { + echo -ne "\n* Configuring /federated/apps/pdnsadmin container.." + spin & + SPINPID=$! + + if [ ! -d "/federated/apps/pdnsadmin" ]; then + mkdir -p /federated/apps/pdnsadmin/data/etc + fi + +cat > /federated/apps/pdnsadmin/docker-compose.yml < /federated/apps/pdnsadmin/.env < /federated/apps/pdnsadmin/data/etc/uwsgi.ini <<'EOF' +[uwsgi] +strict = true +master = true +die-on-term = true +need-app = true + +plugins = python3 + +uid = uwsgi +gid = uwsgi + +chdir = /opt/powerdns-admin +pythonpath = /opt/powerdns-admin + +mount = /=run.py +manage-script-name = true +callable = app + +vacuum = true +harakiri = 20 +buffer-size = 32768 +post-buffering = 8192 +protocol = http +http-socket = 0.0.0.0:9494 +pidfile = /run/uwsgi/%n.pid + +enable-threads = true +EOF + +kill -9 $SPINPID &> /dev/null +echo -ne "done." +} +start_pdnsadmin() { + # Start service with command to make sure it's up before proceeding + start_service "pdnsadmin" "nc -z 172.99.0.10 9494 &> /dev/null" + + # Run MySQL command to create admin user for pdns admin interface + docker exec -it pdns-mysql bash -c "mysql -updns -p$MYSQL_PASSWORD pdns -e '$PDNS_MYSQL_COMMAND;'" + + kill -9 $SPINPID &> /dev/null + echo -ne "done." +} diff --git a/lib/pdnsmysql.sh b/lib/pdnsmysql.sh new file mode 100644 index 0000000..4a815e4 --- /dev/null +++ b/lib/pdnsmysql.sh @@ -0,0 +1,60 @@ +#!/bin/bash +# +# PowerDNS MySQL Service + +PATH=$HOME/.docker/cli-plugins:/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin + +config_pdnsmysql() { + echo -ne "\n* Configuring /federated/apps/pdnsmysql container.." + spin & + SPINPID=$! + + if [ ! -d "/federated/apps/pdnsmysql" ]; then + mkdir -p /federated/apps/pdnsmysql/data/var/lib/mysql + fi + +cat > /federated/apps/pdnsmysql/docker-compose.yml < /federated/apps/pdnsmysql/.env < /dev/null +echo -ne "done." +} +start_pdnsmysql() { + # Start service with command to make sure it's up before proceeding + start_service "pdnsmysql" "nc -z 172.99.0.8 3306 &> /dev/null" + + kill -9 $SPINPID &> /dev/null + echo -ne "done." +} diff --git a/lib/pdnsstatic.sh b/lib/pdnsstatic.sh new file mode 100644 index 0000000..66ad834 --- /dev/null +++ b/lib/pdnsstatic.sh @@ -0,0 +1,64 @@ +#!/bin/bash +# +# PowerDNS Nginx Service + +PATH=$HOME/.docker/cli-plugins:/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin + +config_pdnsstatic() { + echo -ne "\n* Configuring /federated/apps/pdns-static container.." + spin & + SPINPID=$! + + DOMAIN_ARRAY=(${DOMAIN//./ }) + DOMAIN_FIRST=${DOMAIN_ARRAY[0]} + DOMAIN_MIDDLE=${DOMAIN_ARRAY[1]} + DOMAIN_LAST=${DOMAIN_ARRAY[2]} + + if [ ! -d "/federated/apps/pdns-static" ]; then + mkdir -p /federated/apps/pdns-static + fi + +# DOMAIN_ARRAY=(${DOMAIN//./ }) +# DOMAIN_FIRST=${DOMAIN_ARRAY[0]} +# DOMAIN_LAST=${DOMAIN_ARRAY[1]} + +cat > /federated/apps/pdns-static/docker-compose.yml < /federated/apps/pdns-static/.env < /dev/null +echo -ne "done." +} +start_pdnsstatic() { + # Start service with command to make sure it's up before proceeding + start_service "pdns-static" "nc -z 172.99.0.7 80 &> /dev/null" + + kill -9 $SPINPID &> /dev/null + echo -ne "done." +} diff --git a/lib/postgresql.sh b/lib/postgresql.sh index 1c07b0d..b38f447 100644 --- a/lib/postgresql.sh +++ b/lib/postgresql.sh @@ -11,16 +11,12 @@ config_postgresql() { if [ ! -d "/federated/apps/postgresql" ]; then mkdir -p /federated/apps/postgresql/data/var/lib/postgresql /federated/apps/postgresql/data/docker-entrypoint-initdb.d - cp /federated/apps/dns/data/etc/letsencrypt/archive/$DOMAIN/fullchain1.pem /federated/apps/postgresql/data/var/lib/postgresql/server.crt - cp /federated/apps/dns/data/etc/letsencrypt/archive/$DOMAIN/privkey1.pem /federated/apps/postgresql/data/var/lib/postgresql/server.key - chown 999 /federated/apps/postgresql/data/var/lib/postgresql/server.* - chmod 600 /federated/apps/postgresql/data/var/lib/postgresql/server.* + cp /federated/apps/certs/certs/$DOMAIN.crt /federated/apps/postgresql/data/var/lib/postgresql/server.crt + cp /federated/apps/certs/private/$DOMAIN.key /federated/apps/postgresql/data/var/lib/postgresql/server.key + chown 999 /federated/apps/postgresql/data/var/lib/postgresql/server.crt /federated/apps/postgresql/data/var/lib/postgresql/server.key + chmod 600 /federated/apps/postgresql/data/var/lib/postgresql/server.crt /federated/apps/postgresql/data/var/lib/postgresql/server.key fi - DOMAIN_ARRAY=(${DOMAIN//./ }) - DOMAIN_FIRST=${DOMAIN_ARRAY[0]} - DOMAIN_LAST=${DOMAIN_ARRAY[1]} - cat > /federated/apps/postgresql/docker-compose.yml < /dev/null - cp /federated/apps/dns/data/etc/letsencrypt/archive/$DOMAIN/fullchain1.pem /federated/apps/proxy/data/root/certs/$DOMAIN.crt - cp /federated/apps/dns/data/etc/letsencrypt/archive/$DOMAIN/privkey1.pem /federated/apps/proxy/data/root/certs/$DOMAIN.key - fi - DOMAIN_ARRAY=(${DOMAIN//./ }) DOMAIN_FIRST=${DOMAIN_ARRAY[0]} - DOMAIN_LAST=${DOMAIN_ARRAY[1]} + DOMAIN_MIDDLE=${DOMAIN_ARRAY[1]} + DOMAIN_LAST=${DOMAIN_ARRAY[2]} + + if [ ! -d "/federated/apps/proxy" ]; then + mkdir -p /federated/apps/proxy/data/root/certs &> /dev/null + cp /federated/apps/dns/data/etc/letsencrypt/archive/$DOMAIN_MIDDLE.$DOMAIN_LAST/fullchain1.pem /federated/apps/proxy/data/root/certs/$DOMAIN_MIDDLE.$DOMAIN_LAST.crt + cp /federated/apps/dns/data/etc/letsencrypt/archive/$DOMAIN_MIDDLE.$DOMAIN_LAST/privkey1.pem /federated/apps/proxy/data/root/certs/$DOMAIN_MIDDLE.$DOMAIN_LAST.key + fi + +# DOMAIN_ARRAY=(${DOMAIN//./ }) +# DOMAIN_FIRST=${DOMAIN_ARRAY[0]} +# DOMAIN_LAST=${DOMAIN_ARRAY[1]} cat > /federated/apps/proxy/docker-compose.yml < /federated/apps/traefik/docker-compose.yml < /federated/apps/traefik/.env < /dev/null +echo -ne "done." +} + +start_traefik() { + if [ $DEBUG ]; then + # Start /federated/apps/traefik with output to console for debug + docker-compose -f /federated/apps/traefik/docker-compose.yml -p traefik up + [ $? -eq 0 ] && echo -ne "done.\n" || fail "There was a problem starting service /federated/apps/traefik" + else + # Start /federated/apps/traefik with output to /dev/null + docker-compose -f /federated/apps/traefik/docker-compose.yml -p traefik up -d &> /dev/null + + # Keep trying to see that certificates are generated + RETRY="20" + while [ $RETRY -gt 0 ]; do + traefik-certs-dumper file --version v2 --source /federated/apps/traefik/data/letsencrypt/acme.json --dest /federated/certs &> /dev/null + + # Check if certs are generated + ls /federated/certs/private/$DOMAIN.key /federated/certs/certs/$DOMAIN.crt &> /dev/null + if [ $? -eq 0 ]; then + kill -9 $SPINPID &> /dev/null + echo -ne "done." + break + else + if [ "$RETRY" == 1 ]; then + docker-compose -f /federated/apps/traefik/docker-compose.yml -p traefik down &> /dev/null + fail "There was a problem starting service /federated/apps/traefik\nCheck the output of 'docker logs traefik' or turn on\ndebug with -d" + fi + ((RETRY--)) + sleep 9 + fi + done + fi +} diff --git a/lib/vaultwarden.sh b/lib/vaultwarden.sh index f95576a..c274d61 100644 --- a/lib/vaultwarden.sh +++ b/lib/vaultwarden.sh @@ -9,13 +9,18 @@ config_vaultwarden() { spin & SPINPID=$! + DOMAIN_ARRAY=(${DOMAIN//./ }) + DOMAIN_FIRST=${DOMAIN_ARRAY[0]} + DOMAIN_MIDDLE=${DOMAIN_ARRAY[1]} + DOMAIN_LAST=${DOMAIN_ARRAY[2]} + if [ ! -d "/federated/apps/vaultwarden" ]; then mkdir -p /federated/apps/vaultwarden/data/data fi - DOMAIN_ARRAY=(${DOMAIN//./ }) - DOMAIN_FIRST=${DOMAIN_ARRAY[0]} - DOMAIN_LAST=${DOMAIN_ARRAY[1]} +# DOMAIN_ARRAY=(${DOMAIN//./ }) +# DOMAIN_FIRST=${DOMAIN_ARRAY[0]} +# DOMAIN_LAST=${DOMAIN_ARRAY[1]} cat > /federated/apps/vaultwarden/docker-compose.yml < /federated/apps/vaultwarden/.env <