#!/bin/bash
#
# AKTUELLE VERSION auch v20: vorab und fremdes Ausstellen des Cert z.B. auf einer pfSense und von da aus Upload in die 3CX als User sshuser
#
# dieses Skript pflegt die extern bereitgestellten LE Zertifikate nur in die 3CX ein
#
# bash Skript zum Einpflegen extern bereitgestellter LE Zertifikate auf einem Client (hier: unter Debian 3CX, z.B. )
#
# Problem:
# - es wird ein weiterer ssh Benutzer in der 3CX benoetigt, es geht nicht anders, das ist ueblicherweise der Benutzer sshuser
# - nur root kann vmtl. im Debian div. Dienste neu starten lassen, daher laeuft dieses Skript im Debian mit root Rechten
# - die Zertifikate werden vorab irgendwo anders (z.B. einer pfSense Firewall) erstellt, verlaengert und dem Client hier bereitgestellt
#
# die Ausfuehrung ist daher leider zweigeteilt
# Teil 1:
# - extern wird die Zertifikatverlaengerung angestossen und durchgefuehrt falls erforderlich
# - im Anschluss daran werden die Zertifikate als eingeschraenkter Benutzer in die 3CX geladen
# Teil 2:
# - auf der 3CX laeuft dieses Skript, welches die bereitgestellten und die aktuell verwendeten Zertifikate ueberprueft
# - falls erforderlich, werden diese umbenannt, an die richtigen Stellen kopiert, die Rechte entspr. gesetzt und Dienste
# neu gestartet
#
#
# es wird auf dem 3CX Client Computer (debian) benoetigt:
# - ein extra Benutzer mit ssh Zugang, i.d.R. der Benutzer sshuser, anlegen wie folgt:
# adduser --disabled-password --gecos "" sshuser; adduser sshuser users; echo sshuser:passwortsuperstrenggeheim | chpasswd
# - dieses Skript, es sollte unter /root liegen und ausfuehrbar sein
# - ein cron job: (crontab -l ; echo "30 4 * * * /root/clientcert-renew-pbx.domain.de.sh >/dev/null 2>&1") | crontab -
#
# auf einer pfSense wird benoetigt:
# - installiertes Paket cron
# - Paket haproxy und Paket acme, alles vorab umfassend eingerichtet,
# bei der Zertifikatverlaengerung kommt in die Actions List mindestens folgende Zeile:
# scp /conf/acme/pbx.* sshuser@pbxip:/home/sshuser
# - vorab noch die Einrichtung des passwortlosen ssh Zuganges von der pfSense auf die 3CX,
# dazu in der pfSense per ssh eine shell oeffnen und diese folgenden Zeilen je einzeln ausfuehren:
# ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa -q -N '' # generiere einen key fuer ssh, ohne Passphrase (root Kennwort) WENN ES DAS NICHT SCHON GIBT
# ssh-keyscan pbxip >> ~/.ssh/known_hosts # hole den hostkey des Zielsystems
# ssh-copy-id -i ~/.ssh/id_rsa.pub sshuser@pbxip # überträgt die passwortlose Authorisierung der pfSense auf die 3CX, hier erfolgt noch einmalig eine Passwortabfrage des Users sshuser
# scp /conf/acme/pbx.* sshuser@pbxip:/home/sshuser # bei Bedarf: die Zertifikate auf den Zielcomputer - die 3CX - kopieren
#
# Kontrolle ob ssh key schon besteht und das Zielsystem bereits in der Liste ist:
# ls -ahl ~/.ssh/; cat ~/.ssh/known_hosts
#
#
# Suchstichworte: pfsense haproxy letsencrypt upload automatisch skript script shell bash debian 3cx pbx remote
#
_sshusername="sshuser" # der auf der 3CX extra angelegte Benutzer, in dessen Home Directory sollten immer aktuell gueltige LE Zertifikate liegen
_sshpassword="superstrenggeheim" # dessen Passwort, wird hier im Skript gar nicht benoetigt, bleibt leer :)
_fqdn=$(hostname -f) # der FQDN des Letsenrypt Zertifikates abgeleitet vom vollständigen Namen der Maschine, ist auch genau so unter diesem Namen in der pfSense drin
_doupdate=$false
_actcerthash=$(cat /home/$_sshusername/$_fqdn.fullchain | md5sum)
_actkeyhash=$(cat /home/$_sshusername/$_fqdn.key | md5sum)
_nginxcertfile=$(perl -ne 'if( m/^\s+ssl_certificate\s+"?(.*pem)"?;/ ){ print $1; exit }' /etc/nginx/sites-enabled/3cxpbx)
_nginxkeyfile=$(perl -ne 'if( m/^\s+ssl_certificate_key\s+"?(.*pem)"?;/ ){ print $1; exit }' /etc/nginx/sites-enabled/3cxpbx)
_nginxcerthash=$(cat $_nginxcertfile | md5sum)
_nginxkeyhash=$(cat $_nginxkeyfile | md5sum)
_sipcerthash=$(cat /var/lib/3cxpbx/Instance1/Bin/Cert/domain_cert_$_fqdn.pem | md5sum)
_sipkeyhash=$(cat /var/lib/3cxpbx/Instance1/Bin/Cert/domain_key_$_fqdn.pem | md5sum)
if [[ ($_nginxcerthash != $_actcerthash) || ($_sipcerthash != $_actcerthash) || ($_nginxkeyhash != $_actkeyhash) || ($_sipkeyhash != $_actkeyhash) ]]; then
rm $_nginxcertfile
rm $_nginxkeyfile
cp /home/$_sshusername/$_fqdn.fullchain $_nginxcertfile
cp /home/$_sshusername/$_fqdn.key $_nginxkeyfile
chown phonesystem:phonesystem $_nginxcertfile
chown phonesystem:phonesystem $_nginxkeyfile
chmod 644 $_nginxcertfile
chmod 644 $_nginxkeyfile
/etc/init.d/nginx reload
systemctl stop 3CXPhoneSystem01
rm /var/lib/3cxpbx/Instance1/Bin/Cert/domain_cert_$_fqdn.pem
rm /var/lib/3cxpbx/Instance1/Bin/Cert/domain_key_$_fqdn.pem
cp /home/$_sshusername/$_fqdn.fullchain /var/lib/3cxpbx/Instance1/Bin/Cert/domain_cert_$_fqdn.pem
cp /home/$_sshusername/$_fqdn.key /var/lib/3cxpbx/Instance1/Bin/Cert/domain_key_$_fqdn.pem
chown phonesystem:phonesystem /var/lib/3cxpbx/Instance1/Bin/Cert/domain_cert_$_fqdn.pem
chown phonesystem:phonesystem /var/lib/3cxpbx/Instance1/Bin/Cert/domain_key_$_fqdn.pem
chmod 644 /var/lib/3cxpbx/Instance1/Bin/Cert/domain_cert_$_fqdn.pem
chmod 644 /var/lib/3cxpbx/Instance1/Bin/Cert/domain_key_$_fqdn.pem
# _services=$(systemctl list-unit-files --state=enabled |grep -i 3cx |awk '{printf "%s\n", $1}')
# for _service in $_services; do systemctl is-active --quiet $_service || systemctl start $_service; done
for _service in $(systemctl list-unit-files --state=enabled |grep -i service |awk '{printf "%s\n", $1}'); do systemctl is-active --quiet $_service || systemctl start $_service; done
_doupdate=$true
# sicherheitshalber ein Neustart, weil immer mal irgend etwas mit dem 3CX Dienstneustart nicht sauber funktioniert :(
reboot
fi
exit 1