Development discussion of WireGuard
 help / color / mirror / Atom feed
From: Max Schulze <max.schulze@online.de>
To: wireguard@lists.zx2c4.com
Subject: Re: [PATCH v2] wireguard-tools: contrib/reresolve-dns script for Windows Powershell
Date: Tue, 23 Nov 2021 11:14:28 +0100	[thread overview]
Message-ID: <a0506608-2797-7bc2-8786-97678d01832a@online.de> (raw)
In-Reply-To: <68de8cb8-81ce-1f51-22fd-9ef20b24f693@online.de>

v2: Resend as-is, patch got garbled by thunderbird -.-

This is a script I use on windows for dynamic DNS endpoints ("servers").

The big upside is that it supports multiple configurations and does not need hard-coded endpoints or "ping-endpoints".

I would like to apply to get it included into wireguard-tools.

I have tested this in win7 and win10. You might add it to the task scheduler and run this every 3 minutes or so.

Some care has to be taken as to know which user is running the script. The encrypted dpapi-binary file can only be read by the same user that created/saved the tunnels, i.e. \system.

To make it easy to maintain this patch, I have tried to stick it as close to the linux version as possible. Jason, feel free to modify the copyright header as appropriate.

I am in no way the powershell guru, this is more trial-and-error.


NB: Why the limit to 15 chars in the Interface name? Mine had more, thus setting the arbitrary (?) limit to 18 chars.


Signed-off-by: Max Schulze <max.schulze@online.de>
---
 contrib/reresolve-dns/reresolve-dns.ps1 | 57 +++++++++++++++++++++++++
 1 file changed, 57 insertions(+)
 create mode 100644 contrib/reresolve-dns/reresolve-dns.ps1

diff --git a/contrib/reresolve-dns/reresolve-dns.ps1 b/contrib/reresolve-dns/reresolve-dns.ps1
new file mode 100644
index 0000000..951eb33
--- /dev/null
+++ b/contrib/reresolve-dns/reresolve-dns.ps1
@@ -0,0 +1,57 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Copyright (C) 2021 Max Schulze. All Rights Reserved.
+# near-literal Translation of the linux version by Jason A. Donenfeld
+
+# to decrypt the dpapi Credentials, you have to be the same user as the wireguard tunnel service, i.e. "nt authority\system", check with "whoami"
+# this script might be called by task scheduler as 
+#  powershell -NoProfile -NoLogo -NonInteractive -ExecutionPolicy Bypass -Command "Get-ChildItem -File 'c:\program Files\wireguard\data\configurations\*.dpapi'  | foreach {& C:\<path to script>\wireguard_reresolve-dns.ps1 $_.FullName}"
+# if you want to try it in cmd, remember to elevate the user, i.e. with psexec from sysutils
+#  psexec -s -i powershell -NoPr...
+
+Set-StrictMode -Version 3
+Add-Type -AssemblyName System.Security
+
+Set-Variable CONFIG_FILE -Value $args[0].ToString().Trim('"')
+
+$byteCrypted = ((Get-Content -LiteralPath $CONFIG_FILE -Encoding Byte -ReadCount 0))
+
+$config = [System.Security.Cryptography.ProtectedData]::Unprotect($byteCrypted,$null,[System.Security.Cryptography.DataProtectionScope]::LocalMachine)
+
+$config = [System.Text.UTF8Encoding]::UTF8.GetString($config)
+
+Set-Variable Interface -Option Constant -Value $(if ($CONFIG_FILE -match '.?([a-zA-Z0-9_=+.-]{1,18})\.conf.dpapi$') { $matches[1] } else { $null })
+
+function process_peer () {
+  if (-not $PEER_SECTION -or ($PUBLIC_KEY -eq $null) -or ($ENDPOINT -eq $null)) { return }
+  if (-not ((& wg show "$INTERFACE" latest-handshakes) -replace $PUBLIC_KEY -match ('[0-9]+'))) { return }
+  if (((Get-Date) - (New-Object -Type DateTime -ArgumentList 1970,1,1,0,0,0,0).AddSeconds($matches[0]).ToLocalTime()).TotalSeconds -le 135) { return }
+  (& wg set "$INTERFACE" peer "$PUBLIC_KEY" endpoint "$ENDPOINT")
+  reset_peer_section
+}
+
+function reset_peer_section () {
+  Set-Variable PEER_SECTION -Value $null
+  Set-Variable PUBLIC_KEY -Value $null
+  Set-Variable ENDPOINT -Value $null
+}
+
+reset_peer_section
+Set-Variable PEER_SECTION -Value $null
+
+foreach ($line in $config.Split([Environment]::NewLine,[StringSplitOptions]::RemoveEmptyEntries)) {
+  if ($line.Trim().length -gt 0) {
+    $stripped = $line.Trim() -ireplace '\#.*'
+    $key = $stripped -ireplace '=.*'; $key = $key.Trim()
+    $val = $stripped -ireplace '^.*?='; $val = $val.Trim()
+    if ($key -match '\[.*') { process_peer; reset_peer_section; }
+    if ($key -eq '[Peer]') { $PEER_SECTION = $true }
+    if ($PEER_SECTION) {
+      switch ($key) {
+        "PublicKey" { $PUBLIC_KEY = $val; continue; }
+        "Endpoint" { $ENDPOINT = $val; continue; }
+      }
+    }
+  }
+}
+process_peer
-- 
2.33.1


  reply	other threads:[~2021-11-23 10:14 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-11-23  9:59 [PATCH] " Max Schulze
2021-11-23 10:14 ` Max Schulze [this message]
2021-11-23 13:27   ` [PATCH v2] " Christoph Loesch

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=a0506608-2797-7bc2-8786-97678d01832a@online.de \
    --to=max.schulze@online.de \
    --cc=wireguard@lists.zx2c4.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).