2

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 :)

Métoule
  • 13,062
  • 2
  • 56
  • 84

1 Answers1

11

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:

Azure configuration blade

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
Métoule
  • 13,062
  • 2
  • 56
  • 84
  • Glad I could help! Note that this `Startup command` doesn't work yet for Azure functions, and we ended up using Dockerfiles. I've edited my answer to include this info if you need them. – Métoule May 19 '20 at 17:24
  • `RUN sed -i 's/SECLEVEL=2/SECLEVEL=1/g' /etc/ssl/openssl.cnf` made it! Thanks! – mike927 Jun 18 '20 at 15:44
  • @Métoule I've tried this solution for my Azure Linux web app without any luck. It's a .NET5 application. I've added a custom_startup.sh containing exactly the same information as you have suggested. The app runs and everything. When I go to bash and check if openssl.cnf has changed I see that it hasn't (cat cd /etc/ssl/openssl.cnf). Help? – solojuve1897 Mar 08 '21 at 15:48
  • @solojuve1897 I'm now using a Docker container, and still using ASP.NET Core 3.1, so I'm afraid I can't really help. Did you add the script as the startup command, as shown on the screenshot? – Métoule Mar 08 '21 at 16:12
  • @Métoule Yes, it's set as the startup command. Doesn't seem to make the change in the file for some reason. I don't want to go over to using docker images for my web app but maybe I have to if this doesn't work. – solojuve1897 Mar 08 '21 at 18:59
  • @Métoule; I got some error messages in the log: sed: can't read /etc/ssl/openssl.cnf : No such file or directory The commands aren't being executed except the last one which runs the application. I'm really bad using Linux. Is it a permissions issue or something? – solojuve1897 Mar 09 '21 at 08:18
  • 1
    Found the problem: I'm on a Windows-computer. One needs to convert the script to a unix-format. I used Dos2Unix. – solojuve1897 Mar 09 '21 at 09:24
  • This helped me connect a Debian container to a Windows 2012 server! – duyn9uyen Mar 25 '22 at 14:02
  • @Métoule could help to take look at : https://github.com/microsoft/azuredatastudio/issues/11249#issuecomment-1455376523 – Shawn Mar 06 '23 at 03:17