Minimal WinTUN Program Access Denied Opening Tun
Christopher O'Connell
jwriteclub at gmail.com
Tue May 21 17:17:34 CEST 2019
Hello,
I've been very intrigued by WinTUN, and the option of a small, simple TUN
driver, especially one with good golang bindings offers a lot of
opportunity to build interesting things on Windows.
I've been building a minimal program based on the go libraries, my goal
being to just write a simple ICMP endpoint to be able to ping, as a way to
learn the WinTUN code and libraries. Unfortunately, I've run into an issue
that I'm unable to actually read from the tun device, my code always
getting errors like open \\.\Global\WINTUN32768: Access is denied.
In a nutshell, my code does the following (error checking and some other
ancillary code is omitted, please see this gist
<https://gist.github.com/jwriteclub/4f0fa081cb4eb39620702d7f7e212afd> for
the complete code):
func main() {
// These two functions are taken from wireguard windows, added just to
make sure that
// this code is running from the same privilege level as the WireGuard
windows code
checkForAdminGroup()
checkForWow64()
// Create a tun. This works, with the small patch to tun_windows.go
which I submitted earlier
t, err := tun.CreateTun("My Test Tun")
nt := t.(*tun.NativeTun)
// Get the interface and set IPs, etc
iface, err := winipccfg.InterfaceFromLUID(nt.LUID())
iface.SetAddresses("172.16.16.1/24")// Omitting all the mangly code to
create an IPNet
// Listen for Reads
wg := &sync.WaitGroup{}
wg.Add(1)
go func() {
defer wg.Done()
for {
bt := make([]byte, 15000) // Lots of packets
read, err := nt.Read(bt, 0) // Offset of 0 for now, just trying
to read
if err != nil {
fmt.Printf("%#v\n", err)
return
}
fmt.Printf("Read %d bytes\n", read)
}
}()
wg.Wait()
}
I've tried this using two different versions of the WinTUN driver, one
where I just created a simple installer using the v0.1 MSM file on
WinTun.net, and the other by installing WireGuard v0.0.8 from the main
website. In both cases, CreateTun and interface calls work, and I'm able to
see the network adapter added to Windows. However, in both cases, the call
to Read fails. Ultimately, after drilling down, the failing call is in
tun_windows.go in func (tun *NativeTun) openTUN, and the offending
line is tun.tunFileRead,
err = os.OpenFile(name, os.O_RDONLY, 0).
To test out my code, and see if I am missing some key component, I compiled
and ran golang.zx2c4.com/wireguard/main_windows.go, which exhibits the
exact same behavior as my program, ending with an error like ERROR:
(MyTunTest) 2019/05/21 18:14:17 Failed to read packet from TUN device: open
\\.\Global\WINTUN32769: Access is denied.
At this point I was convinced that it might be some factor about my system
which was preventing this from working, but much to my surprise when I
downloaded and ran the current v0.0.8 release version of the WireGuard
client, it worked just fine, and I was able to connect to and route traffic
through a WireGuard server.
I then considered that there was something special about opening the tun
device from a service specifically, as opposed to an elevated user space
process (although I cannot figure out a reason why this should be so). I
whipped up a very quick windows service in C# to only tries to open the
already created WinTUN device (literally, just var tunRead =
File.Open(TUN_NAME, FileMode.Open, FileAccess.Read);, plus all the usual
service boiler plate). I installed this service with the LocalSystem
permission and when starting, it similarly gets an access denied error.
Clearly, the WireGuard windows client is executing some command which puts
the tun into an ready to open state or changes the privileges in some key
way, but I have been unable to find this key command or function. Any help
on a minimum viable program to successfully call Read on a WinTUN object is
most appreciated.
All the best,
~ Christopher
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.zx2c4.com/pipermail/wireguard/attachments/20190521/5d933b4d/attachment-0001.html>
More information about the WireGuard
mailing list