Apply suggestions from code review

Co-authored-by: sanderson042 <steve.anderson@hpe.com>
Signed-off-by: Andres Gomez Coronel <andresgomezcoronel@gmail.com>
This commit is contained in:
Andres-GC 2020-07-31 13:00:58 -03:00 committed by Andres Gomez Coronel
parent 504a821e72
commit db36c9072c
No known key found for this signature in database
GPG Key ID: 9F0C96039D12EBD8
3 changed files with 34 additions and 31 deletions

View File

@ -1,22 +1,22 @@
# Overview # Overview
Nested SPIRE allows SPIRE Servers to be “chained” together, and for all servers to still issue identities in the same trust domain, meaning all Workloads identified in the same trust domain are issued identity documents that can be verified against the root keys of the trust domain. Nested SPIRE allows SPIRE Servers to be “chained” together, and for all SPIRE Servers to issue identities in the same trust domain, meaning all workloads identified in the same trust domain are issued identity documents that can be verified against the root keys of the trust domain.
Nested topologies works by co-locating a SPIRE Agent with every downstream SPIRE Servers being “chained”. The downstream SPIRE Server obtains credentials over the Workload API that it uses to directly authenticate with the upstream SPIRE Server to obtain an intermediate CA. Nested topologies work by co-locating a SPIRE Agent with every downstream SPIRE Server being “chained”. The downstream SPIRE Server obtains credentials over the Workload API that it uses to directly authenticate with the upstream SPIRE Server to obtain an intermediate CA.
To demonstrate a deploy of SPIRE in a nested topology we create a scenario using Docker Compose with a root SPIRE deployment and two SPIRE deployment nested to it. To demonstrate a deployment of SPIRE in a nested topology we create a scenario using Docker Compose with a root SPIRE deployment and two SPIRE deployments nested to it.
![Nested SPIRE diagram][nested-SPIRE-diagram] ![Nested SPIRE diagram][nested-SPIRE-diagram]
[nested-SPIRE-diagram]: images/Nested_SPIRE_Diagram.png "Nested SPIRE Deployment diagram" [nested-SPIRE-diagram]: images/Nested_SPIRE_Diagram.png "Nested SPIRE Deployment diagram"
The Nested topology is well suited for multi-cloud deployments. Due to the ability to mix and match node attestors, the downstream servers can reside and provide identities for Workloads and Agents in different cloud provider environments. The nested topology is well suited for multi-cloud deployments. Due to the ability to mix and match node attestors, the downstream SPIRE Servers can reside and provide identities for workloads and SPIRE Agents in different cloud provider environments.
In this tutorial you will learn how to: In this tutorial you will learn how to:
* Configure SPIRE in a Nested topology. * Configure SPIRE in a nested topology
* Configure the UpstreamAuthority plugin * Configure the UpstreamAuthority plugin
* Create registration entries for nested SPIRE servers * Create registration entries for nested SPIRE Servers
* Test that SVIDs created in a nested configuration are valid in the entire trust domain * Test that SVIDs created in a nested configuration are valid in the entire trust domain
@ -24,29 +24,32 @@ In this tutorial you will learn how to:
Required files for this tutorial can be found in the `nested-spire` directory in https://github.com/spiffe/spire-tutorials. If you didn't already clone the repository please do so now. Required files for this tutorial can be found in the `nested-spire` directory in https://github.com/spiffe/spire-tutorials. If you didn't already clone the repository please do so now.
Before proceeding, review the following: Before proceeding, review the following system requirements:
- A 64 bit Linux or macOS environment - A 64-bit Linux or macOS environment
- Docker and Docker Compose installed - Docker and Docker Compose installed
- Go 1.14.4 or higher - Go 1.14.4 or higher installed
# Part 1: Run Services # Part 1: Run Services
Change to the directory `nested-spire` that contains the required files to complete the tutorial. There are three directories, one for each of the SPIRE deployment, `root`, `nestedA` and `nestedB`. These directories hold the configuration files for the SPIRE Servers and Agents. They will also contain the private keys and certificates created to attest the Agents on the Servers with the [x509pop Node Attestor](https://github.com/spiffe/spire/blob/master/doc/plugin_server_nodeattestor_x509pop.md) plugin. Private Keys and certificates are created at the initialization of the scenario using a go application which details are out of the scope of this tutorial. This tutorial's `nested-spire` main directory contains three subdirectories, one for each of the SPIRE deployments: `root`, `nestedA` and `nestedB`. These directories hold the configuration files for the SPIRE Servers and Agents. They will also contain the private keys and certificates created to attest the Agents on the Servers with the [x509pop Node Attestor](https://github.com/spiffe/spire/blob/master/doc/plugin_server_nodeattestor_x509pop.md) plugin. Private keys and certificates are created at the initialization of the scenario using a Go application, the details of which are out of the scope of this tutorial.
## Creating a Share Directory ## Create a Shared Directory
The first thing to do is to create a local directory that will be volume mounted on the services to share the Workload API between the root SPIRE Agent and its nested SPIRE Servers. The first thing to do is to create a local directory that will be volume mounted on the services to share the Workload API between the root SPIRE Agent and its nested SPIRE Servers.
Change to the directory `nested-spire` that contains the required files to complete the tutorial:
```console
cd your_path/nested-spire
Create the `sharedRootSocket` shared directory:
```console ```console
mkdir sharedRootSocket mkdir sharedRootSocket
``` ```
## Configuring Root SPIRE Deployment ## Configuring Root SPIRE Deployment
Configuration files for [root-server](root/server/server.conf) and [root-agent](root/agent/agent.conf) do not have any special configuration but it worth noting the location defined to bind the workload API socket by the SPIRE Agent: `socket_path ="/opt/spire/sockets/workload_api.sock"`. It will be used later to configure a volume to share the Workload API with the nested servers. Configuration files for [root-server](root/server/server.conf) and [root-agent](root/agent/agent.conf) have not been changed from the default `server.conf` and `agent.conf` files, but it's worth noting the location defined to bind the workload API socket by the SPIRE Agent: `socket_path ="/opt/spire/sockets/workload_api.sock"`. This path will be used later to configure a volume to share the Workload API with the nested SPIRE Servers.
We define all the services for the tutorial at the [docker-compose.yaml](docker-compose.yaml) file. On the `root-agent` service definition we mount the `/opt/spire/sockets` directory from the SPIRE Agent container on the new local directory `sharedRootSocket`. In the next section, when defining the nested SPIRE Server services, we'll use this directory to mount the `root-agent` socket on their containers. We define all the services for the tutorial in the [docker-compose.yaml](docker-compose.yaml) file. In the `root-agent` service definition we mount the `/opt/spire/sockets` directory from the SPIRE Agent container on the new local directory `sharedRootSocket`. In the next section, when defining the nested SPIRE Server services, we'll use this directory to mount the `root-agent` socket on the SPIRE Server containers.
```console ```console
services: services:
@ -64,7 +67,7 @@ We define all the services for the tutorial at the [docker-compose.yaml](docker-
depends_on: ["root-server"] depends_on: ["root-server"]
hostname: root-agent hostname: root-agent
volumes: volumes:
# Share root agent socket to be acceded by nestedA and nestedB servers # Share root agent socket to be accessed by nestedA and nestedB servers
- ./sharedRootSocket:/opt/spire/sockets - ./sharedRootSocket:/opt/spire/sockets
- ./root/agent:/opt/spire/conf/agent - ./root/agent:/opt/spire/conf/agent
- /var/run/:/var/run/ - /var/run/:/var/run/
@ -77,7 +80,7 @@ The same set of configurations are required for the NestedB SPIRE deployment but
SPIRE Server can be configured using different types of plugins. For Nested SPIRE deployments we use the UpstreamAuthority type that allows SPIRE server to integrate with existing PKI systems. For the guide we use the `spire` UpstreamAuthority plugin which uses an upstream SPIRE server in the same trust domain to obtain intermediate signing certificates for SPIRE server. SPIRE Server can be configured using different types of plugins. For Nested SPIRE deployments we use the UpstreamAuthority type that allows SPIRE server to integrate with existing PKI systems. For the guide we use the `spire` UpstreamAuthority plugin which uses an upstream SPIRE server in the same trust domain to obtain intermediate signing certificates for SPIRE server.
The configuration file for the [nestedA-server](./nestedA/server/server.conf) includes the spire UpstreamAuthority plugin definition with the `root-server` as its upstream SPIRE server. The configuration file for the [nestedA-server](./nestedA/server/server.conf) includes the `spire` UpstreamAuthority plugin definition with the `root-server` as its upstream SPIRE Server.
```console ```console
UpstreamAuthority "spire" { UpstreamAuthority "spire" {
@ -89,7 +92,7 @@ The configuration file for the [nestedA-server](./nestedA/server/server.conf) in
} }
``` ```
On the other hand, the definition for the `nestedA-server` service at the [docker-compose.yaml](docker-compose.yaml) file mounts the new local directory `sharedRootSocket` as a volume. Remember from the previous section that the `root-agent` socket is mounted on that directory. That way the `nestedA-server` can access the `root-agent` workload API and fetch its SVID. The Docker Compose definition for the `nestedA-server` service in the [docker-compose.yaml](docker-compose.yaml) file mounts the new local directory `sharedRootSocket` as a volume. Remember from the previous section that the `root-agent` socket is mounted on that directory. That way the `nestedA-server` can access the `root-agent` workload API and fetch its SVID.
```console ```console
nestedA-server: nestedA-server:
@ -107,9 +110,9 @@ On the other hand, the definition for the `nestedA-server` service at the [docke
command: ["-config", "/opt/spire/conf/server/server.conf"] command: ["-config", "/opt/spire/conf/server/server.conf"]
``` ```
## Creates Downstream Registration Entry ## Create Downstream Registration Entry
The `nestedA-server` must be registered on the `root-server` to get SVIDs. We achieve this by creating a registration entry at the root SPIRE Server for the `nestedA-server`. The `nestedA-server` must be registered on the `root-server` to get SVIDs. We achieve this by creating a registration entry in the root SPIRE Server for the `nestedA-server`.
```console ```console
docker-compose exec -T root-server \ docker-compose exec -T root-server \
@ -121,19 +124,19 @@ The `nestedA-server` must be registered on the `root-server` to get SVIDs. We ac
-ttl 3600 -ttl 3600
``` ```
The `-parentID` flag contains the SPIFFE ID of the `root-agent`. The SPIFFE ID of the `root-agent` is created by the [x509pop Node Attestor](https://github.com/spiffe/spire/blob/master/doc/plugin_server_nodeattestor_x509pop.md) plugin which defines the SPIFFE ID as `spiffe://<trust domain>/spire/agent/x509pop/<fingerprint>`. To make the entry clear to the reader, it is expressed as `fingerprint root/agent/agent.crt.pem` indicating that it contains the fingerprint of the agent certificate. The `-parentID` flag contains the SPIFFE ID of the `root-agent`. The SPIFFE ID of the `root-agent` is created by the [x509pop Node Attestor](https://github.com/spiffe/spire/blob/master/doc/plugin_server_nodeattestor_x509pop.md) plugin which defines the SPIFFE ID as `spiffe://<trust domain>/spire/agent/x509pop/<fingerprint>`. A `fingerprint()` function in the shell script calculates the SHA1 fingerprint of the certificate.
The other point to highlight is the `-downstream` option. This option when set, indicates that the entry describes a downstream SPIRE server. The other point to highlight is the `-downstream` option. This option, when set, indicates that the entry describes a downstream SPIRE Server.
## Run the Scenario ## Run the Scenario
Use the `set-env.sh` script to run all the services that compound the scenario. All the configurations described in the previous sections are illustrated in the different services. Use the `set-env.sh` script to run all the services that make up the scenario. The script starts the `root`, `nestedA`, and `nestedB` services with the configuration options described earlier.
Ensure that the current working directory is `.../spire-tutorials/nested-spire` and run: Ensure that the current working directory is `.../spire-tutorials/nested-spire` and run:
```console ```console
bash scripts/set-env.sh bash scripts/set-env.sh
``` ```
Once the script is completed, in another terminal run the following command to review the logs from all the services Once the script is completed, in another terminal run the following command to review the logs from all the services:
```console ```console
docker-compose logs -f -t docker-compose logs -f -t
@ -146,7 +149,7 @@ Now that the SPIRE deployments are ready, let's test the scenario that we've con
## Create Workload Registration Entries ## Create Workload Registration Entries
To test the scenario we create two workload registration entries, one entry per each of the nested SPIRE deployment. The goal of the test case is to demonstrate that SVIDs created in a nested configuration are valid in the entire trust domain, not only in the scope of the server that originated the SVID. To test the scenario we create two workload registration entries, one entry for each nested SPIRE Server (`nestedA` and `nestedB`). The goal of the test is to demonstrate that SVIDs created in a nested configuration are valid in the entire trust domain, not only in the scope of the SPIRE Server that originated the SVID. The following commands demonstrate the command line options we'll use to create the two workload registration entries, but you can run these commands using the `create-workload-registration-entries.sh` script shown a few lines below.
```console ```console
# Workload for nestedA deployment # Workload for nestedA deployment
@ -166,8 +169,8 @@ To test the scenario we create two workload registration entries, one entry per
-ttl 0 -ttl 0
``` ```
The examples uses the `$(fingerprint nestedA/agent/agent.crt.pem)` notation again to show that the `-parentID` flag is set to the SPIFFE ID of the nested SPIRE Agent. TTL equals to zero indicates that the default value of 3600 seconds will be used. Finally, in both cases there is an unix selector to identify any process that is run by the user with id 1001. The examples use the `$(fingerprint nestedA/agent/agent.crt.pem)` form again to show that the `-parentID` flag specifies the SPIFFE ID of the nested SPIRE Agent. The TTL flag value of zero indicates that the default value of 3600 seconds will be used. Finally, in both cases the unix selector assigns the SPIFFE ID to any process with a uid of 1001.
Use the following Bash script to create the registration entries: Use the following Bash script to create the registration entries using the options just described:
```console ```console
bash scripts/create-workload-registration-entries.sh bash scripts/create-workload-registration-entries.sh
@ -175,9 +178,9 @@ Use the following Bash script to create the registration entries:
## Run the Test ## Run the Test
Once both workload registration entries are propagated, let's test that SVIDs created in a nested configuration are valid in the entire trust domain, not only in the scope of the server that originated the SVID. Once both workload registration entries are propagated, let's test that SVIDs created in a nested configuration are valid in the entire trust domain, not only in the scope of the SPIRE Server that originated the SVID.
The test consists on getting a JWT-SVID from the `nestedA-agent` and validate it using the `nestedB-agent`. In both cases, Docker Compose run the processes using the user 1001 to match the workload registration entries created in the previous section. The test consists of getting a JWT-SVID from the `nestedA-agent` SPIRE Agent and validating it using the `nestedB-agent`. In both cases, Docker Compose runs the processes using the uid 1001 to match the workload registration entries created in the previous section.
```console ```console
# Fetch JWT-SVID and extract token # Fetch JWT-SVID and extract token
@ -203,7 +206,7 @@ In SPIRE this is accomplished by propagating every JWT-SVID public signing key t
# Cleanup # Cleanup
When you are finished running this tutorial, you can use the following command to stop all the containers When you are finished running this tutorial, you can use the following command to stop all the containers:
```console ```console
docker-compose down docker-compose down

View File

@ -14,7 +14,7 @@ services:
depends_on: ["root-server"] depends_on: ["root-server"]
hostname: root-agent hostname: root-agent
volumes: volumes:
# Share root-agent socket to be acceded by nested servers # Share root-agent socket to be accessed by nested servers
- ./sharedRootSocket:/opt/spire/sockets - ./sharedRootSocket:/opt/spire/sockets
- ./root/agent:/opt/spire/conf/agent - ./root/agent:/opt/spire/conf/agent
- /var/run/:/var/run/ - /var/run/:/var/run/

View File

@ -47,7 +47,7 @@ check-entry-is-propagated() {
} }
# create a shared folder for root agent socket to be acceded by nestedA and nestedB servers # create a shared folder for root agent socket to be accessed by nestedA and nestedB servers
mkdir -p sharedRootSocket mkdir -p sharedRootSocket