I'm having trouble getting Amazon SNS to send a subscription message to my HTTPS endpoint. The CloudWatch logs report the following:
{
"delivery": {
"deliveryId": "7bdda6a5-0000-5d6d-b0c0-e9b254fde521",
"destination": "https://www.beta.yogacentre.com/webhooks/sns",
"providerResponse": "SSLPeerUnverifiedException in HttpClient",
"dwellTimeMs": 63661,
"attempts": 4
},
"status": "FAILURE"
}
It looks like it doesn't like the SSL certificate I'm using, but I confirmed that the root CA is on the list SNS checks. Chrome reports my connection uses TLS 1.2, so it should be compatible with the recent end of SSLv3 support.
As a sanity check I tried subscribing to a regular HTTP endpoint and it worked right away. What could be causing the problem? My certificate can be found at https://www.beta.yogacentre.com/ in case there is something I missed.
Have a look at the report for this site from SSLLabs and you will see:
This server's certificate chain is incomplete. Grade capped to B.
This means that the server is not properly setup in that it does not sent all needed chain certificates, i.e. everything in the trust path between the leaf certificate for the site and the root certificate trusted by the browser or system. Looking at the details you will see that the server sends only the leaf certificate and the missing certificate for "COMODO RSA Domain Validation Secure Server CA" is marked as "Extra Download".
While some browsers like Chrome will download missing certificates from the internet others don't and applications outside of browsers don't do it either. Thus all these clients which don't know the missing chain certificate will fail because they cannot build the trust chain, which causes the SSLPeerUnverifiedException you see. Therefore you need to fix your server configuration to also sent the missing chain certificates. Details depend on the server configuration.
Although the issue in your case turned out to be the certificate chain, there's another potential cause. As of writing, SNS callbacks don't support TLSv1.3 and will spit back this error if your endpoint only supports TLSv1.3. For the time being, the only way around this appears to be to enable TLSv1.2. I wasn't able to find any documentation notating this.
I encountered this issue with Cloudflare Universal SSL with the minimum version set to TLSv1.3. Changing the minimum version to TLSv1.2 resolved the issue.
Related
I'm working on a REST API that itself makes requests to another REST API -- basically, it provides a more convenient interface and also some extra functionality. Let's call my REST API X and the REST API to which my API calls Y.
Whenever I make requests to the endpoints of Y on my machine with cURL, REST Client, etc; all requests are successful. Like I mentioned, my API X is acting as a wrapper to Y, so when I upload my API to aws Lambda and create the respective endpoints in API Gateway, when I make a request to one of the endpoints I get this message:
Hostname/IP does not match certificate's altnames: Host:
X.execute-api.us-west-2.amazonaws.com. is not in the cert's altnames:
DNS:somehostname.com
So far, I have uploaded two lambdas with their respective endpoints, and the problem above only seems to be happening for one of the endpoints (the request to the other endpoint happens without problem).
I would like to know why this is happening and if this is a problem on my side? Meaning, is there something I am forgetting or something I can do -- except bypassing some security mechanism -- to fix this on my side? Whenever I make requests to the original API Y on my machine I'm not getting any errors so I'm a bit puzzled by this.
I think you're missing how SSL certificates work. Depending on how the certificate is setup for "API Y" you can't just connect to a different server and have it work. While you are conceptually a proxy to the real back end from the client perspective, you're a totally different host and the SSL certificate is for "API Y" only.
This is the same reason that you can't decide that you want to have an API named trustme.google.com - you don't have control over the google.com domain (presumably).
If there is a way to change the hostname that your client connections are using (to something like proxy.yourdomain.tld) then you can setup an SSL certificate for that domain and things should work. However, at that point you may run into CORS issues - post again if you have that issue.
AWS documents how to setup your own SSL certificate for API gateway. It's pretty easy though if you have an existing certificate you may need to use the AWS certificate manager to get a (free) certificate for your API.
Update 03/10/2022: Before your proxy hands off the request to the real backend service, make sure to set Host header to the hostname of the real service, see here.
I also developed a HTTP client -> APIG endpoint -> Lambda -> Host application, where the Lambda acts as a proxy between the client and the 3rd party Host. My Lambda is written in Node.js. I was getting this same exact error when the Lambda tried to invoke the 3rd party Host,
{
"statusCode": 500,
"body": "Hostname/IP does not match certificate's altnames: Host: zyxfghsk.execute-api.us-east-1.amazonaws.com. is not in the cert's altnames: DNS:*.somehost.com, DNS:somehost.com"
}
My setup uses Lambda Proxy integration with APIG, and I pass the set of HTTP headers from the client as-is to the 3rd party Host. I noticed the headers contained header Host: zyxfghsk.execute-api.us-east-1.amazonaws.com, which I think comes from the client. So in the Lambda code, right before passing the request to the 3rd party Host, I just simply delete the Host header from the request, and the problem went away. Another approach I was trying earlier, which also works, but not as ideal is that I was setting NODE_TLS_REJECT_UNAUTHORIZED=0 in the Node.js environment, which effectively disables SSL certificate validation by Node.js.
I believe, though not 100% certain, that in my case at least the error was getting thrown by Node.js certificate validation.
Update 03/10/2022: Before your proxy hands off the request to the real backend service, make sure to set Host header to the hostname of the real service, see here.
If I make a request to my Daphne/Django server in Postman or the Android app we're developing, Daphne serves the certificate, but it's rejected. If I first make a simple get request to https://letsencrypt.org/ and then make a request to my server, the certificate is accepted.
How can I make sure a client will trust my certificate, even if it's the first time this client is seeing a certificate issued by this CA?
Everything bellow can serve as a history of how I studied the problem.
Original title: SSL Certificate works in browser but can't be verified by Postman
I have an AWS EC2 instance running Ubuntu 18.04, with python 3, Django, a bunch of project dependencies, Daphne running with ASGI, with a certificate by Let's Encrypt. Daphne is using port 8000 for HTTP and por 4430 for HTTPS, iptables is configured to redirect requests from port 80 to 8000 and from port 443 to 4430. Django is configured to enforce secure connections with SECURE_SSL_REDIRECT=True in the settings.py file.
There's a "Site in Construction" temporary page being served, and it's properly accessible from every browser and every device I tested so far. If I explicitly type http, I get redirected to https and the certificate is accepted. Every browser I tested (Firefox, Brave, Chrome, Chrome for Android) says cert is good.
Curl outputs the HTML content returned from the server. I don't know if it accepts the certificate or ignores it.
The Problem
Postman, however, says "Error: unable to verify the first certificate". Only works when I disable "SSL certificate verification", which doesn't answer my question: why Postman is unable to verify my Let's Encrypt certificate?
I'm building an API that runs on the same server, using the same domain, and it's meant to be consumed by a mobile app. Currently, the Android app is throwing a "TypeError: Network request failed", which I suspect could be caused by the same thing Postman is complaining about.
When I spin the server locally and configure 1) the app to use http://localhost:8000 and 2) the server not to enforce SSL, it works in browsers, Postman and in the Android app.
I've being looking for answers in many places for days, so any clue will be very welcome.
EDIT
Interesting clue:
If I make a request to my Daphne/Django server, it servers the certificate, which is rejected. But if I first make a request to https://letsencrypt.org/ and then make a request to my server, it works!
This pattern holds true in both Postman and our Android app.
It also happens when I first make a request to https://alloy.city (instead of letsencrypt.org), which is served by a Node.js app, and uses a certificate also issued by the Let's Encrypt CA.
So maybe the question should be: how to configure my server to politely invite clients to add the CA that issued my certificate if they hadn't done it yet?.
Apparently, that's what my Node.js server does.
Yes, in settings, tap ssl verification off
File > Settings > General > SSL Certificate Verification > off
Background: I'm a complete newbie when it comes to certificates.
We have a site running at https://global.projacked.com
The certificate is issued by AWS.
All works well for most of our customers but...
One of them is experiencing the following:
And when I click on "view certificate" I see:
So the question is: can we do anything on our end to make this work?
If not: what can I tell my customer to do to make it work? Is it a question of them updating their certificate? Or might it be cause by them being in a secured network (e.g. VPN)?
Thank you immensely in advance for your help
Your site global.projacked.com is serving a valid SHA-256 certificate. The customer who has reported this issue appears to be having its HTTPS traffic intercepted and inspected by some sort of a MITM software or device (the Issuer -- apotex-CA -- on the certificate they're seeing gives it away). The MITMing entity is generating a certificate that is trusted by the customer's browser but it happens to be a SHA-1 certificate causing Chrome to complain.
You cannot do anything to fix their issue. A lot of MITM software vendors have released updates that create SHA-256 certificates to avoid situations such as this. They can probably check to see if there are updates they can install that generate SHA-256 certificates or read this or this to see if they really need to have TLS traffic intercepted and inspected. Sadly, I've seen organizations where the "solution" to this issue is to install an older version of Chrome that did not care about SHA-1 certificates and disable auto-update. After all, burying your head in the sand is very good at blocking all the noise about this little thing called security.
The certificate issuer should be able to issue a certificate under SHA-256. You'll then need to replace the certificate on the server.
Some certificate authorities can give you new cert as a re-issue of the old one, some will require CSR (Certificate Signing Request) that can be constructed based on the existing private key, which likely resides on the server too.
I am using echo_server_tls example with Chrome client. It works fine when I add the certificate to "Trusted Root Certificate Authorities" in certmgr. But if the certificate is not added there, the connection fails silently.
How can I ask user to accept my certificate in case of "Certificate Authority" error?
My OS is Windows 7
You can't do anything once the certificate error is encountered... it's a security feature. What you can do, however, is instruct users before they attempt to use your server that they must install your root certificate. One possible solution is to have them go to an "insecure" (unencrypted) site where the instructions are, then proceed to the "secure" site.
As a side note, buying a real "signed-by-well-known-authority" certificate is not difficult nor expensive... the cost is far less then the trouble of dealing with self-signed certificates in nearly all scenarios.
OK, solved the problem by setting an http handler using set_http_handler().
Thanks
I keep getting Connection Failed when trying to request data from a page that is on an https:// domain. I did install the ssl cert using the built-in section of the railo admin at https://[mydomain]/railo-context/admin/server.cfm?action=services.certificates however I still get Connection Failed. How should I go forward with debugging this? I have confirmed that this server in particular does have access to the domain I am trying to request from.
You probably need some additional certs installed as Jason has said. Take a close look at the cert and it's chain. Go to the cert issuers site and look for some documentation.
To troubleshoot you can add some logging to your jvm args. I think it's something like:
-Djavax.net.debug=all
The results are either in the OUT log or the server.log. This post on SSL 3.0 has some debugging tips. It's possible that your cert needs to handshake at a lower security level than CF allows (SSL 2.0 instead of 3.0/TLS for instance) and that could cause this behavior - but it's more likely that you simply need an intermediate cert installed.
The problem ended up being the permissions weren't setup properly on the machine. After we had the server administrator fix our permissions to access the Railo-Tomcat Service Control, the requests started working. I'm assuming he fixed some other permissions while he was in there.