Menu="OtherSettings" Type="xmenu" Title="Management Access" Icon="icon-key" Tag="expeditedssl" --- function find_tasks() { global $site; $tasks = []; foreach ($site as $page) { if (empty($page['Menu'])) continue; $menu = strtok($page['Menu'], ' '); switch ($menu[0]) { case '$': $menu = get_ini_key($menu,strtok(' ')); break; case '/': $menu = get_file_key($menu,strtok(' ')); break; } while ($menu !== false) { if (substr($menu,0,5) == 'Tasks') { if (empty($page['Cond'])) $tasks[] = $page['name']; break; } $menu = strtok(' '); } } sort($tasks); return $tasks; } function acceptableCert($certFile, $hostname, $expectedURL) { if (!file_exists($certFile)) return false; $certURLs=null; // get Subject URL and all SAN URLs from cert exec("openssl x509 -noout -subject -nameopt multiline -in $certFile | sed -n 's/ *commonName *= //p' ; openssl x509 -noout -ext subjectAltName -in $certFile | grep -Eo \"DNS:[a-zA-Z 0-9.*-]*\" | sed \"s/DNS://g\"", $certURLs); foreach($certURLs as $certURL) { // adjust for wildcard certs $certURL = str_replace('*', $hostname, $certURL); // case-insensitive compare if (strcasecmp($certURL, $expectedURL) == 0) return true; } return false; } $tasks = find_tasks(); $nginx = parse_ini_file('/var/local/emhttp/nginx.ini'); $addr = (array_key_exists('NGINX_LANIP', $nginx) && $nginx['NGINX_LANIP']) ? $nginx['NGINX_LANIP'] : ((array_key_exists('NGINX_LANIP6', $nginx) && $nginx['NGINX_LANIP6']) ? $nginx['NGINX_LANIP6'] : ''); $keyfile = @file_get_contents($var['regFILE']); $cert2Issuer = ''; $isLEcert = false; if ($keyfile !== false) $keyfile = base64_encode($keyfile); // self-signed or user-provided cert $cert1File = "/boot/config/ssl/certs/{$var['NAME']}_unraid_bundle.pem"; $cert1Present = file_exists("$cert1File"); if ($cert1Present) { $cert1URL = $var['NAME'].".".$var['LOCAL_TLD']; // if user replaced cert without reloading nginx, the cert on the flash could be invalid $cert1URLvalid = acceptableCert($cert1File, $var['NAME'], $cert1URL); $cert1Subject = exec("/usr/bin/openssl x509 -in $cert1File -noout -text | sed -n 's/^.*Subject: //p'"); $cert1Issuer = exec("/usr/bin/openssl x509 -in $cert1File -noout -text | sed -n -e 's/^.*Issuer: //p'"); $cert1Expires = exec("/usr/bin/openssl x509 -in $cert1File -noout -text | sed -n -e 's/^.*Not After : //p'"); $cert1SelfSigned = ($cert1Subject == $cert1Issuer); } // unraid.net, myunraid.net LE cert. could potentially be user provided as well $cert2File = "/boot/config/ssl/certs/certificate_bundle.pem"; $cert2Present = file_exists("$cert2File"); if ($cert2Present) { $cert2Subject = exec("/usr/bin/openssl x509 -in $cert2File -noout -subject -nameopt multiline 2>/dev/null|sed -n 's/ *commonName *= //p'"); $cert2Issuer = exec("/usr/bin/openssl x509 -in $cert2File -noout -text | sed -n -e 's/^.*Issuer: //p'"); $cert2Expires = exec("/usr/bin/openssl x509 -in $cert2File -noout -text | sed -n -e 's/^.*Not After : //p'"); $isLegacyCert = preg_match('/.*\.unraid\.net$/', $cert2Subject); $isWildcardCert = preg_match('/.*\.myunraid\.net$/', $cert2Subject); $isLEcert = $isLegacyCert || $isWildcardCert; $subject2URL = $cert2Subject; if ($isWildcardCert) { if (!$addr) // if eth0 doesn't have an IP address, then show noip.hash.myunraid.net as a placeholder url $subject2URL = str_replace("*", 'noip', $subject2URL); elseif (strpos($addr, ":") === false) $subject2URL = str_replace("*", str_replace(".", "-", $addr), $subject2URL); else $subject2URL = str_replace("*", str_replace(":", "-", $addr), $subject2URL); } if ($isLEcert) { exec("openssl x509 -checkend 2592000 -noout -in $cert2File 2>/dev/null", $arrout, $retval_expired); if (!$addr) { $dnsValid = false; $dnsRebindingProtection = false; } elseif (strpos($addr, ":") === false) { $rebindtest_ip = exec("host -4 -t A rebindtest4.myunraid.net 2>/dev/null|awk '{print \$4}'"); $dnsRebindingProtection = ($rebindtest_ip != "192.168.42.42"); if (!$dnsRebindingProtection) { $cert_ip = exec("host -4 -t A $subject2URL 2>/dev/null|awk '{print \$4}'"); $dnsValid = $cert_ip==$addr; } } else { $rebindtest_ip = exec("host -6 -t AAAA rebindtest6.myunraid.net 2>/dev/null|awk '{print \$4}'"); // more: restore this after TTL expires // $dnsRebindingProtection = ($rebindtest_ip != "fd42::42"); $dnsRebindingProtection = ($rebindtest_ip != "fd42::42") && ($rebindtest_ip != "fd42::"); if (!$dnsRebindingProtection) { $cert_ip = exec("host -6 -t AAAA $subject2URL 2>/dev/null|awk '{print \$4}'"); $dnsValid = $cert_ip==$addr; } } } } $http_port = $var['PORT'] != 80 ? ":{$var['PORT']}" : ''; $https_port = $var['PORTSSL'] != 443 ? ":{$var['PORTSSL']}" : ''; $http_ip_url = "http://{$nginx['NGINX_LANIP']}{$http_port}/"; $https_ip_url = "https://{$nginx['NGINX_LANIP']}{$https_port}/"; $http_ip6_url = "http://{$nginx['NGINX_LANIP6']}{$http_port}/"; $https_ip6_url = "https://{$nginx['NGINX_LANIP6']}{$https_port}/"; $http_mdns_url = "http://{$nginx['NGINX_LANMDNS']}{$http_port}/"; $https_mdns_url = "https://{$nginx['NGINX_LANMDNS']}{$https_port}/"; $https_fqdn_url = "https://{$nginx['NGINX_LANFQDN']}{$https_port}/"; $https_fqdn6_url = "https://{$nginx['NGINX_LANFQDN6']}{$https_port}/"; $urls = array(); // push an array of three values into the $urls array: // 0 - the url // 1 - the url it redirects to, or null // 2 - the certificate file used, or null switch($var['USE_SSL']) { case 'no': if ($nginx['NGINX_LANIP']) $urls[] = [$http_ip_url, null, null, false]; if ($nginx['NGINX_LANIP6']) $urls[] = [$http_ip6_url, null, null, false]; if ($nginx['NGINX_LANMDNS']) $urls[] = [$http_mdns_url, null, null, false]; if ($nginx['NGINX_LANFQDN']) $urls[] = [$https_fqdn_url, null, "certificate_bundle.pem", false]; if ($nginx['NGINX_LANFQDN6']) $urls[] = [$https_fqdn6_url, null, "certificate_bundle.pem", false]; break; case 'yes': if ($nginx['NGINX_LANIP']) $urls[] = [$http_ip_url, $https_ip_url, null, false]; if ($nginx['NGINX_LANIP']) $urls[] = [$https_ip_url, null, "{$var['NAME']}_unraid_bundle.pem", $cert1SelfSigned]; if ($nginx['NGINX_LANIP6']) $urls[] = [$http_ip6_url, $https_ip6_url, null, false]; if ($nginx['NGINX_LANIP6']) $urls[] = [$https_ip6_url, null, "{$var['NAME']}_unraid_bundle.pem", $cert1SelfSigned]; if ($nginx['NGINX_LANMDNS']) $urls[] = [$http_mdns_url, $https_mdns_url, null, false]; if ($nginx['NGINX_LANMDNS']) $urls[] = [$https_mdns_url, null, "{$var['NAME']}_unraid_bundle.pem", $cert1SelfSigned]; if ($nginx['NGINX_LANFQDN']) $urls[] = [$https_fqdn_url, null, "certificate_bundle.pem", false]; if ($nginx['NGINX_LANFQDN6']) $urls[] = [$https_fqdn6_url, null, "certificate_bundle.pem", false]; break; case 'auto': // aka strict if ($nginx['NGINX_LANIP']) $urls[] = [$http_ip_url, $https_fqdn_url, null, false]; if ($nginx['NGINX_LANIP6']) $urls[] = [$http_ip6_url, $https_fqdn6_url, null, false]; if ($nginx['NGINX_LANMDNS']) $urls[] = [$http_mdns_url, $https_fqdn_url, null, false]; if ($nginx['NGINX_LANFQDN']) $urls[] = [$https_fqdn_url, null, "certificate_bundle.pem", false]; if ($nginx['NGINX_LANFQDN6']) $urls[] = [$https_fqdn6_url, null, "certificate_bundle.pem", false]; break; } $cert_time_format = $display['date'].($display['date']!='%c' ? ', '.str_replace(['%M','%R'],['%M:%S','%R:%S'],$display['time']):''); $provisionlabel = $isLEcert ? _('Renew') : _('Provision'); $disabled_provision = $keyfile===false || ($isLEcert && $retval_expired===0) || !$addr ? 'disabled' : ''; $disabled_provision_msg = !$addr ? _('Ensure the primary network card eth0 has an IP address.') : ''; $disabled_upgrade = !$addr ? 'disabled' : ''; $disabled_updatedns = $keyfile!==false && $isLEcert ? '' : 'disabled'; $disabled_delete = $cert2Present && $var['USE_SSL']!='auto' ? '' : 'disabled'; $disabled_auto = $isLEcert && !$dnsRebindingProtection && $dnsValid ? '' : 'disabled'; $upgradelabel = _('Upgrade Cert'); // Get ports in use $portsInUse = []; exec("lsof -Pni|awk '/LISTEN/ && \$9!~/127.0.0.1/ && \$9!~/\\[::1\\]/{print \$9}'|sort -u", $output); $bind = false; //= $var['BIND_MGT']=='yes'; - not used in 6.10 $list = ['*']; if ($addr) array_push($list, $addr); foreach ($output as $line) { [$ip, $port] = my_explode($line[0]=='[' ? ']:' : ':',$line); if ($ip[0]=='[') $ip = substr($ip,1); // ipv6 address if (!in_array($port,$portsInUse) && (!$bind || in_array($ip,$list))) $portsInUse[] = $port; } sort($portsInUse,SORT_NUMERIC); ?>
_(Local access URLs)_: : // url[0] = url // url[1] = redirect url or null // url[2] = certificate used or null // url[3] = is certificate self-signed T/F $n = 0; foreach($urls as $url) { $msg = ""; $url0 = substr_count($url[0]??'',':')>3 ? preg_replace('#(://)(.+)(/$)#','$1[$2]$3',$url[0]) : $url[0]; // IPv6 - IPv4 notation $url1 = substr_count($url[1]??'',':')>3 ? preg_replace('#(://)(.+)(/$)#','$1[$2]$3',$url[1]) : $url[1]; // IPv6 - IPv4 notation if ($url[1]) $msg .= " "._("redirects to")." $url1"; if ($url[2]) $msg .= " "._("uses")." ".$url[2]; if ($url[3]) $msg .= " "._("is a self-signed certificate, ignore the browser's warning and proceed to the GUI").""; echo ($n ? "