It seems there’s still some bugs to be worked out by the Azure guys with this point-to-site Azure VPN feature.
I have been wanting a secure way to access my Azure virtual machines for some time and I only just noticed they added this feature (still in Preview) a few months back. So I went about setting it up.
I had seemingly followed all the official guides. Got past all the the hurdles for the certificate creation stuff using the makecert tool (why doesn’t Azure offer to do all this for you? It’s not like everybody that uses Azure has a Visual Studio command shell installed on their PC!)
I then downloaded the 64-bit VPN Package for my Virtual Network. Installed it. Tried to connect and it was throwing this bizarre error:
A certificate chain processed, but terminated in a root certificate which is not trusted by the trust provider.
After some playing around it turned out that the VPN Package installer has a serious bug in it whereby it simply doesn’t install the Azure Gateway’s certificate into your certificate store. Luckily I had a copy of WinRAR on my machine and so I extracted the installer to take a peek inside and sure enough it contains a .cer certificate file. So I did WinKey+R, mmc, and added a Certificates snap-in for the Local Machine (not Current User!). Then navigated to the Trusted Root Certificates Authorities, right-click and choose the Import task. Find the .cer file you extracted from the VPN Package installer and install it.
Now retry the Azure VPN Connection and the error should go away and you’ll log straight in!
These steps are known good on my Windows 8 machine, with Visual Studio 2012 w/ Update 1 and Mono 2.10.9.
- Install Mono for Windows, from http://www.go-mono.com/mono-downloads/download.html
Choose a decent path, which for me was
C:\Program Files (x86)\Mono-2.10.9
- Load an elevated administrative Command Prompt (Top tip: On Windows 8, hit WinKey+X then choose “Command Prompt (Admin)“)
- From this Command Prompt, execute the following commands (in order):
$ cd "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\Profile"
$ mklink /d Mono "C:\Program Files (x86)\Mono-2.10.9\lib\mono\4.0"
$ cd Mono
$ mkdir RedistList
$ cd RedistList
$ notepad FrameworkList.xml
- Notepad will start and ask about creating a new file, choose Yes.
- Now paste in this text and Save the file:
<?xml version="1.0" encoding="UTF-8"?>
<FileList ToolsVersion="4.0" RuntimeVersion="4.0" Name="Mono 2.10.9 Profile" Redist="Mono_2.10.9">
- From the same Command Prompt, type:
- In the Registry Editor, navigate to:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319\SKUs\and create a new Key folder called
- Now navigate to
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.30319\SKUs\and create the same Key folder again here (this step is only necessary for x64 machines, but since all software developers use those then you’ll probably need to do it!)
- Now load up VS2012 and a project. Goto the Project Properties (Alt+Enter whilst having it selected on Solution Explorer) .
- Choose the Application tab on the left and look for the “Target framework” drop-down list.
- On this list you should see an entry called “Mono 2.10.9 Profile”.
- Select it, and Visual Studio should then convert your project to target the Mono framework. You’ll notice that it will re-reference all your various System assemblies and if you study the filenames they will point to the Mono ones that were created during Step #3.
Note: I was scratching my head at first as I kept getting an error from Visual Studio saying:
This application requires one of the following versions of the .NET Framework:
Do you want to install this .NET Framework version now?
Turns out that even on a x64 machine you MUST add both Registry key SKUs (see Steps #7 and #8). It is not enough to just add the Wow6432Node key, you must add the other as well. I can only assume this is because VS2012 is a 32-bit application. But maybe it’s also affected by whether you’re compiling to Any CPU, x64 or x86… who knows. It doesn’t really matter as long as this fixes it, which it does!
Building and executing your first program
Now that your development environment is nicely setup, you can proceed and build your first program.
The Mono equivalent of MSBuild is called XBuild (not sure why they didn’t call it MBuild or something!). You can build your .csproj by doing the following:
- Load the Mono Command Prompt (it will be on your Start Menu/Screen, just search for “mono”).
- Change directory to your project folder.
- Execute the following command to build your project using the Mono compiler:
$ xbuild /p:TargetFrameworkProfile=""
Note: You must specify the blank
TargetFrameworkProfileparameter as otherwise the compiler will issue warnings along the lines of:
Unable to find framework corresponding to the target framework moniker ‘.NETFramework,Version=v4.0,Profile=Mono’. Framework assembly references will be resolved from the GAC, which might not be the intended behavior.
- Hopefully you’ll not have any errors from the build…
- Now you can run your program using the Mono runtime, to do this:
$ mono --gc=sgen "bin\Debug\helloworld.exe"
Note: You'll definitely want to use the "Sgen" garbage collector (hence the parameter) as the default one in Mono is unbearably slow.
- You can do a quick “smoke test” to verify everything is in order with both your compilation and execution. Have your program execute something like:
… and this should print out a path similar to:
I’ve no idea why it prints it out using 8.3 filename format, but there you go! You’ll notice that if you run your program outside of the Mono runtime then it will pick up the Microsoft CLR version from the GAC.
This is a slight continuation of the previous WebSockets versus REST… fight! post.
Buoyed with enthusiasm of WebSockets, I set about implementing a simple test harness of a WebSockets server in C#.NET using
System.Net.HttpListener. Unfortunately, things did not go well. It turns out that
HttpListener (and indeed, the underlying HTTP Server API a.k.a.
http.sys) cannot be used at all to develop a WebSockets server on current versions of Windows. The
http.sys is simply too strict with its policing of what it believes to be correct HTTP protocol.
In an IETF discussion thread, a Microsoft fellow called Stefen Shackow was quoted as saying the following:
The current technical issue for our stack is that the low-level Windows HTTP driver that handles incoming HTTP request (http.sys) does not recognize the current websockets format as having a valid entity body. As you have noted, the lack of a content length header means that http.sys does not make the nonce bytes in the entity available to any upstack callers. That’s part of the work we will need to do to build websockets support into http.sys. Basically we need to tweak http.sys to recognize what is really a non-HTTP request, as an HTTP request.
Implementation-wise this boils down to how strictly a server-side HTTP listener interprets incoming requests as HTTP. For example a server stack that instead treats port 80 as a TCP/IP socket as opposed to an HTTP endpoint can readily do whatever it wants with the websockets initiation request.
For our server-side HTTP stack we do plan to make the necessary changes to support websockets since we want IIS and ASP.NET to handle websockets workloads in the future. We have folks keeping an eye on the websockets spec as it progresses and we do plan to make whatever changes are necessary in the future.
This is a damn shame. As it stands right now, Server 2008/R2 boxes cannot host WebSockets. At least, not whilst sharing ports 80 and 443 with IIS web server. Because, sure, you could always write your WebSocket server to bind to those ports with a raw TCP socket and rewrite a ton of boilerplate HTTP code that
http.sys can already do, and then put up with the fact that you can’t share the port with IIS on the same box. This is something that most people, me included, do not want to do.
Obviously it isn’t really anyone’s fault because back in the development time frame of Windows 7 and Server 2008/R2 (between 2006 to 2009) they could not have foreseen the WebSockets standard and the impact it might have on the design of APIs for HTTP servers.
The good thing is that Windows 8 Developer Preview seems to have this covered. According to the MSDN documentation, the HTTP Server API’s
HttpSendHttpResponse function supports a new special flag called
HTTP_SEND_RESPONSE_FLAG_OPAQUE that seems to suggest it will put the HTTP session into a sort of “dumb mode” whereby you can pass-thru pretty much whatever you want and
http.sys won’t interfere:
Specifies that the request/response is not HTTP compliant and all subsequent bytes should be treated as entity-body. Applications specify this flag when it is accepting a Web Socket upgrade request and informing HTTP.sys to treat the connection data as opaque data.
This flag is only allowed when the
101, switching protocols.
ERROR_INVALID_PARAMETERfor all other HTTP response types if this flag is used.
Windows Developer Preview and later: This flag is supported.
Aside from the new
System.Net.WebSockets namespace in .NET 4.5, there are also clear indications of this behaviour being exposed in the
HttpListener of .NET 4.5 through a new
HttpListenerContext.AcceptWebSocketAsync() method. The preliminary documentation seems to suggest that this method will support 2008 R2 and Windows 7. But this is almost certainly a misprint because I have inspected these areas of the .NET 4.5 libraries using Reflector and it is very clear that this is not the case:
HttpListenerContext.AcceptWebSocketAsync() method directly calls into
System.Net.WebSockets.WebSocketHelper (static class) which has a corresponding
AcceptWebSocketAsync() method of its own. This method will then call a sanity check method tellingly named
EnsureHttpSysSupportsWebSockets() which evaluates an expression containing the words “
ComNetOS.IsWin8orLater“. I need say no more.
It seems clear now that Microsoft has chosen not to back port this minor HTTP Server API improvement to Server 2008 R2 / Windows 7. So now we must all hope that Windows Server 8 runs a beta program in tandem with the Windows 8 client, and launches within a month of each other. Otherwise Metro app development possibilities are going to be severely limited whilst we all wait for the Windows Server product to host our WebSocket server applications! Even still, it’s a shame that Server 2008 R2 won’t ever be able to host WebSockets.
It will be interesting if Willie Tarreau (of HA-Proxy fame) will come up with some enhancements in his project that might benefit those determined enough to still want to host (albeit, raw TCP-based) WebSockets on Server 2008 R2.
Last night we performed a big switch over in our data centre. We moved everything onto a new managed switch and Sonicwall firewall, re-pointed and re-addressed lots and lots of servers, and well basically just done a bunch of stuff we should have done yonks ago! Everything seemed to go really well except for one thing: our Hyper-V hosts were now throwing really annoying and random disconnection errors when connected straight into a VM using its “Connect…” menu item, or otherwise known as
VMConnect.exe. The connection would work for at least a couple seconds, sometimes for as long as a minute or two. But then it would barf up and the following error message dialog would be displayed.
The full description of the error was as follows:
The connection to the virtual machine was lost. This can occur when a virtual machine stops unexpectedly, or when network problems occur. Try to connect again. If the problem persists, contact your system administator.
Would you like to try to reconnnect?
This was really annoying because we were connecting to local VMs that were present on the exact same VM host from which we were connecting. So presumably there wouldn’t be any packets hitting the network, and thus ruling out any of the new hardware and network changes we had just made.
After racking my brains on it for a bit (which included firing up Wireshark to perform a sanity check), I loaded up TCPView. This is a really great little tool from Mark Russinovich‘s stable called Windows Sysinternals. With this tool running I then retried the VMConnect, so that I could see what socket activities it was performing.
What this showed is that even when connecting to the local VM host using “
localhost” or “
127.0.0.1” as the address (i.e. IPv4) the VMConnect tool was seemingly transforming this into a IPV6 address and then forming a TCPV6 connection. This was interesting.
I immediately went to check whether IPV6 was actually enabled on the VM host’s network adapters. Low and behold, it was not. Turns out that when we flicked over the Gateway IP to point to the new firewall, we also subconciously turned off the IPV6 protocol on the list! A fairly innocuous thing to do, one would think, especially on an internal LAN!
So there you have it. If you come across this problem with Hyper-V, I would recommend you immediately check to ensure that you have not inadvertently disabled the IPV6 protocol on your virtual network adapter for Hyper-V.
The very moment we re-enabled IPV6, the problem with VMConnect constantly disconnecting every few seconds totally went away!
Not many problems get more obscure than this.
Recently I deployed a CentOS 5.5 x64 guest on a Server 2008 R2 Hyper-V host for running a basic mail server. However I quickly noticed that the guest was losing time sync very rapidly, in the order of several positive minutes per hour. This was a surprise as I had already installed the Hyper-V Linux Integration components from Microsoft which I had assumed would just take care of everything for me. Not so, apparently.
I might also add that Dovecot (an IMAP/POP3 server) kept crashing due to the periodic NTP sync being so far out that it resulted in the guest’s clock actually going BACK in time! This appears to be an acknowledged bug in Dovecot but it is understandable why they don’t feel a pressing need to fix it. Though I understand the 2.0 release has. For the record, I was running the 188.8.131.52.el5 release.
Anyway, it turned out that the solution was very simple.
Modify the /boot/grub/grub.conf as follows:
Essentially you need to modify the lines that start with the word “kernel” and add two extra options onto the end:
This sets the clock source to use the Programmable Interrupt Timer (PIT). This is a fairly low level way for the kernel to track time and it works best with Hyper-V and Linux.
This is included more as belt-and-braces than anything. Because setting the PIT clock source (above) should already imply this setting really. But I include it for pure expressiveness 🙂
This adjusts the PIT frequency resolution to be accurate to 10 milliseconds (which is perfectly sufficient for most applications). This isn’t strictly required but it will reduce some CPU load caused by the VM. If the VM will be running time sensitive calculations a lot (such as say a VoIP server or gaming server) then you probably shouldn’t include this option.
Once you’ve done this, save the file and reboot the box.
The time should now be synchronized precisely with the Hyper-V host!
PS: I’ve not tested whether this solution will work without the Hyper-V Linux Integration Components installed, but I believe that it will. As it operates independently of Hyper-V’s clock synchronisation mechanism and relies purely on the virtualised Programmable Interrupt Timer that is exposed by Hyper-V. And the PIT clock source will remain unchanged whether you have the Linux Integration Components installed or not.
PPS: The VMware knowledge base has a great article on this subject: http://kb.vmware.com/kb/1006427. Although take it with a slight pinch of salt (because the subject is Hyper-V) but it certainly gives several more options and ideas to try for different Linux distributions and 32-bit vs 64-bit etc environments.