Execution of commands on an AWS Windows EC2 instance using pywinrm fails because WSMan AllowUnencrypted is set to False - python-3.x

I am trying to connect to a Windows EC2 instance and run some commands against it using pywinrm.
I am using the following code to create a session:
session = winrm.Session(ec2_instance.public_dns_name, auth=(user_name, password))
which works fine.
Now, when I use the session object created above to run a command like:
session.run_ps("hostname") or session.run_cmd("hostname") -> it fails with a timeout error because the firewall rules for WinRM ports 5985 and 5986 are not configured (The security group on AWS side has the ports open but the VM does not have it).
Once the inbound rule for ports 5985 and 5986 is configured on the EC2 instance, running any command fails with the following error:
Exception has occurred: InvalidCredentialsError the specified credentials were rejected by the server
I know that error message is misleading because the credentials are correct.
The reason I say that the credentials are correct because when I run the following from the EC2 instance:
Set-Item -Force WSMan:\localhost\Service\auth\Basic $true
Set-Item -Force WSMan:\localhost\Service\AllowUnencrypted $true
And then run the command using my code, it all works fine.
Now, what I am trying to find is, a way to enable the AllowUnencrypted value through my python code.
I have looked at using Kerberos but it seems like I need to create an AWS Managed Microsoft AD directory which will incur cost to my organization.
I have also tried to use NTLM like this:
protocol = Protocol(
endpoint=f"https://{ec2_instance.public_dns_name}:5985/wsman",
transport="ntlm",
username="Administrator",
password="Password",
server_cert_validation="ignore",
)
shell_id = protocol.open_shell()
But I get the following error:
HTTPSConnectionPool(host='ec2-x-x-x-x.us-west-2.compute.amazonaws.com', port=5985): Max retries exceeded with url: /wsman (Caused by SSLError(SSLError(1, '[SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1129)')))
Any help is appreciated.
Thanks

"HTTPSConnectionPool(host='ec2-x-x-x-x.us-west-2.compute.amazonaws.com', port=5985): Max retries exceeded with url: /wsman (Caused by SSLError(SSLError(1, '[SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1129)')))"
From your error, port 5985 is HTTP listener where as HTTPS should be port 5986.
Change endpoint port to 5986 and give a try "endpoint=f"https://{ec2_instance.public_dns_name}:5986/wsman","
Sorry I'm unable to add comment yet.

Here is the solution that worked for me:
Step 1:
Use AWS SSM to run commands on an EC2 instance. These commands will
Set WMan attributes Basic Authentication to True and AllowUnencrypted to True.
Create Windows Firewall Rules with ports 5985 and 5986.
Set-Item -Force WSMan:\localhost\Service\auth\Basic $true
Set-Item -Force WSMan:\localhost\Service\AllowUnencrypted $true
New-NetFirewallRule -DisplayName "Allow WinRM Ports" -Direction Inbound -Action Allow -Protocol TCP -LocalPort 5985-5986
I got help from here: How to execute commands on AWS Instance using Boto3
AMIs with SSM pre-installed: https://docs.aws.amazon.com/systems-manager/latest/userguide/sysman-install-ssm-win.html
Note: The commands can only be run on an EC2 instance if it has this IAM profile associated to it:
ARN = arn:aws:iam::<your_aws_account_id>:instance-profile/AmazonSSMRoleForInstancesQuickSetup
Name = AmazonSSMRoleForInstancesQuickSetup
This can be done using boto3 EC2 client method associate_iam_instance_profile()
Once the IAM is associated to the EC2 instance, it takes a minute or two to take this effect and get listed under describe_instance_information() method of boto3 ssm client.
Make sure to add a waiting method for your EC2 instance to be listed under the output of the above method before trying to run any command.
Step 2:
Use WinRM python library to bring EBS disk online, initialize, partition and format the disk.
Note: I could have used SSM to run the commands mentioned above but WinRM provides better output which can be converted to JSON and used for further validation.
Step 3:
Code to decrypt password for login:
from winrm.protocol import Protocol
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5
with open(private_key_file_path, "r") as key_file:
key_text = key_file.read()
key = RSA.importKey(key_text)
cipher = PKCS1_v1_5.new(key)
password = cipher.decrypt(base64.b64decode(password_data),None).decode("utf-8")

Related

az login error: Please ensure you have network connection. Error detail: HTTPSConnectionPool(host='login.microsoftonline.com', port=443)

Trying to install the Azure Devops CLI Extension
https://learn.microsoft.com/en-us/azure/devops/cli/?view=azure-devops
az extension add --name azure-devops
is the command I run
I get the following error message
Error Message
I have tried
git config http.sslVerify "false"
I've tried to do multiple azure cli and powershell commands
I've set my context with
Set-AzContext -Subscription "xxxx-xxxx-xxxx-xxxx"
I don't understand what the issue is here.
I've tried running the commands with and without the VPN ( I use Pulse VPN for reference)
I've tried setting powershell's execution policy to Undefined
**Set-ExecutionPolicy -ExecutionPolicy Undefined -Scope CurrentUser**
If someone could please let me know their thoughts on the specific error:
Please ensure you have network connection. Error detail: HTTPSConnectionPool(host='objects.githubusercontent.com', port=443): Max retries exceeded with url: /github-production-release-asset-2e65be/107708057/665228bd-d0c3-4865-b029-624cbc247ca1?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%2F20220701%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20220701T163308Z&X-Amz-Expires=300&X-Amz-Signature=dd9381d3d71deeb228b151ec41140e8238f425ca9bf2882889c6bc9592c782e6&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=107708057&response-content-disposition=attachment%3B%20filename%3Dazure_devops-0.25.0-py2.py3-none-any.whl&response-content-type=application%2Foctet-stream (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:997)')))
I've seen the post here Azure CLI Error and it was of no help
We have tried the same at our local to install the azure devops extension and it works successfully by following the MS DOC as given in question.
Here are the workaround we followed;
az login
Select-AzSubscription -Subscription subscriptionID
And it has been logged in successfully:-
After then installing az extension add --name azure-devops and it works.
Below are az --version we used ;
NOTE:- For the error make sure that you are using the latest version of az cli and enabled the port in your local (Windows security> Advance settings> Inbound Rule> add new rule then add your required port (443) and enable the same).
For configuration details here : How to open port in windows firwall .
For more information please refer the below links:-
Similar SO THREAD|Why Azure CLI login fails? "Connection actively refused" & az login command fails - Azure cli .
BLOG| MICROSOFT TECHNET .

Can't install azure cli extension : Error detail: HTTPSConnectionPool(host='objects.githubusercontent.com', port=443)

Trying to install the Azure Devops CLI Extension
https://learn.microsoft.com/en-us/azure/devops/cli/?view=azure-devops
az extension add --name azure-devops
is the command I run
I get the following error message
Error Message I have tried
git config http.sslVerify "false"
I've tried to do multiple azure cli and powershell commands
I've set my context with
Set-AzContext -Subscription "xxxx-xxxx-xxxx-xxxx"
I don't understand what the issue is here.
I've tried running the commands with and without the VPN ( I use Pulse VPN for reference)
I've tried setting powershell's execution policy to Undefined
Set-ExecutionPolicy -ExecutionPolicy Undefined -Scope CurrentUser
If someone could please let me know their thoughts on the specific error:
Please ensure you have network connection. Error detail: HTTPSConnectionPool(host='objects.githubusercontent.com', port=443): Max retries exceeded with url: /github-production-release-asset-2e65be/107708057/665228bd-d0c3-4865-b029-624cbc247ca1?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%2F20220701%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20220701T163308Z&X-Amz-Expires=300&X-Amz-Signature=dd9381d3d71deeb228b151ec41140e8238f425ca9bf2882889c6bc9592c782e6&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=107708057&response-content-disposition=attachment%3B%20filename%3Dazure_devops-0.25.0-py2.py3-none-any.whl&response-content-type=application%2Foctet-stream (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:997)')))
Normally, when executing the command line "az extension add --name azure-devops", it will go to the Azure DevOps CLI Extension GitHub Repo to download the latest release of the extension.
You can try to manually open the Azure DevOps CLI Extension GitHub Repo and download the extension on your browser:
If you also cannot manually access the GitHub Repo and download the extension, check whether there is any networking restriction or firewall set on your machine and the current network.
If you can manually access the GitHub Repo and download the extension, try to manually install the extension on your machine.

Fetch secrets and certificates from AzureKeyVault inside Docker container

I have a .net framework console application. Inside this application, I'm fetching secrets and certificates from keyvault using tenantId, client Id and Client Secret.
Application is fetching secrets and certificates properly.
Now I have containerized the application using Docker. After running the image I'm unable to fetch secrets and certificates. I'm getting below error:
" Retry failed after 4 tries. Retry settings can be adjusted in ClientOptions.Retry. (No such host is known.) (No such host is known.) (No such
host is known.) (No such host is known.)"
To resolve the error, please try the following workarounds:
Check whether your container was setup behind an nginx reverse proxy.
If yes, then try removing the upstream section from the nginx reverse proxy and set proxy_pass to use docker-compose service's hostname.
After any change make sure to restart WSL and Docker.
Check if DNS is resolving the host names successfully or not, otherwise try adding the below in your docker-compose.yml file.
dns:
- 8.8.8.8
Try removing auto generated values by WSL in /etc/resolv.conf and add DNS like below if above doesn't work.
# [network]
# generateResolvConf = false
nameserver 8.8.8.8
Try restarting the WSL by running below command as an Admin:
Restart-NetAdapter -Name "vEthernet (WSL)"
Try installing a Docker Desktop update as a workaround.
For more in detail, please refer below links:
Getting "Name or service not known (login.microsoftonline.com:443)" regularly, but occasionally it succeeds? · Discussion #3102 · dotnet/dotnet-docker · GitHub
ssl - How to fetch Certificate from Azure Key vault to be used in docker image - Stack Overflow

Running powershell/powercli scripts in VMware VCenter connection automation

I'm running a set of powerCLI scripts from Ubuntu to connect to VCenter do a bunch of configuration changes. Every script is invoked via SSH, so it is connecting and disconnecting to the VCenter everytime. This is rather time consuming, is it possible to setup powerCLI/powershell environment to connect to a VCenter automatically? Or, maintain a session of a powerCLI/powershell so remote connections can re-use it? One possibility is to use "screen" command to share the session, but i'm hoping someone has a more elegant idea.
You can use PowerCLI6.5.1 to do most of what you are asking. Install
from the PowerShell gallery.
Find the Module
Find-Module -Name VMware.PowerCLI
Install
Install-Module -Name VMware.PowerCLI –Scope CurrentUser
if you run into an error during installation I fixed it with AllowClobber "-AllowClobber" command
Import-Module VMware.PowerCLI
A couple of examples
Connect-VIServer "Server" -SessionId $sessionId
Connect to a server and save the session ID - $serverObject.SessionId You will be able to restore a existing server connection.
Connect-VIServer "Server" -User user -Password pass -SaveCredentials
Will save the credentials to the credential store. That way you can reuse them and they are encrypted.
See here for more info
https://blogs.vmware.com/PowerCLI/2017/04/powercli-install-process-powershell-gallery.html

Trouble deploying multiple HTTPS sites to single host in TFS 2015

I'm trying to deploy multiple websites to a single host running IIS from TFS 2015. I'm trying to have all sites use the "Server Name Indication Required" option so that they all can run under the same IP address. (This setup works fine in IIS if I manually set everything up -- my question / problem comes from deploying from TFS 2015).
The FIRST site in the deploy chain works fine, but the any subsequent one seems to fail with the following error:
System.Exception: SSL Certificate add failed, Error: 183 Cannot create a file when that file already exists.
Each of the sites I'm deploying has a different SSL certificate and I've imported them all properly to the Local Machine\Personal store.
A screenshot of the release definition with the "IIS Web App Management" task highlighted is shown below.
Any suggestions on how to resolve this error within the release definition so that I can deploy cleanly without manual intervention?
I guess one thing I could try is to do ALL of the IIS management steps from PowerShell but was hoping to use the tools a little more fully rather than rolling new scripts to do what it seems that they SHOULD be able to do natively.
Any insight is appreciated.
The error message will appear if you try to bind the certificate to a port which is already binded to this or another certificate.
You can try to set different ports for the sites.
You can also try adding a step (Command line/Powershell step) to delete the existing binding before next deploy step if that does not affect the sites.
eg:
$> netsh http delete sslcert ipport:1.1.1.1:443
Reference below articles to delete the binding:
How to: Configure a Port with an SSL Certificate
Remove an SSL certificate from your server
How to remove SSL bindings using powershell
I got things working - but I had to basically eliminate the binding configuration from the WinRM - IIS App Management tasks. I kept everything the same but specified NO binding information at all in those tasks, then added a target machine power shell script that looked like this (thumbprints and site domains changed):
Import-Module WebAdministration
if ($null -eq (Get-WebBinding | Where-Object {$_.BindingInformation -eq "*:443:iddev.mydomain.com"}))
{
New-WebBinding -Name "Identity-B2B" -Port 443 -Protocol "https" -HostHeader "iddev.mydomain.com" -SslFlags 1
New-Item -Path "IIS:\SslBindings\!443!iddev.mydomain.com" -Thumbprint "88E811B7A9417DACAAAAAAAAAA1C36AA0BA238FF1E0F" -SSLFlags 1
}
if ($null -eq (Get-WebBinding | Where-Object {$_.BindingInformation -eq "*:443:iddev.myotherdomain.com"}))
{
New-WebBinding -Name "Identity-B2C" -Port 443 -Protocol "https" -HostHeader "iddev.myotherdomain.com" -SslFlags 1
New-Item -Path "IIS:\SslBindings\!443!iddev.myotherdomain.com" -Thumbprint "BE38195A2BBBBBBBBBBBBBBB1C2AB5762C9" -SSLFlags 1
}

Resources