Minimal WinTUN Program Access Denied Opening Tun
Christopher O'Connell
jwriteclub at gmail.com
Tue May 21 17:59:24 CEST 2019
So I must have messed up my service installer and wasn't really running as
the LocalSystem, because with some tweaking it does open now. I further
confirmed this using the PSExec64 utility and calling the basic code to run
as the system user and it runs correctly.
So it seems that the WinTUN device does restrict itself to being opened as
the system user. It might be good to add such a note to the documentation
for WinTUN (I'm happy to make an edit and push a patch if others would like
that).
I'm also interested in the rationale for requiring the system user to open
the device?
All the best,
~ Christopher
On Tue, May 21, 2019 at 6:17 PM Christopher O'Connell <jwriteclub at gmail.com>
wrote:
> 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/5bb15bb7/attachment.html>
More information about the WireGuard
mailing list