PITA
This is more of shell related issue but I see it often to be a confusing and frustrating issue when building a container image. The issue is when one needs to access a resource over HTTPS protocol, Powershell can throw an error similar to this:
PS C:\> Invoke-WebRequest -Uri 'https://repo.contoso.com'
Invoke-WebRequest : The request was aborted: Could not create SSL/TLS secure channel.
At line:1 char:1
+ Invoke-WebRequest -Uri 'https://repo.contoso.com'
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebExc
eption
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
The issue here is that Powershell has TLS 1.0 set as its SecurityProtocol
. When a remote server enforses TLS 1.1, 1.2 or higher, you can get the error requesting HTTPS resource.
Solution
The solution would be different depending on the base image you use servercore
or nanoserver
.
servercore
The servercore
has full blown Powershell (PS) (at least at this moment but PS Core is closing in on it fast). In full version of PS, one can change SecurityProtocol
setting to allow different version of TLS/SSL protocol to be used Invoke-WebRequest
a.k.a. iwr
a.k.a. curl
.
Here is how you can set it to use TLS 1.2
:
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]'Tls12'
One can also tell PS to respect a number of known security protocols at the same time:
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]'Ssl3,Tls,Tls11,Tls12'
Once SSL/TLS issue is out of the way, you may still encounter an error like this:
PS C:\> iwr -Uri 'https://repo.contoso.com'
iwr : The response content cannot be parsed because the Internet Explorer engine is not available, or Internet
Explorer's first-launch configuration is not complete. Specify the UseBasicParsing parameter and try again.
At line:1 char:1
+ iwr -Uri 'https://repo.contoso.com'
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotImplemented: (:) [Invoke-WebRequest], NotSupportedException
+ FullyQualifiedErrorId : WebCmdletIEDomNotSupportedException, Microsoft.PowerShell.Commands.InvokeWebRequestCommand
Follow the suggestion in the error message and add UseBasicParsing
flag to your Invoke-WebRequest
command:
PS C:\> (iwr -Uri 'https://repo.contoso.com' -UseBasicParsing).StatusCode
200
Now the command should succeed (unless your container inside enterprise domain that requires proxy to access the Internet resources).
Things are a bit easier with Powershell Core (PSCore) 6+ where
SkipCertificateCheck
was added to ease work with HTTPS resources. I think it should be analogous tocurl -k
on Linux.
nanoserver
While nanoserver
image looks attractive with it’s small (in Windows world) size, its shell options somewhat weak. The nanoserver
based on core 10.0.14393
(WS 2016) gives you a lean version of Powershell
(Powershell Core) and good ol’ CMD
. The Powershell Core (PSCore) has very limited set of commands and settings comparing to full version in servercore
. For instance, there is no [System.Net.ServicePointManager]::SecurityProtocol
setting available to tweak TLS version. Newer versions of nanoserver
have no PS shell as they are optimized for .NET Core
applications.
However, Microsoft maintains an image of nanoserver
which does include PSCore. If don’t feel like learning batch scripting and hacking your way through CMD
shell, I’d recommend to look into one of the mcr.microsoft.com/powershell images.
With PSCore 6+ one can request HTTPS resource like this:
iwr -SkipCertificateCheck -Uri 'https://repo.contoso.com'
Disable SSL/TLS certificate verification
There is no easy way to disable cert verification in Powershell. The only way I found to disable the check involves a script posted on stackoverflow post. While the script worked in servercore
image, it failed for me in nanoserver:10.0.14393.XXXX
image.
Couldn’t find a way around it in nanoserver
except for using PSCore 6+ where iwr
has a flag SkipCertificateCheck
.