How to configure ssl for API in kong - ssl

I'm working on kong 0.13.1. Following the docs I added certificate as follows:
{
"data": [
{
"cert": "certificate is really here",
"created_at": 1529667116000,
"id": "6ae77f49-a13f-45b1-a370-8d53b35d7bfd",
"key": "The key is really here",
"snis": [
"myapp.local",
"mockbin.myapp.local"
]
}
],
"total": 1
}
Then added an API which works perfectly well with http:
{
"data": [
{
"created_at": 1529590900803,
"hosts": [
"mockbin.myapp.local"
],
"http_if_terminated": false,
"https_only": false,
"id": "216c23c5-a1ae-4bef-870b-9c278113f8f8",
"name": "mockbin",
"preserve_host": false,
"retries": 5,
"strip_uri": true,
"upstream_connect_timeout": 60000,
"upstream_read_timeout": 60000,
"upstream_send_timeout": 60000,
"upstream_url": "http://localhost:3000"
}
],
"total": 1
}
But unfortunately Kong keeps sending me a default cert located in /usr/local/kong/ssl/kong-default.crt
I'm testing it with:
openssl s_client -connect localhost:8443/products -host mockbin.myapp.local -debug
Back in the days there was a dynamic ssl plugin (where api ssl was added with version 0.3.0) but it's gone since 0.10 update.
I know that it's kinda fix my code configuration question but possibly someone else might also run into similar issue.

I spent some time on figuring it out but I didn't manage to fix it. As kong docs say, api is deprecated so I ended up with rewriting everything to routes and services and I advise you to do the same. Routes and services work perfectly well when implementing step by step based on docs.

The Kong documentation seems clear on how to use the administrative api to configure ssl certificates. It is certainly easier to maintain the certificate at the global level, rather than service and route-specific administration.
Others looking for the answer to this question should find it straightforward, to follow the instructions in the latest Kong documentation linked above.

Related

Rate limit policy settings is not applied using AspNetCoreRateLimit

I am using AspNetCoreRateLimit version 4.0.1 and I have done all the setup in .net core 6 web api. I can see rate limit is working when I send a call via postman.
However, when I add IpRateLimitPolicies with specific IP address, the settings won't be applied.
I use postman and this time in the proxy I added the ip address to 127.0.0.1. I can see the ip hitting the api is set correctly when I use Request.HttpContext.Connection.RemoteIpAddress;
I registered them as follow in program.cs:
_serviceCollection.AddOptions();
_serviceCollection.AddMemoryCache();
_serviceCollection.Configure<IpRateLimitOptions>(builder.Configuration.GetSection("IpRateLimiting"));
_serviceCollection.Configure<IpRateLimitPolicies>(builder.Configuration.GetSection("IpRateLimitPolicies"));
_serviceCollection.AddInMemoryRateLimiting();
_serviceCollection.AddSingleton<IIpPolicyStore, MemoryCacheIpPolicyStore>();
_serviceCollection.AddSingleton<IRateLimitCounterStore, MemoryCacheRateLimitCounterStore>();
_serviceCollection.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
_serviceCollection.AddSingleton<IRateLimitConfiguration, RateLimitConfiguration>();
Also added:
app.UseIpRateLimiting();
My appsettings also looks like:
{
"IpRateLimiting": {
"EnableEndpointRateLimiting": false,
"StackBlockedRequests": false,
"RealIPHeader": "X-Real-IP",
"ClientIdHeader": "X-ClientId",
"IpWhitelist": [ ],
"EndpointWhitelist": [],
"ClientWhitelist": [],
"HttpStatusCode": 429,
"GeneralRules": [
{
"Endpoint": "*",
"Period": "10s",
"Limit": 1
}
]
},
"IpRateLimitPolicies": {
"IpRules": [
{
"Ip": "127.0.0.1",
"Rules": [
{
"Endpoint": "*",
"Period": "20s",
"Limit": 2
}
]
}
]
}
But apparently the settings under IpRateLimitPolicies won't be applied.
I wonder if I have missed anything here?
Thank you
After testing, I think the AspNetCoreRateLimit package is not compatible in .net5 and .net6. Maybe the .net core3.1 version will be more stable.
You can submit issues on github.
Apparently I have missed some configuration in program.cs or startup.cs:
https://github.com/stefanprodan/AspNetCoreRateLimit/issues/305
Since we are using startup I have added the following in Configure method
var ipPolicyStore = app.ApplicationServices.GetRequiredService();
ipPolicyStore.SeedAsync().GetAwaiter().GetResult();

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

Dynamic bridging with $BRIDGE/new

I followed instructions found here Mosquitto-Dynamic Bridging and here https://github.com/Tifaifai/mosquitto#to-dynamically-createdeleteshow-a-bridge-use about dynamic bridging in MQTT with Mosquitto.
The last link is the forked version of Mosquitto, but pull request 653 has been included into the main repo of Mosquitto.
So I tried to create my bridge, first with the Mosquitto configuration file. It is a success.
Then I tried to create the bridge dynamically by sending a message on the topic $BRIDGE/new as explained in the second link.
Here is the content:
connection myBridge
address IP_ADDRESS_OF_DISTANT_MOSQUITTO:1883
topic # both 0
remote_clientid myClientID
remote_username myUsername
remote_password myPassword
In fact, I just copied the content of the configuration file that worked fine.
Success? No.
So a I tried the JSON version of the message:
{
"bridges": [
{
"connection": "myBridge",
"addresses": [
{
"address": "IP_ADDRESS_OF_DISTANT_MOSQUITTO",
"port": 1883
}
],
"topic": "#",
"direction": "both",
"qos": 0,
"remote_username": "myUsername",
"remote_password": "myPassword"
}
]
}
Success? Also no.
I forgot something: I use v2.0.12 and v2.0.14 releases of Mosquitto.
Does someone as any clue to help me found the way of using dynamic bridging?
Thanks
If you look at the latest PR for this (https://github.com/eclipse/mosquitto/pull/1926) you can see that this is targeted at mosquitto v2.1.0 so it has not been merged into the master branch and released yet.
So it will not work with v2.0.x
PR 653 was not merged.

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

What are the steps to implement HTTPS with Google Cloud Containers?

Can’t find any resources that simply say here’s where your cert goes and here’s how to enable it. I have the cert there when I run gcloud compute ssl-certificates list. I have a cluster with kubernetes running and exposing http traffic via this service:
{
"kind": "Service",
"apiVersion": "v1",
"metadata": {
"name": "foo-frontend-service"
},
"spec": {
"selector": {
"app": "foo-frontend-rc"
},
"ports": [
{
"protocol": "TCP",
"port": 80,
"targetPort": 3009
}
]
}
}
Need to know how to put the cert in the right place to be utilized
Need to know how to reconfigure my service
Need to know what my new SSL endpoint will be. Is it the same?
K8s doesn't have special TLS support for the ordinary services. You need to use one of the following methods:
using Ingress: see http://kubernetes.io/docs/user-guide/ingress/#tls. You need to choose a Ingress controller which implements the Ingress functionalities, you can use GLBC if you are on GCE, or you can use the nginx one. Both of them supports TLS. Please note that the Ingress is still beta feature with limitations.
The service-loadbalancer in the contrib repo also supports tls: https://github.com/kubernetes/contrib/tree/master/service-loadbalancer#ssl-termination