Fix “This server supports TLS 1.0 and TLS 1.1” on Qualys SSLlabs test

Over the years, we published some popular articles on how to get the best score on SSLLabs tests.

This year, we’re back on that popular issue, that can now be solved. In January 2020, Qualys changed their test to give note “B” when TLS 1.0 and 1.1 are still supported.

By default, IIS server gives that result on Qualys SSLLabs test.

Even in the last IIS version (10), these protocols they are still enabled by default. (list of default protocols status)

Now, this is what you need to do to avoid that validation message: “This server supports TLS 1.0 and TLS 1.1. Grade capped to B.”

How to fix that on IIS: (Link on microsoft article)

For TLS 1.0: (link on Microsoft article)
For TLS 1.1: (link)

To avoid complexe registry edit, you can copy-paste the following config in a file called “disable-tls-10-11.reg”, created using notepad. then double-click on it.

Content of the file:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Server]
"Enabled"=dword:00000000

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Server]
"Enabled"=dword:00000000

Save it, and double-click on it, and accept all confirmations, to add these settings to your registry database.

Then reboot your computer, and run your SSL test again. Grade A reached!

How-to allow AWS IAM users access to Billing Dashboard

You found that page because you tried to create an IAM user, and allow Billing dashboard access.

You set it all the required permissions, like “AdministratorAccess” or “Billing”, and it didn’t work.

Then, you also tried to add an “inline policy”, by selecting “Billing” service, + “All Billing Actions” (aws-portal:*), and it’s still not working.

When using that IAM user to access billing dashboard, you always see that message:
“You Need Permissions – You don’t have permission to access billing information for this account. Contact your AWS administrator if you need help. If you are an AWS administrator, you can provide permissions for your users or groups by making sure that (1) this account allows IAM and federated users to access billing information and (2) you have the required IAM permissions.”

You follow provided help link, and it doesn’t help, they only tell you again and again that you should enable billing access to iam users. But, like most of AWS documentation, they never tell you HOW to do that easily!

I will tell you, because I lost hours to find it, and I want to help someone who have the same issue.

Login with your “root” account. Then, go to “my account” menu on top right, or follow that link: “My Account“.

On that page, search for “IAM User and Role Access to Billing Information“.

There’s a warning in that section: “IAM user/role access to billing information is deactivated“.

Finally, all you need is to click “Edit”, check the box, hit Update, and you’re done!

How to export all Route53 DNS zones entries

I recently had to export all Route53 DNS entries, just to do some cleanup of them. I was surprised that there is no “official” way to export them all from the AWS console!
I found the cli53 tool, but it doesn’t do exactly what I need.

So, I decided to write my own powershell script. I share it with you, I hope it may help!

Feel free to send me your suggestions to make it better!

$zones = Get-R53HostedZoneList | select name,id,ResourceRecordSetCount | sort -Property name

foreach ($zone in $zones) {
    [string]::Format(“[{0}] [{1}] ({2})”,$zone.Name, $zone.Id, $zone.ResourceRecordSetCount)
    $recordsets = Get-R53ResourceRecordSet -HostedZoneId $zone.id 
    $recordsets = $recordsets.ResourceRecordSets | sort -Property type # | where type -EQ 'a'
    foreach ($rs in $recordsets){              
        [string]::Format(“`n[{0}] [{1}] ({2})”,$rs.type, $rs.name, $rs.ResourceRecords.Count)
        foreach ($record in $rs.ResourceRecords){
            [string]::Format("   {0}", $record.Value)
        }
    }
    "`n-----------------------------`n"
}

How to make your server-side javascript code private in IIS

You learned that you can use Server-Side Javascript mixed in our ASP Classic VBScript application.

Next, you want to create tons of javascript files, and mix them with your old ASP. You can name them “.asp”, or “.inc”, like you did with your old VBScript files.  But, what about using intellisense in a standard editor from these extensions?

The best way to use intellisense in your favorite editor, like Visual Studio Code or anything else, is to name these files with the .js extension.

But, there’s a security issue.  If you name these files like that, they should be returned to your client in plain text if called from a web browser.  You don’t want your server-side code to be exposed through IIS.

What you need to do, is just put all these files in a specific folder, in which you will disable all IIS handlers, by using the following steps.

  1. In your application root, create a folder called private.
  2. In that folder, create a web.config file, and add this content:
<system.webServer>
  <handlers>
    <clear />
  </handlers>
</system.webServer>

You can now add all your server-side JS in that folder, and they will private to your ASP code.

If you call that js file in the browser, you will get a 404:

From your ASP page in the root, include them like this:

<script runat="server" language="javascript" src="private/code.js"></script>

That’s all! Happy Coding.

How to mix Classic ASP and Server-Side Javascript

Sometimes I need to fix some old Classic ASP applications or add small new features to them.

Because I do Javascript or C# every day for new apps, it hurts to get back to VBScript for these old apps!

That’s why I try to do these using Server-Side Javascript instead.  But wait, how can I mix NodeJS and VBScript?  The answer is, you can’t.  But, there was Server-Side JS before NodeJS exists!

Now, look at this.

You have a ASP Classic site like this:

<body>
<% dim product : product = "apple"
response.write product %>
...

And you need to create a new function to get the product name.

But, you don’t want to do it in VBScript, because you prefer JavaScript.

All you need to do is to create an “include” file, in pure javascript, like this:

includeJS.inc:

function getProduct(){
	var product = "banana";
	return product;
}

And, add it to your existing ASP file:

<script runat="server" language="javascript" src="includeJS.js" ></script>

Finally, you can fix your existing code like this:

<% dim product : product = getProduct()
response.write product %>

Yes, the VB code can call JS function directly.
Also, your JS code can also use already existing VBScript functions and variables.

(edit 2020-12-23) I just added a working sample for this, that you can download, including web.config “urlrewrite” to keep your js-code hidden from browser direct call.

IIS can run Server-Side Javascript since 1997

When I read articles about NodeJS, they almost all consider NodeJS like if Ryan Dahl invented Server-Side Javascript.

But, did you know that, in IIS 3.0 on Windows NT 4.0, it was possible to run server-side javascript?

On May 15, 1997, Microsoft released the Service Pack 3 of Windows NT4, introducing Active Server Page technology (ASP).

Classic ASP was built to run Active Script.  VBScript AND JScript are the first Active Script languages developped, and were included in all versions of Windows since 95.  And, that “Jscript”, can be used to run server-side javascript.

Wait, JScript is not JavaScript?  Yes it is. Just another name.  FireFox 1.0 run something named JavaScript 1.5, and IE6 run JScript 5.0  And, both were, in fact, ECMAScript 3.0. (more info)

That said, it means that if you still need to work with Classic ASP application, to maintain old software that can’t be rewritten, you can write some JavaScript to do that.  And, it is totally compatible with existing VBScript app!

Now, look at this sample of a 100% server-side javascript in an classic ASP file.

I’ll show you, in another article, how you can add some javascript in your existing Classic ASP / VBscript application.

Useful url rewrite rules for IIS

These are some rules I use in IIS to make all my web sites works as expected.

What I need to automate in all site:

  • Remove prefix “www.”
  • Redirect “http” to “https”, as http will soon disappear, thanks to LetsEncrypt.

Also, for very simple static sites, I want to make all pages respond to the same fixed static page, and get no 404.

You can do that without any code, when using the IIS Rewrite extension.  You first need to install the extension to your existing IIS configuration. (link)

This is an example of my IIS configuration:

  • Site 1: “https://foxontherock.com”
  • Site 2: “https://fredericmalenfant.com”
  • Site 3: default (ip binding)

Bindings strategy

The first strategy can be to add these rules to all your sites, one by one.
Exemple for site 1, these are the 4 bindings configuration:

  • http://foxontherock.com
  • http://www.foxontherock.com
  • https://foxontherock.com
  • https://www.foxontherock.com

If you set your IIS bindings like that, you need to add the rewrite rules to all your sites, one by one.

But there’s another simple strategy that I prefer, by using a “default” site on IIS.
On the first and second sites, I only set the “final” binding, e.g. foxontherock.com and fredericmalenfant.com, both on port 443 without www.

On the “default” site, I configure the bindings to respond to all other requests on my public IP address.

That way, I only need to add the redirect rules on the default site, as the redirection will be handled by the redirected site after.

IIS Rewrite Rules

First rule: Remove www prefix.

<rule name="Remove www" stopProcessing="true">
 <match url="(.*)" ignoreCase="true" />
 <conditions logicalGrouping="MatchAll">
  <add input="{HTTP_HOST}" pattern="^www\.(.+)$" />
 </conditions>
 <action type="Redirect" url="https://{C:1}/{R:0}" redirectType="Permanent" />
</rule>

Second rule: redirect http to https

<rule name="Redirect to https" stopProcessing="true">
 <match url="(.*)" />
 <conditions>
  <add input="{HTTPS}" pattern="off" ignoreCase="true" />
 </conditions>
 <action type="Redirect" url="https://{HTTP_HOST}/{R:0}" redirectType="Permanent" />
</rule>

The third rule can be set to all sites, and is used to get a fixed page always responding, without 404.

<rule name="Default page" stopProcessing="true">
 <match url=".*" />
 <conditions>
  <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
  <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
 </conditions>
 <action type="Rewrite" url="index.html" />
</rule>

Finally, you can add the “canonical” meta on that page to make robots index only 1 page, not all possible url.

(index.html)
<head>
...
<link rel="canonical" href="https://foxontherock.com/" />
</head>

Disable ssl3 for more security

SSL3 is over.  Some servers keep it active because they need to serve pages to IE6/XP users.  But, these days are over, as most of the updated to, at least IE8, and they have all the last updates allowing to connect using TLS 1.1 or 1.2.

SSL3 can also be enabled by default on older Windows Servers, like 2008 R2, even if you installed all Windows Updates.

Now, it’s time to disable SSL3 completely.

If your SSL3 is active, you may get one of these warnings from Qualys SSL Test:

  • This server is vulnerable to the POODLE attack. If possible, disable SSL 3 to mitigate. Grade capped to C.
  • This server uses SSL 3, which is obsolete and insecure. Grade capped to B.

It’s easy to disable it from a Windows registry, as described here.

Solution

Create a file, called DisableSSL3.reg, and copy that content on it:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Server]
"Enabled"=dword:00000000

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Server]
"Enabled"=dword:00000000

Save it, double-click on it, and accept.

Finally, reboot, and all SSL3 server services are disabled on your Windows server.

How to get “A” Rating on Qualys SSL Labs Test

That blog is hosted on an Amazon EC2 Instance, running Windows 2012 R2 Server.  And our SSL certificated is provided by Let’s Encrypt.

Starting from that default configuration, we ran the SSL test, and we got a B note.  We wanted to get the “A” Rating, and these are the 2 major warning we had to solve.

  • “This server supports weak Diffie-Hellman (DH) key exchange parameters”
  • “This server accepts RC4 cipher, but only with older protocols”

Solution

We were able to fix these issues with some simple registry tweaks that we describe in these articles

Then, after we ran these steps, we now have our A Grade!

Now, if you want an even better grade, you can continue to solve these little warnings that the SSLLabs test can give you.

How to solve RC4 warning on Qualys SSLLabs Test

In a previous article, I talked about how you can solve the Diffie-Hellman warning on Qualys SSLLabs test, by applying a registry configuration.

Now, we’ll talk about another common warning that most AWS EC2 customer can get.  By default, we got that security issue from SSLLabs:

This server accepts RC4 cipher, but only with older protocols. Grade capped to B.

Solution

Microsoft proposes a solution for disabling the 3 weak RC4 cipher suites in that article.
You need to create 1 new registry entry.  Create an empty text file called rc4fix.reg, and paste that content to it:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC4 128/128]
"Enabled"=dword:00000000

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC4 40/128]
"Enabled"=dword:00000000

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC4 56/128]
"Enabled"=dword:00000000

Then, double-click on it to apply these settings, an reboot.

Finally, run your SSL test again, that warning disappeared.