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

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

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

Ocelot microgateway hosted in IIS

Hi I was trying to implement ocelot for our experimental tests on dev.
Here is end-point of api that I want to reach by via ocelot. using 443 port for both of project.
but getting 502 bad gateway all the time.
end point => https://localhost/document/api/v1/Documents/XYZ
"ReRoutes": [
{
"DownstreamPathTemplate": "/document/api/v1/Documents/{name}",
"DownstreamScheme": "https",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 443
}
],
"UpstreamPathTemplate": "/apigateway/{name}/document",
"UpstreamHttpMethod": [ "Post" ],
"Priority": 0
}
],
"GlobalConfiguration": {
"BaseUrl": "https://localhost:443"
}
}
Microgateway alias name =>"apigateway"
Api alias name => "document"
In addition this I was able to debug on visiual studio but whenever I host both app on my local IIS getting 502 bad gateway
It appears that the configuration you have used is redirecting the request to the gateway itself, resulting in a circle.
i.e. the upstream call to the base URL of "localhost:443" is redirecting to the downstream "localhost:443" - the same.
Furthermore, the later versions of Ocelot appear to look for Routes in the configuration instead of ReRoutes documentation

How to configure ssl for API in kong

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.

Can't Connect to Service via Marathon-lb using DCOS

I recently went through the tutorial for load balancing apps in DCOS using marathon-lb (in the example they balance some nginx containers: https://dcos.io/docs/1.9/networking/marathon-lb/marathon-lb-advanced-tutorial/). I am trying to use this approach to internally load balance my own custom application. The custom app I am using is a play scala app. I have the internal marathon-lb set up and can successfully use it for the nginx container but when I try to use my own docker image I cannot get this to work. I start up my service with my custom image and I can access the service fine by using the IP and port that gets assigned to it (i.e. if the service gets deployed on 10.0.0.0 and is available on port 1234 then curl http://10.0.0.0:1234/ works as expected and I can also make my api calls as defined in my application routes). However, when I try to access the app through the load balancer (curl -i http://marathon-lb-internal.marathon.mesos:10002, where 10002 is the service port) then I get this message:
HTTP/1.0 503 Service Unavailable
Cache-Control: no-cache
Connection: close
Content-Type: text/html
<html><body><h1>503 Service Unavailable</h1>
No server is available to handle this request.
</body></html>
For reference, here is my json file I'm using to start my custom service:
{
"id": "my-app",
"container": {
"type": "DOCKER",
"docker": {
"image": "my_repo/my_image:1.0.0",
"network": "BRIDGE",
"portMappings": [
{ "hostPort": 0, "containerPort": 9000, "servicePort": 10002, "protocol": "tcp" }
],
"parameters": [
{ "key": "env", "value": "USER_NAME=user" },
{ "key": "env", "value": "USER_PASSWORD=password" }
],
"forcePullImage": true
}
},
"instances": 1,
"cpus": 1,
"mem": 1000,
"healthChecks": [{
"protocol": "HTTP",
"path": "/v1/health",
"portIndex": 0,
"timeoutSeconds": 10,
"gracePeriodSeconds": 10,
"intervalSeconds": 2,
"maxConsecutiveFailures": 10
}],
"labels":{
"HAPROXY_GROUP":"internal"
},
"uris": [ "https://s3.amazonaws.com/my_bucket/my_docker_credentials" ]
}
I had the same problem and found the solution here
marathon-lb health check failing on all spray.io containers
Need to add
"HAPROXY_0_BACKEND_HTTP_HEALTHCHECK_OPTIONS": " http-send-name-header Host\n timeout check {healthCheckTimeoutSeconds}s\n"
To your config so that the REST layer doesn't bark on the health check from marathon

How to attach pre-uploaded SSL cert to ELB in CloudFormation template?

I've been trying to attach a SSL certificate that I'm currently using for one of my Elastic Load Balancing Instances on a new Cloud Formation Template but each time I get:
Server Certificate not found for the key
And then the Cloudformation template starts to roll back at that point.
"Listeners" : [
{
"LoadBalancerPort" : "443",
"InstancePort" : "80",
"SSLCertificateId" : "start_certname_com",
"Protocol" : "HTTPS"
},...
Amazon is asking for the The ARN of the SSL certificate to use. and I believe this is correct since this is the exact string which appears in the dropdown of the current set up ELB which takes 443 to port 80 on the instances.
Am I missing something on my Listener?
You can derive the ARN for a certificate in CloudFormation with only the certificate name. No need to run a command line tool and hard code the value into your CloudFormation template.
"Parameters":{
"Path":{
"Description":"AWS Path",
"Default":"/",
"Type":"String"
}
}
...
"Listeners" : [
{
"LoadBalancerPort" : "443",
"InstancePort" : "80",
"SSLCertificateId" : {
"Fn::Join":[
"",
[
"arn:aws:iam::",
{
"Ref":"AWS::AccountId"
},
":server-certificate",
{
"Ref":"Path"
},
"start_certname_com"
]
]
},
"Protocol" : "HTTPS"
},...
This determines your account id with the {"Ref":"AWS::AccountId"} pseudo parameter and combines it with the other elements needed to form the ARN. Note that I'm using a variable called Path in case you've set a path for your certificate. If not the default of "/" works fine.
This solution was mentioned by #Tristan and is an extension of merrix143243's solution
I've actually figured out how to do this while waiting for the answer, you need to use the IAM CLI tools provided by amazon and then use the command
iam-servercertgetattributes -s certname
This will provide you a string like:
arn:aws:iam::123456789123:server-certificate/start_certname_com
This is the value you place in the "SSLCertificateId" value pair field
The setup instructions for the IAM command line tools (CLI) can be found at:
http://docs.aws.amazon.com/IAM/latest/CLIReference/Setup.html
Download the tool kit from aws here
http://aws.amazon.com/developertools/AWS-Identity-and-Access-Management/4143
All in all your final block will look like:
"Listeners" : [
{
"LoadBalancerPort" : "443",
"InstancePort" : "80",
"SSLCertificateId" : "arn:aws:iam::123456789123:server-certificate/start_certname_com",
"Protocol" : "HTTPS"
},...
Here's how you get the long cert name with the latest AWS CLI:
pip install awscli
aws iam list-server-certificates