I tried to look around the forums regarding my issue but can’t really seem to solve it. I am currently trying to get TLS working with a basic station connection, but maybe I am misunderstanding the documentation.
Without any authentication basic station mode on my dragino LPS8 runs without issue, however I am now trying to get authentication, and keep running into a tls:bad certificate error. I generated the certs with chirpstack-certificates, made sure to add my network server as a host, and the hex encrypted text for the gateway uid CA inside chirpstack-gateway-bridge cert json config. I then assume that I would either put these same bridge certs into the gateway itself, or to use the cert gen when you add a gateway via the web interface, both of which don’t end up working. If someone could explain how each cert works and how they got it working that would be helpful.
So to add some more context, I am running everything inside docker. The compose file will stand up everything correctly and auto-generate the certs. I also make sure to add the network server ip to the list of hosts before the certs are generated. I tried connecting to mqtt via tls from the same certs generated for the gateway from a different host and that works fine, but I wanted to get the basic station working.
This is what the logs for the gateway (Dragino LPS8) looks like:
cert. version : 3
serial number : 02:76:73:C6:B9:FA:4D:36:C3:80:46:9A:ED:B5:64:65:48:5B:0D:82
issuer name : CN=Chirpstack CA
subject name : CN=Chirpstack CA
issued on : 2025-06-10 14:24:00
expires on : 2030-06-09 14:24:00
signed using : RSA with SHA-256
RSA key size : 2048 bits
basic constraints : CA=true
key usage : Key Cert Sign, CRL Sign
2025-06-10 14:31:03.987 station[AIO:INFO] /etc/station/tc.crt:
cert. version : 3
serial number : 12:4E:AA:39:E6:88:83:B4:45:6E:66:83:99:C8:CA:47:00:6E:31:00
issuer name : CN=Chirpstack CA
subject name : CN=a840411fa6044150
issued on : 2025-06-10 14:29:43
expires on : 2026-06-10 21:12:55
signed using : RSA with SHA-256
EC key size : 256 bits
subject alt name :
dNSName : a840411fa6044150
key usage : Digital Signature
ext key usage : TLS Web Clien�2025-06-10 14:31:03.987 station[TCE:INFO] Connecting to INFOS: wss://192.168.200.223:3001
2025-06-10 14:31:04.012 station[AIO:INFO] TLS server certificate verification failed: The certificate Common Name (CN) does not match with the expected CN
2025-06-10 14:31:04.013 station[AIO:DEBU] [8] WS connection shutdown...
2025-06-10 14:31:04.014 station[TCE:INFO] INFOS reconnect backoff 30s (retry 3)
And inside the docker container I have an error of:
chirpstack-gateway-bridge-basicstation-1 | 2025/06/10 14:32:14 http: TLS handshake error from 172.22.0.1:41022: remote error: tls: bad certificate
I tried to change Chirpstack CA to my network server ip, 192.168.200.223, but no matter what I do I still get the Common Name (CN) does not match.
When i use openssl verify -CAfile ca.pem tls.pem it also comes back as ok.
Any ideas? I’m sure that I am missing something, but obviously can’t seem to find it.
Would you mind sharing the certificate overviews, like the you already shared for the CA, of both the gateway’s and the gateway bridge’s certificate? Might be able to to tell whats wrong from that.
Also FYI I have read about issues for Chirpstack basicstation TLS generally. But I don’t think that’s this.
Hi zosre,
i am having the same issue as you describe it. My environment is diffrent (debian 12 into proxmox vm) but the result is identical.
I followed the instructions exactly, but I can’t get TLS to work. I suspect there’s something wrong, but despite checking several times, I’m not making any progress.
Thank you for replying, I saw the same error in this issue, but didn’t really see how it got resolved. I understand that in order for the gateway to connect with the bridge, the tls cert is supposed to contain the gateway eui. I also changed the CN of the CA to my server ip just to see if that would work, but still getting the same error.
In chirpstack-certificates/chirpstack-gateway-bridge/basicstation I have
{
"CN": "192.168.200.223", <- local server ip
"hosts": [
"127.0.0.1",
"localhost",
"192.168.200.223" <- local server ip
],
"key": {
"algo": "rsa",
"size": 2048
}
}
Then when running I would navigate to the gateway certificates page to generate certs for the gateway to connect. This is how the same error would come up.
...
cert. version : 3
serial number : 12:4E:AA:39:E6:88:83:B4:45:6E:66:83:99:C8:CA:47:00:6E:31:00
issuer name : CN=192.168.200.223
subject name : CN=a840411fa6044150 <- EUI of gateway
issued on : 2025-06-10 14:29:43
expires on : 2026-06-10 21:12:55
signed using : RSA with SHA-256
EC key size : 256 bits
subject alt name :
dNSName : a840411fa6044150
key usage : Digital Signature
ext key usage : TLS Web Clien�2025-06-10 14:31:03.987 station[TCE:INFO] Connecting to INFOS: wss://192.168.200.223:3001
2025-06-10 14:31:04.012 station[AIO:INFO] TLS server certificate verification failed: The certificate Common Name (CN) does not match with the expected CN
2025-06-10 14:31:04.013 station[AIO:DEBU] [8] WS connection shutdown...
2025-06-10 14:31:04.014 station[TCE:INFO] INFOS reconnect backoff 30s (retry 3)
I assume there is something I am fundamentally misunderstanding about how certs work, I admit I am pretty new to security in general. Hopefully this provides the needed context to fix the problem.
could you please specify the source files you’re using?
That is, ca-csr.json, ca-config.json, and mqtt-server.json.
From my understanding, these files represent the basis of the configuration.
I would also like to see the contents of /etc/hosts.
I suspect we’re making a fundamental mistake there.
Best regards,
Dieter
Both my ca-csr.json and ca-config.json are left as default, my understanding is that the CN of the CA does not need to be changed to a specific IP. I did try changing them just to make sure that wasn’t the issue, and it does not help/solve anything. My mqtt-server.json is also the same as my certificate.json for the gateway, since they are all hosted on the same ip. Since its running on docker, /etc/hosts contains some docker dns and ips, but if I bind the gateway to 0.0.0.0 it still listens to the host ip I assume. I also tried running network_mode: host in the docker container on my Linux machine, but still getting the same error. I also see a similar issue raised here. I am really confused on what the issue could be, I mean I have exhaustibly made sure that the ip is correct, all of the certs are correctly generated, they can be verified with openssl s_client, but the actually connection seems to fail.
I had the same problem and I just found a solution for me. Instead of the IP, I gave the gateway and the certificate the name of the DNS that resolves the IP of the server. Hope is usefull.
This ended up being the way I solved it as well. I knew that self signed static ip certs are not standard at all, but I was just trying to get things started and then progress from there.
Anyway after a lot of headache, I used duckdns to create a host that would point to my local ip, setting up self certs via that hostname, and also having to put that record in the gateway /etc/hosts file. After that, it worked first try no problem, which is great but also a little frustrating because of the lack of distinct error logs.
So yea, quite literally the only issue was that I was using a static ip in the CN instead of a hostname. Everything starts up automatically via docker, generates certs, traefik hosts it on https, generating the certs from the webui, putting them into the gateway. I still think its possible, just maybe a security check within the dragino gateway and or how basics station works that didn’t want to complete the full transaction.
Now to tackle having my own DNS and using certbot!