#!/usr/bin/env bash set -euo pipefail LOGFILE=/opt/logs/commander.log err_report() { echo "ERROR! On line $1 in commander script" } trap 'err_report $LINENO' INT TERM ERR dn=$(dirname $0) source "$dn/utils.sh" function wait_server() { local url="$1" local status=0 local cnt=0 set +e res=$(curl -o /dev/null -sSLk --head --write-out '%{http_code}\n' $url 2>&1) if [ $? -ne 0 ]; then echo -n $res fi set -e while [ $cnt -lt 40 ] && [ "$status" != "200" ]; do status=$(curl -o /dev/null -sSL --head --write-out '%{http_code}\n' $url 2>>$LOGFILE) let cnt=$cnt+1 if [ "$status" != "200" ]; then sleep 5 fi done } read txt case $txt in "docker-restart") cd /opt/boulder COMPOSE_HTTP_TIMEOUT=120 docker compose restart boulder bmysql bconsul bpkilint gui nginx &>>$LOGFILE sleep 45 wait_up $PS_MYSQL &>>$LOGFILE wait_up $PS_CONSUL 2 &>>$LOGFILE wait_up $PS_PKILINT &>>$LOGFILE wait_up $PS_LABCA &>>$LOGFILE wait_up $PS_BOULDER $PS_BOULDER_COUNT &>>$LOGFILE ;; "acme-request") wait_up $PS_BOULDER $PS_BOULDER_COUNT &>>$LOGFILE cd /etc/nginx/ssl [ -e account.key ] || openssl genrsa 4096 > account.key [ -L labca_key.pem ] || mv labca_key.pem labca_key_rsa.pem [ -e labca_key_rsa.pem ] || openssl genrsa 4096 > labca_key_rsa.pem [ -e labca_key_ecdsa.pem ] || openssl ecparam -name secp384r1 -genkey -out labca_key_ecdsa.pem set +e curve_count=$(openssl pkey -pubin -in /opt/boulder/labca/certs/webpki/issuer-01-pubkey.pem -text | grep -i curve | wc -l) set -e [ "$curve_count" == "0" ] && ln -sf labca_key_rsa.pem labca_key.pem || /bin/true [ "$curve_count" != "0" ] && ln -sf labca_key_ecdsa.pem labca_key.pem || /bin/true if [ -e labca_cert.pem ]; then if [ ! -e domain.csr ]; then san=$(openssl x509 -noout -text -in labca_cert.pem | grep DNS:) openssl req -new -utf8 -sha256 -key labca_key.pem -subj "/" -reqexts SAN -config <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=$san")) > domain.csr fi hash=$(openssl x509 -hash -noout -in labca_cert.pem) issuer_hash=$(openssl x509 -issuer_hash -noout -in labca_cert.pem) fi if [ "$hash" == "$issuer_hash" ] || ! expires=$(openssl x509 -checkend 172800 -noout -in labca_cert.pem); then url=$(grep 'DEFAULT_DIRECTORY_URL =' /opt/labca/acme_tiny.py | sed -e 's/.*=[ ]*//' | sed -e 's/\"//g') wait_server $url sleep 10 /opt/labca/renew sleep 5 cd /opt/boulder docker compose exec -i boulder ./bin/boulder crl-updater --config labca/config/crl-updater.json -runOnce -debug-addr :18021 /opt/labca/checkcrl fi ln -sf /opt/labca/cron_d /etc/cron.d/labca ln -sf /opt/labca/logrotate_d /etc/logrotate.d/labca ;; "acme-change") read fqdn cd /etc/nginx/ssl [ -L labca_key.pem ] || mv labca_key.pem labca_key_rsa.pem [ -e labca_key_rsa.pem ] || openssl genrsa 4096 > labca_key_rsa.pem [ -e labca_key_ecdsa.pem ] || openssl ecparam -name secp384r1 -genkey -out labca_key_ecdsa.pem set +e curve_count=$(openssl pkey -pubin -in /opt/boulder/labca/certs/webpki/issuer-01-pubkey.pem -text | grep -i curve | wc -l) set -e [ "$curve_count" == "0" ] && ln -sf labca_key_rsa.pem labca_key.pem || /bin/true [ "$curve_count" != "0" ] && ln -sf labca_key_ecdsa.pem labca_key.pem || /bin/true openssl req -new -utf8 -sha256 -key labca_key.pem -subj "/" -reqexts SAN -config <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:$fqdn")) > domain.csr url=$(grep 'DEFAULT_DIRECTORY_URL =' /opt/labca/acme_tiny.py | sed -e 's/.*=[ ]*//' | sed -e 's/\"//g') wait_server $url sleep 10 /opt/labca/renew ;; "nginx-remove-redirect") perl -i -p0e 's/\n # BEGIN temporary redirect\n location = \/ \{\n return 302 \/admin\/;\n }\n # END temporary redirect\n//igs' /etc/nginx/conf.d/labca.conf ;; "nginx-reload") cd /opt/boulder docker compose exec nginx nginx -s reload &>>$LOGFILE ;; "nginx-restart") cd /opt/boulder docker compose restart nginx &>>$LOGFILE ;; "log-cert") [ -f /etc/nginx/ssl/acme_tiny.log ] && tail -200 /etc/nginx/ssl/acme_tiny.log || /bin/true exit 0 ;; "log-commander") [ -f $LOGFILE ] && tail -200 $LOGFILE || /bin/true exit 0 ;; "log-control-notail") cd /opt/boulder docker compose logs --no-color --tail=50 control ;; "log-cron") [ -f /opt/logs/cron.log ] && tail -n200 -f /opt/logs/cron.log || /bin/true exit 0 ;; "log-boulder") cd /opt/boulder docker compose logs -f --no-color --tail=50 boulder ;; "log-boulder-notail") cd /opt/boulder docker compose logs --no-color --tail=50 boulder ;; "log-audit") cd /opt/boulder docker compose logs --no-color boulder | grep "\[AUDIT\]" | grep -v "grpc: parseServiceConfig error unmarshaling due to unexpected end of JSON input" | tail -50 docker compose logs -f --no-color --tail=0 boulder | grep "\[AUDIT\]" ;; "log-activity") cd /opt/boulder echo "GMT" docker compose logs --no-color boulder | grep "\[AUDIT\]" | grep -v "grpc: parseServiceConfig error unmarshaling due to unexpected end of JSON input" | tail -15 exit 0 ;; "log-labca") cd /opt/boulder docker compose logs -f --no-color --tail=50 gui ;; "log-labca-notail") cd /opt/boulder docker compose logs --no-color --tail=50 gui ;; "log-web") cd /opt/boulder docker compose logs -f --no-color --tail=50 nginx ;; "log-components") nginx=$(docker inspect $(docker ps --format "{{.Names}}" | grep -- -nginx-) | grep -i started | grep -v depends_on | sed -e "s/[^:]*:\(.*\)/\1/" | sed -e "s/.*\"\(.*\)\".*/\1/") svc=$(docker inspect $(docker ps --format "{{.Names}}" | grep -- -control-) | grep -i started | grep -v depends_on | sed -e "s/[^:]*:\(.*\)/\1/" | sed -e "s/.*\"\(.*\)\".*/\1/") boulder=$(docker inspect $(docker ps --format "{{.Names}}" | grep -- -boulder-) | grep -i started | grep -v depends_on | sed -e "s/[^:]*:\(.*\)/\1/" | sed -e "s/.*\"\(.*\)\".*/\1/") labca=$(docker inspect $(docker ps --format "{{.Names}}" | grep -- labca-gui) | grep -i started | grep -v depends_on | sed -e "s/[^:]*:\(.*\)/\1/" | sed -e "s/.*\"\(.*\)\".*/\1/") mysql=$(docker inspect $(docker ps --format "{{.Names}}" | grep -- -bmysql-) | grep -i started | grep -v depends_on | sed -e "s/[^:]*:\(.*\)/\1/" | sed -e "s/.*\"\(.*\)\".*/\1/") consul=$(docker inspect $(docker ps --format "{{.Names}}" | grep -- -bconsul-) | grep -i started | grep -v depends_on | sed -e "s/[^:]*:\(.*\)/\1/" | sed -e "s/.*\"\(.*\)\".*/\1/") pkilint=$(docker inspect $(docker ps --format "{{.Names}}" | grep -- -bpkilint-) | grep -i started | grep -v depends_on | sed -e "s/[^:]*:\(.*\)/\1/" | sed -e "s/.*\"\(.*\)\".*/\1/") echo "$nginx|$svc|$boulder|$labca|$mysql|$consul|$pkilint" exit 0 ;; "log-uptime") timezone=$(cat /etc/timezone) uptime=$(uptime -s) echo "$timezone|$uptime" exit 0 ;; "log-stats") docker stats --no-stream -a | grep " labca-" ;; "revoke-cert") read serial read reason cd /opt/boulder docker compose exec boulder bin/boulder admin -config labca/config/admin.json revoke-cert -serial $serial -reason $reason -dry-run=false 2>&1 ;; "test-email") read recipient cd /opt/boulder docker compose exec boulder bin/boulder mail-tester --config labca/config/expiration-mailer.json $recipient 2>&1 ;; "boulder-start") cd /opt/boulder COMPOSE_HTTP_TIMEOUT=120 docker compose up -d bmysql bconsul bpkilint wait_up $PS_MYSQL &>>$LOGFILE wait_up $PS_CONSUL 2 &>>$LOGFILE wait_up $PS_PKILINT &>>$LOGFILE COMPOSE_HTTP_TIMEOUT=120 docker compose up -d boulder wait_up $PS_BOULDER $PS_BOULDER_COUNT &>>$LOGFILE ;; "boulder-stop") cd /opt/boulder docker compose stop boulder docker compose stop bmysql bconsul bpkilint wait_down $PS_MYSQL &>>$LOGFILE wait_down $PS_CONSUL &>>$LOGFILE wait_down $PS_PKILINT &>>$LOGFILE wait_down $PS_BOULDER &>>$LOGFILE ;; "boulder-restart") cd /opt/boulder COMPOSE_HTTP_TIMEOUT=120 docker compose restart boulder bmysql bconsul bpkilint &>>$LOGFILE sleep 30 wait_up $PS_MYSQL &>>$LOGFILE wait_up $PS_CONSUL 2 &>>$LOGFILE wait_up $PS_PKILINT &>>$LOGFILE wait_up $PS_BOULDER $PS_BOULDER_COUNT &>>$LOGFILE ;; "labca-restart") cd /opt/boulder COMPOSE_HTTP_TIMEOUT=120 docker compose restart gui sleep 15 wait_up $PS_LABCA &>>$LOGFILE ;; "mysql-restart") cd /opt/boulder set +e COMPOSE_HTTP_TIMEOUT=120 docker compose restart bmysql set -e ;; "consul-restart") cd /opt/boulder set +e COMPOSE_HTTP_TIMEOUT=120 docker compose restart bconsul set -e ;; "pkilint-restart") cd /opt/boulder set +e COMPOSE_HTTP_TIMEOUT=120 docker compose restart bpkilint set -e ;; "log-backups") ls -1tr /opt/backup || /bin/true exit 0 ;; "log-server-backup") /opt/labca/backup exit 0 ;; "backup-delete") read backup rm -f /opt/backup/$backup ;; "backup-restore") read backup /opt/labca/restore "$backup" sleep 3 ;; "server-restart") cd /opt/boulder nohup docker compose restart gui & >/dev/null nohup docker compose restart nginx & >/dev/null ;; "version-update") cd $dn branch="$(git symbolic-ref --short HEAD 2>/dev/null)" || branch="(none)" if [ "$branch" == "master" ] || [ "$branch" == "main" ] || [ "$branch" == "(none)" ]; then nohup /labca/install &>>$LOGFILE else nohup /labca/install -b $branch &>>$LOGFILE fi ;; "gen-root-crl") cd /opt/labca/gui /opt/labca/bin/labca-gui -config /opt/labca/data/config.json -renewcrl 999 &>>$LOGFILE /opt/labca/checkcrl &>>$LOGFILE ;; "gen-issuer-crl") cd /opt/boulder docker compose exec -i boulder ./bin/boulder crl-updater -config labca/config/crl-updater.json -runOnce -debug-addr :18021 &>>$LOGFILE /opt/labca/checkcrl &>>$LOGFILE ;; "check-crl") /opt/labca/checkcrl &>>$LOGFILE ;; "apply") [ ! -e /opt/labca/apply ] || /opt/labca/apply &>>$LOGFILE [ ! -e /opt/labca/gui/apply ] || /opt/labca/gui/apply &>>$LOGFILE [ -e /opt/labca/apply ] || [ -e /opt/labca/gui/apply ] || echo "Could not find apply script!" ;; "git-version") if [ -x /usr/bin/git ]; then git config --global --add safe.directory /opt/labca &>>$LOGFILE gd=$(git describe --always --tags HEAD) echo "$gd" else echo "unknown" fi exit 0 ;; *) echo "Unknown command '$txt'. ERROR!" exit 1 ;; esac echo "ok"