forked from edgexfoundry/edgex-docs
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(sdk): HOW-TO enable remote device-service service via overlay ne…
…twork Demonstrate how to setup edgex in docker swarm and how to use an overlay network to provide encryption between contrainers. closes edgexfoundry#135 Signed-off-by: adam-w-mitchell <[email protected]>
- Loading branch information
1 parent
8766080
commit 656d841
Showing
2 changed files
with
221 additions
and
0 deletions.
There are no files selected for viewing
221 changes: 221 additions & 0 deletions
221
docs_src/microservices/security/Ch-Docker-Swarm-SecuringDeviceServices.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,221 @@ | ||
# Security for EdgeX Stack | ||
|
||
This page shows how to secure communication between core EdgeX services and various device services by utilizing docker swarm to create an encrypted overlay network between two hosts. We are showcasing two interesting concepts here. | ||
|
||
1) Securing the traffic between core and device services | ||
2) Setting up an EdgeX Stack cross platform using docker swarm | ||
|
||
## Docker Swarm Overlay Network | ||
|
||
Docker's overlay network driver is a software abstraction on top of physical networking hardware to link multiple nodes together in a distributed network. This allows nodes/containers running on the network to communicate securely, if encryption in enabled. | ||
|
||
We created two docker swarm nodes for this example a manager node and a worker node. The manager node is running all of the core EdgeX services and the worker node runs the device services. Using the docker daemon's overlay network abstraction and enabling security we can have secure communication between these nodes. | ||
|
||
![image](overlay-network.png) | ||
|
||
|
||
## Reference implementation example | ||
|
||
The reference implementation example can be found in this repository: | ||
[Reference example device-service docker-swarm overlay network](https://add-repo/README.md) | ||
|
||
### Setup remote running Virtual Machine | ||
|
||
In this example setup, similar to the the [SSH example](https://github.com/edgexfoundry/edgex-docs/blob/master/docs_src/microservices/security/Ch-SSH-Tunneling-HowToSecureDeviceServices.md), `vagrant` is used on the top of `Virtual Box` to set up the secondary/remote VM. | ||
|
||
Download vagrant from Hashicorp website or if you're on Ubuntu via `sudo apt install virtualbox` and `sudo apt install vagrant`. We have a simple vagrant file used for this tutorial [here](https://github.com/edgexfoundry/edgex-examples/blob/swarm/security/docker-swarm/ssh-tunneling/Vagrantfile) | ||
|
||
This vagrant file sets the hostname for the new VM and installs docker. | ||
|
||
### Getting the VM running | ||
|
||
- Launch the worker node or VM if it is not yet running: | ||
|
||
|
||
This will create the VM select your network interface and let the prompt continue. Once the prompt finishes, ignore the VMs popup window, we will be login in via SSH in the next step. | ||
|
||
```sh | ||
vagrant up | ||
``` | ||
|
||
- ssh into the worker node via from your host's terminal: | ||
|
||
```sh | ||
vagrant ssh | ||
``` | ||
|
||
This will give you a terminal prompt in the worker node where you will run the `sudo docker swarm join` command in a few steps. | ||
|
||
### Connecting the swarm nodes | ||
|
||
With the VM up and running we need to connect the two nodes using docker swarm. | ||
|
||
The following command initializes a docker swarm and is to be ran on the host machine: | ||
|
||
```sh | ||
sudo docker swarm init --advertise-addr <your host ip address> | ||
``` | ||
|
||
The previous command will output a token use this token in the following join command. This joins the worker node to the cluster, to be ran your vagrant VM (worker-node): | ||
|
||
```sh | ||
sudo docker swarm join --token <token> <manager ip address>:2377 | ||
``` | ||
|
||
Next, I will walk-through the changes we made to the docker-stack.yml file to convert the edgex compose file into a docker swarm stack file. | ||
|
||
### Setting up the docker-stack-edgex.yml file | ||
|
||
All of the following changes are already done in the examples repo. I will just outline the necessary changes to go from a compose file to stack file. | ||
|
||
First, remove 'restart' command from compose file; 'restart' is not a valid command in docker swarm. | ||
|
||
Next, we define constraints that the edgex core services must not run on the worker node add this section of yml to the 'docker-stack-edgex.yml'. We will do the inverse for the device-service to ensure it does run on the worker node thus ensuring it uses the overlay network to communicate with the other services. Note that this is already done in the example directory. | ||
|
||
```yaml | ||
deploy: | ||
placement: | ||
constraints: | ||
- node.hostname != worker-node | ||
``` | ||
Here is the inverse of the previous yml block. This gets added to the device services in the stack file. | ||
```yaml | ||
deploy: | ||
placement: | ||
constraints: | ||
- node.hostname == worker-node | ||
``` | ||
### Adding Host Mounted Volumes | ||
In docker swarm bind mount volumes need to be explicitly defined in the stack yml file. Below are the fist three bind mount volume definitions. Additionally, you must create the directories on the host before the stack file in ran. | ||
Note that, this is only an example in a production deployment you would want to use a network filesystem or create the shared volumes between containers. | ||
```yaml | ||
secrets-volume: | ||
driver: local | ||
driver_opts: | ||
o: bind | ||
type: none | ||
device: /tmp/edgex/secrets/ | ||
secrets-ca-volume: | ||
driver: local | ||
driver_opts: | ||
o: bind | ||
type: none | ||
device: /tmp/edgex/secrets/ca/ | ||
edgex-consul: | ||
driver: local | ||
driver_opts: | ||
o: bind | ||
type: none | ||
device: /tmp/edgex/secrets/edgex-consul/ | ||
... | ||
``` | ||
|
||
The full docker-stack file is included here: | ||
|
||
[docker-stack-edgex.yml file](https://github.com/edgexfoundry/edgex-examples/security/remote_devices/docker-swarm/docker-stack-edgex.yml) | ||
|
||
### Other changes in docker-stack-edgex.yml file | ||
|
||
Another change we had to make in the docker-stack-edgex.yml file is to disable `IPC_LOCK` because the `cap_add` flag in vault's configuration is not supported in docker swarm. To do this we add `SKIP_SETCAP=true` and `disable_mlock = "true"` to vault in the stack file. | ||
|
||
```yaml | ||
vault: | ||
image: vault:1.3.1 | ||
hostname: edgex-vault | ||
networks: | ||
edgex-network: | ||
aliases: | ||
- edgex-vault | ||
ports: | ||
- "8200:8200" | ||
# cap_add not allowed in docker swarm, this is a security issue and I don't recommend disabling this in production | ||
# cap_add: | ||
# - "IPC_LOCK" | ||
tmpfs: | ||
- /vault/config | ||
entrypoint: ["/vault/init/start_vault.sh"] | ||
environment: | ||
- VAULT_ADDR=https://edgex-vault:8200 | ||
- VAULT_CONFIG_DIR=/vault/config | ||
- VAULT_UI=true | ||
- SKIP_SETCAP=true | ||
- | | ||
VAULT_LOCAL_CONFIG= | ||
listener "tcp" { | ||
address = "edgex-vault:8200" | ||
tls_disable = "0" | ||
cluster_address = "edgex-vault:8201" | ||
tls_min_version = "tls12" | ||
tls_client_ca_file ="/tmp/edgex/secrets/edgex-vault/ca.pem" | ||
tls_cert_file ="/tmp/edgex/secrets/edgex-vault/server.crt" | ||
tls_key_file = "/tmp/edgex/secrets/edgex-vault/server.key" | ||
tls_perfer_server_cipher_suites = "true" | ||
} | ||
backend "consul" { | ||
path = "vault/" | ||
address = "edgex-core-consul:8500" | ||
scheme = "http" | ||
redirect_addr = "https://edgex-vault:8200" | ||
cluster_addr = "https://edgex-vault:8201" | ||
} | ||
default_lease_ttl = "168h" | ||
max_lease_ttl = "720h" | ||
disable_mlock = "true" | ||
volumes: | ||
- vault-file:/vault/file:z | ||
- vault-logs:/vault/logs:z | ||
- vault-init:/vault/init:ro,z | ||
- edgex-vault:/tmp/edgex/secrets/edgex-vault:ro,z | ||
depends_on: | ||
- consul | ||
- security-secrets-setup | ||
deploy: | ||
placement: | ||
constraints: | ||
- node.hostname != worker-node | ||
``` | ||
The next and final change in the stack yml file is to ensure the EdgeX services are binding to the correct host. In Geneva we do this by adding a common variable `Service_ServerBindAddr: "0.0.0.0"` to ensure that the service will bind to any host and not be limited to the hostname. | ||
|
||
### Running the docker stack file | ||
|
||
With all of these changes in place we are ready to run the stack file. We included a script to run the stack file and create the volumes needed in the stack file. This script simply creates the volumes directories and runs the `docker stack deploy ...` command. | ||
|
||
```sh | ||
sudo ./run.sh | ||
``` | ||
|
||
Once the stack is up you can run the following command to view the running services: | ||
|
||
```sh | ||
sudo docker stack services edgex-overlay | ||
``` | ||
|
||
### Confirming results | ||
|
||
To ensure the device service is running on the worker node you can run the `docker node ps` command. Now check that you see the device service running on the `worker-node` while all of the other services are running on your host. | ||
|
||
We have encryption enabled but how to we confirm that the overlay network is encrypting our data? | ||
|
||
We can use `tcpdum` with a protocol filter for ESP (Encapsulating Security Payload) traffic on the worker node this allows us to sniff and ensure the traffic is coming over the expected encrypted protocol. | ||
|
||
`sudo tcpdump -p esp` | ||
|
||
### Tearing everything down | ||
|
||
To remove the stack run the command: | ||
|
||
```sh | ||
sudo ./down.sh | ||
``` | ||
|
||
This will remove the volumes and the stack. | ||
|
||
To remove the swarm itself run: on the worker node `docker swarm leave` and on the host machine `docker swarm leave --force`. | ||
|
||
To remove the vagrant VM run `vagrant destroy` on the host. |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.