Trying to create a webhook subscription to an Event Grid topic fails with an error reported in the Azure portal:
Deployment has failed with the following error..."Webhook validation handshake failed for https://xxx.xxx.xxx.xxx:10443/event. Http POST request failed with response code Unknown
My webhook is a .NET core test app using a Kestrel server. I can see from logging that there is an incoming connection from Azure when I try to create the subscription, but this is immediately followed by a disconnect.
Microsoft.AspNetCore.Server.Kestrel: Debug: Connection id "0HMCE876DPTD6" accepted.
Microsoft.AspNetCore.Server.Kestrel: Debug: Connection id "0HMCE876DPTD6" started.
Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets: Debug: Connection id "0HMCE876DPTD6" received FIN.
Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets: Debug: Connection id "0HMCE876DPTD6" sending FIN because: "The client closed the connection."
Microsoft.AspNetCore.Server.Kestrel: Debug: Connection id "0HMCE876DPTD6" disconnecting.
Microsoft.AspNetCore.Server.Kestrel: Debug: Connection id "0HMCE876DPTD6" stopped.
It appears that there is an error during the TLS handshake. Are there any specific requirements for TLS for the webhook. I'm using the default certificate ("ASP.NET Core HTTPS development certificate"). This won't be trusted by Azure - is that a problem?
As per the documentation Using self-signed certificates for validation isn't supported. You need to use a signed certificate from a commercial certificate authority (CA) instead. You can also go through this troubleshooting document if it helps.
A little background:
I have a Tesla Powerwall which has it's own built in web server that can be accessed on the local network. It only allows SSL connections and uses a self signed certificate. I have setup port forwarding that allows me to connect to the web server remotely. For a while, i've had working node.js apps both on a local Pi and also a remote AWS instance that made requests to the Powerwall web server to retrieve bits of information.
Since yesterday, Tesla updated my Powerwall and now everything has stopped working. I can only assume they have changed something regarding how the web server handles it's self signed SSL certificate.
Firstly, my Pi running on the local network would not make successful node.js requests to the local server. I managed to get this working by adding an entry to my /etc/hosts file like this:
192.168.1.42 powerwall
and now my node.js app can successfully connect again using https://powerwall
When using Safari or Chrome to connect remotely, I can connect if I use my IP address (After trusting the self signed cert) but cannot connect when using my DDNS address that points to home. (I have confirmed the DDNS is working). It gives me the error:
Safari can’t open the page “https://home.xxxxxx.com:4444” because Safari can’t establish a secure connection to the server “ home.xxxxxx.com”.
My AWS node.js app will not connect regardless of me using the IP address or DDNS address giving me the error:
Client network socket disconnected before secure TLS connection was established
This is how I am trying to connect:
request({
url: 'https://xx.xx.xx.xx:xxxx/api/system_status/soe',
method: 'GET',
rejectUnauthorized: false,
requestCert: true,
agent: false,
headers: headers
}
I have tried adding:
secureProtocol: 'TLSv1_method'
and attempted with the methods TLSv1_method TLSv1_1_method TLSv1_2_method in case it needed a specific method, with no luck.
Does the above sound like the SSL settings on the server have been screwed down?
What can I do to:
a) access the site remotely through a browser using the DDNS address
b) force node.js to not be interested in the SSL certificate at all and just connect
----- EDIT
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
46:.....
Signature Algorithm: ecdsa-with-SHA256
Issuer: C=US, ST=California, L=Palo Alto, O=Tesla, OU=Tesla Energy Products, CN=335cbec3e3d8baee7742f095bd4f8f17
Validity
Not Before: Mar 29 22:17:28 2019 GMT
Not After : Mar 22 22:17:28 2044 GMT
Subject: C=US, ST=California, L=Palo Alto, O=Tesla, OU=Tesla Energy Products, CN=335cbec3e3d8baee7742f095bd4f8f17
Subject Public Key Info:
Public Key Algorithm: id-ecPublicKey
Public-Key: (256 bit)
pub:
04:ca...
ASN1 OID: prime256v1
NIST CURVE: P-256
X509v3 extensions:
X509v3 Key Usage: critical
Digital Signature, Key Encipherment
X509v3 Extended Key Usage:
TLS Web Server Authentication
X509v3 Basic Constraints: critical
CA:FALSE
X509v3 Subject Alternative Name:
DNS:teg, DNS:powerwall, DNS:powerpack, IP Address:192.168.90.1, IP Address:192.168.90.2, IP Address:192.168.91.1
With HTTPS, the domain needs to match what’s signed in the cert; it’s usually the public domain.
It’s not supposed to be the IP, and it certainly won't be the DDNS hostname (if I understood correctly) you’re pointing at it.
There are 3 possible approaches;
Add the certificate from the powerwall as a ‘known’ rootCA (as already suggested),
Tell node.js to skip checking the validity of the certificate, or
Try with HTTP 😬
Proper operation of the HTTPS connection process will also depend on you accessing the powerwall using the domain name registered in the certificate (which may require your DNS server to respond with the appropriate IP when the lookup is made ~> like DNS spoofing proof-of-concept for a CTF).
Also, to your musings in comments, while some browsers may allow you to override an expired or self-signed cert (or when connecting via IP), but it’s very sketchy to connect with a domain and get a cert that specifies and entirely different domain (which is why the browser might not even present you the option).
HTH
Post-resolution update:
How to get the DNS name to match what's on the certificate:
add an entry in the client system's /etc/hosts or equivalent
connect using the hostname (not the IP)
When connecting over public Internet:
How to get public-internet connections through to the local host:
get a public-facing HTTPS cert (e.g.) that matches your DDNS domain or /etc/hosts entry
Host a HTTP-proxy
relay requests from Internet (hopefully with filtering/validation) to the powerwall
(you will have 2 HTTPS connections: one from AWS -> proxy, one from proxy->powerwall)
Host a custom API that will return exactly the [minimum] info needed by the AWS service
How to trust a self-signed certificate? (this wasn't the blocking factor)
Try this for debugging:
openssl s_client \
-connect 192.168.1.42:4444 \
-CAfile /path/to/self-signed-cert \
-verify_hostname powerwall \
-debug
Can find more options in openssl s_client -help
Do you have any servers running on your home network (apache, nginx, etc)? You're probably trying to connect to https://my.ddns.com and you're passing it directly to powerwall, which has a certificate for powerwall.
Connecting to a host that returns a certificate which does not contain that hostname will cause a TLS error. You probably want to run a forward proxy, where your server hosts my.ddns.com, sets up the TLS connection and then forwards the traffic (without TLS) to 192.168.1.44.
I would like to run a mqtt client on a web browser using web sockets with HTTPS. With HTTP, I have no problem. Here is the code on the web browser when using HTTP.
<script>
var client = mqtt.connect( 'wss://127.0.0.1:3000', {username:'test_user', password:'test_password'} );
client.subscribe("mqtt/test");
client.on("message", function(topic, payload) {
alert([topic, payload].join(": "));
client.end();
});
client.publish("mqtt/test", "testing hello world!");
</script>
This is how I start the stand-alone mosca broker to use HTTPS on websockets.
mosca --very-verbose --key ./tls-key.pem --cert ./tls-cert.pem --credentials ./credentials.json --https-port 3000 --https-bundle --https-static ./ | pino
How should I change my mqtt client code on the browser to connect to the Mosca broker on websockets via HTTPS?
As discussed in the other questions you have asked, the web browser has it's own list of trusted CA certificates, your self signed certificate will not be in this list so the connection is going to fail.
You can import your own trusted certs into your browser, but how to do this differs with each browser and you have to do it for EVERY instance of the browser so only really useful for individual testing.
If you need to allow members of the public (or browsers you can't install your certificate on) to connect to your broker then you will have to get a certificate from a recognised CA. You will have to either pay for this or use a service like http://letsencrypt.org
You have problems due to the use of self-signed certificate
Instead - you can use:
service cloudflare as front (with https and wss in free plan). Read about cloud flare
Get Temporary sertificates from letsencrypt (has a free plans). Read about letsencrypt
Get Trusted paid certificate
I have a https client that is using ssl to connect to an apache server.
When the client try to connect to the apache server via https I got the following error:
SSL Library Error: 336151570 error:14094412:SSL routines:SSL3_READ_BYTES:sslv3 alert bad certificate Subject CN in certificate not server name or identical to CA!?
what could be the problem and how to solve it?
Subject CN in certificate not server name or identical to CA!?
Your certificate does not match the host nameyou access. Check your site against [SSLLabs](
https://www.ssllabs.com/ssltest/analyze.html).
I have a NoMachineNX server setup with the following status
./nxserver --status
NX> 161 Enabled service: nxserver.
NX> 161 Enabled service: nxd.
I am unable to connect to this NX server using my NoMachineNX client. The connection request stays at processing state with the message "Waiting for the desktop user to authorize your connection".
I have sudo privileges for the server. I had used the same credentials in the server and at the client.
"Waiting for the desktop user to authorize your connection".
As it says, someone on the server needs to authorize your connection. If it's yourself that's going to be difficult :-) then you should set the server configuration by unchecking the box'Require permission to let users connect'.