Menu="OtherSettings" Type="xmenu" Title="Management Access" Icon="icon-key" Tag="expeditedssl" --- /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'"); $isWildcardCert = preg_match('/.*\.myunraid\.net$/', $cert2Subject); $subject2URL = $cert2Subject; $dnsValid = false; $dnsRebindingProtection = false; if ($isWildcardCert) { exec("openssl x509 -checkend 2592000 -noout -in $cert2File 2>/dev/null", $arrout, $retval_expired); 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); $dnsValid = false; $dnsRebindingProtection = false; } elseif (strpos($addr, ":") === false) { // eth0 is IPv4 $subject2URL = str_replace("*", str_replace(".", "-", $addr), $subject2URL); $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 { // eth0 is IPv6 $subject2URL = str_replace("*", str_replace(":", "-", $addr), $subject2URL); $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; } } } } // Tailscale LE cert $cert3File = "/boot/config/ssl/certs/ts_bundle.pem"; $cert3Present = file_exists("$cert3File"); if ($cert3Present) { $cert3Subject = exec("/usr/bin/openssl x509 -in $cert3File -noout -subject -nameopt multiline 2>/dev/null|sed -n 's/ *commonName *= //p'"); $cert3Issuer = exec("/usr/bin/openssl x509 -in $cert3File -noout -text | sed -n -e 's/^.*Issuer: //p'"); $cert3Expires = exec("/usr/bin/openssl x509 -in $cert3File -noout -text | sed -n -e 's/^.*Not After : //p'"); } // Note: this disables FQDN6 urls since they are not supported by myunraid.net DNS currently if (!empty($nginx['NGINX_LANFQDN6'])) { unset($nginx['NGINX_LANFQDN6']); } $http_port = _var($var, 'PORT', '80') != '80' ? ":{$var['PORT']}" : ''; $https_port = _var($var, 'PORTSSL', '443') != '443' ? ":{$var['PORTSSL']}" : ''; $http_ip_url = 'http://'._var($nginx, 'NGINX_LANIP').$http_port.'/'; $https_ip_url = 'https://'._var($nginx, 'NGINX_LANIP').$https_port.'/'; // bare IPv6 addresses need to be surrounded in brackets $http_ip6_url = 'http://'.'['._var($nginx, 'NGINX_LANIP6').']'.$http_port.'/'; $https_ip6_url = 'https://'.'['._var($nginx, 'NGINX_LANIP6').']'.$https_port.'/'; $http_mdns_url = 'http://'._var($nginx, 'NGINX_LANMDNS').$http_port.'/'; $https_mdns_url = 'https://'._var($nginx, 'NGINX_LANMDNS').$https_port.'/'; $https_fqdn_url = 'https://'._var($nginx, 'NGINX_LANFQDN').$https_port.'/'; $https_fqdn6_url = 'https://'._var($nginx, 'NGINX_LANFQDN6').$https_port.'/'; $urls = []; // push an array of five values into the $urls array: // 0 - type of url ['LAN','WLAN','WAN','WG','TAILSCALE'] // 1 - the url // 3 - the url it redirects to, or null // 4 - the certificate file used, or null // 5 - self-signed certificate, or false // define LAN access urls and redirects that change based on USE_SSL setting switch (_var($var, 'USE_SSL', 'no')) { case 'no': if (!empty($nginx['NGINX_LANIP'])) { $urls[] = ['LAN', $http_ip_url, null, null, false]; } if (!empty($nginx['NGINX_LANIP6'])) { $urls[] = ['LAN', $http_ip6_url, null, null, false]; } if (!empty($nginx['NGINX_LANMDNS'])) { $urls[] = ['LAN', $http_mdns_url, null, null, false]; } break; case 'yes': if (!empty($nginx['NGINX_LANIP'])) { $urls[] = ['LAN', $http_ip_url, $https_ip_url, null, false]; } if (!empty($nginx['NGINX_LANIP'])) { $urls[] = ['LAN', $https_ip_url, null, "{$var['NAME']}_unraid_bundle.pem", $cert1SelfSigned]; } if (!empty($nginx['NGINX_LANIP6'])) { $urls[] = ['LAN', $http_ip6_url, $https_ip6_url, null, false]; } if (!empty($nginx['NGINX_LANIP6'])) { $urls[] = ['LAN', $https_ip6_url, null, "{$var['NAME']}_unraid_bundle.pem", $cert1SelfSigned]; } if (!empty($nginx['NGINX_LANMDNS'])) { $urls[] = ['LAN', $http_mdns_url, $https_mdns_url, null, false]; } if (!empty($nginx['NGINX_LANMDNS'])) { $urls[] = ['LAN', $https_mdns_url, null, "{$var['NAME']}_unraid_bundle.pem", $cert1SelfSigned]; } break; case 'auto': // aka strict if (!empty($nginx['NGINX_LANIP']) && !empty($nginx['NGINX_LANFQDN'])) { $urls[] = ['LAN', $http_ip_url, $https_fqdn_url, null, false]; } if (!empty($nginx['NGINX_LANIP6']) && !empty($nginx['NGINX_LANFQDN6'])) { $urls[] = ['LAN', $http_ip6_url, $https_fqdn6_url, null, false]; } if (!empty($nginx['NGINX_LANMDNS']) && !empty($nginx['NGINX_LANFQDN'])) { $urls[] = ['LAN', $http_mdns_url, $https_fqdn_url, null, false]; } break; } // define FQDN urls for each interface // when multiple FQDN urls are available for a given interface, make sure they are sorted asort($nginx); foreach ($nginx as $key => $host) { if (!$host) { continue; } // Only process keys that include 'FQDN' if (strpos($key, 'FQDN') === false) { continue; } // Extract the interface from the key, e.g., 'NGINX_LANFQDN' -> 'LAN', 'NGINX_WANFQDN' -> 'WAN', NGINX_WG0FQDN -> WG, NGINX_TAILSCALE1FQDN -> TAILSCALE // Note: this specifically excludes FQDN6 urls since they are not supported by myunraid.net DNS currently if (preg_match('/^NGINX_([A-Z]+)(\d*)FQDN$/', $key, $matches)) { $interface = $matches[1]; // Interface type (LAN, WAN, WG, TAILSCALE, etc.) // ignore the WAN interface because we don't have access to the WANPORT here if ($interface == "WAN") { continue; } $pem = null; if (str_ends_with($host, '.myunraid.net')) { $pem = 'certificate_bundle.pem'; } elseif (str_ends_with($host, '.ts.net')) { $pem = 'ts_bundle.pem'; } $url = 'https://'.$host.$https_port."/"; $urls[] = [$interface, $url, null, $pem, false]; } } // determine whether there are urls for a given list of interfaces function has_urls(array $interfaces) { global $urls; foreach ($urls as $url) { if (in_array($url[0], $interfaces)) { return true; } } return false; } // show all urls for a given list of interface function show_urls(array $interfaces) { global $urls; // 0 - type of url ['LAN','WLAN','WAN','WG','TAILSCALE'] // 1 - the url // 3 - the url it redirects to, or null // 4 - the certificate file used, or null // 5 - self-signed certificate, or false $output = ""; $linestart = "
 
"; $lineend = "
\n"; $first = true; foreach ($urls as $url) { if (in_array($url[0], $interfaces)) { $msg = "$url[1]"; if ($url[2]) { $msg .= " "._("redirects to")." $url[2]"; } if ($url[3]) { $msg .= " "._("uses")." ".$url[3]; } $msg .= ""; if ($url[4]) { $msg .= " "._("is a self-signed certificate, ignore the browser's warning and proceed to the GUI").""; } // 2nd+ urls need leading $linestart $output .= ($first ? "" : $linestart).$msg.$lineend; $first = false; } } if ($first) { $output = "none"; } else { // strip final trailing $lineend as it will be added by markdown $output = substr($output, 0, strlen($lineend) * -1); } echo $output; } $cert_time_format = $display['date'].($display['date'] != '%c' ? ', '.str_replace(['%M','%R'], ['%M:%S','%R:%S'], $display['time']) : ''); $provisionlabel = $isWildcardCert ? _('Renew') : _('Provision'); $disabled_provision = $keyfile === false || ($isWildcardCert && $retval_expired === 0) || !$addr ? 'disabled' : ''; $disabled_provision_msg = !$addr ? _('Ensure the primary network card eth0 has an IP address.') : ''; $disabled_delete = $cert2Present && $var['USE_SSL'] != 'auto' ? '' : 'disabled'; $disabled_auto = $isWildcardCert && !$dnsRebindingProtection && $dnsValid ? '' : 'disabled'; // 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); ?>
"> _(User 'root')_: : [_(Manage)_](/Settings/Users/ManagementAccess/UserEdit?name=root) _(Start page)_: : :mgmt_start_page_help: _(Use TELNET)_: : :mgmt_use_telnet_help: _(TELNET port)_: : :mgmt_telnet_port_help: _(Use SSH)_: : :mgmt_use_ssh_help: _(SSH port)_: : :mgmt_ssh_port_help: _(Use UPnP)_: : :mgmt_use_upnp_help: _(Use SSL/TLS)_: : :mgmt_use_ssl_tls_help: _(HTTP port)_: : :mgmt_http_port_help: _(HTTPS port)_: : :mgmt_https_port_help: _(Local TLD)_: : :mgmt_local_tld_help:   :

_(Local access URLs)_: : :mgmt_local_access_urls_help: _(WireGuard URLs)_: : :mgmt_wg_access_urls_help: _(Tailscale URLs)_: : :mgmt_tailscale_access_urls_help:
_(Self-signed or user-provided certificate)_: : _(Certificate URL)_: : $cert1URL"?> _(Certificate URL)_: : _(Certificate URL)_: : _(Certificate not valid for)_ _(Certificate issuer)_: : _(is a self-signed certificate, ignore the browser's warning when using this certificate)_ _(Certificate expiration)_: : _(Self-signed certificate file)_: : _(Not present)_
">
_(Unraid Let's Encrypt certificate)_: : _(Certificate URL)_: : $cert2Subject"?> _(Certificate issuer)_: : _(Certificate expiration)_: :   : _(DNS Rebinding Protection is ENABLED)_   : _(DNS Propagation is PENDING)_ _(CA-signed certificate file)_: : _(Not present)_   :
_(Tailscale Let's Encrypt certificate)_: : _(Certificate URL)_: : $cert3Subject"?> _(Certificate issuer)_: : _(Certificate expiration)_: : :mgmt_certificate_expiration_help:
"WireGuard" and the "WireGuard" logo are registered trademarks of Jason A. Donenfeld