Recently it was merged a really wonderful PR in the current main branch of NervesHub, that eases the self hosting setup and, I can confirm after test it, that it really eases the deployment. It is friendly and easy to manage.
It is part of the development of the NervesHub 2.0: Introducing NervesHub 2.0. Thus it is important to keep in mind that the documentation is also in progress of update, although the NervesHub team is doing a really great work with both parts, the development and the documentation about it and the deployment process.
So, thanks to this PR and the documentation about the self hosting setup provided in the readme of the repository, I got it deployed on my cloud server!
Now I am in the step of trying to link my Nerves devices to my NervesHub instance and, although I understand the theory and practically everything about the related and necessary stuff to use NervesHubLink, I feel bit lost with the certificates configuration. At this moment I am getting this error on the server side:
May 11 03:01:05 nerveshub nerves_hub[529627]: 03:01:05.118 level=notice TLS :server: In state :wait_cert received CLIENT ALERT: Fatal - Unknown CA
And this error with any mix task of NervesHub (for example, mix nerves_hub.ca_certificate list
):
$ mix nerves_hub.ca_certificate list
NervesHub server: nerveshub.DOMAIN.EXT:4001
NervesHub organization: ORG
13:45:47.397 [notice] TLS :client: In state :wait_cert at ssl_handshake.erl:2111 gener
ated CLIENT ALERT: Fatal - Unknown CA
Failed to list CA certificates
reason: {:error, {:tls_alert, {:unknown_ca, 'TLS client: In state wait_cert at ssl_han
dshake.erl:2111 generated CLIENT ALERT: Fatal - Unknown CA\n'}}}
In my environment variables I have NERVES_HUB_HOST
pointing to my instance, NERVES_HUB_PORT
as 4001, the one for the devices endpoint and then I have NERVES_HUB_KEY
and NERVES_HUB_CERT
with the key and cert generated in the NervesHub setup I did in the server. Of course, I also have a generated token for my user in NERVES_HUB_TOKEN
.
But I think the problem is that I am mixing concepts related with the certificates and I am configuring it in the wrong way. Letās see what I did in the NervesHub setup.
Before the deployment step I had to generate the certificates for my NervesHub instance, so I follow the next instructions, but of course adapted to my domain:
$ openssl genrsa -out ca.key 2048
$ openssl req -x509 -new -nodes -key ca.key -sha256 -days 1825 -out ca.pem -subj '/OU=NervesHub/'
$ openssl genrsa -out device.nerves-hub.org-key.pem
$ openssl req -new -key device.nerves-hub.org-key.pem -out device.nerves-hub.org.csr -subj '/CN=device.nerves-hub.org/'
$ nvim device.nerves-hub.org.ext
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = device.nerves-hub.org
$ openssl x509 -req -in device.nerves-hub.org.csr -CA ca.pem -CAkey ca.key -CAcreateserial -out device.nerves-hub.org.pem -days 825 -sha256 -extfile device.nerves-hub.org.ext
$ sudo mv device.nerves-hub.org-key.pem /etc/ssl/
$ sudo mv device.nerves-hub.org.pem /etc/ssl/
So I replaced all device.nerves-hub.org
by device.nerveshub.DOMAIN.EXT
(DOMAIN.EXT
is correct, I am just hiding it because I prefer to not have links to it). And in my nerves_hub.env
I have the next related with the host/ports for each endpoint, that I think is correct after read several times the instructions:
HOST=nerveshub.DOMAIN.EXT
PORT=4000
URL_SCHEME=https
URL_PORT=443
DEVICE_HOST=device.nerveshub.DOMAIN.EXT
DEVICE_PORT=4001
API_HOST=nerveshub.DOMAIN.EXT
API_PORT=4002
API_URL_PORT=443
And finally, in my Nerves device I added NervesHubLink package poiting to its git repository and specifying the branch nerves-hub-2.0
(I also tested it with main
and the latest version available in Hex). In config.exs
I set the next:
config :nerves_hub_link,
device_api_host: "nerveshub.DOMAIN.EXT",
device_api_port: 4001,
device_api_sni: "nerveshub.DOMAIN.EXT",
ssl: [
cert: "priv/ca.pem",
keyfile: "priv/ca.key",
]
cert: "priv/ca.pem"
corresponds with NERVES_HUB_CERT
and key: priv/ca.key
corresponds with NERVES_HUB_KEY
, generated with the previous openssl
commands in the server:
$ openssl genrsa -out ca.key 2048
$ openssl req -x509 -new -nodes -key ca.key -sha256 -days 1825 -out ca.pem -subj '/OU=NervesHub/'
And I know that I should provide cacerts
option too, but I am really lost with the certificates hehe.
My theory is:
- I am not understanding what cert, key and ca I must use in my Nerves device.
- I may be confused in the certificates generation step of NervesHub and I may be misunderstood something important for the step of linking a device with the hub.
This has become a long thread and probably quite confusing and with different problems, sorry about that hehe. I just hope someone can enlighten me in the darkness that I have been involved in with the certificates.
Edit: I am reading the next threads looking for a possible answer to my error/confusion: