Skip to content

Commit

Permalink
feat: generate certificate set for WebGUI
Browse files Browse the repository at this point in the history
  • Loading branch information
dkaser committed Aug 27, 2024
1 parent 82763d0 commit 15b27af
Show file tree
Hide file tree
Showing 8 changed files with 85 additions and 7 deletions.
1 change: 0 additions & 1 deletion src/usr/local/emhttp/plugins/tailscale/daily.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
$docroot = $docroot ?? $_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp';

require_once "{$docroot}/plugins/tailscale/include/common.php";
require_once "{$docroot}/plugins/tailscale/include/tailscale-status.php";

foreach (glob("{$docroot}/plugins/tailscale/include/daily/*.php") as $file) {
require_once $file;
Expand Down
3 changes: 3 additions & 0 deletions src/usr/local/emhttp/plugins/tailscale/include/common.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<?php

require_once "/usr/local/emhttp/plugins/tailscale/include/translate.php";
require_once "/usr/local/emhttp/plugins/tailscale/include/tailscale-status.php";
require_once "/usr/local/emhttp/plugins/tailscale/include/webgui-cert.php";

function logmsg($message, $priority = LOG_INFO)
{
Expand All @@ -17,6 +19,7 @@ function run_command($command, $alwaysShow = false, $show = true)
logmsg($command);
}
exec("{$command} 2>&1", $output, $retval);

if (($retval != 0) || $alwaysShow) {
logmsg("Command returned {$retval}" . PHP_EOL . implode(PHP_EOL, $output));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<?php

refreshWebGuiCert();
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@ function apply_flag($setting, $flag)
apply_flag('ACCEPT_ROUTES', '--accept-routes');
apply_flag('ACCEPT_DNS', '--accept-dns');

run_command("/usr/local/sbin/tailscale set --stateful-filtering=false");
run_command("/usr/local/sbin/tailscale set --stateful-filtering=false");
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
<?php

if ($tailscale_config["INCLUDE_INTERFACE"] == 1) {
refreshWebGuiCert($false);

logmsg("Restarting Unraid services");
exec($restart_command);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<?php

refreshWebGuiCert();
44 changes: 44 additions & 0 deletions src/usr/local/emhttp/plugins/tailscale/include/webgui-cert.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

function refreshWebGuiCert($restartIfChanged = true)
{
$status = getTailscaleStatus();

$certDomains = $status->CertDomains;

if (count($certDomains) === 0) {
logmsg("Cannot generate certificate for WebGUI -- HTTPS not enabled for Tailnet.");
return;
}

$dnsName = $certDomains[0];

$certFile = "/boot/config/plugins/tailscale/state/certs/{$dnsName}.crt";
$keyFile = "/boot/config/plugins/tailscale/state/certs/{$dnsName}.key";
$pemFile = "/boot/config/ssl/certs/ts_bundle.pem";

clearstatcache();

$pemHash = '';
if (file_exists($pemFile)) {
$pemHash = sha1_file($pemFile);
}

logmsg("Certificate bundle hash: {$pemHash}");

run_command("tailscale cert --cert-file={$certFile} --key-file={$keyFile} --min-validity=720h {$dnsName}");

if (
file_exists($certFile) && file_exists($keyFile) && filesize($certFile) > 0 && filesize($keyFile) > 0
) {
file_put_contents($pemFile, file_get_contents($certFile));
file_put_contents($pemFile, file_get_contents($keyFile), FILE_APPEND);

if ((sha1_file($pemFile) != $pemHash) && $restartIfChanged) {
logmsg("WebGUI certificate has changed, restarting nginx");
run_command("/etc/rc.d/rc.nginx reload");
}
} else {
logmsg("Something went wrong when creating WebGUI certificate, skipping nginx update.");
}
}
33 changes: 28 additions & 5 deletions src/usr/local/emhttp/plugins/tailscale/tailscale-watcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,21 @@
$timer = 15;
$need_ip = true;

$tsName = '';

logmsg("Starting tailscale-watcher");

while (true) {
sleep($timer);

unset($tailscale_ipv4);

$interfaces = net_get_interfaces();
$interfaces = net_get_interfaces();

if (isset($interfaces["tailscale1"]["unicast"])) {
foreach ($interfaces["tailscale1"]["unicast"] as $interface) {
if (isset($interface["address"])) {
if ($interface["family"] == 2) {
$tailscale_ipv4 = $interface["address"];
$timer = 60;
$timer = 60;
}
}
}
Expand All @@ -32,7 +32,10 @@
logmsg("Tailscale IP detected, applying configuration");
$need_ip = false;

foreach (glob("{$docroot}/plugins/tailscale/include/tailscale-watcher/*.php") as $file) {
$status = getTailscaleStatus();
$tsName = $status->Self->DNSName;

foreach (glob("{$docroot}/plugins/tailscale/include/tailscale-watcher/on-ip/*.php") as $file) {
try {
require $file;
} catch (Exception $e) {
Expand All @@ -48,7 +51,27 @@
logmsg("Caught exception in {$file} : " . $e->getMessage());
}
}

// Watch for changes to the DNS name (e.g., if someone changes the tailnet name or the Tailscale name of the server via the admin console)
// If a change happens, refresh the Tailscale WebGUI certificate
$status = getTailscaleStatus();
$newTsName = $status->Self->DNSName;

if ($newTsName != $tsName) {
logmsg("Detected DNS name change");
$tsName = $newTsName;

foreach (glob("{$docroot}/plugins/tailscale/include/tailscale-watcher/on-name-change/*.php") as $file) {
try {
require $file;
} catch (Exception $e) {
logmsg("Caught exception in {$file} : " . $e->getMessage());
}
}
}
} else {
logmsg("Waiting for Tailscale IP");
}

sleep($timer);
}

0 comments on commit 15b27af

Please sign in to comment.