Azure Linux web app: change OpenSSL default security level? - azure

In my Azure Linux web app, I'm trying to perform an API call to an external provider, with a certificate. That call fails, while it's working fine when deploying the same code on a Windows app service plan. The equivalent cURL command line is:
curl --cert-type p12 --cert /var/ssl/private/THUMBPRINT.p12 -X POST https://www.example.com
The call fails with the following error:
curl: (58) could not load PKCS12 client certificate, OpenSSL error error:140AB18E:SSL routines:SSL_CTX_use_certificate:ca md too weak
The issue is caused by OpenSSL 1.1.1d, which by defaults requires a security level of 2, and my certificate is signed with SHA1 with RSA encryption:
openssl pkcs12 -in THUMBPRINT.p12 -nodes | openssl x509 -noout -text | grep 'Signature Algorithm'
Signature Algorithm: sha1WithRSAEncryption
Signature Algorithm: sha1WithRSAEncryption
On a normal Linux VM, I could edit /etc/ssl/openssl/cnf to change
CipherString = DEFAULT#SECLEVEL=2
to security level 1, but on an Azure Linux web app, the changes I make to that file are not persisted..
So my question is: how do I change the OpenSSL security level on an Azure web app? Or is there a better way to allow the use of my weak certificate?
Note: I'm not the issuer of the certificate, so I can't regenerate it myself. I'll check with the issuer if they can regenerate it, but in the meantime I'd like to proceed if possible :)

A call with Microsoft support led me to a solution. It's possible to run a script whenever the web app container starts, which means it's possible to edit the openssl.cnf file before the dotnet app in launched.
To do this, navigate to the Configuration blade of your Linux web app, then General settings, then Startup command:
The Startup command is a command that's ran when the container starts. You can do what you want, but it HAS to launch your app, because it's no longer done automatically.
You can SSH to your Linux web app, and edit that custom_startup.sh file:
#!/usr/sh
# allow weak certificates (certificate signed with SHA1)
# by downgrading OpenSSL security level from 2 to 1
sed -i 's/SECLEVEL=2/SECLEVEL=1/g' /etc/ssl/openssl.cnf
# run the dotnet website
cd /home/site/wwwroot
dotnet APPLICATION_DLL_NAME.dll
The relevant doc can be found here: https://learn.microsoft.com/en-us/azure/app-service/containers/app-service-linux-faq#built-in-images
Note however that the Startup command is not working for Azure Functions (at the time of writing May 19th, 2020). I've opened an issue on Github.
To work around this, I ended up creating custom Docker images:
Dockerfile for a webapp:
FROM mcr.microsoft.com/appsvc/dotnetcore:3.1-latest_20200502.1
# allow weak certificates (certificate signed with SHA1)
# by downgrading OpenSSL security level from 2 to 1
RUN sed -i 's/SECLEVEL=2/SECLEVEL=1/g' /etc/ssl/openssl.cnf
Dockerfile for an Azure function:
FROM mcr.microsoft.com/azure-functions/dotnet:3.0.13614-appservice
# allow weak certificates (certificate signed with SHA1)
# by downgrading OpenSSL security level from 2 to 1
RUN sed -i 's/SECLEVEL=2/SECLEVEL=1/g' /etc/ssl/openssl.cnf

Related

Git clone from gitlab fails on linux, while working in Windows git bash

I'm new to Linux, just installed Lubuntu and faced the problem -
when i'm trying to clone my remote work repo from my company's git:
$ sudo git clone https://path/to/repo.git
I keep on receiving error:
Cloning into 'repo'...
fatal: unable to access 'https://path/to/repo.git/': server certificate verification failed. CAfile: none CRLfile: none
I know it's mentioning certificates, but i do not have any. And before, i worked on windows and was able to simply git clone this repo without any certs.
This error means that the git client cannot verify the integrity of the certificate chain or root. The proper way to resolve this issue is to make sure the certificate from the remote repository is valid, and then added to the client system.
Update list of public CA
The first thing I would recommend is to simply update the list of root CA known to the system as show below.
# update CA certificates
sudo apt-get install apt-transport-https ca-certificates -y
sudo update-ca-certificates
This may help if you are dealing with a system that has not been updated for a long time, but of course won’t resolve an issue with private certs.
Fetch certificates, direct connection
The error from the git client will be resolved if you add the certs from the remote git server to the list of locally checked certificates. This can be done by using openssl to pull the certificates from the remote host:
openssl s_client -showcerts -servername git.mycompany.com -connect git.mycompany.com:443 </dev/null 2>/dev/null | sed -n -e '/BEGIN\ CERTIFICATE/,/END\ CERTIFICATE/ p' > git-mycompany-com.pem
This will fetch the certificate used by “https://git.mycompany.com”, and copy the contents into a local file named “git-mycompany-com.pem”.
Fetch certificates, web proxy
If this host only has access to the git server via a web proxy like Squid, openssl will only be able to leverage a squid proxy if you are using a version of OpenSSL 1.1.0 and higher. But if you are using an older version of OpenSSL, then you will need to workaround this limitation by using something like socat to bind locally to port 4443, and proxy the traffic through squid and to the final destination.
# install socat
sudo apt-get install socat -y
# listen locally on 4443, send traffic through squid "squidhost"
socat TCP4-LISTEN:4443,reuseaddr,fork PROXY:squidhost:git.mycompany.com:443,proxyport=3128
Then in another console, tell OpenSSL to pull the certificate from the localhost at port 4443.
openssl s_client -showcerts -servername git.mycompany.com -connect 127.0.0.1:4443 </dev/null 2>/dev/null | sed -n -e '/BEGIN\ CERTIFICATE/,/END\ CERTIFICATE/ p' > git-mycompany-com.pem
Add certificate to local certificate list
Whether by proxy or direct connection, you now have a list of the remote certificates in a file named “git-mycompany-com.pem”. This file will contain the certificate, its intermediate chain, and root CA certificate.
The next step is to have this considered by the git client when connecting to the git server. This can be done by either adding the certificates to the file mentioned in the original error, in which case the change is made globally for all users OR it can be added to this single users’ git configuration.
** Adding globally **
cat git-mycompany-com.pem | sudo tee -a /etc/ssl/certs/ca-certificates.crt
** Adding for single user **
git config --global http."https://git.mycompany.com/".sslCAInfo ~/git-mycompany-com.pem
Which silently adds the following lines to ~/.gitconfig
[http "https://git.mycompany.com/"]
sslCAInfo = /home/user/git-mycompany-com.pem
Avoid workarounds
Avoid workarounds that skip SSL certification validation. Only use them to quickly test that certificates are the root issue, then use the sections above to resolve the issue.
git config --global http.sslverify false
export GIT_SSL_NO_VERIFY=true
I know there is an answer already. Just for those who use a private network, like Zscaler or so, this error can occur if your rootcert needs to be updated. Here a solution on how this update can be achieve if using WSL on a Windows machine:
#!/usr/bin/bash
# I exported the Zscaler certifcate out of Microsoft Cert Manager. It was located under 'Trusted Root Certification > Certificates' as zscaler_cert.cer.
# Though the extension is '.cer' it really is a DER formatted file.
# I then copied that file into Ubuntu running in WSL.
# Convert DER encoded file to CRT.
openssl x509 -inform DER -in zscaler_cert.cer -out zscaler_cert.crt
# Move the CRT file to /usr/local/share/ca-certificates
sudo mv zscaler_cert.crt /usr/local/share/ca-certificates
# Inform Ubuntu of new cert.
sudo update-ca-certificates

.NET Core build in docker linux container fails due to SSL authentication to Nuget

I was given a .NET Core project to run in a Linux Docker container to do the build, everything seems to be okay on the docker configuration side, but when I run this command: dotnet publish -c Release -o out, I get the SSL authentication error below.
The SSL connection could not be established, see inner exception. Authentication failed because the remote party has closed the transport stream.
I did my research and apparently it seemed that I was missing:
the environment variables Kestrel for ASPNET (as per https://github.com/aspnet/AspNetCore.Docs/issues/6199), which I add to my docker-compose, but I don't think it is the issue.
a Developer .pfx certificate, so I updated my docker-compose with the Kestrel Path to the certs file as seen below.
version: '3'
services:
netcore:
container_name: test_alerting_comp
tty: true
stdin_open: true
image: alerting_netcore
environment:
- http_proxy=http://someproxy:8080
- https_proxy=http://someproxy:8080
- ASPNETCORE_ENVIRONMENT=Development
- ASPNETCORE_URLS=https://+;http://+
- ASPNETCORE_HTTPS_PORT=443
- ASPNETCORE_Kestrel__Certificates__Default__Password="ABC"
- ASPNETCORE_Kestrel__Certificates__Default__Path=/root/.dotnet/corefx/cryptography/x509stores/my
ports:
- "8080:80"
- "443:443"
build: .
#context: .
security_opt:
- seccomp:unconfined
volumes:
- "c:/FakePath/git/my_project/src:/app"
- "c:/TEMP/nuget:/root"
networks:
- net
networks:
net:
I re-run the docker container and executed dotnet publish -c Release -o out with the same results.
From my host I can do this to my local NuGet:
A) wget https://nuget.local.com/api/v2 without issues,
B) but from the container I can't.
C) However from the container I can do this to official NuGet wget https://api.nuget.org/v3/index.json, so definetely my proxy is working okay.
Debugging SSL issue:
The given .pfx certificate is a self-signed one, and it is working okay from Windows OS (at least I was told that).
strace shows me from where the certs are being pulled from as below
root#9b98d5447904:/app# strace wget https://nuget.local.com/api/v2 |& grep certs open("/etc/ssl/certs/ca-certificates.crt", O_RDONLY) = 3
I exported the .pfx as follows:
openssl pkcs12 -in ADPRootCertificate.pfx -out my_adp_dev.crt then moved it to /usr/local/share/ca-certificates/, removed the private part, just left in the file public part (-----BEGIN CERTIFICATE----- -----END CERTIFICATE----- ) executed update-ca-certificates and I could see 1 added, double checked in file /etc/ssl/certs/ca-certificates.crt and the new cert was in there.
Executed this again wget https://nuget.local.com/api/v2 and failed.
I used OpenSSL to get more info and as you can see it is not working, the cert has a weird CN, because they used a wildcard for the subject and to me this is wrong, but they state that .pfx is working in Windows OS.
root#ce21098e9643:/usr/local/share/ca-certificates# openssl s_client -connect nuget.local.com:443 -CApath /etc/ssl/certs
CONNECTED(00000003)
depth=0 CN = *.local.com
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 CN = *.local.com
verify error:num=21:unable to verify the first certificate
verify return:1
---
Certificate chain
0 s:/CN=\x00*\x00l\x00o\x00c\x00a\x00l\x00.\x00c\x00o\x00m
i:/C=ES/ST=SomeCity/L=SomeCity/OU=DEV/O=ASD/CN=Development CA
---
Server certificate
-----BEGIN CERTIFICATE-----
XXXXXXXXXXX
XXXXXXXXXXX
-----END CERTIFICATE-----
subject=s:/CN=\x00*\x00l\x00o\x00c\x00a\x00l\x00.\x00c\x00o\x00m
issuer=i:/C=ES/ST=SomeCity/L=SomeCity/OU=DEV/O=ASD/CN=Development CA
---
No client certificate CA names sent
Peer signing digest: SHA1
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 1284 bytes and written 358 bytes
Verification error: unable to verify the first certificate
---
New, TLSv1.2, Cipher is ECDHE-RSA-AES256-SHA384
Server public key is 1024 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1.2
Cipher : ECDHE-RSA-AES256-SHA384
Session-ID: 95410000753146AAE1D313E8538972244C7B79A60DAF3AA14206417490E703F3
Session-ID-ctx:
Master-Key: B09214XXXXXXX0007D126D24D306BB763673EC52XXXXXXB153D310B22C341200EF013BC991XXXXXXX888C08A954265623
PSK identity: None
PSK identity hint: None
SRP username: None
Start Time: 1558993408
Timeout : 7200 (sec)
Verify return code: 21 (unable to verify the first certificate)
Extended master secret: yes
---
I don't know what issue I'm facing, but it appears to be that:
A) the self-signed .pfx was wrongly configured, and now that it is being used in Linux it doesn't work as it should.
B) I need some more config in the container, which I'm not aware of.
What else should I do?
I'm thinking on probaly create other cert to use from Linux hosts.
Is it feasible to create another self-signed cert with OpenSSL for IIS ver 8 and import it to IIS?.
Any ideas are welcome, cheers.
ANSWERING TO MYSELF
It was not a Linux container issue, it is a certificate issue in the web server (IIS), because we are using self-signed certificates and in this way the cert will be always an invalid certificate. Self-signed certs works okay on Windows OS side, doesn't matter the invalid error. Of course self-signed certs are just for a test environment or so.
From Linux OS when you are trying to pull packages from NuGet you will get the error below, because:
1) The cert is indeed invalid, and
2) because apparently there is not an option to ignore an invalid certificate from Linux side.
The SSL connection could not be established, see inner exception.
The remote certificate is invalid according to the validation procedure.
The solution is you are working in a corporate environment, is to request to System Administrator a proper signed certificate, for that you generate a CSR from your web server, in my case IIS, then pass it to them, so they will send you back a .cer file to install in that web server.
The other option that I was trying to do but I couldn't due to the limitations of my corporate environment, is to create a fake CA (with OpenSSL), then you sign the CSR's yourself to have some valid certificates for your Dev or test environment.
Apologizes for answering this myself, but I believe it is worth to share my findings.
Hope it helps.
I had a similar problem. Docker build would not restore my nugets.
Unable to load the service index for source https://api.nuget.org/v3/index.json.
The SSL connection could not be established, see inner exception.
Authentication failed because the remote party has closed the transport stream.
(On a Mac running Catalina)
I turned off Fiddler and then it all worked again.

az login command fails - Azure cli

Installed Azure CLI on windows, ran az login command and running into following error
Version I am running is : 2.0.37
Azure cli 2.0 is written in python, it will verify ssl certificate when setting request. Make sure you don't have any proxy setting. I met same error when fiddler is running.
To work with proxy, we have to set REQUESTS_CA_BUNDLE env variable to certificate path. See related issue comment.
Make a complete example of fiddler.
Exported fiddler's certificate to desktop.
Tools -> Options, HTTPS tab, Actions -> Export Root Certificate to Desktop.
Use OpenSSL to convert to .pem file as Python doesn't accept .cer file.
openssl x509 -inform der -in FiddlerRoot.cer -out FiddlerRoot.pem.
Configure env variable in PS: $env:REQUESTS_CA_BUNDLE= '{folderpath}\FiddlerRoot.pem'
Then everything should work.
If you are using a command
az login
then it will try to take you though the browser and you have to provider your username and password there only.
If you want to login in the hell only then use
az login -u your_username -p your_password
This should work.
I was getting this with Azure CLI v2.3.2, what worked for me was copying the link it opened into a new incognito Chrome window and logging in as normal

Error connecting to Azure Virtual Network - Point to Site

I followed this tutorial to create a point-to-site connection:
https://learn.microsoft.com/en-us/azure/vpn-gateway/vpn-gateway-howto-point-to-site-resource-manager-portal
Now, when i try to connect the VPN I get this error:
A certificate could not be found that can be used with this Extensible Authentication Protocol. (Error 798)
It doesn't even work in the computer that I generated the self-signed cert. Neither it works in another client that I installed the pfx private key and fails in both with the same error.
Any ideas?
Ok turns out the document to create the certs are not complete here and not mentioning anything about the client cert and it just says how to create a root cert:
https://learn.microsoft.com/en-us/azure/vpn-gateway/vpn-gateway-certificates-point-to-site
Here is what I had to do to make it work:
Create root cert:
makecert -sky exchange -r -n "CN=AzureRootCert" -pe -a sha1 -len 2048 -ss My "AzureRootCert.cer"
Create client cert:
makecert.exe -n "CN=AzureClientCert" -pe -sky exchange -m 96 -ss My -in "AzureRootCert" -is my -a sha1
Then the rest is documented. so have to export the root cert and upload to Azure and then download the VPN tool.

Azure management certificate is not working

we create azure management certiicate both using "makecert" and using IIS7..And uploaded it in the azure site also.But noting seems to be working .Is there any other reason behind this?
API throws 403 errors.Powershell cmdlets throws Authentication failed error.
Working with different certificate file types and the various parameters to makecert can be a bit confusing. Ultimately, you need to upload a CER file (does not contain private key) to the management portal for management API authentication, and use a PFX (contains private key) for signing requests.
When you need to use SSL, you need to upload a PFX file to your hosted service via the management portal, the management API, or you can use a tool like one of Cerebrata's.
We use the following batch file to create our certificate files (replace CAPS_HERE text):
makecert -r -pe -a sha1 -n "CN=CERTIFICATE_NAME_HERE" -ss My -len 2048 -sp "Microsoft Enhanced RSA and AES Cryptographic Provider" -sy 24 CER_FILE_NAME_HERE.cer
makecert -r -pe -n "CN=CERTIFICATE_NAME_HERE" -sky exchange "CER_FILE_NAME_HERE.cer" -sv "PVK_FILE_NAME_HERE.pvk"
pvk2pfx -pvk "PVK_FILE_NAME_HERE.pvk" -spc "CER_FILE_NAME_HERE.cer" -pfx "PVK_FILE_NAME_HERE.pfx" -pi PASSWORD_HERE
Additionally, some links:
http://blogs.msdn.com/b/kaushal/archive/2010/11/05/ssl-certificates.aspx
http://www.lombard.me/2008/03/summary-of-x509-certificate-file-types.html
http://technet.microsoft.com/en-us/library/cc770735.aspx
Another alternative is to download a publishsettings file - this automatically configures a certificate public key in your azure subscription and downloads the cert to your machine.
You can use Get-AzurePublishSettingsFile to download a publishsettings file, or log in at:
https://manage.windowsazure.com/publishsettings/index?client=powershell

Resources