Putting AWS cloudfront in front of ec2 throws 502 error - ssl

I am trying to add SSL to my EC2 instance that hosts my API's in a node.js server by:
1) Provisioning a certificate from Certificate Manager
2) Putting Cloudfront in front of my EC2 instance
3) Adding record set in Route53
Before I actually added the record set in Route 53, I made a GET request via postman to my health check api
GET cloudfrontdistro.cloudfront.net/health
And the response was a 502 with the message
We can't connect to the server for this app or website at this time. There might be too much traffic or a
configuration error. Try again later, or contact the app or website owner.
Relevant details about my Cloudfront distro:
I used a Custom SSL Cert - the one that I got from ACM)
TLSv1.2_2018 security policy
Origin domain name is ec2-xx-xxx-xxx-xxx.compute-1.amazonaws.com
Minimum origin SSL protocol is TLSv1
Origin protocol policy is HTTPS Only
HTTP Port 80
HTTPS Port 443
Viewer Protocol Policy is Redirect HTTP to HTTPS
Allowed HTTP Methods are GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE
Any help would greatly be appreciated! TIA!

I have similar problem Please look at this (https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/cnames-and-https-requirements.html).. One of the domain names in the certificate must match the domain name that you specify for Origin Domain Name. If no domain name matches, CloudFront returns HTTP status code 502 (Bad Gateway) to the viewer.

Related

Invalid certificate for "localhost" on Cloudflared

I am running a web server (Wordpress) locally using XAMPP (using Apache) and forwarding it to my Cloudflare-hosted domain using a Cloudflared tunnel. I am having an issue with the certificate when connecting over my domain.
I have a certificate I received from Cloudflare which is valid for my domain installed in XAMPP's location for its certificate, and I know that it is being sent with the HTTPS result. Also, my "SSL/TLS encryption mode" on Cloudflare is "Full (Strict)".
When connecting from the browser, I get a 502 Bad Gateway error, and Cloudflared prints this error: error="Unable to reach the origin service. The service may be down or it may not be responding to traffic from cloudflared: x509: certificate is valid for *.example.com, example.com, not localhost where example.com is my domain.
If I go to
http://example.com or https://example.com, I get the above error.
http://localhost, the website loads but does not load any of the resources, since Wordpress loads the resources by querying the domain, https://example.com/path/to/resource.
https://localhost, the same as above happens, but Chrome also give me a warning that the certificate is not valid.
Here are the ingress rules in Cloudflared's config.yml.
ingress:
- hostname: ssh.example.com # I haven't gotten this one to work yet.
service: ssh://localhost:22
- hostname: example.com # This is the one having a problem.
service: https://localhost
- service: https://localhost
What I believe is happening is that Cloudflared receives the certificate which is valid for my domain (*.example.com, example.com) and then tries to execute the ingress rule by going to https://localhost, but the certificate is not valid for localhost. I don't think I should just get a certificate which is valid for localhost AND example.com. Do I need one certificate (valid for localhost) to be returned whenever http(s)://localhost is called and another (valid for example.com) that Cloudflared checks when it tries to execute an ingress rule involving example.com? If so, how do I do this?
I solved it by using the noTLSVerify option in Cloudflared's config.yml. When a client connects to my domain, it goes like this:
Client > Cloudflare > Cloudflared instance running on my machine > Origin (which also happens to be my machine: https://localhost)
The certificate sent back by the Origin was not valid for the address Cloudflared was accessing it from, localhost, but by adding these lines to config.yml,
originRequest:
noTLSVerify: true
I think Cloudflared does not check the certificate received from the origin, although it still returns the certificate to Cloudflare, which checks it against my domain.

Internal and external services running behind Traefik in Docker Swarm mode

I'm having some trouble finding any way to make my situation workable. I have 2 applications:
1: External service web application running on sub1.domain.com. If I run this application behind traefik with acme (LetsEncrypt) it works fine. I have a few more backend services (api/auth) that all run with a valid LetsEncrypt certificate and get their http traffic redirected to https by traefik
[entryPoints.http.redirect]
entryPoint = "https"
I have to have some form of http to https forwarding for this service.
2: Internal service web application running on sub2.domain.com. I have a self signed trusted certificate (internal CA) which works fine behind traefik if I set it as a default certificate, or if I use it in the application itself (inside tomcat). However, since it is an internal service I can live without ssl for this if it solves my problem. However, this does not work with traefik's http to https forwarding.
I have been trying to get these 2 services to run behind the same traefik instance but all the possible scenarios I could think of do not work because they are either still work in progress or just plain not working.
Scenarios
1: No http to https redirect, don't bother with https for the internal service and just use http. Then inside the backend for the external webservice redirect to https.
Problems:
Unable to have 2 traefik ports which traefik forwards too Unable to
forward 1 single port to another proto (since the backend is always
either http or https port)
Use ACME over the default cert
2: Use ACME over default certificate
someone else thought this was a good idea. It's just not working yet.
3: Re-use backend ssl certificate. Have traefik just redirect without "ssl termination". I'm not sure if this is the same thing but there is an option called "passTLSCert". However it seems that this is only possible with frontends defined in the .toml file which do not work (probably because I use docker for backends).
4: use DNS-01 challenge to create an SSL certificate for my internal service.
Sounds like this could work, so I'm now using CloudFlare and have an api key. However, it does not seem to work for subdomains. and there is no reply on my issue report: https://github.com/containous/traefik/issues/1953
EDIT: I might be able to fix the issue described in 4 to get this to work. It seems the internal DNS might be conflicting with traefik
Someone decided that on our internal DNS zones would be added per subdomain, meaning that the SOA request returned the subdomain as the name. This does not play nice with cloudflare since the internal dns zone is not the same as the cloudflare dns.
Changing this to a main zone with a records for the subdomains fixed the issue (in combination with the delayDontCheckDNS option).

Getting "IDX10108: The address specified is not valid as per HTTPS scheme" when calling IdentityServer4 in AWS

We've implemented an Identity Server using IdentityServer4 and have deployed it to AWS. It works great until we enabled https on the ELB. Now when the client tries to authenticate we get the following error:
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[0]
An unhandled exception has occurred while executing the request
System.InvalidOperationException: IDX10803: Unable to obtain configuration from: 'https://int.mycompany.com/.well-known/openid-configuration'. ---> System.ArgumentException: IDX10108: The address specified is not valid as per HTTPS scheme. Please specify an https address for security reasons. If you want to test with http address, set the RequireHttps property on IDocumentRetriever to false.
From what I've read the client is not happy with the certificate. This could possibly be related to the host name of the identity server and the name in the certificate. We have a valid wildcard certificate with subject "*.mycompany.com". We configured the client with Authority as "https://int.mycompany.com" so that seems to line up.
I've also read in these load balancing configuration that some headers have to be forwarded to the middleware but I'm not exactly sure how that would work.
Looks like HTTPS request are not recognized as such. Try to add the following settings into ConfigureServices method in the Startup class:
services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders = ForwardedHeaders.XForwardedProto;
});
From HTTP Headers and Elastic Load Balancing AWS documentation:
The X-Forwarded-Proto request header helps you identify the protocol (HTTP or HTTPS) that a client used to connect to your server. Your server access logs contain only the protocol used between the server and the load balancer; they contain no information about the protocol used between the client and the load balancer. To determine the protocol used between the client and the load balancer, use the X-Forwarded-Proto request header. Elastic Load Balancing stores the protocol used between the client and the load balancer in the X-Forwarded-Proto request header and passes the header along to your server.

Anyone mangaged to use google cloud loadbalancing from https to http?

I have set up an instance reachable on http.
I have set up an instance group containing that instance.
I have set up Loadbalancing using an self signed ssl cert.
The external IP of the LB and the instance can be reached.
The forwarding of the request from the LB runs into an time out.
The config for Loadbalancing says "you have 0 instances without errors, you have 1 instance with errors."
I don't see any log entries in the apache logs coming from the lb frontend.
There is no http connection from Google addresses showing up.
Any ideas where to look for or hints to a good guide (not the rather good google docu)?
Yes. You can use Compute Engine HTTPS load balancer with HTTP backend services. Select HTTP as Backend services protocol. For health check, use HTTP health check. Add GCE firewall rules to open tcp:80 for 130.211.0.0/22 and tcp:443 for 0.0.0.0/0 source IP ranges.

WL-Proxy-Client-Cert header not sent

I m using Oracle HTTP Server as reverse proxy for WebLogic. I have set up SSL on both the proxy and the server with client certificate authentication. It works and the clients get authenticated by OHS, but i need to pass client certificate information to WebLogic so i can look at this certificate in my servlet. Documentation says that the proxy can forward client certificate within "WL-Proxy-Client-Cert" http header to the WebLogic server.
However, i can't get this to work. Within my servlet i tried both request.getHeader() and request.getAttribute() and getting null. I looked at both headers and attributes of the request objects and don't see anything like WL-Proxy-Client-Cert. In fact i don't see any headers starting with WL, only couple of headers starting with X-WebLogic, none of which has the certificate.
I did enable "Client Cert Proxy Enabled" option in Administration Console as described in the docs. Also i know that clients get authenticated since i see the certificate requested by the browser, after which i can successfully access the site.
Am i missing something?
I have finally got an answer from Oracle support on this. The problem was that i had to add one SSL directive to my virtual host configuration:
SSLOptions +ExportCertData
It goes under "IfModule ossl_module", right next to "SSLVerifyClient require" directive that specifies 2-way authentication for the proxy.
Note that after this, in the servlet, the certificate will be present in the usual "javax.servlet.request.X509Certificate" attribute, as if the server was doing client certificate authentication itself (no extra headers are received).
Also, note that you can have the server use 1-way SSL, if you feel secure with authentication done by the proxy, and you will still receive the certificate in the attribute in your servlet (in this case you should probably add a filter as they recommend to ensure the requests come from the proxy only). I have a feeling it will work even if the server port is regular http, though i haven't tested it yet.