#!/bin/bash # # Federated Computer DNS Service PATH=$HOME/.docker/cli-plugins:/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin config_dns() { echo -ne "\n* Configuring fstack/dns container.." spin & SPINPID=$! EXTERNAL_IP_LASTDIGIT=`echo $EXTERNALIP | awk -F . '{ print $4 }'` EXTERNALIP_INADDR=`echo $EXTERNALIP | awk -F . '{ print $3"."$2"."$1".in-addr.arpa"}'` EXTERNALIP_INADDR_CAPS=`echo $EXTERNALIP | awk -F . '{ print $3"."$2"."$1".IN-ADDR.ARPA"}'` mkdir -p fstack/dns/data/root mkdir -p fstack/dns/data/etc/bind/zones mkdir -p fstack/dns/data/var/log/letsencrypt cat > fstack/dns/docker-compose.yml <<'EOF' version: '3.8' services: dns: image: alpine:latest container_name: dns hostname: dns restart: always working_dir: /root networks: fstack: ipv4_address: 172.99.0.10 volumes: - ./data/etc/bind:/etc/bind - ./data/etc/letsencrypt:/etc/letsencrypt - ./data/var/log/letsencrypt:/var/log/letsencrypt - ./data/root:/root ports: - "53:53/udp" - "53:53/tcp" command: [ "/root/dns-cert.sh" ] networks: fstack: external: true EOF cat > fstack/dns/data/root/dns-cert.sh <<'EOF' #!/bin/sh -x PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin if [ ! -e /etc/bind/.firstdone ]; then # Install bind and certbot packages apk add --no-cache bind apk add --no-cache certbot # Install ACME DNS script if [ ! -e /root/acme-dns-auth.py ]; then wget https://github.com/joohoi/acme-dns-certbot-joohoi/raw/master/acme-dns-auth.py chmod +x acme-dns-auth.py fi [ ! -e /usr/bin/python ] && ln -s /usr/bin/python3 /usr/bin/python # Run rndc to create bind keys for rndc to run rndc-confgen -a cat /etc/bind/rndc.key >> /etc/bind/named.conf # Run Certbot and insert CNAME record into bind configuration DOMAIN=`ls /etc/bind/zones | head -1` echo "Trying to certbot for DOMAIN $DOMAIN" CNAME_RECORD=`certbot certonly --manual --manual-auth-hook /root/acme-dns-auth.py --preferred-challenges dns --debug-challenges -d \*.$DOMAIN -d $DOMAIN --agree-tos --email hostmaster@$DOMAIN -n 2>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 # Reload Bind configuration without restarting the container or process named -f -g & crond & # rndc reload $DOMAIN # rndc reload sleep 7 # Run Certbot again to generate the certificate certbot certonly --manual --manual-auth-hook /root/acme-dns-auth.py --preferred-challenges dns --debug-challenges -d \*.$DOMAIN -d $DOMAIN --agree-tos --email hostmaster@$DOMAIN -n &> /dev/null if [ $? -eq 0 ]; then echo "[fstack]: SUCCESS generating certificates for $DOMAIN!" echo "[fstack]: Certificates are at /etc/letsencrypt/live/$DOMAIN" echo -ne "#!/bin/sh\n\n/usr/bin/certbot renew -q" > /etc/periodic/15min/certbot-renew.sh chmod +x /etc/periodic/15min/certbot-renew.sh else touch /etc/bind/.failedcert touch /etc/bind/.firstdone echo "[fstack]: FAILED generating certificates for $DOMAIN" echo "[fstack]: Check that you have DNS setup properly" exit 2; fi touch /etc/bind/.firstdone wait -n elif [ -e /etc/bind/.firstdone ] && [ -e /etc/bind/.failedcert ]; then DOMAIN=`ls /etc/bind/zones | head -1` named -f -g & crond & sleep 7 # Run Certbot again to generate the certificate certbot certonly --manual --manual-auth-hook /root/acme-dns-auth.py --preferred-challenges dns --debug-challenges -d \*.$DOMAIN -d $DOMAIN --agree-tos --email hostmaster@$DOMAIN -n &> /dev/null if [ $? -eq 0 ]; then rm /etc/bind/.failedcert echo "[fstack]: SUCCESS generating certificates for $DOMAIN!" echo "[fstack]: Certificates are at /etc/letsencrypt/live/$DOMAIN" else touch /etc/bind/.failedcert echo "[fstack]: FAILED generating certificates for $DOMAIN" echo "[fstack]: Check that you have DNS setup properly" exit 2; fi wait -n else [ ! `pgrep -x named` ] && named -f -g && crond fi EOF chmod +x fstack/dns/data/root/dns-cert.sh cat > fstack/dns/data/etc/bind/named.conf < fstack/dns/data/etc/bind/zones/$DOMAIN < fstack/dns/data/etc/bind/zones/$DOMAIN.rev < /dev/null } start_dns() { echo -ne "\n* Starting fstack/dns service.." spin & SPINPID=$! if [ $DEBUG ]; then # Start fstack/dns with output to console for debug docker-compose -f fstack/dns/docker-compose.yml -p dns up [ $? -eq 0 ] && echo -ne "done.\n" || fail "There was a problem starting service fstack/dns" else # Start fstack/dns with output to /dev/null docker-compose -f fstack/dns/docker-compose.yml -p dns up -d &> /dev/null # Keep trying to see that certificates are generated RETRY="18" while [ $RETRY -gt 0 ]; do ls fstack/dns/data/etc/letsencrypt/live/$DOMAIN/*.pem &> /dev/null if [ $? -eq 0 ]; then kill -9 $SPINPID &> /dev/null echo -ne "done." # echo -ne "* Certificates at fstack/dns/data/etc/letsencrypt/live/$DOMAIN\n" break else if [ "$RETRY" == 1 ]; then docker-compose -f fstack/dns/docker-compose.yml -p dns down &> /dev/null fail "There was a problem starting service fstack/dns\nCheck the output of 'docker logs dns' or turn on\ndebug with -d" fi ((RETRY--)) sleep 9 fi done fi }