Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add documentation to set up Hawkbit in HTTPS from server start #10

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
204 changes: 123 additions & 81 deletions hawkbit-https.md
Original file line number Diff line number Diff line change
@@ -1,131 +1,127 @@
# Deploying HTTPS on Hawkbit

In this document, we will see how to deploy https on Hawkbit and how to configure it on your
targets with FullMetalUpdate.
In this document, we will see how to set up HTTPS transactions on Hawkbit and how to configure it on your
targets. The final goal of this process is to make your OTA updates secure.

## Setting up the server

### Getting a certificate

Like every other HTTPS service, Hawkbit requires a signed certificate from a Certificate
Authority to comply with SSL protocols. We will not through how to get one, as there
plenty of resources already available on them. Hawkbit also requires the private key
linked to the certificate.
Authority to comply with SSL protocols.

**Warning:** this setup will not work with self-signed certificates. Please reach out to
us [on gitter][gitter] if you need to configure self-signed certificates.
The following lines will allow you to get a self signed certificate **suitable for test environments only**.

### Modifying the docker-compose
```
sudo apt-get update && sudo apt-get upgrade
sudo apt-get install openssh
openssl req -x509 -newkey rsa:4096 -keyout privateKey.pem -out certificate.crt -days 3650 -nodes
openssl pkcs12 -export -out keyStore.p12 -inkey privateKey.pem -in certificate.crt
```
You will need a passphrase for `privateKey.pem`, which we will denote as #key-passphrase, as well as an export password for the `keyStore.p12`, which we will denote as #p12-password.

Go to the cloud directory (`fullmetalupdate-cloud-demo`) and edit `docker-composer.yml`.
Go the `hawkbit:`, and change all the `8080` to `8443` in the `expose` and `ports`
subsections.
**Warning:** Password of `keyStore.p12` (ie, #p12-password) must be at least 6 characters long and contains letters AND numbers.

Exit, and restart the server using `./StopServer.sh` and `./StartServer.sh`. The server is
not yet configured for https.
You will then obtain a certificate `certificate.crt` (the public key is included into this certificate), a private key `privateKey.pem` and a pkcs12 binary `keyStore.p12`. This last one is a special kind of file storing cryptographic objects, in our case your certificate as well as your private key.

### Getting the server's CONTAINER ID
**Warning:** This setup will not work for production environments. Please reach out to
us [on gitter][gitter] if you need to configure proper certificates.

Before setting HTTPS up, you need to take note of the Hawkbit's server container id. You
must have run `./StartServer.sh` from the `fullmetalupdate-cloud-demo` directory.
**Coming soon:** Proper certificate generation with Let's Encrypt and certbot python tool.

Run this command:

```
docker ps -a
```
### Modifying the docker-compose

And take note of the `fullmetalupdate/hawkbit`'s CONTAINER ID. We will denote it as
`<hawkbit-id>` in this document.
Go to the cloud directory (`fullmetalupdate-cloud-demo`) and do :

### Setting up the certificates for Hawkbit
`git checkout add-https`

Hawkbit requires a single certificate file generated from the `pem` and the `key` files,
assuming that the `pem` file is the certificate, and the `key` file is the private key
linked to it.
This branch holds everything you need to set up Hawkbit to work with HTTPS. We will come back to this repo later.

First, create a [`p12` file][wiki_p12] from the last two file:
### Converting the `p12` file into a `jks` file

```
openssl pkcs12 -export -out cert.p12 -in CA.pem -inkey CA.key
```
`keytool`is a tool used to manage Java KeyStore (JKS) files.
JavaKeyStore objects are used by Hawkbit (note that Hawkbit client is written in Java) to manage certificates. We have to use it because Hawkbit does not seem to be able to deal with pkcs12 files.

`CA.pem` and `CA.key` are the certificate and the private key. Enter the private key's
passphrase, which we will denote as `<key-passphrase>` in this document, and type in the
export password, which we will denote as `<p12-password>`. **Warning**: this password must
be at least 6 character long, and contain letters and numbers.
Go in a the directoy where you generated `privateKey.pem`, `certificate.crt` and `keyStore.p12`.

This will create a `cert.p12` file. Copy this file to the currently running container :
You can now generate the jks file :

```
docker cp cert.p12 <hawkbit-id>:/opt/hawkbit/
sudo apt-get install keytool
keytool -importkeystore -srckeystore keyStore.p12 -srcstoretype pkcs12 \
-destkeystore keyStore.jks -deststoretype pkcs12 \
-alias 1 -deststorepass #p12-password
```

### Converting the `p12` file into a `jks` file
First, enter the destination keystore password : **this must be the same as #p12-password**. Then, enter the source keystore password : #p12-password.

The Hawkbit container embeds `keytool`, the tool used to manage the Java KeyStore (JKS).
This is what is used by Hawkbit to manage certificates.
You finally get a JKS file as `keyStore.jks`, which you can use to configure Hawkbit.

Run a shell in the container by executing:
### Building new docker image fullmetalupdate/build-yocto:v2.0

```
docker exec -it <hawkbit-id> /bin/sh
```
#### Configuring Hawkbit's options for SSL/TLS

Execute `ls`: you should see the `cert.p12` file generated above. Execute the following
command to convert the `p12` file into a `jks` file:

```
keytool -importkeystore -srckeystore cert.p12 -srcstoretype pkcs12 \
-destkeystore cert.jks -deststoretype pkcs12 \
-alias 1
```
Go to your FullMetalupdate local repo `dockerfiles` (or clone it on our Github) and configure `hawkbit/application.properties` file with the appropriate parameters.

First, enter the destination keystore password : **this must be the same as
`<p12-password>`**.
**1st solution : Use config.sh script**

Then, enter the source keystore password : `<p12-password>`.
Move your JavaKeyStore file to the `hawkbit` directory.

You can now exit the container by executing `exit`.
`mv /home/user/path/to/keyStore.jks hawkbit/`

### Setting up Hawkbit's options for SSL/TLS
Run `config.sh` script and give #p12-password when it is required.

Create an `application.properties` file which contains these parameters :
**2nd solution : By hand**

```
# UI demo account
1) UI demo account
hawkbit.server.ui.demo.password=admin
hawkbit.server.ui.demo.user=admin
hawkbit.server.ui.demo.tenant=DEFAULT

# User Security
2) User Security
security.user.name=admin
security.user.password=admin

# SSL/TLS Configuration
3) SSL/TLS Configuration
server.port=8443
hawkbit.artifact.url.protocols.download-http.protocol=https
hawkbit.artifact.url.protocols.download-http.port=8443
security.require-ssl=true
server.use-forward-headers=true
server.ssl.key-store=/opt/hawkbit/cert.jks
server.ssl.key-password=<p12-password>
server.ssl.key-store-password=<p12-password>
server.ssl.key-store=/opt/hawkbit/keyStore.jks
server.ssl.key-password=#p12-password
server.ssl.key-store-password=#p12-password
```
Don't forget to replace #p12-password accordingly.

Replace `<p12-password>` accordingly.

Copy this file the currently running container :
#### Setting up the build
You will need to generate a new docker image based on a Dockerfile specially written to set up HTTPS on Hawkbit. This step can take up to 1 hour depending on your computer.

```
docker cp application.properties <hawkbit-id>:/opt/hawkbit/
git clone https://github.com/FullMetalUpdate/dockerfiles.git
git checkout add-https
docker build -t "fullmetalupdate/hawkbit:v2.0" hawkbit/Dockerfile
```

This will replace the existing `application.properties`. If you already configured it
please `sh` into the container and append the previous content instead.
**Note:** When the container is running, you can access it by running `docker exec -it fullmetalupdate-cloud-demo_hawkbit_1 sh`. This will give you the hand on the container by opening a bourne shell inside the container.

At this point, the Hawkbit server is ready to be started.

Go to the cloud directory (`fullmetalupdate-cloud-demo`) and do :

`./StartServer`

Eventually if it is the first time you configure your target, you can lauch :

`./ConfigureServer`

Finally :

`firefox https://localhost:8443 &`

The server is all set up! One last step: stop the server (`./StopServer`) and start it
again (`./StartServer`). You can now connect to `https://<your-hostname>.local:8443`.
This last command will open the Hawkbit Web Client, working well in HTTPS! But your embedded target is not ready yet to support HTTPS OTA updates.

## Setting up the targets

Expand All @@ -136,42 +132,88 @@ Before proceeding further, **close any instanciation of the build-yocto docker**

1. Go to your Yocto directory (`fullmetalupdate-yocto-demo`)

1. Edit the `config.cfg.sample` and make the following changes :
2. Edit the `config.cfg` file and make the following changes :

* change `hawkbit_url_port` to `8443`
* change `hawkbit_ssl` to `true`

1. Exit, and execute `bash ConfigureBuild.sh`
3. Move your certificate (after renaiming it) into Yocto build container :

1. Execute `./Startbuild.sh fullmetalupdate-os`. It should build the fullmetalupdate
```
mv /path/to/certificate.crt /path/to/ca-certificates.crt
docker cp /path/to/ca-certificates.crt \
fullmetalupdate/hawkbit:v2.0:/data/yocto/build/tmp/fullmetalupdate-os/work/x86_65-linux/curl-native/7.69.1-r0/ recipe-sysroot-native/etc/ssl/certs
```

4. Modify a few things to leverage SSL/TLS security (our current certificate is self signed, and whether your browser, curl, or the HTTP API do not like it and fail to compile or execute beacuse of that) :

First, add `-k` option to `curl` bash command in `curl_post()` Yocto function in `build/yocto/source/meta-fullmetalupdate/classes/fullmetalupdae.bbclass` file.

Secondly, go to FMU client repo (`fullmetalupdate/`, a repo you can clone on FullMetalUpdate Github) and modify the source code in `fullmetalupdate.py`:
```
@@ -76,8 +76,8 @@ async def main():
logging.basicConfig(level=LOG_LEVEL,
format='%(asctime)s %(levelname)-8s %(message)s',
datefmt='%Y-%m-%d %H:%M:%S')
-
- async with aiohttp.ClientSession() as session:
+ connTCP = aiohttp.TCPConnector(verify_ssl=False)
+ async with aiohttp.ClientSession(connector=connTCP) as session:
client = FullMetalUpdateDDIClient(session, HOST, SSL, TENANT_ID, TARGET_NAME,
AUTH_TOKEN, ATTRIBUTES)
```

5. Execute `./Startbuild.sh fullmetalupdate-os`. It should build the fullmetalupdate
client again. Then you can flash the new image to your target, which will contain the
new settings.

1. After starting the target, you should see your device's IP in the target's
information panel
6. After starting the target, you should see your device's new IP in the target's information panel on Hawkbit Web Client, which we will denote as #IP.

7. To finish the deployment, you can use the `send-file` script furnished in FullMetalUpdate/dev-scripts to apply the modification done to FMU client source code.

`./send-file.sh fullmetalupdate.py #IP`

After this final step, you can start deploying your apps updates and OS updates as usual, but by benefiting from the security of HTTPS.

### Configuration on the already deployed target

> Note : these changes will be permanent only if you made the changes on the build system
> as described in the last section. Otherwise, the following changes will be lost on the
> as described in the last section. Otherwise, the following changes, made to the target, will be lost on the
> next OS update.

If you have already deployed your target and have remote access to it, please follow these
steps :

1. Remount `/usr` as read-write by executing: `mount -o remount,rw /usr`

1. Edit the configuration file by executing `vi
/usr/fullmetalupdate/rauc_hawkbit/config.cfg`
1. Edit the configuration file by executing `vi /usr/fullmetalupdate/rauc_hawkbit/config.cfg`

1. Make the following changes :

* change `hawkbit_url_port` to `8443`
* change `hawkbit_ssl` to `true`

1. Restart the FullMetalUpdate client by executing `systemctl restart fullmetalupdate`
1. go to FMU client repo (`fullmetalupdate/`, a repo you can clone on FullMetalUpdate Github) and modify the source code in `fullmetalupdate.py`:
```
@@ -76,8 +76,8 @@ async def main():
logging.basicConfig(level=LOG_LEVEL,
format='%(asctime)s %(levelname)-8s %(message)s',
datefmt='%Y-%m-%d %H:%M:%S')
-
- async with aiohttp.ClientSession() as session:
+ connTCP = aiohttp.TCPConnector(verify_ssl=False)
+ async with aiohttp.ClientSession(connector=connTCP) as session:
client = FullMetalUpdateDDIClient(session, HOST, SSL, TENANT_ID, TARGET_NAME,
AUTH_TOKEN, ATTRIBUTES)
```

1. After starting the target, you should see your device's new IP in the target's information panel, which we will denote as #IP.

1. To finish the deployment, you can use the send-file script furnished in fullmetalupdate/dev-scripts to apply the modification done to FMU client source code.

`./send-file.sh fullmetalupdate.py #IP`

1. You should see your device's IP in the target's information panel
You can verify with `journalctl -f | grep fullmetalupdate.sh` that your FMU client is working properly again, in HTTPS.


[wiki_p12]: https://fr.wikipedia.org/wiki/PKCS12
Expand Down