Make Kestrel use Ubuntu's self-signed certs - asp.net-core

Ubuntu already has self-signed certs, /etc/ssl/certs/ssl-cert-snakeoil.pem and /etc/ssl/private/ssl-cert-snakeoil.key
Is it possible to use those with a netcore app on Kestrel instead of generating a PFX?
If so, what's the required config?

Kestrel added support for pem files so you can specify them in configuration specifed here:
https://learn.microsoft.com/en-us/aspnet/core/fundamentals/servers/kestrel/endpoints?view=aspnetcore-6.0#replace-the-default-certificate-from-configuration-1
{
"HttpsInlineCertAndKeyFile": {
"Url": "https://localhost:5002",
"Certificate": {
"Path": "<path to .pem/.crt file>",
"KeyPath": "<path to .key file>",
"Password": "$CREDENTIAL_PLACEHOLDER$"
}
}
}

Related

ASP.NET Core (3.1) re-using IIS certificate in self-hosted (Kestrel) application

I have an ASP.NET Core (3.1) application which is self-hosted and running as a service. I would like to expose an HTTPS endpoint for it. On the same machine there is an IIS instaled with already configured https together with certificate:
The certificate seems to stored in local computer certificate store:
I can also list it via the powershell:
> get-childitem cert:\LocalMachine\My\ | format-table NotAfter, Subject
NotAfter Subject
-------- -------
27.10.2023 07:38:45 <irrelevant>
08.03.2022 09:52:44 CN=a7642e58-2cdf-4e9b-a277-60fad84d7c64, DC=3336d6b0-b132-47ee-a49b-3ab470a5336e
23.02.2022 21:51:53 CN=a7642e58-2cdf-4e9b-a277-60fad84d7c64, DC=3336d6b0-b132-47ee-a49b-3ab470a5336e
27.10.2031 06:48:06 CN=a7642e58-2cdf-4e9b-a277-60fad84d7c64
26.10.2024 10:41:03 E=****.com, CN=****, OU=IT, O=****, L=****, S=***, C=**
I changed the appsettings.json to use the certificate from the store:
{
"Logging": {
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Warning"
}
},
"AllowedHosts": "*",
"Kestrel": {
"EndPoints": {
"Http": {
"Url": "http://*:5000"
},
"HttpsDefaultCert": {
"Url": "https://*:5001"
}
},
"Certificates": {
"Default": {
"Subject": "E=****.com, CN=****, OU=IT, O=****, L=****, S=***, C=**",
"Store": "My",
"Location": "LocalMachine",
"AllowInvalid": "true"
}
}
}
}
However this does not seem to work. I always get the following error:
System.InvalidOperationException: The requested certificate E=****.com, CN=****, OU=IT, O=****, L=****, S=***, C=** could not be found in LocalMachine/My with AllowInvalid setting: True
I do not know what could be the problem. The only thing that I think might be problematic is that the certificate subject actually contains newlines in the subject:
I do not know if this is the problem and I do not know how to enter it in the appsettings.json as multiline values can not be entered.
I've managed to track down the issue. Kestrel uses FindBySubjectName when searching for certificate.
FindBySubjectName does a sub-string search and will not match the full Subject of the certificate. If your certificate subject is something like 'CN=my-certificate' then searching for 'CN=my-certificate' will not find anything. Searching only for 'my-certificate' will work.
Additional note: In addition to specifying the correct search expression, make sure that the account under which you are running the application has sufficient permissions to read the certificate from certificate store. Certificates do have ACL so you do not have to run your app as an administrator.
I refer to the documentation for configuring the SSL certificates for Asp.NetCore app running on Kestrel.
I noticed some URL and ports settings also get stored in Properties/LaunchSettings.json file.
See Here: Configure endpoints for the ASP.NET Core Kestrel web server
Further, I noticed that you have put the Certificate under Defaults. I found other ways to configure the certificate. You could try to test them.
In the following appsettings.json example:
Set AllowInvalid to true to permit the use of invalid certificates (for example, self-signed certificates).
Any HTTPS endpoint that doesn't specify a certificate (HttpsDefaultCert in the example that follows) falls back to the cert defined under Certificates:Default or the development certificate.
{
"Kestrel": {
"Endpoints": {
"Http": {
"Url": "http://localhost:5000"
},
"HttpsInlineCertFile": {
"Url": "https://localhost:5001",
"Certificate": {
"Path": "<path to .pfx file>",
"Password": "$CREDENTIAL_PLACEHOLDER$"
}
},
"HttpsInlineCertAndKeyFile": {
"Url": "https://localhost:5002",
"Certificate": {
"Path": "<path to .pem/.crt file>",
"KeyPath": "<path to .key file>",
"Password": "$CREDENTIAL_PLACEHOLDER$"
}
},
"HttpsInlineCertStore": {
"Url": "https://localhost:5003",
"Certificate": {
"Subject": "<subject; required>",
"Store": "<certificate store; required>",
"Location": "<location; defaults to CurrentUser>",
"AllowInvalid": "<true or false; defaults to false>"
}
},
"HttpsDefaultCert": {
"Url": "https://localhost:5004"
}
},
"Certificates": {
"Default": {
"Path": "<path to .pfx file>",
"Password": "$CREDENTIAL_PLACEHOLDER$"
}
}
}
}
Schema notes:
Endpoints names are case-insensitive. For example, HTTPS and Https are equivalent.
The Url parameter is required for each endpoint. The format for this parameter is the same as the top-level Urls configuration parameter except that it's limited to a single value.
These endpoints replace those defined in the top-level Urls configuration rather than adding to them. Endpoints defined in code via Listen are cumulative with the endpoints defined in the configuration section.
The Certificate section is optional. If the Certificate section isn't specified, the defaults defined in Certificates:Default are used. If no defaults are available, the development certificate is used. If there are no defaults and the development certificate isn't present, the server throws an exception and fails to start.
The Certificate section supports multiple certificate sources.
Any number of endpoints may be defined in Configuration as long as they don't cause port conflicts.
Reference: Replace the default certificate from configuration

Newman loads the pfx certificate but it is not used to connect to the endpoint

I'm having issue in execute a postman collection, from newman, which involves loading a pfx certificate to establish a TLSMA connection.
From the Postman application, the certificate is loaded correctly (from the setting) and used for the domain https://domain1.com to connect with a TLSMA counterpart server.
When I export the json collection and environment there is no mention about domain and certificate associated.
Checking the json schema here newman accepts a certificate definition in the request but applying it does not work, here my example:
"request": {
"method": "GET",
"header": [],
"certificate": {
"name": "Dev or Test Server",
"matches": ["https://domain1.com/*"],
"cert": { "src": "./certificate.pfx" }
},
"url": {
"raw": "https://domain1.com/as/authorization.oauth2",
"host": ["https://domain1.com"],
"path": ["as", "authorization.oauth2"],
"query": [
{
I also tried to apply the certificate configuration in an external file cert-list.json with the following content:
[{
"name": "Dev or Test Server",
"matches": ["https://domain1.com/*"],
"cert": { "src": "./certificate-t.pfx" }
}]
but it does not work either.
Here the newman command:
newman run domain.postman_collection.json -n 1 --ssl-client-cert-list cert-list.json -e env.postman_environment.json -r cli --verbose
Do you know where I am doing wrong?
Change cert to pfx
try:
[{
"name": "Dev or Test Server",
"matches": ["https://domain1.com/*"],
"pfx": { "src": "./certificate-t.pfx" }
}]

Self-Signed SSL certificate for local IP

Development certificate created by command dotnet dev-certs https --trust is works. I want to create a self-signed certificate for local IP in my LAN.
I've created a self-signed certificate by command:
New-SelfSignedCertificate -NotBefore (Get-Date) -NotAfter (Get-Date).AddYears(2) -Subject "192.168.1.100" -KeyAlgorithm "RSA" -KeyLength 2048 -HashAlgorithm "SHA256" -CertStoreLocation "Cert:\LocalMachine\My" -KeyUsage KeyEncipherment -FriendlyName "HTTPS development certificate" -TextExtension #("2.5.29.19={critical}{text}","2.5.29.37={critical}{text}1.3.6.1.5.5.7.3.1","2.5.29.17={critical}{text}DNS=192.168.1.100")
Then I copied certificate in trusted folder in certificates store:
After this I edited appsettings.Development.json:
"Kestrel": {
"Endpoints": {
"localhostHttp": {
"Url": "http://192.168.1.100:5000"
},
"localhostHttps": {
"Url": "https://192.168.1.100:5001",
"Certificate": {
"Subject": "192.168.1.100",
"Store": "Root",
"Location": "CurrentUser",
"AllowInvalid": true
}
}
}
But no result:
Is possible to create certificate like this?

Asp.net core not using the correct certificate

I am trying to understand how certificates work with asp.net 5.0. I have created a self signed certificate using PKI Client and installed it to the certificate store trusted root.
I have updated my Kestrel config as below
"Kestrel": {
"EndPoints": {
"Http": {
"Url": "http://localhost:5000"
},
"HttpsInlineCertStore": {
"Url": "https://*:5001",
"Certificate": {
"Subject": "pal.com",
"Store": "My",
"Location": "LocalMachine",
"AllowInvalid": "false" // Set to true to allow invalid certificates (e.g. self-signed)
}
}
}
}
When I run my server and browse to path https://pal.com:5001/ it complains about the certificate. It looks like the browser is using the asp.net core development certificate
I am new to asp.net and ssl. Am I missing anything here?
ok, I got this working. That was me doing things incorrectly, I added Kestrel config in launchSettings file rather than appsettings. It worked after moving the config to appsettings.json file

Terminating HTTPS on EC2 Instances Running Tomcat

I'm trying to enable HTTPS on my AWS EC2 instance that is being deployed using Elastic Beanstalk. The documentation to do this requires you to add this snippet in a directory .ebextensions/https-instance.config in the root directory of your app. I had to replace certificate file contents and private key contents with my certificate and key, respectively. I initially received an incorrect format error so I converted the snippet they provided to JSON and re-uploaded it -
{
"files": {
"/etc/httpd/conf.d/ssl.conf": {
"owner": "root",
"content": "LoadModule ssl_module modules/mod_ssl.so\nListen 443\n<VirtualHost *:443>\n <Proxy *>\n Order deny,allow\n Allow from all\n </Proxy>\n\n SSLEngine on\n SSLCertificateFile \"/etc/pki/tls/certs/server.crt\"\n SSLCertificateKeyFile \"/etc/pki/tls/certs/server.key\"\n SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH\n SSLProtocol All -SSLv2 -SSLv3\n SSLHonorCipherOrder On\n \n Header always set Strict-Transport-Security \"max-age=63072000; includeSubdomains; preload\"\n Header always set X-Frame-Options DENY\n Header always set X-Content-Type-Options nosniff\n \n ProxyPass / http://localhost:8080/ retry=0\n ProxyPassReverse / http://localhost:8080/\n ProxyPreserveHost on\n \n</VirtualHost>\n",
"group": "root",
"mode": "000644"
},
"/etc/pki/tls/certs/server.crt": {
"owner": "root",
"content": "-----BEGIN CERTIFICATE-----\ncertificate file contents\n-----END CERTIFICATE-----\n",
"group": "root",
"mode": "000400"
},
"/etc/pki/tls/certs/server.key": {
"owner": "root",
"content": "-----BEGIN RSA PRIVATE KEY-----\nprivate key contents # See note below.\n-----END RSA PRIVATE KEY-----\n",
"group": "root",
"mode": "000400"
}
},
"container_commands": {
"killhttpd": {
"command": "killall httpd"
},
"waitforhttpddeath": {
"command": "sleep 3"
}
},
"packages": {
"yum": {
"mod_ssl": []
}
}
}
The deployment aborts with the error -
[Instance: i-0x012x0123x012xyz] Command failed on instance. Return code: 1 Output: httpd: no process found. container_command killhttpd in my-app-name/.ebextensions/https-instance.config failed. For more detail, check /var/log/eb-activity.log using console or EB CLI.
I can tell that the error is being caused due to container_commands key which stops httpd after the configuration so that the new https.conf and certificate can be used. It tells me that it's trying to kill httpd but it can't find any such process running. service httpd status shows that httpd.worker (pid 0123) is running and I can also access my app online. /var/log/eb-activity.log also has nothing logged in it.
I've seen a few others post the same problem online but I could not find any solutions to it. Is there something that I'm doing wrong here?
You ebextensions is trying to execute killall httpd, but your process is called httpd.worker.
Change the line in the ebextensions to be killall httpd.worker.