Skip to main content

Secure tunnel using Hybrid Connections

I observed an interesting trend in a few last years. Even if more and more companies migrate to cloud providers like Azure or migrate to IoT era, a common requirement that still popups for all clients is the need of a secure tunnel - Remote Screen Sharing, FTP, Remote Access and so on.

In the end the requirement is simple but very hard to fulfill. The need of a secure tunnel (like a VPN) between their devices or systems to their backends. When you combine this with scalability and integration with different system it can become an expensive and complicated nightmare.
If you look in my past post, you’ll see that I played with different solutions like Service Bus Relay and OpenSSL.

Hybrid Connections
But now, it seems that Microsoft made a surprise for us – Hybrid Connections. This is a new feature of Azure Service Bus Relays that allows us to create a point-to-point connection in a secure and reliable way.
Before jumping to code, let’s see why I am so excited about it. From the latency point of view, the latency is extremely low. I establish a RDP connection to a computer that is in Europe from USA and I was impress that there was no difference between Team Viewer and Hybrid Connection. This bidirectional communication can pass firewall as long as both clients have an open port to make requests – ports like 443 or 80 can be used with success.

Old Port Bridge
If you remember there was an implementation of Port Bridge done some years ago by @Clements Vasters on top of Service Bus Relay. Using that implementation, we would be able to establish a secure tunnel between two endpoints.
The downside of that solution, from the implementation point of view, was related to dependencies and some magic inside the source code. Some WCF stuff were needed to be able to support this kind of scenarios. Migrating the solution to Linux was not impossible, but very expensive.

The NEW Port Bridge – no WCF dependency 
Now, the new solution that is implemented over Hybrid Connections doesn’t has anymore this dependency. This means that we can run with success not only on Windows systems, but also from Linux and why not, it might be possible from .NET Core also.
Why I’m so excited that there is no WCF dependency? It means that we can write a C++ or Java Script application for this, enabling me to create secure tunnels on dummy devices that runs custom Linux distributions.

Another cool stuff is that the new implementation supports a list of ports that can be specified to be mapped to port bridge. It means that we can tunnel applications that requests multiple ports, not only one. With some twicks, I think that even apps with dynamic ports might be able to work, but it might require some work.
The full sample and how you can use it can be found of GitHub: https://github.com/Azure/azure-relay-dotnet/tree/master/samples/portbridge

Playing with Hybrid Connections
Hybrid connections allows us to do pretty cools stuff. On top of having a secure tunnel, we can send any stream of data from one location to another. With just a few lines of codes, we can stream data from one machine to another.

A simple and name sample of the client app can be found on GihHub (https://github.com/Azure/azure-relay-dotnet/blob/master/samples/simple/Client/Program.cs). As we can see, we just need to open a Hybrid Connection and read or write content. Using HybridConnectionClient we can open a stream to read content and another one to write. So simple to establish a stream communication between two endpoints from internet.
On the server side, the code is very similar. The difference is that on the server we need to listen and accept a connection over Hybrid Connection. An important step here is to not forget to Close the relay connection once you finish what you have to do.

JavaScript and Hybrid Connection
The super-duper thing, that we will talk more in the next post is the native support for Web Sockets. This means that we can write code, without the need of a custom library that discuss directly with a Hybrid Connection.
Just a copy-paste sample code from Clements GitHub:
      var host = window.document.location.host.replace(/:.*/, '');
      var ws = new WebSocket('wss://cvrelaywus.servicebus.windows.net:443/$hc/public?sb-hc-action=connect');// &sb-hc-token={{token}}');
      ws.onmessage = function (event) {
        updateStats(JSON.parse(event.data));

Conclusion
Things looks a lot better for situations when you need to establish a tunnel between two endpoints. Even if the use cases that are covered are edge cases, the extra value is enormous.

Comments

Popular posts from this blog

How to check in AngularJS if a service was register or not

There are cases when you need to check in a service or a controller was register in AngularJS.
For example a valid use case is when you have the same implementation running on multiple application. In this case, you may want to intercept the HTTP provider and add a custom step there. This step don’t needs to run on all the application, only in the one where the service exist and register.
A solution for this case would be to have a flag in the configuration that specify this. In the core you would have an IF that would check the value of this flag.
Another solution is to check if a specific service was register in AngularJS or not. If the service was register that you would execute your own logic.
To check if a service was register or not in AngularJS container you need to call the ‘has’ method of ‘inhector’. It will return TRUE if the service was register.
if ($injector.has('httpInterceptorService')) { $httpProvider.interceptors.push('httpInterceptorService&#…

ADO.NET provider with invariant name 'System.Data.SqlClient' could not be loaded

Today blog post will be started with the following error when running DB tests on the CI machine:
threw exception: System.InvalidOperationException: The Entity Framework provider type 'System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer' registered in the application config file for the ADO.NET provider with invariant name 'System.Data.SqlClient' could not be loaded. Make sure that the assembly-qualified name is used and that the assembly is available to the running application. See http://go.microsoft.com/fwlink/?LinkId=260882 for more information. at System.Data.Entity.Infrastructure.DependencyResolution.ProviderServicesFactory.GetInstance(String providerTypeName, String providerInvariantName) This error happened only on the Continuous Integration machine. On the devs machines, everything has fine. The classic problem – on my machine it’s working. The CI has the following configuration:

TeamCity.NET 4.51EF 6.0.2VS2013
It seems that there …

[Post-Event] Codecamp Conference Cluj-Napoca - Nov 19, 2016

Last day I was invited to another Codecamp Conference, that took place in Cluj-Napoca. Like other Codecamp Conferences, the event was very big, with more than 1.000 participants and 70 sessions. There were 10 tracks in parallel, so it was pretty hard to decide at  what session you want to join.
It was great to join this conference and I hope that you discovered something new during the conference.
At this event I talked about Azure IoT Hub and how we can use it to connect devices from the field. I had a lot of demos using Raspberry PI 3 and Simplelink SensorTag. Most of the samples were written in C++ and Node.JS and people were impressed that even if we are using Microsoft technologies, we are not limited to C# and .NET. World and Microsoft are changing so fast. Just looking and Azure IoT Hub and new features that were launched and I'm pressed (Jobs, Methods, Device Twin).
On backend my demos covered Stream Analytics, Event Hub, Azure Object Storage and DocumentDB.

Title:
What abo…