mirror of
https://github.com/netbirdio/netbird.git
synced 2026-07-19 04:59:56 +00:00
add mdm helper (windows) (can be deleted later)
This commit is contained in:
@@ -1,9 +1,11 @@
|
||||
# MDM dev cheatsheet (macOS)
|
||||
# MDM dev cheatsheet
|
||||
|
||||
Edits `/Library/Managed Preferences/io.netbird.client.plist`. Daemon picks up
|
||||
changes within ≤60s; no restart needed.
|
||||
Two platform helpers, same field set. The daemon's MDM ticker picks up changes
|
||||
within ≤60s and restarts the engine in-process — no service restart needed.
|
||||
|
||||
Run the interactive TUI:
|
||||
## macOS — `mdm-toggle.sh`
|
||||
|
||||
Edits `/Library/Managed Preferences/io.netbird.client.plist`.
|
||||
|
||||
```bash
|
||||
./mdm-toggle.sh tui
|
||||
@@ -12,6 +14,25 @@ Run the interactive TUI:
|
||||
Keys: number to edit a field, **k** to kick the daemon, **c** to clear the
|
||||
plist, **l** to view recent MDM log lines, **r** to refresh, **q** to quit.
|
||||
|
||||
## Windows — `mdm-toggle.ps1`
|
||||
|
||||
**▶ [Launch the TUI](mdm-tui.bat)** (double-click `mdm-tui.bat` — it self-elevates).
|
||||
|
||||
Edits `HKLM\Software\Policies\NetBird` (the key Group Policy / Intune ADMX /
|
||||
a Registry CSP profile would populate — see `client/mdm/policy_windows.go`).
|
||||
Self-elevates (HKLM writes need admin). Or run it directly:
|
||||
|
||||
```powershell
|
||||
.\mdm-toggle.ps1
|
||||
```
|
||||
|
||||
Same keys as the macOS TUI: number to edit a field, **k** to kick the daemon,
|
||||
**c** to clear the policy key, **r** to refresh, **q** to quit. Registry type
|
||||
mapping (mirrors `readRegistryValue`): `string → REG_SZ`, `integer → REG_DWORD`,
|
||||
`bool → REG_DWORD` (1=true / 0=false), `array → REG_MULTI_SZ`. Value names are
|
||||
case-insensitive (the loader canonicalises against the known key set);
|
||||
service: `Netbird`.
|
||||
|
||||
## Known keys
|
||||
|
||||
- Strings/ints: `managementURL`, `preSharedKey`, `wireguardPort`, `splitTunnelMode` (`allow`/`disallow`)
|
||||
|
||||
196
client/ui/scripts/mdm-toggle.ps1
Normal file
196
client/ui/scripts/mdm-toggle.ps1
Normal file
@@ -0,0 +1,196 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Interactive tester for NetBird's MDM policy on Windows.
|
||||
|
||||
.DESCRIPTION
|
||||
Edits HKLM\Software\Policies\NetBird (the same registry key the OS would
|
||||
populate from Group Policy / Intune ADMX ingestion / a Registry CSP profile,
|
||||
see client/mdm/policy_windows.go). The MDM ticker re-reads the key within
|
||||
<=60s; the daemon restarts the engine itself in-process - no service restart
|
||||
needed for a change to take effect (the [k] kick only forces an immediate
|
||||
re-read or recovers a wedged daemon).
|
||||
|
||||
Value-type mapping (mirrors readRegistryValue):
|
||||
string -> REG_SZ
|
||||
integer -> REG_DWORD
|
||||
bool -> REG_DWORD (1=true, 0=false) GetBool treats !=0 as true
|
||||
array -> REG_MULTI_SZ
|
||||
|
||||
Requires elevation (writing HKLM). Re-launches itself elevated if needed.
|
||||
|
||||
Keys: number to edit a field, [k] kick the daemon, [c] clear the whole
|
||||
policy key, [r] refresh, [q] quit.
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
param()
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
$PolicyPath = 'HKLM:\Software\Policies\NetBird'
|
||||
|
||||
# Known keys and their registry types. Order drives the TUI numbering.
|
||||
$Fields = @(
|
||||
@{ Key = 'managementURL'; Type = 'string' }
|
||||
@{ Key = 'preSharedKey'; Type = 'string' }
|
||||
@{ Key = 'wireguardPort'; Type = 'integer' }
|
||||
@{ Key = 'splitTunnelMode'; Type = 'string' } # allow / disallow
|
||||
@{ Key = 'splitTunnelApps'; Type = 'array' }
|
||||
@{ Key = 'rosenpassEnabled'; Type = 'bool' }
|
||||
@{ Key = 'rosenpassPermissive'; Type = 'bool' }
|
||||
@{ Key = 'disableClientRoutes'; Type = 'bool' }
|
||||
@{ Key = 'disableServerRoutes'; Type = 'bool' }
|
||||
@{ Key = 'allowServerSSH'; Type = 'bool' }
|
||||
@{ Key = 'disableAutoConnect'; Type = 'bool' }
|
||||
@{ Key = 'blockInbound'; Type = 'bool' }
|
||||
@{ Key = 'disableMetricsCollection'; Type = 'bool' }
|
||||
@{ Key = 'disableAdvancedView'; Type = 'bool' }
|
||||
@{ Key = 'disableProfiles'; Type = 'bool' }
|
||||
@{ Key = 'disableNetworks'; Type = 'bool' }
|
||||
@{ Key = 'disableUpdateSettings'; Type = 'bool' }
|
||||
)
|
||||
|
||||
# ---- elevation --------------------------------------------------------------
|
||||
|
||||
function Test-Admin {
|
||||
$id = [Security.Principal.WindowsIdentity]::GetCurrent()
|
||||
(New-Object Security.Principal.WindowsPrincipal $id).IsInRole(
|
||||
[Security.Principal.WindowsBuiltinRole]::Administrator)
|
||||
}
|
||||
|
||||
if (-not (Test-Admin)) {
|
||||
Write-Host 'Elevation required for HKLM writes - relaunching as admin...' -ForegroundColor Yellow
|
||||
Start-Process -FilePath 'powershell.exe' -Verb RunAs -ArgumentList @(
|
||||
'-NoProfile', '-ExecutionPolicy', 'Bypass', '-File', "`"$PSCommandPath`"")
|
||||
exit 0
|
||||
}
|
||||
|
||||
# ---- ANSI helpers (VT; conhost on Win10+ and Windows Terminal support it) ----
|
||||
|
||||
$IsTty = -not [Console]::IsOutputRedirected
|
||||
$e = [char]27
|
||||
function C($code) { if ($IsTty) { "${e}[${code}m" } else { '' } }
|
||||
$Reset = C '0'; $Bold = C '1'; $Dim = C '2'
|
||||
$Green = C '32'; $Red = C '31'; $Yellow = C '33'; $Cyan = C '36'
|
||||
|
||||
# ---- service ----------------------------------------------------------------
|
||||
|
||||
function Restart-Daemon {
|
||||
$svc = Get-Service -Name 'Netbird', 'netbird' -ErrorAction SilentlyContinue | Select-Object -First 1
|
||||
if (-not $svc) { Write-Host 'Netbird service not found.' -ForegroundColor Red; return }
|
||||
Write-Host "restarting service ($($svc.Name))..."
|
||||
Restart-Service -Name $svc.Name -Force
|
||||
}
|
||||
|
||||
# ---- registry read/write ----------------------------------------------------
|
||||
|
||||
function Ensure-PolicyKey {
|
||||
if (-not (Test-Path $PolicyPath)) { New-Item -Path $PolicyPath -Force | Out-Null }
|
||||
}
|
||||
|
||||
function Read-Value {
|
||||
param([string]$Key)
|
||||
if (-not (Test-Path $PolicyPath)) { return $null }
|
||||
$item = Get-ItemProperty -Path $PolicyPath -Name $Key -ErrorAction SilentlyContinue
|
||||
if ($null -eq $item) { return $null }
|
||||
return $item.$Key
|
||||
}
|
||||
|
||||
function Set-Value {
|
||||
param([string]$Key, [string]$Type, $Value)
|
||||
Ensure-PolicyKey
|
||||
switch ($Type) {
|
||||
'array' { Set-ItemProperty -Path $PolicyPath -Name $Key -Value ([string[]]$Value) -Type MultiString }
|
||||
'integer' { Set-ItemProperty -Path $PolicyPath -Name $Key -Value ([int]$Value) -Type DWord }
|
||||
'bool' { Set-ItemProperty -Path $PolicyPath -Name $Key -Value ([int]$Value) -Type DWord }
|
||||
default { Set-ItemProperty -Path $PolicyPath -Name $Key -Value ([string]$Value) -Type String }
|
||||
}
|
||||
}
|
||||
|
||||
function Clear-Value {
|
||||
param([string]$Key)
|
||||
if (Test-Path $PolicyPath) {
|
||||
Remove-ItemProperty -Path $PolicyPath -Name $Key -ErrorAction SilentlyContinue
|
||||
}
|
||||
}
|
||||
|
||||
function Clear-PolicyKey {
|
||||
if (Test-Path $PolicyPath) {
|
||||
Remove-Item -Path $PolicyPath -Recurse -Force
|
||||
Write-Host "removed $PolicyPath"
|
||||
} else {
|
||||
Write-Host '(already absent)'
|
||||
}
|
||||
}
|
||||
|
||||
# ---- TUI --------------------------------------------------------------------
|
||||
|
||||
function Render-Value {
|
||||
param($Raw, [string]$Type)
|
||||
if ($null -eq $Raw -or ($Raw -is [string] -and $Raw -eq '')) {
|
||||
return "$Dim-$Reset"
|
||||
}
|
||||
switch ($Type) {
|
||||
'bool' {
|
||||
if ([int]$Raw -ne 0) { "${Green}[+] true$Reset" } else { "${Red}[-] false$Reset" }
|
||||
}
|
||||
'array' { "${Cyan}[$($Raw -join ' ')]$Reset" }
|
||||
default { "$Yellow$Raw$Reset" }
|
||||
}
|
||||
}
|
||||
|
||||
function Render-Screen {
|
||||
Clear-Host
|
||||
Write-Host "$Bold==== NetBird MDM Tester (Windows) ====$Reset"
|
||||
Write-Host "${Dim}key:$Reset $PolicyPath`n"
|
||||
for ($i = 0; $i -lt $Fields.Count; $i++) {
|
||||
$f = $Fields[$i]
|
||||
$raw = Read-Value $f.Key
|
||||
$num = ('[{0,2}]' -f ($i + 1))
|
||||
$val = Render-Value $raw $f.Type
|
||||
Write-Host (" $Bold$num$Reset {0,-30} {1} $Dim({2})$Reset" -f $f.Key, $val, $f.Type)
|
||||
}
|
||||
Write-Host ''
|
||||
Write-Host " ${Bold}[k]$Reset kick daemon ${Bold}[c]$Reset clear key ${Bold}[r]$Reset refresh ${Bold}[q]$Reset quit"
|
||||
Write-Host ''
|
||||
}
|
||||
|
||||
function Edit-Field {
|
||||
param([int]$Index)
|
||||
if ($Index -lt 1 -or $Index -gt $Fields.Count) { Write-Host ' (out of range)'; Start-Sleep -Milliseconds 600; return }
|
||||
$f = $Fields[$Index - 1]
|
||||
$cur = Read-Value $f.Key
|
||||
switch ($f.Type) {
|
||||
'bool' {
|
||||
# Cycle: unset -> true -> false -> unset
|
||||
if ($null -eq $cur) { Set-Value $f.Key 'bool' 1 }
|
||||
elseif ([int]$cur -ne 0) { Set-Value $f.Key 'bool' 0 }
|
||||
else { Clear-Value $f.Key }
|
||||
}
|
||||
'array' {
|
||||
Write-Host " current: $($cur -join ' ')"
|
||||
$line = Read-Host ' new array (space-separated, empty to unset)'
|
||||
if ([string]::IsNullOrWhiteSpace($line)) { Clear-Value $f.Key }
|
||||
else { Set-Value $f.Key 'array' ($line -split '\s+' | Where-Object { $_ }) }
|
||||
}
|
||||
default {
|
||||
Write-Host " current: $cur"
|
||||
$line = Read-Host " new $($f.Type) (empty to unset)"
|
||||
if ([string]::IsNullOrWhiteSpace($line)) { Clear-Value $f.Key }
|
||||
else { Set-Value $f.Key $f.Type $line }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host 'starting MDM tester (q to quit)'
|
||||
while ($true) {
|
||||
Render-Screen
|
||||
$choice = Read-Host '>'
|
||||
switch -Regex ($choice) {
|
||||
'^(q|quit|exit)$' { Write-Host 'bye'; return }
|
||||
'^(k|kick)$' { Restart-Daemon; Start-Sleep -Milliseconds 600 }
|
||||
'^(c|clear)$' { Clear-PolicyKey; Start-Sleep -Milliseconds 600 }
|
||||
'^(r|)$' { } # redraw
|
||||
'^\d+$' { Edit-Field ([int]$choice) }
|
||||
default { Write-Host ' (unknown - number to edit, k/c/r/q)'; Start-Sleep -Milliseconds 600 }
|
||||
}
|
||||
}
|
||||
4
client/ui/scripts/mdm-tui.bat
Normal file
4
client/ui/scripts/mdm-tui.bat
Normal file
@@ -0,0 +1,4 @@
|
||||
@echo off
|
||||
REM Double-click launcher for the NetBird MDM tester (Windows).
|
||||
REM The .ps1 self-elevates.
|
||||
powershell -NoProfile -ExecutionPolicy Bypass -File "%~dp0mdm-toggle.ps1"
|
||||
Reference in New Issue
Block a user