Skip to content

Commit

Permalink
feat: add tailnet lock support
Browse files Browse the repository at this point in the history
  • Loading branch information
dkaser committed Jul 4, 2023
1 parent 1ed41f7 commit 35c2327
Show file tree
Hide file tree
Showing 10 changed files with 155 additions and 3 deletions.
1 change: 0 additions & 1 deletion .php-cs-fixer.dist.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

$finder = PhpCsFixer\Finder::create()
->files()
->name('*.page')
->in(__DIR__)
;

Expand Down
49 changes: 49 additions & 0 deletions src/usr/local/emhttp/plugins/tailscale/Tailscale-2-Lock.page
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
Menu="Tailscale"
Icon="tailscale.png"
Title="Lock"
Type="xmenu"
Tag="lock"
---
<?php
$signingNode = false;

switch (true) {
case $tailscale_output['lock_signing']:
$signingNode = true;
break;
case $tailscale_output['lock_signed']:
echo "Your tailnet has lock enabled and the current node is signed. This is not currently a signing node.<br />";
echo "If you wish to make this a signing node, you will need to trust the following key from a signing node:<br /><br />";
echo $tailscale_output['lock_pubkey'];
break;
case $tailscale_output['lock_enabled']:
echo "Your tailnet has lock enabled and the current node is not signed. This node will not be able to communicate with the tailnet.<br />";
echo "To enable this node, trust the following key from a signing node:<br /><br />";
echo $tailscale_output['lock_nodekey'];
break;
default:
echo "Your tailnet does not have lock enabled.";
break;
}

if ($signingNode) {
?>

<form markdown="1" method="POST" action="/update.php" target="progressFrame">
<input type="hidden" name="#command" value="/usr/local/emhttp/plugins/tailscale/approve-nodes.php" />

### Tailscale Lock: Approve Nodes

<table style="margin-top: 5px;">
<?php
foreach ($tailscale_output['lock_pending'] as $lockHost => $lockKey) {
echo "<tr><td><input type='checkbox' name='#arg[]' value='{$lockKey}' /></td><td>{$lockHost}<br />{$lockKey}</td></tr>";
}
?>
</table>

<input type="submit" name="#apply" value="Approve">
</form>


<?php } ?>
9 changes: 9 additions & 0 deletions src/usr/local/emhttp/plugins/tailscale/approve-nodes.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/usr/bin/php -q
<?php

require "include/common.php";

foreach (array_slice($argv, 1) as $key => $value) {
logmsg("Tailnet lock: signing {$value}");
exec("tailscale lock sign {$value}");
}
66 changes: 66 additions & 0 deletions src/usr/local/emhttp/plugins/tailscale/include/tailscale-lock.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php

function getTailscaleLockEnabled($lock)
{
return $lock->Enabled;
}

function getTailscaleLockSigned($lock)
{
if ( ! getTailscaleLockEnabled($lock)) {
return false;
}

return $lock->NodeKeySigned;
}

function getTailscaleLockNodekey($lock)
{
if ( ! getTailscaleLockEnabled($lock)) {
return false;
}

return $lock->NodeKey;
}

function getTailscaleLockPubkey($lock)
{
if ( ! getTailscaleLockEnabled($lock)) {
return false;
}

return $lock->PublicKey;
}

function getTailscaleLockSigning($lock)
{
if ( ! getTailscaleLockSigned($lock)) {
return false;
}

$isTrusted = false;
$myKey = getTailscaleLockPubkey($lock);

foreach ($lock->TrustedKeys as $item) {
if ($item->Key == $myKey) {
$isTrusted = true;
}
}

return $isTrusted;
}

function getTailscaleLockPending($lock)
{
if ( ! getTailscaleLockSigning($lock)) {
return array();
}

$pending = array();

foreach ($lock->FilteredPeers as $item) {
$pending[$item->Name] = $item->NodeKey;
}

return $pending;
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,9 @@ function getTailscalePrefs()
exec("tailscale debug prefs", $out_prefs);
return json_decode(implode($out_prefs));
}

function getTailscaleLock()
{
exec("tailscale lock status -json=true", $out_status);
return json_decode(implode($out_status));
}
16 changes: 15 additions & 1 deletion src/usr/local/emhttp/plugins/tailscale/include/webgui-info.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ function printRow($title, $value)
return "<tr><td>{$title}</td><td>{$value}</td></tr>" . PHP_EOL;
}

function getStatusInfo($status, $prefs)
function getStatusInfo($status, $prefs, $lock)
{
$tsVersion = isset($status->Version) ? $status->Version : "Unknown";
$keyExpiration = isset($status->Self->KeyExpiry) ? $status->Self->KeyExpiry : "Disabled";
Expand All @@ -14,6 +14,7 @@ function getStatusInfo($status, $prefs)
$tags = isset($status->Self->Tags) ? implode("<br />", $status->Self->Tags) : "";
$loggedIn = isset($prefs->LoggedOut) ? ($prefs->LoggedOut ? "No" : "Yes") : "Unknown";
$tsHealth = isset($status->Health) ? implode("<br />", $status->Health) : "";
$lockEnabled = getTailscaleLockEnabled($lock) ? "Yes" : "No";

$output = "";
$output .= printRow("Tailscale Version", $tsVersion);
Expand All @@ -23,6 +24,19 @@ function getStatusInfo($status, $prefs)
$output .= printRow("Online", $online);
$output .= printRow("Key Expiration", $keyExpiration);
$output .= printRow("Tags", $tags);
$output .= printRow("Tailscale Lock: Enabled", $lockEnabled);

if (getTailscaleLockEnabled($lock)) {
$lockSigned = getTailscaleLockSigned($lock) ? "Yes" : "No";
$lockSigning = getTailscaleLockSigning($lock) ? "Yes" : "No";
$pubKey = getTailscaleLockPubkey($lock);
$nodeKey = getTailscaleLockNodekey($lock);

$output .= printRow("Tailscale Lock: Node Key Signed", $lockSigned);
$output .= printRow("Tailscale Lock: Is Signing Node", $lockSigning);
$output .= printRow("Tailscale Lock: Node Key", $nodeKey);
$output .= printRow("Tailscale Lock: Public Key", $pubKey);
}

return $output;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,24 @@
require_once "{$docroot}/plugins/tailscale/include/tailscale-status.php";
require_once "{$docroot}/plugins/tailscale/include/webgui-info.php";
require_once "{$docroot}/plugins/tailscale/include/webgui-key-expiration.php";
require_once "{$docroot}/plugins/tailscale/include/tailscale-lock.php";

$tailscale_output = array();

$tailscale_status = getTailscaleStatus();
$tailscale_prefs = getTailscalePrefs();
$tailscale_lock = getTailscaleLock();

$tailscale_output['key_expiry_warning'] = getKeyExpirationWarning($tailscale_status);
$tailscale_output['status_info'] = getStatusInfo($tailscale_status, $tailscale_prefs);
$tailscale_output['status_info'] = getStatusInfo($tailscale_status, $tailscale_prefs, $tailscale_lock);
$tailscale_output['connection_info'] = getConnectionInfo($tailscale_status, $tailscale_prefs);

$tailscale_output['attach_file_tree'] = ($var['fsState'] == 'Started') ? "$('#taildropdir').fileTreeAttach();" : "";
$tailscale_output['background_color'] = strstr('white,azure', $display['theme']) ? '#f2f2f2' : '#1c1c1c';

$tailscale_output['lock_enabled'] = getTailscaleLockEnabled($tailscale_lock);
$tailscale_output['lock_signed'] = getTailscaleLockSigned($tailscale_lock);
$tailscale_output['lock_signing'] = getTailscaleLockSigning($tailscale_lock);
$tailscale_output['lock_pending'] = getTailscaleLockPending($tailscale_lock);
$tailscale_output['lock_pubkey'] = getTailscaleLockPubkey($tailscale_lock);
$tailscale_output['lock_nodekey'] = getTailscaleLockNodekey($tailscale_lock);

0 comments on commit 35c2327

Please sign in to comment.