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

NOISSUE - Fix certs and vault deployment, reorganize and remove unnecessary vars #1368

Merged
merged 13 commits into from
Mar 2, 2021
16 changes: 8 additions & 8 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -150,10 +150,8 @@ MF_CERTS_SIGN_CA_PATH=/etc/ssl/certs/ca.crt
MF_CERTS_SIGN_CA_KEY_PATH=/etc/ssl/certs/ca.key
MF_CERTS_SIGN_HOURS_VALID=2048h
MF_CERTS_SIGN_RSA_BITS=2048
MF_CERTS_VAULT_HOST=
MF_CERTS_VAULT_PKI_PATH=pki_int
MF_CERTS_VAULT_ROLE=agent
MF_CERTS_VAULT_TOKEN=
MF_CERTS_VAULT_HOST=http://certs:8200


### Vault
MF_VAULT_HOST=vault
Expand All @@ -164,11 +162,13 @@ MF_VAULT_UNSEAL_KEY_3=
MF_VAULT_TOKEN=
MF_VAULT_CA_NAME=mainflux
MF_VAULT_CA_ROLE_NAME=mainflux
MF_VAULT_CA_DOMAIN_NAME=mainflux.com
MF_VAULT_PKI_PATH=pki
mteodor marked this conversation as resolved.
Show resolved Hide resolved
MF_VAULT_PKI_INT_PATH=pki_int
MF_VAULT_CA_CN=mainflux.com
MF_VAULT_CA_OU='Mainflux Cloud'
mteodor marked this conversation as resolved.
Show resolved Hide resolved
MF_VAULT_CA_ORG='Mainflux Company'
MF_VAULT_CA_COUNTRY=Serbia
MF_VAULT_CA_LOC=BG
MF_VAULT_CA_O='Mainflux Labs'
MF_VAULT_CA_C=Serbia
MF_VAULT_CA_L=Belgrade

### LoRa
MF_LORA_ADAPTER_LOG_LEVEL=debug
Expand Down
4 changes: 2 additions & 2 deletions certs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ To issue a certificate:

TOK=`curl -s --insecure -S -X POST http://localhost/tokens -H 'Content-Type: application/json' -d '{"email":"edge@email.com","password":"12345678"}' | jq -r '.token'`

curl -s -S -X POST http://localhost:8204/certs -H "Authorization: $TOK" -H 'Content-Type: application/json' -d '{"thing_id":<thing_id>, "rsa_bits":2048, "key_type":"rsa"}'
curl -s -S -X POST http://localhost:8204/certs -H "Authorization: $TOK" -H 'Content-Type: application/json' -d '{"thing_id":<thing_id>, "key_bits":2048, "key_type":"rsa"}'
```

```json
Expand Down Expand Up @@ -50,4 +50,4 @@ In this mode certificates can also be revoked:

```bash
curl -s -S -X DELETE http://localhost:8204/certs/revoke -H "Authorization: $TOK" -H 'Content-Type: application/json' -d '{"thing_id":"c30b8842-507c-4bcd-973c-74008cef3be5"}'
```
```
4 changes: 2 additions & 2 deletions certs/openapi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -120,14 +120,14 @@ components:
required:
- thing_id
- days_valid
- rsa_bits
- key_bits
properties:
thing_id:
type: string
format: uuid
days_valid:
type: string
rsa_bits:
key_bits:
type: integer

responses:
Expand Down
18 changes: 9 additions & 9 deletions cmd/certs/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,10 @@ const (
defSignHoursValid = "2048h"
defSignRSABits = ""

defVaultHost = ""
defVaultRole = "mainflux"
defVaultToken = ""
defVaultPKIPath = "pki_int"
defVaultHost = ""
defVaultRole = "mainflux"
defVaultToken = ""
defVaultPKIIntPath = "pki_int"
mteodor marked this conversation as resolved.
Show resolved Hide resolved

envPort = "MF_CERTS_HTTP_PORT"
envLogLevel = "MF_CERTS_LOG_LEVEL"
Expand Down Expand Up @@ -96,10 +96,10 @@ const (
envSignHoursValid = "MF_CERTS_SIGN_HOURS_VALID"
envSignRSABits = "MF_CERTS_SIGN_RSA_BITS"

envVaultHost = "MF_CERTS_VAULT_HOST"
envVaultPKIPath = "MF_CERTS_VAULT_PKI_PATH"
envVaultRole = "MF_CERTS_VAULT_ROLE"
envVaultToken = "MF_CERTS_VAULT_TOKEN"
envVaultHost = "MF_CERTS_VAULT_HOST"
envVaultPKIIntPath = "MF_VAULT_PKI_INT_PATH"
mteodor marked this conversation as resolved.
Show resolved Hide resolved
envVaultRole = "MF_VAULT_CA_ROLE_NAME"
envVaultToken = "MF_VAULT_TOKEN"
)

var (
Expand Down Expand Up @@ -231,7 +231,7 @@ func loadConfig() config {
signRSABits: signRSABits,

pkiToken: mainflux.Env(envVaultToken, defVaultToken),
pkiPath: mainflux.Env(envVaultPKIPath, defVaultPKIPath),
pkiPath: mainflux.Env(envVaultPKIIntPath, defVaultPKIIntPath),
pkiRole: mainflux.Env(envVaultRole, defVaultRole),
pkiHost: mainflux.Env(envVaultHost, defVaultHost),
}
Expand Down
16 changes: 8 additions & 8 deletions docker/addons/certs/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,19 +57,19 @@ services:
MF_CERTS_HTTP_PORT: ${MF_CERTS_HTTP_PORT}
MF_CERTS_SERVER_CERT: ${MF_CERTS_SERVER_CERT}
MF_CERTS_SERVER_KEY: ${MF_CERTS_SERVER_KEY}
MF_CERTS_SIGN_CA_PATH: ${MF_CERTS_SIGN_CA_PATH}
MF_CERTS_SIGN_CA_KEY_PATH: ${MF_CERTS_SIGN_CA_KEY_PATH}
MF_CERTS_SIGN_HOURS_VALID: ${MF_CERTS_SIGN_HOURS_VALID}
MF_CERTS_SIGN_RSA_BITS: ${MF_CERTS_SIGN_RSA_BITS}
MF_VAULT_TOKEN: ${MF_VAULT_TOKEN}
MF_VAULT_CA_NAME: ${MF_VAULT_CA_NAME}
MF_VAULT_CA_ROLE_NAME: ${MF_VAULT_CA_ROLE_NAME}
MF_VAULT_PKI_PATH: ${MF_VAULT_PKI_PATH}
MF_SDK_BASE_URL: ${MF_SDK_BASE_URL}
MF_SDK_THINGS_PREFIX: ${MF_SDK_THINGS_PREFIX}
MF_JAEGER_URL: ${MF_JAEGER_URL}
MF_AUTH_GRPC_URL: ${MF_AUTH_GRPC_URL}
MF_AUTH_GRPC_TIMEOUT: ${MF_AUTH_GRPC_TIMEOUT}
MF_CERTS_SIGN_CA_PATH: ${MF_CERTS_SIGN_CA_PATH}
MF_CERTS_SIGN_CA_KEY_PATH: ${MF_CERTS_SIGN_CA_KEY_PATH}
MF_CERTS_SIGN_HOURS_VALID: ${MF_CERTS_SIGN_HOURS_VALID}
MF_CERTS_SIGN_RSA_BITS: ${MF_CERTS_SIGN_RSA_BITS}
MF_CERTS_VAULT_TOKEN: ${MF_CERTS_VAULT_TOKEN}
MF_CERTS_VAULT_HOST: ${MF_CERTS_VAULT_HOST}
MF_CERTS_VAULT_PKI_PATH: ${MF_CERTS_VAULT_PKI_PATH}
MF_CERTS_VAULT_ROLE: ${MF_CERTS_VAULT_ROLE}
volumes:
- ../../ssl/certs/ca.key:/etc/ssl/certs/ca.key
- ../../ssl/certs/ca.crt:/etc/ssl/certs/ca.crt
Expand Down
30 changes: 26 additions & 4 deletions docker/addons/vault/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,27 @@ This is Vault service deployment to be used with Mainflux.

When the Vault service is started, some initialization steps need to be done to set things up.

## Configuration

| Variable | Description | Default |
| ------------------------- | ----------------------------------------------------------------------- | -------------- |
| MF_VAULT_HOST | Vault service address | vault |
| MF_VAULT_PORT | Vault service port | 8200 |
| MF_VAULT_UNSEAL_KEY_1 | Vault unseal key | "" |
| MF_VAULT_UNSEAL_KEY_2 | Vault unseal key | "" |
| MF_VAULT_UNSEAL_KEY_3 | Vault unseal key | "" |
| MF_VAULT_TOKEN | Vault cli access token | "" |
| MF_VAULT_PKI_PATH | Vault secrets engine path for CA | pki |
| MF_VAULT_PKI_INT_PATH | Vault secrets engine path for intermediate CA | pki_int |
| MF_VAULT_CA_ROLE_NAME | Vault secrets engine role | mainflux |
| MF_VAULT_CA_NAME | Certificates name used by `vault-set-pki.sh` | mainflux |
| MF_VAULT_CA_CN | Common name used for CA creation by `vault-set-pki.sh` | mainflux.com |
| MF_VAULT_CA_OU | Org unit used for CA creation by `vault-set-pki.sh` | Mainflux Cloud |
| MF_VAULT_CA_O | Organization used for CA creation by `vault-set-pki.sh` | Mainflux Labs |
| MF_VAULT_CA_C | Country used for CA creation by `vault-set-pki.sh` | Serbia |
| MF_VAULT_CA_L | Location used for CA creation by `vault-set-pki.sh` | Belgrade |


## Setup

The following scripts are provided, which work on the running Vault service in Docker.
Expand Down Expand Up @@ -42,18 +63,19 @@ Use 3 out of five keys presented and put it into .env file and than start the co

2. `vault-unseal.sh`

This can be run after the initialization to unseal Vault, which is necessary for it to be used to store and/or get
secrets.
This can be run after the initialization to unseal Vault, which is necessary for it to be used to store and/or get secrets.
This can be used if you don't want to restart the service.

The unseal environment variables need to be set in `.env` for the script to work.
The unseal environment variables need to be set in `.env` for the script to work (`MF_VAULT_TOKEN`, `MF_VAULT_UNSEAL_KEY_1`,
`MF_VAULT_UNSEAL_KEY_2`, `MF_VAULT_UNSEAL_KEY_3`).

This script should not be necessary to run after the initial setup, since the Vault service unseals itself when
starting the container.

3. `vault-set-pki.sh`

This script is used to generate the root certificate, intermediate certificate and HTTPS server certificate.
After it runs, it copes the necessary certificates and keys to the `docker/ssl/certs` folder.
After it runs, it copies the necessary certificates and keys to the `docker/ssl/certs` folder.

The CA parameters are obtained from the environment variables starting with `MF_VAULT_CA` in `.env` file.

Expand Down
2 changes: 1 addition & 1 deletion docker/addons/vault/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ volumes:

services:
vault:
image: vault:${MF_RELEASE_TAG}
image: vault:1.6.2
container_name: mainflux-vault
ports:
- ${MF_VAULT_PORT}:8200
Expand Down
2 changes: 1 addition & 1 deletion docker/addons/vault/vault-init.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/bash
set -euo pipefail

vault() {
Expand Down
36 changes: 19 additions & 17 deletions docker/addons/vault/vault-set-pki.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/bash
set -euo pipefail

scriptdir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
Expand All @@ -17,12 +17,12 @@ vault() {
}

vaultEnablePKI() {
vault secrets enable -path pki_${MF_VAULT_CA_NAME} pki
vault secrets tune -max-lease-ttl=87600h pki_${MF_VAULT_CA_NAME}
vault secrets enable -path ${NAME_PKI_PATH} pki
vault secrets tune -max-lease-ttl=87600h ${NAME_PKI_PATH}
}

vaultAddRoleToSecret() {
vault write pki_${MF_VAULT_CA_NAME}/roles/${MF_VAULT_CA_NAME} \
vault write ${NAME_PKI_PATH}/roles/${MF_VAULT_CA_NAME} \
allow_any_name=true \
max_ttl="4300h" \
default_ttl="4300h" \
Expand All @@ -31,36 +31,35 @@ vaultAddRoleToSecret() {

vaultGenerateRootCACertificate() {
echo "Generate root CA certificate"
vault write -format=json pki_${MF_VAULT_CA_NAME}/root/generate/exported \
common_name="\"$MF_VAULT_CA_DOMAIN_NAME CA Root\"" \
vault write -format=json ${NAME_PKI_PATH}/root/generate/exported \
common_name="\"$MF_VAULT_CA_CN CA Root\"" \
ou="\"$MF_VAULT_CA_OU\""\
organization="\"$MF_VAULT_CA_ORG\"" \
country="\"$MF_VAULT_CA_COUNTRY\"" \
locality="\"$MF_VAULT_CA_LOC\"" \
organization="\"$MF_VAULT_CA_O\"" \
country="\"$MF_VAULT_CA_C\"" \
locality="\"$MF_VAULT_CA_L\"" \
ttl=87600h | tee >(jq -r .data.certificate >data/${MF_VAULT_CA_NAME}_ca.crt) \
>(jq -r .data.issuing_ca >data/${MF_VAULT_CA_NAME}_issuing_ca.crt) \
>(jq -r .data.private_key >data/${MF_VAULT_CA_NAME}_ca.key)
}

vaultGenerateIntermediateCAPKI() {
echo "Generate Intermediate CA PKI"
export NAME_PKI_INT_PATH="pki_int_$MF_VAULT_CA_NAME"
vault secrets enable -path=${NAME_PKI_INT_PATH} pki
vault secrets tune -max-lease-ttl=43800h ${NAME_PKI_INT_PATH}
}

vaultGenerateIntermediateCSR() {
echo "Generate intermediate CSR"
vault write -format=json ${NAME_PKI_INT_PATH}/intermediate/generate/exported \
common_name="$MF_VAULT_CA_DOMAIN_NAME Intermediate Authority" \
common_name="$MF_VAULT_CA_CN Intermediate Authority" \
| tee >(jq -r .data.csr >data/${MF_VAULT_CA_NAME}_int.csr) \
>(jq -r .data.private_key >data/${MF_VAULT_CA_NAME}_int.key)
}

vaultSignIntermediateCSR() {
echo "Sign intermediate CSR"
docker cp data/${MF_VAULT_CA_NAME}_int.csr mainflux-vault:/vault/${MF_VAULT_CA_NAME}_int.csr
vault write -format=json pki_${MF_VAULT_CA_NAME}/root/sign-intermediate \
vault write -format=json ${NAME_PKI_PATH}/root/sign-intermediate \
csr=@/vault/${MF_VAULT_CA_NAME}_int.csr \
| tee >(jq -r .data.certificate >data/${MF_VAULT_CA_NAME}_int.crt) \
>(jq -r .data.issuing_ca >data/${MF_VAULT_CA_NAME}_int_issuing_ca.crt)
Expand Down Expand Up @@ -97,9 +96,9 @@ vaultSetupCARole() {
vaultGenerateServerCertificate() {
echo "Generate server certificate"
vault write -format=json ${NAME_PKI_INT_PATH}/issue/${MF_VAULT_CA_ROLE_NAME} \
common_name="$MF_VAULT_CA_DOMAIN_NAME" ttl="8670h" \
| tee >(jq -r .data.certificate >data/${MF_VAULT_CA_DOMAIN_NAME}.crt) \
>(jq -r .data.private_key >data/${MF_VAULT_CA_DOMAIN_NAME}.key)
common_name="$MF_VAULT_CA_CN" ttl="8670h" \
| tee >(jq -r .data.certificate >data/${MF_VAULT_CA_CN}.crt) \
>(jq -r .data.private_key >data/${MF_VAULT_CA_CN}.key)
}

vaultCleanupFiles() {
Expand All @@ -114,6 +113,9 @@ fi

readDotEnv

export NAME_PKI_PATH="${MF_VAULT_PKI_PATH}_${MF_VAULT_CA_NAME}"
export NAME_PKI_INT_PATH="${MF_VAULT_PKI_INT_PATH}_${MF_VAULT_CA_NAME}"

mkdir -p data

vault login ${MF_VAULT_TOKEN}
Expand All @@ -133,8 +135,8 @@ vaultCleanupFiles

echo "Copying certificate files"

cp -v data/${MF_VAULT_CA_DOMAIN_NAME}.crt ${MAINFLUX_DIR}/docker/ssl/certs/mainflux-server.crt
cp -v data/${MF_VAULT_CA_DOMAIN_NAME}.key ${MAINFLUX_DIR}/docker/ssl/certs/mainflux-server.key
cp -v data/${MF_VAULT_CA_CN}.crt ${MAINFLUX_DIR}/docker/ssl/certs/mainflux-server.crt
cp -v data/${MF_VAULT_CA_CN}.key ${MAINFLUX_DIR}/docker/ssl/certs/mainflux-server.key
cp -v data/${MF_VAULT_CA_NAME}_int.key ${MAINFLUX_DIR}/docker/ssl/certs/ca.key
cp -v data/${MF_VAULT_CA_NAME}_int.crt ${MAINFLUX_DIR}/docker/ssl/certs/ca.crt
cp -v data/${MF_VAULT_CA_NAME}_int_bundle.crt ${MAINFLUX_DIR}/docker/ssl/bundle.pem
Expand Down
2 changes: 1 addition & 1 deletion provision/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ Provision service has `/certs` endpoint that can be used to generate certificate
- `users_token` - users authentication token or API token
- `thing_id` - id of the thing for which certificate is going to be generated
```bash
curl -s -X POST http://localhost:8190/certs -H "Authorization: <users_token>" -H 'Content-Type: application/json' -d '{"thing_id": "<thing_id>", "rsa_bits":4096, "days_valid":"2400h" }'
curl -s -X POST http://localhost:8190/certs -H "Authorization: <users_token>" -H 'Content-Type: application/json' -d '{"thing_id": "<thing_id>", "key_bits":4096, "days_valid":"2400h" }'
```
```json
{
Expand Down