xoseperez / basicstation-docker

Basics™ Station Packet Forward protocol using Docker
41 stars 8 forks source link

Send failed: X509 - Certificate verification failed #4

Closed chaudhariatul closed 1 year ago

chaudhariatul commented 1 year ago

While connecting RAK7371 to Things Stack running on a localhost in docker container these are the errors I get on the basicstation container.

The root certificate created while creating self-signed certificates is added to /usr/local/share/ca-certificates/ and sudo update-ca-certificates

I'm running this on a 64 bit raspibian on Raspberry Pi 4B with 8GB ram.

basicstation    | key usage  2022-08-12 05:32:20.606 [CUP:VERB] Retrieving update-info from CUPS https://192.168.0.247:443...
basicstation    | 2022-08-12 05:32:20.607 [CUP:DEBU] CUPS Request: {"router":"dca6:32ff:fec5:abba","cupsUri":"https://192.168.0.247:443","tcUri":null,"cupsCredCrc":3844209922,"tcCredCrc":2077607535,"station":"2.0.6(corecell/stdn) 2022-08-02 06:48:52","model":"corecell","package":null,"keys":[]}
basicstation    | 2022-08-12 05:32:20.619 [AIO:ERRO] [4] Send failed: X509 - Certificate verification failed, e.g. CRL, CA or signature check failed
basicstation    | 2022-08-12 05:32:20.619 [AIO:DEBU] [4] HTTP connection shutdown...
basicstation    | 2022-08-12 05:32:20.619 [CUP:INFO] Interaction with CUPS failed - retrying in 1m
basicstation    | 2022-08-12 05:32:20.619 [TCE:INFO] Starting TC engine
basicstation    | 2022-08-12 05:32:20.619 [TCE:ERRO] No TC URI configured
basicstation    | 2022-08-12 05:32:20.619 [TCE:INFO] Router rejected or retry limit reached. Invoking CUPS.
basicstation    | 2022-08-12 05:32:20.619 [TCE:INFO] Terminating TC engine
basicstation    | 2022-08-12 05:32:20.619 [CUP:INFO] Starting a CUPS session in 60 seconds.
xoseperez commented 1 year ago

Hi @chaudhariatul !

Not sure if you are already doing it like this but: since you are using CUPS you should define the CUPS_TRUST variable when creating your basicstation container (in the docker-compose.yml file, for instance). The content of the variable should be a one-liner of the root certificate, someting you can get by:

cat <path_to_ca.pem_file> | tr -d '\n'
chaudhariatul commented 1 year ago

Hi @xoseperez , yes I have tried as your document suggests to use the certificate in one line. I have also added the root certificate created from this step to the linux host where I'm running the basicstation.

https://www.thethingsindustries.com/docs/getting-started/installation/certificates/

xoseperez commented 1 year ago

Hi @chaudhariatul. The BasicStation container does not have access to its root certificates folder, s that step is unneeded. The error suggests the certificate is wrong. If you can login into the stack webUI without problem (after accepting the self-signed certificate) then they have been created right.Double check that you are correctly generating the one-line cert from the ca.pem file used in your The Things Stack instance. Also, check that you are accessing the The Things Stack instance using the hostname you used for the certificate, it should be the same hostname/IP you are using to access the UI.

chaudhariatul commented 1 year ago

Hi @xoseperez ,

That's correct. I used the ca.pem file in the docker-compose.yml file.

Is there a way to skip 'CN' verification or disable SSL check?

I'm still getting this error:


basicstation    | 2022-08-22 01:54:22.599 [SYS:INFO] Logging     : stderr (maxsize=10000000, rotate=3)
basicstation    | 2022-08-22 01:54:22.600 [SYS:INFO] Station Ver : 2.0.6(corecell/stdn) 2022-08-02 06:49:20
basicstation    | 2022-08-22 01:54:22.600 [SYS:INFO] Package Ver : (null)
basicstation    | 2022-08-22 01:54:22.600 [SYS:INFO] mbedTLS Ver : 2.28.0
basicstation    | 2022-08-22 01:54:22.600 [SYS:INFO] proto EUI   : e45f:1ff:fe92:2f6    (station.conf)
basicstation    | 2022-08-22 01:54:22.600 [SYS:INFO] prefix EUI  : ::1  (builtin)
basicstation    | 2022-08-22 01:54:22.600 [SYS:INFO] Station EUI : e45f:1ff:fe92:2f6
basicstation    | 2022-08-22 01:54:22.600 [SYS:INFO] Station home: ./   (builtin)
basicstation    | 2022-08-22 01:54:22.600 [SYS:INFO] Station temp: /var/tmp/    (builtin)
basicstation    | 2022-08-22 01:54:22.600 [SYS:WARN] Station in NO-CUPS mode
basicstation    | 2022-08-22 01:54:22.602 [RAL:DEBU] execvp argv[0]: </proc/self/exe>
basicstation    | 2022-08-22 01:54:22.602 [RAL:DEBU]        argv[1]: <-S>
basicstation    | 2022-08-22 01:54:22.603 [RAL:DEBU]        argv[2]: <(null)>
basicstation    | 2022-08-22 01:54:22.605 [S00:INFO] Logging     : stderr (maxsize=10000000, rotate=3)
basicstation    | 2022-08-22 01:54:22.605 [S00:INFO] Station Ver : 2.0.6(corecell/stdn) 2022-08-02 06:49:20
basicstation    | 2022-08-22 01:54:22.606 [S00:INFO] Package Ver : (null)
basicstation    | 2022-08-22 01:54:22.606 [S00:INFO] mbedTLS Ver : 2.28.0
basicstation    | 2022-08-22 01:54:22.606 [S00:INFO] proto EUI   : e45f:1ff:fe92:2f6    (station.conf)
basicstation    | 2022-08-22 01:54:22.606 [S00:INFO] prefix EUI  : ::1  (builtin)
basicstation    | 2022-08-22 01:54:22.606 [S00:INFO] Station EUI : e45f:1ff:fe92:2f6
basicstation    | 2022-08-22 01:54:22.606 [S00:INFO] Station home: ./   (builtin)
basicstation    | 2022-08-22 01:54:22.606 [S00:INFO] Station temp: /var/tmp/    (builtin)
basicstation    | 2022-08-22 01:54:22.606 [S00:INFO] Station slave: 0
basicstation    | 2022-08-22 01:54:22.606 [S00:WARN] Station in NO-CUPS mode
basicstation    | 2022-08-22 01:54:22.606 [S00:INFO] Slave LGW (0) - started.
basicstation    | 2022-08-22 01:54:22.602 [RAL:INFO] Master has started slave: pid=34 idx=0 (attempt 1)
basicstation    | 2022-08-22 01:54:22.802 [TCE:INFO] Starting TC engine
basicstation    | 2022-08-22 01:54:22.803 [AIO:INFO] ./tc.trust: 
basicstation    | cert. version     : 3
basicstation    | serial number     : 2F:64:54:79:96:FC:EC:F9:24:31:F6:36:CD:BD:74:79:43:6A:55:93
basicstation    | issuer name       : C=US, ST=CA, L=SJ, O=Tech, CN=Tech
basicstation    | subject name      : C=US, ST=CA, L=SJ, O=Tech, CN=Tech
basicstation    | issued  on        : 2022-08-22 01:47:00
basicstation    | expires on        : 2027-08-21 01:47:00
basicstation    | signed using      : ECDSA with SHA256
basicstation    | EC key size       : 256 bits
basicstation    | basic constraints : CA=true
basicstation    | key usage         : Key Cert Sign, CRL Sign
basicstation    | 2022-08-22 01:54:22.803 [TCE:INFO] Connecting to INFOS: wss://192.168.0.47:8887
basicstation    | 2022-08-22 01:54:22.838 [AIO:INFO] TLS server certificate verification failed: The certificate Common Name (CN) does not match with the expected CN
basicstation    | 2022-08-22 01:54:22.838 [AIO:DEBU] [4] WS connection shutdown...
basicstation    | 2022-08-22 01:54:22.838 [TCE:INFO] INFOS reconnect backoff 0s (retry 0)
basicstation    | 2022-08-22 01:54:22.838 [AIO:INFO] ./tc.trust: 
basicstation    | cert. version     : 3
basicstation    | serial number     : 2F:64:54:79:96:FC:EC:F9:24:31:F6:36:CD:BD:74:79:43:6A:55:93
basicstation    | issuer name       : C=US, ST=CA, L=SJ, O=Tech, CN=Tech
basicstation    | subject name      : C=US, ST=CA, L=SJ, O=Tech, CN=Tech
basicstation    | issued  on        : 2022-08-22 01:47:00
basicstation    | expires on        : 2027-08-21 01:47:00
basicstation    | signed using      : ECDSA with SHA256
basicstation    | EC key size       : 256 bits
basicstation    | basic constraints : CA=true
basicstation    | key usage         : Key Cert Sign, CRL Sign
basicstation    | 2022-08-22 01:54:22.839 [TCE:INFO] Connecting to INFOS: wss://192.168.0.47:8887
basicstation    | 2022-08-22 01:54:22.873 [AIO:INFO] TLS server certificate verification failed: The certificate Common Name (CN) does not match with the expected CN
basicstation    | 2022-08-22 01:54:22.873 [AIO:DEBU] [4] WS connection shutdown...
basicstation    | 2022-08-22 01:54:22.873 [TCE:INFO] INFOS reconnect backoff 10s (retry 1)
xoseperez commented 1 year ago

No, there is no way and I guess that's the point. It certainly looks like the IP you are using to access the TTS (192.168.0.47) is not the one the certificate was generated against. How are you accessing the TTS web UI? You could try using the same IP or domain name.

chaudhariatul commented 1 year ago

Hi @xoseperez ,

I created the certificates using cfssl and this as the cert.json. In the web ui in the browser I'm accessing using the same IP.

{
  "hosts": ["192.168.0.47"],
  "names": [
    {"C": "US", "ST": "CA", "L": "SJ", "O": "Tech"}
  ]
}

This maybe an issue with Thingstack open source: https://www.thethingsnetwork.org/forum/t/rak2287-with-open-source-stack-on-localhost/58561

xoseperez commented 1 year ago

Hi @chaudhariatul, sorry it took me some time to debug the issue. I found using an IP is somewhat limited on the options it offers. I had to tweak the way the certificate is being created. You can check how I am doing it here:

https://github.com/xoseperez/the-things-stack-docker/blob/b650dbf2673318c5e78d71b17a2a07ab50736e91/runner/entrypoint.sh#L115-L119

But, even this way not all combinations are working. This tables tries to summarize my tests, hope it can help you find a working approach:

BasicStation
configuration
If Common Name is
an IP
If Common Name is
a domain name
Using localhost: LNS1 OK OK
Using localhost: CUPS1 ERROR (Common Name mismatch) OK2
Using localhost: Web UI OK OK
Using IP: LNS ERROR (Common Name mismatch) ERROR (Common Name mismatch)
Using IP: CUPS ERROR (CA check fail) ERROR (CA check fail)
Using IP: Web UI OK OK3
Using domain name: LNS ERROR (Common Name mismatch) OK
Using domain name: CUPS ERROR (CA check fail) OK
Using domain name: Web UI OK4 OK
  1. Basicstation in the same machine as TTS and using network_mode host.
  2. Works only if the domain name resolves OK from the basicstation container (CUPS response redirects to wss://<domain_name>:8887)
  3. User gets redirected to https://<domain_name> after login, hence domain name must resolve to the IP.
  4. User gets redirected to https://<ip> after login, hence domain name must resolve to the same IP.

So:

  1. Using a domain name for your machine is the best option. Set certificate common name to that name. The name should resolve from the same machine and from the network that will be accessing the server. Use the same domain name everywhere.
  2. If you cannot have a domain name, you can use the IP of the machine as certificate common name. If your BasicStation container is in the same machine set it to network_mode host and use LNS pointing to wss://localhost:8887. CUPS does not work. This is OK for isolated standalone gateways (packet forwarder and network server).
chaudhariatul commented 1 year ago

@xoseperez I sincerely appreciate your efforts here!

I will definitely try this today and update you!

chaudhariatul commented 1 year ago

Hi @xoseperez I'm still getting the same error

basicstation    | 2022-08-28 03:58:05.460 [TCE:INFO] INFOS reconnect backoff 0s (retry 0)
basicstation    | 2022-08-28 03:58:05.460 [AIO:INFO] ./tc.trust: 
basicstation    | cert. version     : 3
basicstation    | serial number     : 21:94:0F:B3:7C:21:4F:C2:60:79:31:38:A1:2E:2A:97:8A:4F:3E:E1
basicstation    | issuer name       : C=ES, ST=Catalunya, L=Barcelona, O=TTN Catalunya, CN=192.168.0.247
basicstation    | subject name      : C=ES, ST=Catalunya, L=Barcelona, O=TTN Catalunya, CN=192.168.0.247
basicstation    | issued  on        : 2022-08-28 03:47:00
basicstation    | expires on        : 2027-08-27 03:47:00
basicstation    | signed using      : RSA with SHA-256
basicstation    | RSA key size      : 2048 bits
basicstation    | basic constraints : CA=true, max_pathlen2022-08-28 03:58:05.460 [TCE:INFO] Connecting to INFOS: wss://192.168.0.247:8887
basicstation    | 2022-08-28 03:58:05.481 [AIO:INFO] TLS server certificate verification failed: The certificate Common Name (CN) does not match with the expected CN
basicstation    | 2022-08-28 03:58:05.481 [AIO:DEBU] [4] WS connection shutdown...
basicstation    | 2022-08-28 03:58:05.482 [TCE:INFO] INFOS reconnect backoff 10s (retry 1)

Do you have any DNS service running on your raspberry? If yes What are the A records added?

xoseperez commented 1 year ago

I have a pi-hole running on the same network. Used that to assign a name to the raspberry under a domain of mine. It should resolve from your BasicStation container and from the PC you us to access the TTS.

lns.example.com A 192.168.0.247

And then use that same domain name in your ttn-lw-stack.yml file. If your basicstation container is in the same machine as the TTS, just use wss://localhost:8887 as your LNS server (set the container to network_mode host so localhost resolves to the host).

chaudhariatul commented 1 year ago

@xoseperez Perfect! That worked!

xoseperez commented 1 year ago

Great!! So good you finally made it work!

beitler commented 1 year ago

Just for future reference, there could be another approach to address the issue. LoRa Basics Station allows to disable the server name indication (SNI) check by setting the environment variable TLS_SNI=false. The SNI check is mostly needed when public CAs are used in your security architecture (as it is the case on the public TTN network, where the certificates are signed by Let's Encrypt). When you operate your own CA, then just checking the validity of the server certificate is enough in most scenarios. Hence, it is safe to set TLS_SNI=false whenever private CAs are used. Maybe you can give that a try?

xoseperez commented 1 year ago

Sure @beitler, will test it and update the docs. Thanks for sharing!

xoseperez commented 1 year ago

Tested all the scenarios where it was not working before and they all work with "TLS_SNI: false" in the environment section. Thanks again @beitler ! Will update the documentation now.