Securing StifleR with SSL | 2pint Knowledge Base

Securing StifleR with SSL

If you are reading this then you are interested in StifleR, SSL and all things Certificate related.

This artical has been superceded.

Please refer to the StifleR Planning and Deployment Guide, companion document "Securing StifleR Operations Using SSL" which not only contains information on Securing StifleR but also how to set up and use the underlying Configuration Manager security environment.

Self hosting SignalR is very straight forward to set up, which is great if you need to hook SignalR as an event source to standard Windows based application such as a Service a WPF or Winforms desktop application that needs to send push notifications to many users.

Unfortunately, however, one aspect of self-hosting that's not quite so transparent or well documented, is how to run a self-hosted SignalR service under SSL. The Windows certificate store and the creation, configuration and installation of certificates is still a pain. There's no UI in Windows that provides linking endpoints to certificates and the process is not very well documented end to end. It's easy enough once you know what command line tool you need to call, but this process could certainly be made a little smoother and better documented. This article is intended to provide some details around this configuration and hopefully a more coherent description of setting up a certificate for self-hosting an OWIN service in general and then specifically for SignalR.

Self-Hosting and Open Web Interface for .NET (OWIN)

When you're self-hosting SignalR as we are in StifleR you're essentially using the hosting services provided by OWIN/Katana. OWIN is a low level spec for implementing custom hosting providers that can be used interchangeably. The idea is to decouple the hosting process from a specific implementation and make it pluggable, so you can choose your hosting implementations.

Katana is Microsoft's implementation of OWIN, that provides a couple of specific implementations. For self-hosting there's the HttpListener based host which is completely decoupled from IIS and its infrastructure. For hosting inside of ASP.NET there also is an ASP.NET based implementation that is used for SignalR apps running inside of ASP.NET. Both implementations provide the base hosting support for SignalR, so that for the most part the same code base can be used for running SignalR under ASP.NET or under your own self-hosted EXEs like services, console or desktop apps.

Binding certificates to SSL Ports for Self-Hosting

Self-hosting under HttpListener is wonderful and completely self-contained, but one of the downsides of not being part of IIS is that it also doesn't know about certificates that are installed for IIS, which means that certificates you want to use have to be explicitly bound to a port. Note that you can use IIS certificates and if you need to acquire a full certificate for use with a self-hosted application, going through the IIS certificate process is the easiest way to get the certificate loaded. If you need a certificate for local testing too IIS's self-signed certificate creation tool makes that very easy as well (I'll describe that below).

For now, let's assume that you already have a certificate installed in the Windows certificate store. In order to bind the certificate to a self-hosted endpoint, you have to use the NETSH command line utility to register it on the machine (all on one line):

netsh http add sslcert ipport=0.0.0.0:8082
           appid={12345678-db90-4b66-8b01-88f7af2e36bf}
           certhash=d37b844594e5c23702ef4e6bd17719a079b9bdf

For every endpoint mapping you need to supply 3 values:

  • The ipport which identifies the ip and port
    Specified as ipport=0.0.0.0:8082 where the zeros mean all ip addresses on port 8082. Otherwise you can also specify a specific IP Address.

  • The certhash which is the Certificate's Thumbprint
    The certhash is the id that maps the certificate to the IP endpoint above.  You can find this hash by looking at the certificate in the Windows Certificate store. More on this in a minute.

  • An AppID which is fixed for HttpListener Hosting
    This value is static so always use appid={12345678-db90-4b66-8b01-88f7af2e36bf}

 

Once the above command has been run you should check if it worked by checking the binding as follows:

netsh http show sslcert ipport=0.0.0.0:8082

which should give you a display similar to this:

 

 

Finding the CertHash

To find the certhash, you need to find the certificate's ThumbPrint which can be found in a couple of ways using either of the following:

  • The IIS Certificate Manager

  • The Windows Certificate Storage Manager

Using IIS to get Certificate Info

If IIS is installed, then this is the easier option. From here you can easily see all installed certificates. The UI is also the easiest way to create local self-signed certificates.

To look up an existing certificate, simply bring up the IIS Management Console, go to the Machine node, then Server Certificates:

 

You can see the certificate hash in the rightmost column. You can also double click and open the certificate and go in the Details of the certificate. Look for the thumbprint which contains the hash.

 

Unfortunately, it is difficult to copy the hash from either of these interfaces, so you either have to copy it manually or remove the spaces from the thumbprint data in the dialog.

Note: When copying the thumbprint from Certificate Manager in the details window, a hidden character may get copied at the start. You can check this by using the cursor to move through it - delete it if it's there! Leaving it in can cause the "The Parameter is Incorrect" message despite everything looking fine at the command prompt. This was noted in testing on Windows 8 and Server 2012.

Using IIS to create a self-signed Certificate

If you don't have a full server certificate yet, but you'd like to test with SSL operations locally you can also use the IIS Admin interface to very easily create a self-signed certificate

Here's how to do it:

  • Go to the machine root of the IIS Service Manager

  • Go to the Server Certificates Item in the IIS section

  • On the left click Create Self-Signed Certificate

  • Give it a name, and select the Personal store

  • Click OK

 

  • Job Done!

Copy the self-signed Certificate to the Trusted Root Certification Store

Once you have a self-signed certificate, you need one more step to make the certificate trusted so that HTTP clients will accept it on your machine without certificate errors. The process involves copying the certificate from the personal store to the trusted machine store.

To do this:

  • From the StartMenu use Manage Computer Certificates

  • Go into Personal | Certificates and find your certificate

  • Drag and Copy (Ctrl-Drag) the certificate to Trusted Root Certificates | Certificates

 

You should now have a certificate that browsers will trust. This has been tested for IE, Chrome and Safari, but FireFox will need some special steps (thanks to Eric Lawrence) and Opera requires specific registration of certificates.


Using a full IIS Certificate

Self-signed certificates are great for testing under SSL to make sure your application works, but it's not practical for production apps as the certificate would have to be installed on any machine you'd expect to trust this certificate.

Once you go to production, especially public production you'll need an 'official' certificate signed by a one of the global certificate authorities for $$$.

The easiest way to do this is to purchase a full IIS certificate and install it in IIS. The IIS certificate can also be used for self-hosted applications using the HttpListener so it will work just fine with a self-hosted SignalR or any HttpListener application.

Once the time comes to go live, register a new certificate through IIS, then use netsh http add sslcert  to register that certificate as shown above. A public SSL certificate in most cases is already recognized so no further certificate store moving is required - all you need is the netsh registration to tie it to a particular port and app Id.

Running SignalR with SSL

With the certificate installed, switching SignalR to start with SSL is as easy as changing the startup URL.

Self Hosted Server Configuration

In the self hosted server, you now specify the new SSL URL in your startup factory invocation, which is done on the StifleR.ClientApp.config file:

<add key="StiflerServers" value="https://NUC5.2PSTEST1.LOCAL:1414/>
 

This binds SignalR to the all IP addresses on port 1414. You can also specify a specific IP address, but using * is more portable especially if you set the value as part of a shared configuration file.

OWIN uses a startup class (SignalRStartup in this case) to handle OWIN and SignalR HubConfiguration, but the only thing that needs to change is the startup URL and your self-hosted server is ready to go.

SignalR Dashboard Url Configuration

On the Web Page to consume the SignalR service to hubs or connections change the script URL that loads up the SignalR client library for your hubs or connections like this in your app.js files:

 
app.value('backendServerUrl', 'https://localhost:1414');
 

where here is my exact local machine name that has the certificate registered to it. As with all certificates make sure that the domain name matches the certificate's name exactly. For local machines that means don't use localhost if the certificate is assigned to your local machines NetBios name as it is by default. Don't use your IP address either - use whatever the certificate is assigned to.

You'll also need to assign the hub URL to your SSL URL as part of the SignalR startup routine that is used internally in the Stifler Server Service:

     <add key="ListenToUrl" value="https://*:1414/" />
     <add key="PerformanceListenToUrl" value="https://*:1314/" />

From a development perspective, other than the two small URL code changes, there isn't anything that changes for SSL operation, which is nice.

And… you're done!

SSL Configuration

SSL usage is becoming ever more important as more and more application require transport security. Even if your self-hosted SignalR application doesn't explicitly require SSL, if the SignalR client is hosted inside of a Web page that's running SSL you have to run SignalR under SSL. If you don’t do this you will see browser error messages or failures under some browsers that will reject mixed content on SSL pages.

SSL configuration is always a drag as it's not intuitive and requires a bit of research. It'd be nice if the HttpListener certificate configuration was as easy as IIS configuration or better yet, if self-hosted apps could just use already installed IIS certificates. Unfortunately, it's not quite that easy and you do need to run a command line utility with some magic ID associated with it.

Installing a certificate isn't rocket science, but it's not exactly well documented. While looking for information I found a few unrelated articles that discuss the process but a few were dated and others didn't specifically cover SignalR or even self-hosting Web sites. So I hope this post makes it a little easier to find this information in the proper context.

This article focuses on SignalR self-hosting with SSL, but the same concepts can be applied to any self-hosted application using HttpListener.