diff --git a/scripts/cloudron-support b/scripts/cloudron-support index 9628e3266..04b685817 100755 --- a/scripts/cloudron-support +++ b/scripts/cloudron-support @@ -181,6 +181,19 @@ function check_unbound() { success "unbound is running" } +function check_dashboard_cert() { + local -r dashboard_domain=$(mysql -NB -uroot -ppassword -e "SELECT value FROM box.settings WHERE name='dashboard_domain'" 2>/dev/null) + local -r nginx_conf_file="/home/yellowtent/platformdata/nginx/applications/dashboard/my.${dashboard_domain}.conf" + local -r cert_file=$(sed -n -e 's/.*ssl_certificate [[:space:]]\+\(.*\);/\1/p' "${nginx_conf_file}") + + local -r cert_expiry_date=$(openssl x509 -enddate -noout -in "${cert_file}" | sed -e 's/notAfter=//') + + if ! openssl x509 -checkend 100 -noout -in "${cert_file}" >/dev/null 2>&1; then + fail "Certificate has expired. Certificate expired at ${cert_expiry_date}" + exit 1 + fi +} + function check_nginx() { local -r dashboard_domain=$(mysql -NB -uroot -ppassword -e "SELECT value FROM box.settings WHERE name='dashboard_domain'" 2>/dev/null) @@ -199,6 +212,16 @@ function check_nginx() { success "nginx is running" } +# this confirms that https works properly without any proxy (cloudflare) involved +function check_dashboard_site_loopback() { + 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 --resolve "my.${dashboard_domain}:443:127.0.0.1" "https://my.${dashboard_domain}" >/dev/null; then + fail "Could not load dashboard website with loopback check" + exit 1 + fi +} + function check_node() { expected_node_version="$(sed -ne 's/readonly node_version=\(.*\)/\1/p' /home/yellowtent/box/scripts/installer.sh)" current_node_version="$(node --version | tr -d '\n' | cut -c2-)" # strip trailing newline and 'v' prefix @@ -229,14 +252,58 @@ function check_docker() { success "docker is running" } -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 - fail "Could not reach dashboard domain. Is Hairpin NAT functional?" +function check_node() { + expected_node_version="$(sed -ne 's/readonly node_version=\(.*\)/\1/p' /home/yellowtent/box/scripts/installer.sh)" + current_node_version="$(node --version | tr -d '\n' | cut -c2-)" # strip trailing newline and 'v' prefix + + if [[ "${current_node_version}" != "${expected_node_version}" ]]; then + fail "node version is incorrect. Expecting ${expected_node_version}. Got ${current_node_version}." + echo "You can try the following to fix the problem:" + echo " ln -sf /usr/local/node-${expected_node_version}/bin/node /usr/bin/node" + echo " ln -sf /usr/local/node-${expected_node_version}/bin/npm /usr/bin/npm" + echo " systemctl restart box" exit 1 fi - success "Hairpin NAT is good" + success "node version is correct" +} + +function check_docker() { + if ! systemctl is-active -q docker; then + info "Docker is down. Trying to restart docker ..." + systemctl restart docker + + if ! systemctl is-active -q docker; then + fail "Docker is still down, please investigate the error using 'journalctl -u docker'" + exit 1 + fi + fi + + success "docker is running" +} + +function check_dashboard_site_domain() { + local -r dashboard_domain=$(mysql -NB -uroot -ppassword -e "SELECT value FROM box.settings WHERE name='dashboard_domain'" 2>/dev/null) + local -r domain_provider=$(mysql -NB -uroot -ppassword -e "SELECT provider FROM box.domains WHERE domain='${dashboard_domain}'" 2>/dev/null) + + # TODO: check ipv4 and ipv6 + if ! output=$(curl --fail -s https://my.${dashboard_domain}); then + fail "Could not load dashboard domain." + if [[ "${domain_provider}" == "cloudflare" ]]; then + echo "Maybe cloudflare proxying is not working. Delete the domain in Cloudflare dashboard and re-add it. This sometimes re-establishes the proxying" + else + echo "Hairpin NAT is not working. Please check if your router supports it" + fi + exit 1 + fi + + if ! echo $output | grep -q "Cloudron Dashboard"; then + fail "https://my.${dashboard_domain} is not the dashboard domain. Check if DNS is set properly to this server" + host my.${dashboard_domain} 127.0.0.1 # could also result in cloudflare + exit 1 + fi + + success "Dashboard is reachable via domain name" } function check_expired_domain() { @@ -301,10 +368,13 @@ function troubleshoot() { check_node check_docker check_host_mysql + check_dashboard_cert # do not restart nginx blindly, won't come up without valid cert check_nginx # requires mysql to be checked + check_dashboard_site_loopback # checks website via loopback check_box check_unbound - check_hairpin_nat # requires mysql to be checked + check_dashboard_cert + check_dashboard_site_domain # check website via domain name check_expired_domain }