How to Install a Let's Encrypt TLS Certificate Into IIS on Windows

by Oliver 2. June 2016 09:00

We're slowly getting ready to present our youngest child, lemon, to the open public. In the process we moved the tracking app itself from www.lemontimetracker.com to app.lemontimetracker.com. Our currently installed TLS certificate covers only the domains lemontimetracker.com and www.lemontimetracker.com, so we need a new certificate for the app subdomain. Let's Encrypt Provides TLS Certificates on Linux – and on Windows, too For a few months we've been using free TLS certificates provided by Let's Encrypt for Camping.Info but these were created and are being managed on a CentOS system that also runs our NGINX reverse proxy and load balancer. In contrast to Camping.Info, we access lemon directly on the Windows hosting server without going through NGINX. So we needed a way to create and install a Let's Encrypt certificate on a Windows Server 2012 box. Thanks to Rick Strahl and his recent post on Using Let's Encrypt with IIS on Windows this was an easy task. His walkthrough on using letsencrypt-win-simple, "A Simple ACME Client for Windows", was all I needed to get the job done. For brevity, here's a list of steps you need to do to get an IIS site TLS encrypted. Using letsencrypt-win-simple to install a TLS certificate into IIS Log onto the machine where the site is hosted that you want to equip with SSL/TLS. Get the latest ZIP containing an exe and some SSH Windows DLLs. Unpack into a location dear to you. Open a command prompt in that location. Run letsencrypt Follow the instructions, i.e.: Pick an IIS site binding from the list. (You can ignore the other options at the bottom.) Lean back and watch the magic happen! Problems you might run into When I ran the tool for the first time on our live server, I was greeted with this error: System.CmomponentModel.Win32Exception (0x80004005): A specified logon session does not exist. It may already have been terminated. It might have had something to do with the missing tick in the "Require Server Name Indication" check box for the https binding for app.lemontimetracker.com: After checking that, the https version worked like a charm. HTTPS in IIS on Windows is simple now Try it yourself! Happy encrypting :-)

HTTP Error 500.19 - Internal Server Error: 0x8007007b Cannot read configuration file

by Oliver 20. March 2013 15:24

While setting up a specification tests project for our new TeamReview tool, I was facing an HTTP 500.19 error when hosting our site in IIS Express. There are lots of questions on stackoverflow concerning this error, Microsoft has a whole page on it, but there is a whole bunch of suberrors that this error addresses. Error 0x8007007b: Cannot read configuration file Unfortunately, none of the above mentioned links contained or solved the specific error code I was seeing: Error Code    0x8007007b Config Error    Cannot read configuration file Config File    \\?\C:\Projects\_teamaton\teamreview\TeamReview.Specs\bin\Debug\..\..\..\TeamReview.Web\web.config After some reading, trying, fiddling, it appeared to me that maybe the path to the config file somehow messed up IIS Express. I admit that it was at least a bit unusual to use the parent directory dots. But it came from my test harness code where I wanted to use relative paths and used Path.Combine() to do that: var webPath = Path.Combine(Environment.CurrentDirectory, "..", "..", "..", "TeamReview.Web"); Pitfall: .. in path Well, it turns out IIS Express didn't like it. Once I called it with a cleaned up path string, everything just worked: "C:\Program Files (x86)\IIS Express\iisexpress.exe" /path:"C:\Projects\_teamaton\teamreview\TeamReview.Web" /port:12345 /systray:false So, watch out for your physical path values when using IIS Express! Use DirectoryInfo to navigate up your directory tree To get the correct path without using absolute paths but also avoiding the .. I used the DirectoryInfo class: var webPath = Path.Combine( new DirectoryInfo(Environment.CurrentDirectory).Parent.Parent.Parent.FullName, "TeamReview.Web");

Using Non-ASCII / Unicode URLs on Your Web Site

by Oliver 24. August 2012 16:22

We’re still working on Marinas.info and were wondering if we should change any of the behavior that we use in Camping.info. There we allow for all kinds of unicode characters, from those in Eastern European languages such as Polish to the Cyrillic letters of the Russian alphabet – but we encode them properly using HttpServerUtility.UrlPathEncode(). This is the behavior that RFC 3986 on URIs defines in section 2.1. It also means that all links that are rendered on pages on Camping.info are correctly encoded and will work in all browsers, even text based ones. Problems with Internet Explorer The drawback of encoded URLs is that Internet Explorer will not decode them in the address the way all other major browsers do (Firefox, Chrome, Opera, haven’t checked Safari), so all those Internet Explorer users out there will see something like http://pl.camping.info/polska/%C5%9Bl%C4%85skie/camping-pod-d%C4%99bowcem-20149/po%C5%82o%C5%BCenie – which is, to put it mildly, unreadable. Go ahead and copy that URL into any of the other browsers and they will reformat it to http://pl.camping.info/polska/śląskie/camping-pod-dębowcem-20149/położenie but behind the scene will still use the encoded URL. Another problem occurs when you enter a URL that contains non-ASCII characters directly into IE’s address bar. The initial page load will succeed as IE properly encodes the URL. But once you want to POST to the same page IE changes its behavior to something in my eyes inconsistent generating an error. A deeper look behind the IE scenes This is what the error looks like in Fiddler: As you can see, IE replaced the Polish special characters from the first three URL segments and encoded only the last part which is also what’s inside the form’s action attribute: Who would have thought! As you can see in the first screenshot, for the URL www.camping.info/österreich/niederösterreich something similar happens with the difference that IE replaces the ö by the byte with value F6 in hex or 246 in decimal. To make the following screenshots I saved the whole request (as Fiddler intercepted it) to a file and looked at it using the hex editor HxD: According to the table http://www.utf8-chartable.de/, F6 is the Unicode code point for the small letter ö, whose UTF-8 representation is C3 B6 which we can find e.g. in the referrer of the same request: So it turns out IE uses 3(!) different encodings to transmit the same letter ö: its Unicode code point, the URL encoded version proposed by RFC 3986, and the UTF-8 encoded version. Wow! Unfortunately, IIS and our application don’t play well with that. Conclusion - Support Encoded URLs anyway We decided anyway to support those encoded URLs for our new portals including Marinas.info to be able to SEO our pages according to their content even through their URL. Maybe IE 10 will decode those URLs in the address bar and get a grip on handling URL and form action uniformly – for their users’ sake! Happy encoding!

Running a multi-lingual web application: System.IO.PathTooLongException

by Oliver 4. March 2011 15:18

We definitely have long paths on our client’s platform www.camping.info, for example for a concrete rating on the detail page of a campsite with a long name in a state with a long name - http://www.camping.info/deutschland/schleswig-holstein-und-hamburg/campingplatz-ferien-und-campinganlage-schuldt-19573/bewertung/r23989 - but the path (everything after the .info including the ‘/’) is still only 112 characters long which is still a long way from the 260 character barrier that’s the default in ASP.NET (see the MSDN). The problem Well, the same page in Greek for example has the following URL: http://el.camping.info/γερμανία/σλέσβιχ-χολστάιν-αμβούργο/campingplatz-ferien-und-campinganlage-schuldt-19573/αξιολόγηση/r23989, at least that is what we see in the browser bar. Essentially, this URL will be encoded when requesting the page from the server so it becomes a gigantic http://el.camping.info/%CE%B3%CE%B5%CF%81%CE%BC%CE%B1%CE%BD%CE%AF%CE%B1/%CF%83%CE%BB%CE%AD%CF%83%CE%B2%CE%B9%CF%87-%CF%87%CE%BF%CE%BB%CF%83%CF%84%CE%AC%CE%B9%CE%BD-%CE%B1%CE%BC%CE%B2%CE%BF%CF%8D%CF%81%CE%B3%CE%BF/campingplatz-ferien-und-campinganlage-schuldt-19573/%CE%B1%CE%BE%CE%B9%CE%BF%CE%BB%CF%8C%CE%B3%CE%B7%CF%83%CE%B7/r23989! Now the path of the URL is a whopping 310 characters long! That’s quite a bit over the limit - but even for shorter URLs the cyrillic or greek equivalents surpass the limit not as rarely as one would think once they are URL encoded. The exception you get when exceeding the default of 260 chars is: System.IO.PathTooLongException: The specified path, file name, or both are too long. The fully qualified file name must be lessthan 260 characters, and the directory name must be less than 248 characters. And this is what the error looks like in Elmah: The solution You don’t have to search long to find a solution to this problem on the web: http://forums.asp.net/t/1553460.aspx/2/10. Just make sure the httpRuntime node contains the properties maxUrlLength AND relaxedUrlToFileSystemMapping like so: <httpRuntime maxUrlLength="500" relaxedUrlToFileSystemMapping="true" /> You might wonder what the relaxedUrlToFileSystemMapping property really does: you can read more on MSDN. In short, if set to true “the URL does not have to comply with Windows path rules” (MSDN). Happy coding, Oliver

About Oliver

shades-of-orange.com code blog logo I build web applications using ASP.NET and have a passion for javascript. Enjoy MVC 4 and Orchard CMS, and I do TDD whenever I can. I like clean code. Love to spend time with my wife and our children. My profile on Stack Exchange, a network of free, community-driven Q&A sites

About Anton

shades-of-orange.com code blog logo I'm a software developer at teamaton. I code in C# and work with MVC, Orchard, SpecFlow, Coypu and NHibernate. I enjoy beach volleyball, board games and Coke.