#!/bin/bash set -eu -o pipefail # scripts requires root if [[ ${EUID} -ne 0 ]]; then echo "This script should be run as root. Run with sudo" exit 1 fi readonly PASTEBIN="https://paste.cloudron.io" readonly LINE="\n========================================================\n" readonly HELP_MESSAGE=" Cloudron Support and Diagnostics Tool Options: --enable-remote-access Enable SSH Remote Access for the Cloudron support team --send-diagnostics Collects server diagnostics and uploads it to ${PASTEBIN} --troubleshoot Dashboard down? Run tests to identify the potential problem --owner-login Login as owner --help Show this message " function enable_remote_access() { local -r cloudron_support_public_key="ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGWS+930b8QdzbchGljt3KSljH9wRhYvht8srrtQHdzg support@cloudron.io" local -r ssh_user="cloudron-support" local -r keys_file="/home/cloudron-support/.ssh/authorized_keys" echo -n "Enabling Remote Access for the Cloudron support team..." mkdir -p $(dirname "${keys_file}") # .ssh does not exist sometimes touch "${keys_file}" # required for concat to work if ! grep -q "${cloudron_support_public_key}" "${keys_file}"; then echo -e "\n${cloudron_support_public_key}" >> "${keys_file}" chmod 600 "${keys_file}" chown "${ssh_user}" "${keys_file}" fi echo "Done" } function check_host_mysql() { if ! systemctl is-active -q mysql; then echo "MySQL is down. Maybe restarting fixes it" systemctl restart mysql if ! systemctl is-active -q mysql; then echo "MySQL is still down, please investigate the error by inspecting /var/log/mysql/error.log" exit 1 fi fi echo "MySQL is OK" } function owner_login() { check_host_mysql local -r owner_username=$(mysql -NB -uroot -ppassword -e "SELECT username FROM box.users WHERE role='owner' AND username IS NOT NULL AND active=1 ORDER BY creationTime LIMIT 1" 2>/dev/null) local -r owner_password=$(pwgen -1s 12) local -r dashboard_domain=$(mysql -NB -uroot -ppassword -e "SELECT value FROM box.settings WHERE name='dashboard_domain'" 2>/dev/null) mysql -NB -uroot -ppassword -e "INSERT INTO box.settings (name, value) VALUES ('ghosts_config', '{\"${owner_username}\":\"${owner_password}\"}') ON DUPLICATE KEY UPDATE name='ghosts_config', value='{\"${owner_username}\":\"${owner_password}\"}'" 2>/dev/null echo "Login at https://my.${dashboard_domain} as ${owner_username} / ${owner_password} . This password may only be used once." } function send_diagnostics() { local -r log="/tmp/cloudron-support.log" echo -n "Generating Cloudron Support stats..." rm -rf $log echo -e $LINE"Linux"$LINE >> $log uname -nar &>> $log echo -e $LINE"Ubuntu"$LINE >> $log lsb_release -a &>> $log echo -e $LINE"Dashboard Domain"$LINE >> $log mysql -NB -uroot -ppassword -e "SELECT value FROM box.settings WHERE name='dashboard_domain'" &>> $log 2>/dev/null || true echo -e $LINE"Docker containers"$LINE >> $log if ! timeout --kill-after 10s 15s docker ps -a &>> $log 2>&1; then echo -e "Docker is not responding" >> $log fi echo -e $LINE"Filesystem stats"$LINE >> $log df -h &>> $log echo -e $LINE"Appsdata stats"$LINE >> $log du -hcsL /home/yellowtent/appsdata/* &>> $log || true echo -e $LINE"Boxdata stats"$LINE >> $log du -hcsL /home/yellowtent/boxdata/* &>> $log echo -e $LINE"Backup stats (possibly misleading)"$LINE >> $log du -hcsL /var/backups/* &>> $log || true echo -e $LINE"System daemon status"$LINE >> $log systemctl status --lines=100 box mysql unbound cloudron-syslog nginx collectd docker &>> $log echo -e $LINE"Box logs"$LINE >> $log tail -n 100 /home/yellowtent/platformdata/logs/box.log &>> $log echo -e $LINE"Interface Info"$LINE >> $log ip addr &>> $log echo -e $LINE"Firewall chains"$LINE >> $log iptables -L &>> $log has_ipv6=$(cat /proc/net/if_inet6 >/dev/null 2>&1 && echo "yes" || echo "no") echo -e "IPv6: ${has_ipv6}" >> $log [[ "${has_ipv6}" == "yes" ]] && ip6tables -L &>> $log echo "Done" echo -n "Uploading information..." paste_key=$(curl -X POST ${PASTEBIN}/documents --silent --data-binary "@$log" | python3 -c "import sys, json; print(json.load(sys.stdin)['key'])") echo "Done" echo -e "\nPlease email the following link to support@cloudron.io : ${PASTEBIN}/${paste_key}" } function check_unbound() { if ! systemctl is-active -q unbound; then echo "unbound is down. updating root anchor to see if it fixes it" unbound-anchor -a /var/lib/unbound/root.key systemctl restart unbound if ! systemctl is-active -q unbound; then echo "unbound is still down, please investigate the error using 'journalctl -u unbound'" exit 1 fi fi test_resolve=$(dig cloudron.io @127.0.0.1 +short) if [[ -z "test_resolve" ]]; then echo "DNS is not resolving, maybe try forwarding all DNS requests using the --use-external-dns option" exit 1 fi echo "unbound is OK" } function check_nginx() { if ! systemctl is-active -q nginx; then echo "nginx is down. checking if this is because of invalid certs" # TODO: delete config files that use invalid certs and restart nginx fi echo "nginx is OK" } function check_docker() { if ! systemctl is-active -q docker; then echo "Docker is down. Maybe restarting fixes it" systemctl restart docker if ! systemctl is-active -q docker; then echo "Docker is still down, please investigate the error using 'journalctl -u docker'" exit 1 fi fi echo "docker is OK" } function check_hairpin_nat() { local -r dashboard_domain=$(mysql -NB -uroot -ppassword -e "SELECT value FROM box.settings WHERE name='dashboard_domain'" 2>/dev/null) if ! curl --fail -s https://my.${dashboard_domain} >/dev/null; then echo "Could not query dashboard domain. Is Hairpin NAT functional?" exit 1 fi echo "Hairpin NAT is OK" } function check_expired_domain() { local -r dashboard_domain=$(mysql -NB -uroot -ppassword -e "SELECT value FROM box.settings WHERE name='dashboard_domain'" 2>/dev/null) local -r expdate=$(whois ${dashboard_domain} | egrep -i 'Expiration Date:|Expires on|Expiry Date:' | head -1 | awk '{print $NF}') local -r expdate_secs=$(date -d"$expdate" +%s) local -r curdate_secs="$(date +%s)" if (( curdate_secs > expdate_secs )); then echo "Domain appears to be expired" exit 1 fi echo "Domain is valid and has not expired" } function use_external_dns() { local -r $conf_file="/etc/unbound/unbound.conf.d/forward-everything.conf" echo "Forwarding all DNS requests to Google/Cloudflare DNS. To remove the forwarding, please delete $conf and 'systemctl restart unbound'" cat > $conf_file <