Category Archives: Security

Testing for Specific Versions of TLS Protocols Using curl

Ever need to set your web server a specific protocol version of TLS for web servers and need a quick way to test that out to confirm? Let’s check out how to use curl to go just that.

This code here uses curl with the parameters --tlsv1.1 --tls-max 1.1, which will force the max TLS protocol version to 1.1. Using the --verbose parameter gives you the ability to see the TLS handshake and get the output sent to standard out.

The webserver here has a policy that allows only TLS version 1.2+. So in the output, when forcing curl to use TLS version 1.1, the SSL_connect fails since the webserver only permits 1.2+

curl --verbose  --tlsv1.1 --tls-max 1.1
*   Trying
* Connected to ( port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/cert.pem
  CApath: none
* TLSv1.1 (OUT), TLS handshake, Client hello (1):
* LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection to 
* Closing connection 0
curl: (35) LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection to 

Now, let’s tell curl to use TLS protocol version of 1.2 with the parameters --tlsv1.2 --tls-max 1.2 and see if we can successfully access the webserver. The output below shows a successful TLS 1.2 TLS handshake and some output from the webserver.

curl --verbose  --tlsv1.2 --tls-max 1.2
*   Trying
* Connected to ( port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/cert.pem
  CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN, server did not agree to a protocol
* Server certificate:
*  start date: May 14 00:00:00 2020 GMT
*  expire date: Jul  6 12:00:00 2022 GMT
*  subjectAltName: host "" matched cert's ""
*  issuer: C=US; O=DigiCert Inc; CN=DigiCert SHA2 Secure Server CA
*  SSL certificate verify ok.
> GET / HTTP/1.1
> Host:
> User-Agent: curl/7.64.1
> Accept: */*
< HTTP/1.1 301 Moved Permanently
< Content-Type: text/html; charset=UTF-8
< Location:
< Server: Microsoft-IIS/10.0
< Set-Cookie: ApplicationGatewayAffinity=ca74a2f7c1dea41a8e5010ecf6deda4f944f5539661e08399d8fae0062592401;Path=/;
< Set-Cookie: ApplicationGatewayAffinityCORS=ca74a2f7c1dea41a8e5010ecf6deda4f944f5539661e08399d8fae0062592401;Path=/;;SameSite=None;Secure
< Date: Thu, 20 May 2021 13:48:14 GMT
< Content-Length: 148
<head><title>Document Moved</title></head>
* Connection #0 to host left intact
<body><h1>Object Moved</h1>This document may be found <a HREF="">here</a></body>* 
Closing connection 0

OpenSSH Resources for Windows and PowerShell

Had a conversation with a good friend in the SQL Community about OpenSSH and how it fits as a transport layer for PowerShell Remoting. I pointed him towards several resources I have online. So here’s a post aggregating those resources.

If you’re looking to get started with OpenSSH on Linux and Windows Systems check out thisPowerShell Summit presentation I did in 2018. This covers OpenSSH in theory and practice.

Session: OpenSSH Internals for PowerShell Pros

  • Remote Access Concepts
  • OpenSSH Architecture
  • Authentication Methods (including Key Based Authentication)
  • OpenSSH Server and Client Configuration

If you’re looking to get started with OpenSSH based PowerShell Remoting check out this session from PowerShell Summit in 2018 co-presented with Richard Siddaway.

Session: PowerShell Remoting: Installing and TroubleShooting in a Multiplatform Environment

  • Installing OpenSSH on Windows and Linux
  • Authentication Users (Including AD Authentication)
  • Setting Up PowerShell Remoting on Windows and Linux
  • Troubleshooting OpenSSH

Shortly after I did the sessions above, OpenSSH was released as a Window Capability, check out this blog post on how to install OpenSSH at the command line using Add-WindowsCapability.  This also applies to Windows 2016 Server. 

Session: Firewall Evasion and Remote Access with OpenSSH

  • OpenSSH is much more than just remote terminal access to servers, it provides a full suite of remote connectivity methods to your network and its services. In this session, we will look at how to use OpenSSH and its forwarding, tunneling and VPN capabilities so that we can reach securely reach network services that are behind firewalls and other security boundaries. Common use cases for these techniques are cloud jump boxes, secure access into segmented networks and being able to get remote access and move data around in poorly secured networks….these tips are things that will likely get you some extra attention from your security team

Blog Post: Configuring Passwordless PowerShell Remoting over SSH

Blog Post: Distributing SSH User Keys via PowerShell

Blog Post: Installing OpenSSH Server on Windows 10

Blog Post: PowerShell Remoting in Multi-Platform Environments using OpenSSH

We Speak Linux – OpenSSH For Windows Pros

I’m proud to announce that I will be speaking at this months We Speak Linux Webinar. Each month We Speak Linux brings cross platform training to the Windows world. Sign up now here!

On Thursday, December 2 at 11:00 Central I’m presenting:

OpenSSH for Windows Pros

Here’s the abstract:

In PowerShell Core we can use OpenSSH as the transport layer to carry our remoting sessions between our systems. In this session we’ll look at OpenSSH architecture, Authentication methods, including key authentication, sshd configuration, and troubleshooting methods when things go wrong! 

In this session we’ll cover the following:

  • OpenSSH Architecture
  • Installation on Windows
  • Authentication methods
  • Key based authentication
  • sshd Configuration
  • Troubleshooting OpenSSH 

Please sign up for this session here!

Also, we record our sessions each month and upload them to YouTube for your viewing pleasure, check out the list here! You’ll find some of the biggest names in the business helping you learn topics such as DevOps, Containers, PowerShell Core, Linux command line basics and more!


Image result for linux tux

Installing OpenSSH Server on Windows 10

So in yesterday’s post we learned that the OpenSSH client is included with the Windows 10, Update 1803!  Guess, what else is included in this server, an OpenSSH Server! Yes, that’s right…you can now run an OpenSSH server on your Windows 10 system and get a remote terminal! So in this post, let’s check out what we need to do to get OpenSSH Server up and running.

First, we’ll need to ensure we update the system to Windows 10, Update 1803. Do that using your normal update mechanisms.

With that installed, let’s check out the new Windows Capabilities (Features) available in this Update, we can use PowerShell to search through them.

PS C:\> Get-WindowsCapability -Online | Where-Object -Property Name -Like "OpenSSH*"

Name : OpenSSH.Client~~~~
State : Installed

Name : OpenSSH.Server~~~~
State : NotPresent

Now to install OpenSSH server, we can use the Add-WindowsCapability cmdlet

PS C:\WINDOWS\system32> Add-WindowsCapability -Online -Name  OpenSSH.Server~~~~

To confirm it’s installation we can use the Get-WindowsCapability cmdlet again, and this time it’s state is “Installed”

PS C:\WINDOWS\system32> Get-WindowsCapability -Online | Where-Object -Property Name -Like "OpenSSH.Server*"

Name  : OpenSSH.Server~~~~
State : Installed

With that installed, let’s take a look at where sshd lives on our Windows system and that’s in C:\Windows\System32\OpenSSH\

PS C:\> Get-ChildItem C:\Windows\System32\OpenSSH\

Directory: C:\Windows\System32\OpenSSH

Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 3/10/2018 12:20 PM 343552 scp.exe
-a---- 3/10/2018 8:20  PM 355840 sftp-server.exe
-a---- 3/10/2018 12:20 PM 408064 sftp.exe
-a---- 3/10/2018 12:20 PM 531968 ssh-add.exe
-a---- 3/10/2018 12:20 PM 495616 ssh-agent.exe
-a---- 3/10/2018 12:20 PM 657920 ssh-keygen.exe
-a---- 3/10/2018 12:20 PM 594944 ssh-keyscan.exe
-a---- 3/10/2018 8:20  PM 154624 ssh-shellhost.exe
-a---- 3/10/2018 12:20 PM 894464 ssh.exe
-a---- 3/10/2018 8:20  PM 970752 sshd.exe
-a---- 1/30/2018 7:55  PM 2143   sshd_config_default

On Windows systems, network daemons run as “Services”. We can see with the Get-Service cmdlet, the installer added ssd and also ssh-agent!

PS C:\Users\aen> Get-Service -Name *ssh*

Status   Name               DisplayName
------   ----               -----------
Stopped  ssh-agent          OpenSSH Authentication Agent
Stopped  sshd               OpenSSH SSH Server

As you can see the state is stopped, so let’s start the Services and also set them to start on boot

PS C:\WINDOWS\system32> Get-Service -Name *ssh* | Set-Service -StartupType Automatic
PS C:\WINDOWS\system32> Get-Service -Name *ssh* | Start-Service

We can use netstat to see if we’re up and running

PS C:\WINDOWS\system32> netstat -bano | more

Active Connections

  Proto  Local Address          Foreign Address        State           PID
  TCP                 LISTENING       12764

So now that it’s up and running, you should know that the configuration files and host keys live in ProgramData\ssh\ so if you need to change the behavior of SSH you’ll head for the sshd_config file and when finished, restart your service with Restart-Service -Name sshd 

PS C:\Users\aen> Get-ChildItem -Path 'C:\ProgramData\ssh\'

    Directory: C:\ProgramData\ssh

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----        5/17/2018   8:35 AM                logs
-a----        5/17/2018   8:35 AM              7
-a----        1/30/2018   4:55 PM           2143 sshd_config
-a----        5/17/2018   8:35 AM            668 ssh_host_dsa_key
-a----        5/17/2018   8:35 AM            613
-a----        5/17/2018   8:35 AM            227 ssh_host_ecdsa_key
-a----        5/17/2018   8:35 AM            185
-a----        5/17/2018   8:35 AM            419 ssh_host_ed25519_key
-a----        5/17/2018   8:35 AM            105
-a----        5/17/2018   8:35 AM           1675 ssh_host_rsa_key
-a----        5/17/2018   8:35 AM            405

You’ll likely need to open your Windows firewall, which can be done with the following cmdlet on PowerShell 5.1

New-NetFirewallRule -Name sshd -DisplayName 'OpenSSH Server (sshd)' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22

So let’s test it out, I’m going to ssh from my Mac into my Windows 10 laptop

My-MacBook-Pro:~ aen$ ssh demo@
The authenticity of host ' (' can't be established.
ECDSA key fingerprint is SHA256:eQti/VKAXhTgbLGTqD3n/QOxcPvfdIT6rwuIK+8F5Vs.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '' (ECDSA) to the list of known hosts.
demo@'s password:

Microsoft Windows [Version 10.0.17134.48]
(c) 2018 Microsoft Corporation. All rights reserved.

demo@W10LAPPY C:\Users\demo>

And that’s it, you can now install OpenSSH server on your Windows 10 system. I can only imagine it’s a matter of time before this hits the server side of things! Bravo PowerShell Team, bravo!

OpenSSH is now Part of Windows!

Today is a big day! The OpenSSH client version 7.6p1 is now part of the Windows 10 operating system! Microsoft released Windows 10 Update 1803 and included in that release is the OpenSSH client, which is installed as part of the update.

That’s right an SSH client as part of the Windows operating system by default! Also included with this update is the OpenSSH Server which is included as an Windows Feature on Demand.

Let’s take a look at what this is all made of!

Start off by updating your system to Windows 10, version 1803. You can do this via your normal Windows Update mechanism.

Here you see I have installed Windows 10, version 1803.

Screen Shot 2018 05 16 at 8 07 53 PM

With that, let’s look at what we got in the update! We’ll search our Windows Capabilities (Features)

PS C:\> Get-WindowsCapability -Online | Where-Object -Property Name -Like "OpenSSH*"

Name : OpenSSH.Client~~~~
State : Installed

Name : OpenSSH.Server~~~~
State : NotPresent

Cool, so we know OpenSSH is installed, but where? Let’s check out C:\Windows\System32\OpenSSH\

PS C:\> Get-ChildItem C:\Windows\System32\OpenSSH\

Directory: C:\Windows\System32\OpenSSH

Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 3/10/2018 12:20 PM 343552 scp.exe
-a---- 3/10/2018 8:20  PM 355840 sftp-server.exe
-a---- 3/10/2018 12:20 PM 408064 sftp.exe
-a---- 3/10/2018 12:20 PM 531968 ssh-add.exe
-a---- 3/10/2018 12:20 PM 495616 ssh-agent.exe
-a---- 3/10/2018 12:20 PM 657920 ssh-keygen.exe
-a---- 3/10/2018 12:20 PM 594944 ssh-keyscan.exe
-a---- 3/10/2018 8:20  PM 154624 ssh-shellhost.exe
-a---- 3/10/2018 12:20 PM 894464 ssh.exe
-a---- 3/10/2018 8:20  PM 970752 sshd.exe
-a---- 1/30/2018 7:55  PM 2143   sshd_config_default

Let’s look a littler closer at the ssh.exe

PS C:\> C:\windows\system32\OpenSSH\ssh.exe -V OpenSSH_for_Windows_7.6p1, LibreSSL 2.6.4

So this looks like all of the usual suspects in an OpenSSH installation. But it does look like sshd.exe and ssh_config_default came along for the ride during the update even though we didn’t install the OpenSSH.Server Feature!  More on that in my next blog post…

A big shoutout goes out to the PowerShell team for making this happen, check out the project on GitHub. The code is here and the issues and releases are here!

Distributing SSH User Keys via PowerShell

Folks in the Linux world are used to moving SSH keys to and from systems enabling password-less authentication. Let’s take a minute to look at what it takes to use PowerShell to distribute SSH user keys to remote systems.

In the OpenSSH package there’s a command ssh-copy-id which is a bash script that copies a user’s public key to a remote system. There’s a little intelligence in the script to set things up properly on the remote system for password-less key based authentication. If the appropriate directory and key file aren’t set up, ssh-copy-id will create the directory and key file with the correct permissions on remote system. As far as I can tell, ssh-copy-id has not been implemented in the Win32-OpenSSH port. So that leaves us with implementing this functionality ourselves, in PowerShell.

Since ssh-copy-id isn’t implemented on the OpenSSH port for Windows (because it’s a bash script), I wanted to replicate that functionality so that I could easily copy ssh user keys to systems, consistently and easily. So I implemented this functionality as PowerShell. 

Let’s walk though this…and first up, let’s discuss what’s needed for password-less, key based authentication.

The Components of Password-less Key Based Authentication

For password-less key based authentication to work, you need to copy the user’s public key from the local system you want to authenticate from, to the remote system. On the remote system, this key file has to live in a place where the SSH deamon expects it, and that’s in the file ~./ssh/authorized_keys by default.

Let’s take a second to look at the details of how this needs to be configured on a remote system.

  • authorized_keys – this is the default file in which user public keys are stored. The permissions on this file should be 600. Which is read/write for the owner and no access to group or other/world.

-rw-r–r–. 1 demo demo 412 Feb 18 08:53 .ssh/authorized_keys 

  • ~./ssh – the authorized_keys file lives in a hidden directory in your home directory. That’s what that syntax means, the ~ (tilde) is short for the current user’s home directory and that . (dot) indicates that the directory is a hidden directory. Now, the permissions on this directory should be 700, this means it’s it’s read/write/execute to the owner and no access to group or other/world. The execute bit on a directory gives you access to list the contents of the directory and enter that directory.

drwx——. 2 demo  demo         29 Feb 18 08:53 .ssh

It’s kinda like ssh-copy-id, but in PowerShell

First up, I’m assuming that you have SSH remoting already configured, have generated your ssh user key and that you’re on a Windows, Linux/Mac system and you want to copy and SSH user key to a Linux/Mac system. I plan on covering copying keys to Windows systems in an upcoming post. The only real difference between the two is how you set permissions on the .ssh directory and the authorized_keys file. 
The first thing that we want to do is to create a PSSession to our host. We’ll reuse this session a few times to execute the required commands on the remote host. This demo user is the user we will want to setup key based authentication for. This session creation will ask for our password. Hopefully this is the last time you have to type it ;)

$s New-PSSession -HostName “” -UserName demo

Then, we’ll read in our public key from our local system into a variable. It’s imperative that you read the public key, The other file, id_rsa is your private key. That needs to stay on the system you want to authenticate from and needs to stay secure.

$key Get-Content -Path ~/.ssh/

Next, we’ll want to check to see if the .ssh directory exists in the home directory of our user on the remove system. If not, create the .ssh directory.

Invoke-Command -Session $s -ScriptBlock { If(!(Test-Path -Path ~./ssh)) { New-Item ~/.ssh -ItemType Directory} } 

Now, with the directory in place, let’s be sure the permissions are set properly, and that’s 700 in octal notation.

Invoke-Command -Session $s -ScriptBlock { chmod 700 ~/.ssh  }  

After that, we can copy our key to the remote system’s authorized_keys file. We’ll take advantage of the Out-File cmdlet and use the -Append switch to handle file existence on the remote system and append our key to an existing file or create a new file if it doesn’t exist yet. All that fancy syntax around Invoke-Command is so we can pass a local variable into the Out-File cmdlet over our remoting session.

Invoke-Command -Session $s -ScriptBlock { param([string] $key) Out-File -FilePath ~/.ssh/authorized_keys -Append -InputObject $key } -Args $key

Now, with the file on the remote system, let’s ensure the permissions are set properly.

Invoke-Command -Session $s -ScriptBlock { chmod 600 ~/.ssh/authorized_keys  }

..and with that let’s take it for a test run and see if we can open a PSSession without a password using Enter-PSSession

PS /Users/demo> Enter-PSSession -HostName server1 -UserName demo
[server1]: PS /home/demo> 

Now, there’s a few things I want to point out. This code here is to highlight the needed steps to configure key based authentication. I certainly could (and should) make this code more production ready…but I’ll leave that up to you as the reader. What I really want to highlight here are the steps required for proper key distribution to remote systems, such as directories, files and the required permissions. Oh, if you’re like why don’t you just use ssh-copy-id…fan out remoting. We can use this technique to easily distribute our keys to many systems.

I hope this helps you get an understanding of how key based authentication works, how to configure it and also how to get those keys out to your remote systems!

New Pluralsight Course – LFCE: Network and Host Security

My new course “LFCE: Network and Host Security” in now available on Pluralsight here! If you want to learn about the course, check out the trailer here or if you want to dive right in check it out here!

This course targets IT professionals that design and maintain RHEL/CentOS based enterprises. It aligns with the Linux Foundation Certified System Administrator (LFCS) and Linux Foundation Certified Engineer (LFCE) and also Redhat’s RHCSA and RHCE certifications. The course can be used by both the IT pro learning new skills and the senior system administrator preparing for the certification exam

Let’s take your LINUX sysadmin skills to the next level and get you started on your LFCS/LFCE learning path.

If you’re in the SQL Server community and want to learn how Linux secure your Linux systems…this course is for you too! You have heard that Microsoft has SQL Server for Linux now, right, if not…read this!

The modules of the course are:

  • Linux Security Concept and Architectures – Introduction you into the fundamental concepts needed for securing your environment
  • Securing Hosts and Services – iptables and TCP Wrappers – Host based firewall concepts and techniques with iptables and TCP Wrappers
  • Securing Hosts and Services – firewalld – Learn leverage firewalld to develop more complex firewalls systems…simply. Including concepts such zones, service, ports and NAT
  • Remote Access – OpenSSH – We’ll look at encryption, authentication and how to configure SSH for public authentication
  • Remote Access – Tools and Techniques  – SSH is more than just remote access, we’ll look at secure copy, tunneling and how to use windowing systems such as X11 and VNC…securely.

Pluralsight Redhat Linux

Check out the course at Pluralsight!

Configuring Passwordless PowerShell Remoting over SSH

Open Source PowerShell has been on fire, getting tons of community support and really making people think about what’s to come with a single language to manage a heterogenous data center.

To highlight this point, in my recent Pluralsight Play By Play Microsoft Open Source PowerShell on Linux and Mac with Jason Helmick and Jeffrey Snover I did a demo on using PowerShell remoting where I connected from a Linux machine to three other machines and retrieved lists of top processes from each…two Linux and one Windows. I used one script to accomplish this and no passwords. A simple implementation highlighting a very big idea. After, some people have asked…how did I do this without passwords?

Open Source PowerShell Remoting uses SSH as its communication protocol, so when we connect to a remote system using PowerShell Remoting we’ll need to enter a password. Normally SSH requires passwords to log into remote systems but it also allows for what’s called passwordless authentication, which means users can log into remote systems without having to key in a password. It does this, securely, by using a key pair to authenticate the user to the server. Basically you generate a key pair, copy the public key to the remote server and there you have it…you no longer have to enter a password when you SSH into the remote system. Let’s see how this is done.

You need a couple things to set up this demo

  1. A user account with the same name on each computer – create a user on each machine, Linux and Windows, with the same username.
  2. OpenSSH configured on all hosts – easy on Linux. It’s there by default. On Windows check out this link. Once you complete the installation of OpenSSH on your Windows system, test logging into that system from a remote computer with SSH. This will use the password for a user on that Windows system (likely the one you just created in step 1). If that doesn’t work, you won’t be able to proceed.
  3. Open Source PowerShell installed on all hosts – check out this link here.
  4. Enable PowerShell Remoting over SSH – check out this link here. Once you have this configured, be certain to test PowerShell remoting, using passwords. Test Linux to Linux and also Linux to Windows.

Now once we have the ability to connect to our hosts with SSH and we’ve confirmed we can use PowerShell SSH Remoting, we can move on to configuring passwordless authentication.

First, on your Linux machine (I’m using a Mac, but there literally is no difference here) you can use your existing public key if you have one, which is stored in your home directory in .ssh/ or you can generate a new one.

To generate a new SSH key pair on your Linux machine

  1. Type ssh-keygen
  2. The program will ask you for a file name, just press enter
  3. It will then ask you for a passphrase, press enter again and once more to confirm
You should get output that looks like this:

Demo-MacBook-Pro:.ssh demo$ ssh-keygen 

Generating public/private rsa key pair.

Enter file in which to save the key (/Users/demo/.ssh/id_rsa): 

Enter passphrase (empty for no passphrase): 

Enter same passphrase again: 

Your identification has been saved in /Users/demo/.ssh/id_rsa.

Your public key has been saved in /Users/demo/.ssh/

The key fingerprint is:

SHA256:g5SyXmke+OAmYSl4nxc4wcRnsyeDO6RE9/Q9FKlcpKY demo@demo-MacBook-Pro.local

The key’s randomart image is:

+—[RSA 2048]—-+

|   ..    .oo     |

|  .oo =. .+      |

| . .+*o=o=       |

|. ..oB=== o      |

|o.=o*.E+S  .     |

| +.=oO o .       |

|  . *.+          |

|   o .           |

|                 |


Copy the public key from the Linux machine to the Windows Server
Now copy the contents of the file you just created to C:\Users\username\.ssh\authorized_keys on your Windows machine. Where username is the user you want to use for Remoting. You’ll likely copy and paste the contents of this file to the remote computer…if you do this ensure the contents are all on one line. I’m not going to go into how to configure this on Linux as there are plenty of blogs about how to do this on Linux – check it out here.
You’ll want to make sure you copy the same public key to all the hosts you’d like to authenticate with from this private key. In our case, the two Linux machines and the Windows machine have the same public key in the authorized_keys file on each server, inside user accounts with the same name.
Confirm you have Authorized Keys configured on your Windows SSH server
Now on the Windows machine in C:\Program Files\OpenSSH\sshd_config verify that this line is uncommented, which it should be by default. If not, uncomment it and restart the ssh service. This is the place SSH will look for keys when a user logs into the system via…SSH.

AuthorizedKeysFile .ssh/authorized_keys

Make sure that if you’re running SSH as a service, the account the service is running as had the ability to read this file. In my case the account NT SERVICE\SSHD needed read access.

Confirm SSH passwordless access from Linux (or Mac) to Windows

With that you should be able to connect from your Linux (or Mac) to your Windows machine from the machine where you generated your SSH key without any password. Likewise for your Linux machines.

Demo-MacBook-Pro:~ demo$ ssh demo@

Microsoft Windows [Version 10.0.14393]

(c) 2016 Microsoft Corporation. All rights reserved.


demo@DESKTOP C:\Users\demo>

Let that sink in for a second, I just SSH’d into a Windows machine…

…and finally connect via PowerShell remoting over SSH with passwordless authentication

OK now we’re in the home stretch…we can now create a PowerShell remoting session over SSH with passwordless authentication.

PS /Users/demo> Enter-PSSession-HostName -UserName demo                                       

[]: PS C:\Users\demo\Documents>

And there we have it we’re able to connect to using PowerShell Remoting over SSH without a password.

Questions about Linux? PowerShell? Please feel free to ask or on Twitter @nocentino

Encrypting Connections To SQL Server Using Certificates

Encrypting Connections To SQL Server Using Certificates

In this post we’re going to cover configuring a connection string in .NET applications for encrypting connections to SQL Server using certificates. The audience for this document is a developer that needs to configure encrypted connections from applications to a database server.

Encrypting connections with SQL Server using Certificates consists of two parts:

  • An appropriately configured connection string
  • A server certificate installed on the Database Engine (not covered in this post)

Configuring a Connection String

To configure a .NET connection string you will need to set the following parameters

  • Server – the fully qualified domain name (FQDN) of the SQL Server. The name here will need to exactly match the server common name or a subject alternative name configured in the certificate.
  • Database – the database context used for this connection
  • uid – the username of this connection
  • password – the password for the user
  • Encrypt – set to ‘yes’ to encrypt or ‘no’ or remove to disable encryption 
  • TrustServerCertificate – will bypass validating the certificate. This is useful if the certificate is untrusted, the common name or subject alternative name do not match what is in the certificate or the certificate is expired. This is useful for testing and troubleshooting. Enabling this in production environments is strongly discouraged as the destination certificate is not validated.

Configuring a Connection String On a Single Instance

When connecting to a single instance, a valid certificate must be installed on the instance. The server parameter in the connection string needs to be configured as the subject/common name in the certificate and the server configured in the connection string must match this name. In figure 1, the subject is the connection string server parameter should match this name.


Figure 1 – Certificate with Subject/Common Name

Configuring a Connection String On Availability Groups

A valid certificate must be installed on all servers/replicas in the Availability Group. The subject/common name in the certificate should match the local server. The subject alternative names in the certificate should match the availability group listener DNS name. The server parameter of the connection string will use this name. In figure 2, the AG listener is, the connection string server parameter should match this name.

Subject Alternative Name

Figure 2 – Certificate with Subject Alternative Names

Configuring a Connection String With Aliases

Often application connection strings are configured using an alias (DNS CNAME), rather than the actual host name (A record) of the SQL Server. Upon the connection’s DNS request, the DNS server responds to the CNAME request for the alias with the A record data for the actual server.  This means the certificates common name or subject alternative name do not have to include the alias (DNS CNAME). This applies to single instances and Availability Groups.

Example Connection Strings

    1. Example connection to a single instance when the server has a valid certificate

      <connectionStrings><add name=myConnectionString;database=TestDB1;uid=user1;password=s3cur31y;Encrypt=yes/></connectionStrings>

    2. Example connection to an availability group listener when each server has a valid certificate with the appropriate subject alternative name



Here are a few errors that you may encounter when connecting to SQL Server with an encrypted connection. Basically when validation fails there will be an exception thrown with information similar to these examples.

When opening a connection string asking for encryption, but an untrusted certificate

System.Data.SqlClient.SqlException (0x80131904): A connection was successfully established with the server, but then an error occurred during the login process. (provider: SSL Provider, error: 0 – The certificate chain was issued by an authority that is not trusted.) —> System.ComponentModel.Win32Exception (0x80004005): The certificate chain was issued by an authority that is not trusted

When opening a connection string, but the certificate is expired

System.Data.SqlClient.SqlException (0x80131904): A connection was successfully established with the server, but then an error occurred during the login process. (provider: SSL Provider, error: 0 – The received certificate has expired.) —> System.ComponentModel.Win32Exception (0x80004005): The received certificate has expired


Connection String Syntax –

Enable Encrypted Connections to the Database Engine –