Envoy SDS Example with SPIRE

环境说明

Envoy Mesh使用的网络: 172.31.92.0/24
3个Service:
  • web-server:ip地址172.31.92.5
  • echo-server:ip地址172.31.92.6
  • spire-server:ip地址172.31.92.7

生成ca证书

openssl.conf

# environment variable values
CERT_DIR=certs

[ ca ]
# `man ca`
default_ca = CA_default

[ CA_default ]
# Directory and file locations.
dir               = ${ENV::CERT_DIR}
certs             = $dir
crl_dir           = $dir/crl
new_certs_dir     = $dir
database          = $dir/index.txt
serial            = $dir/serial
# certificate revocation lists.
crlnumber         = $dir/crlnumber
crl               = $dir/crl/intermediate-ca.crl
crl_extensions    = crl_ext
default_crl_days  = 30
default_md        = sha256

name_opt          = ca_default
cert_opt          = ca_default
default_days      = 375
preserve          = no
policy            = policy_loose

[ policy_loose ]
# Allow the CA to sign a range of certificates.
countryName             = optional
stateOrProvinceName     = optional
localityName            = optional
organizationName        = optional
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional

[ req ]
# `man req`
default_bits        = 4096
distinguished_name  = req_distinguished_name
string_mask         = utf8only
default_md          = sha256

[ req_distinguished_name ]
countryName                    = Country Name (2 letter code)
stateOrProvinceName            = State or Province Name
localityName                   = Locality Name
0.organizationName             = Organization Name
organizationalUnitName         = Organizational Unit Name
commonName                     = Common Name

# Certificate extensions (`man x509v3_config`)

[ v3_ca ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true, pathlen:0
keyUsage = critical, digitalSignature, cRLSign, keyCertSign

[ client_cert ]
basicConstraints = CA:FALSE
nsCertType = client
nsComment = "OpenSSL Generated Client Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth

[ server_cert ]
basicConstraints = CA:FALSE
nsCertType = server
nsComment = "OpenSSL Generated Server Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth

创建证书

创建目录
# mkdir certs/{ca,echo,web} 
# touch certs/index.txt
# touch certs/serial
# echo "1000" >  certs/serial
# echo "unique_subject = no" > certs/index.txt.attr  # Sign multiple certs for the same CN

生成ca证书
# openssl genrsa -out certs/ca/agent-cacert.key.pem 4096
# openssl req -config openssl.conf -new -x509 -days 3650 -sha256 -key certs/ca/agent-cacert.key.pem -extensions v3_ca -out certs/ca/agent-cacert.crt.pem -subj /CN=ca

生成web证书
# openssl genrsa -out certs/web/agent.key.pem 2048
# openssl req -config openssl.conf -new -sha256 -key certs/web/agent.key.pem -out certs/web/agent.csr -subj /CN=web
# openssl ca -batch -config openssl.conf -extensions server_cert -days 3650 -notext -md sha256 -in certs/web/agent.csr -out certs/web/agent.crt.pem -cert certs/ca/agent-cacert.crt.pem -keyfile certs/ca/agent-cacert.key.pem

生成echo证书
# openssl genrsa -out certs/echo/agent.key.pem 2048
# openssl req -config openssl.conf -new -sha256 -key certs/echo/agent.key.pem -out certs/echo/agent.csr -subj /CN=echo
# openssl ca -batch -config openssl.conf -extensions server_cert -days 3650 -notext -md sha256 -in certs/echo/agent.csr -out certs/echo/agent.crt.pem -cert certs/ca/agent-cacert.crt.pem -keyfile certs/ca/agent-cacert.key.pem

spire-server

spire-server.conf

server {
	bind_address = "0.0.0.0"
	bind_port = "9081"
	socket_path = "/tmp/spire-server/private/api.sock"
	trust_domain = "wgs.com"
	data_dir = "/opt/spire/data/server"
	log_level = "DEBUG"
	# log_file = "/opt/spire/server.log"
	log_file = "/dev/stdout"	
	default_svid_ttl = "1h"
	ca_subject = {
		country = ["US"],
		organization = ["SPIFFE"],
		common_name = "",
	}
}

plugins {
	DataStore "sql" {
		plugin_data {
			database_type = "sqlite3"
			connection_string = "/opt/spire/data/server/datastore.sqlite3"
		}
	}
	NodeAttestor "x509pop" {
		plugin_data {
			ca_bundle_path = "/opt/spire/conf/server/agent-cacert.pem"
		}
	}


	KeyManager "disk" {
		plugin_data = {
			keys_path = "/opt/spire/data/server/keys.json"
		}
	}
}

Dockerfile

FROM uhub.service.ucloud.cn/xk-base/spire-server:1.4.0
  
# Override spire configurations
COPY conf/spire-server.conf /opt/spire/conf/server/server.conf
COPY conf/agent-cacert.crt.pem /opt/spire/conf/server/agent-cacert.pem

WORKDIR /opt/spire

web-server

web-server可执行程序源代码参考https://github.com/spiffe/spire-examples/tree/main/examples/envoy

spire-agent.conf

agent {
	data_dir = "/opt/spire/data/agent"
	log_level = "DEBUG"
	# log_file = "/opt/spire/agent.log"
	log_file = "/dev/stdout"	
	server_address = "spire-server"
	server_port = "9081"
	socket_path ="/tmp/agent.sock"
	trust_bundle_path = "/opt/spire/conf/agent/bootstrap.crt"
	trust_domain = "wgs.com"
}

plugins {
	NodeAttestor "x509pop" {
		plugin_data {
			private_key_path = "/opt/spire/conf/agent/agent.key.pem"
			certificate_path = "/opt/spire/conf/agent/agent.crt.pem"
		}
	}
	KeyManager "disk" {
		plugin_data {
			directory = "/opt/spire/data/agent"
		}
	}
	WorkloadAttestor "unix" {
		plugin_data {
		}
	}
}

envoy.yaml

node:
  id: "id_02"
  cluster: "cluster_02"

admin:
  profile_path: /tmp/envoy.prof
  access_log_path: /tmp/admin_access.log
  address:
    socket_address:
       address: 0.0.0.0
       port_value: 9901

static_resources:
  listeners:
  - name: web_to_echo_mtls_listener
    address:
      socket_address:
        address: 127.0.0.1
        port_value: 8001
    filter_chains:
    - filters:
      - name: envoy.filters.network.http_connection_manager
        typed_config:
          "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
          common_http_protocol_options:
            idle_timeout: 1s
          codec_type: auto
          access_log:
          - name: envoy.access_loggers.file
            typed_config:
              "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
              path: "/dev/stdout"
          stat_prefix: ingress_http
          route_config:
            name: service_route
            virtual_hosts:
            - name: web_to_echo_mtls
              domains: ["*"]
              routes:
              - match:
                  prefix: "/"
                route:
                  cluster: web_to_echo_mtls
          http_filters:
          - name: envoy.filters.http.router
          
  - name: web_to_echo_tls_listener
    address:
      socket_address:
        address: 127.0.0.1
        port_value: 8002
    filter_chains:
    - filters:
      - name: envoy.filters.network.http_connection_manager
        typed_config:
          "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
          common_http_protocol_options:
            idle_timeout: 1s
          codec_type: auto
          access_log:
          - name: envoy.access_loggers.file
            typed_config:
              "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
              path: "/dev/stdout"
          stat_prefix: ingress_http
          route_config:
            name: service_route
            virtual_hosts:
            - name: web_to_echo_tls
              domains: ["*"]
              routes:
              - match:
                  prefix: "/"
                route:
                  cluster: web_to_echo_tls
          http_filters:
          - name: envoy.filters.http.router
          
  clusters:
  - name: spire_agent
    connect_timeout: 0.25s
    http2_protocol_options: {}
    load_assignment:	
      cluster_name: spire_agent
      endpoints:	
      - lb_endpoints:	
        - endpoint:	
            address:	
              pipe:	
                path: /tmp/agent.sock
                
  - name: web_to_echo_mtls
    connect_timeout: 0.25s
    type: strict_dns
    lb_policy: ROUND_ROBIN
    load_assignment:	
      cluster_name: web_to_echo_mtls
      endpoints:	
      - lb_endpoints:	
        - endpoint:	
            address:	
              socket_address:	
                address: echo	
                port_value: 8001
    transport_socket:
      name: envoy.transport_sockets.tls
      typed_config:
        "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
        common_tls_context:
          tls_certificate_sds_secret_configs:
            - name: "spiffe://wgs.com/web-server"
              sds_config:
                api_config_source:
                  api_type: GRPC
                  grpc_services:
                    envoy_grpc:
                      cluster_name: spire_agent
                  transport_api_version: V3
                resource_api_version: V3
          combined_validation_context:
            # validate the SPIFFE ID of the server (recommended)
            default_validation_context:
              match_subject_alt_names:
                exact: "spiffe://wgs.com/echo-server"
            validation_context_sds_secret_config:
              name: "spiffe://wgs.com"
              sds_config:
                api_config_source:
                  api_type: GRPC
                  grpc_services:
                    envoy_grpc:
                      cluster_name: spire_agent
                  transport_api_version: V3
                resource_api_version: V3
          tls_params:
            ecdh_curves:
              - X25519:P-256:P-521:P-384
              
  - name: web_to_echo_tls
    connect_timeout: 0.25s
    type: strict_dns
    lb_policy: ROUND_ROBIN
    load_assignment:	
      cluster_name: web_to_echo_tls
      endpoints:	
      - lb_endpoints:	
        - endpoint:	
            address:	
              socket_address:	
                address: echo	
                port_value: 8002
    transport_socket:
      name: envoy.transport_sockets.tls
      typed_config:
        "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
        common_tls_context:
          combined_validation_context:
            # validate the SPIFFE ID of the server (recommended)
            default_validation_context:
              match_subject_alt_names:
                exact: "spiffe://wgs.com/echo-server"
            validation_context_sds_secret_config:
              name: "spiffe://wgs.com"
              sds_config:
                api_config_source:
                  api_type: GRPC
                  grpc_services:
                    envoy_grpc:
                      cluster_name: spire_agent
                  transport_api_version: V3
                resource_api_version: V3
          tls_params:
            ecdh_curves:
              - X25519:P-256:P-521:P-384

Dockerfile

FROM uhub.service.ucloud.cn/xk-base/spire-agent:1.4.0 as spire
  
FROM envoyproxy/envoy-alpine:v1.20.0
RUN mkdir -p /opt/spire/conf/agent
RUN mkdir -p /opt/spire/data/agent
COPY --from=spire /opt/spire/bin/spire-agent /opt/spire/bin/spire-agent
COPY conf/envoy.yaml /etc/envoy/envoy.yaml
COPY conf/spire-agent.conf /opt/spire/conf/agent/agent.conf
COPY conf/agent.key.pem /opt/spire/conf/agent/agent.key.pem
COPY conf/agent.crt.pem /opt/spire/conf/agent/agent.crt.pem
COPY web-server /usr/local/bin/web-server

WORKDIR /opt/spire
CMD /usr/local/bin/envoy -l debug -c /etc/envoy/envoy.yaml --log-path /tmp/envoy.log

echo-server

echo-server可执行程序源代码参考https://github.com/spiffe/spire-examples/tree/main/examples/envoy

spire-agent.conf

agent {
	data_dir = "/opt/spire/data/agent"
	log_level = "DEBUG"
	# log_file = "/opt/spire/agent.log"
	log_file = "/dev/stdout"
	server_address = "spire-server"
	server_port = "9081"
	socket_path ="/tmp/agent.sock"
	trust_bundle_path = "/opt/spire/conf/agent/bootstrap.crt"
	trust_domain = "wgs.com"
}

plugins {
	NodeAttestor "x509pop" {
		plugin_data {
			private_key_path = "/opt/spire/conf/agent/agent.key.pem"
			certificate_path = "/opt/spire/conf/agent/agent.crt.pem"
		}
	}
	KeyManager "disk" {
		plugin_data {
			directory = "/opt/spire/data/agent"
		}
	}
	WorkloadAttestor "unix" {
		plugin_data {
		}
	}
}

 envoy.yaml

node:
  id: "id_01"
  cluster: "cluster_01"
  
admin:
  profile_path: /tmp/envoy.prof
  access_log_path: /tmp/admin_access.log
  address:
    socket_address:
       address: 0.0.0.0
       port_value: 9901  
  
static_resources:
  listeners:
  - name: listener-sds-mtls
    address:
      socket_address:
        address: 0.0.0.0
        port_value: 8001
    filter_chains:
    - filters:
      - name: envoy.filters.network.http_connection_manager
        typed_config:
          "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
          common_http_protocol_options:
            idle_timeout: 1s
          forward_client_cert_details: sanitize_set
          set_current_client_cert_details:
              uri: true
          codec_type: auto
          access_log:
          - name: envoy.access_loggers.file
            typed_config:
              "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
              path: "/dev/stdout"
          stat_prefix: ingress_http
          route_config:
            name: local_route
            virtual_hosts:
            - name: local_service
              domains: ["*"]
              routes:
              - match:
                  prefix: "/"
                route:
                  cluster: echo_server
          http_filters:
          - name: envoy.filters.http.router
      transport_socket:
        name: envoy.transport_sockets.tls
        typed_config:
          "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
          common_tls_context:
            tls_certificate_sds_secret_configs:
            - name: "spiffe://wgs.com/echo-server"
              sds_config:
                api_config_source:
                  api_type: GRPC
                  grpc_services:
                    envoy_grpc:
                      cluster_name: spire_agent
                  transport_api_version: V3
                resource_api_version: V3
            combined_validation_context:
              # validate the SPIFFE ID of incoming clients (optionally)
              default_validation_context:
                match_subject_alt_names:
                  exact: "spiffe://wgs.com/web-server"
              # obtain the trust bundle from SDS
              validation_context_sds_secret_config:
                name: "spiffe://wgs.com"
                sds_config:
                  api_config_source:
                    api_type: GRPC
                    grpc_services:
                      envoy_grpc:
                        cluster_name: spire_agent
                    transport_api_version: V3
                  resource_api_version: V3
            tls_params:
              ecdh_curves:
                - X25519:P-256:P-521:P-384
                
  - name: listener-sds-tls
    address:
      socket_address:
        address: 0.0.0.0
        port_value: 8002
    filter_chains:
    - filters:
      - name: envoy.filters.network.http_connection_manager
        typed_config:
          "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
          common_http_protocol_options:
            idle_timeout: 1s
          forward_client_cert_details: sanitize_set
          set_current_client_cert_details:
              uri: true
          codec_type: auto
          access_log:
          - name: envoy.access_loggers.file
            typed_config:
              "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
              path: "/dev/stdout"
          stat_prefix: ingress_http
          route_config:
            name: local_route
            virtual_hosts:
            - name: local_service
              domains: ["*"]
              routes:
              - match:
                  prefix: "/"
                route:
                  cluster: echo_server
          http_filters:
          - name: envoy.filters.http.router
      transport_socket:
        name: envoy.transport_sockets.tls
        typed_config:
          "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
          common_tls_context:
            tls_certificate_sds_secret_configs:
            - name: "spiffe://wgs.com/echo-server"
              sds_config:
                api_config_source:
                  api_type: GRPC
                  grpc_services:
                    envoy_grpc:
                      cluster_name: spire_agent
                  transport_api_version: V3
                resource_api_version: V3
            tls_params:
              ecdh_curves:
                - X25519:P-256:P-521:P-384

  clusters:
  - name: spire_agent
    connect_timeout: 0.25s
    http2_protocol_options: {}
    load_assignment:	
      cluster_name: spire_agent
      endpoints:	
      - lb_endpoints:	
        - endpoint:	
            address:	
              pipe:	
                path: /tmp/agent.sock
                
  - name: echo_server
    connect_timeout: 0.25s
    type: strict_dns
    lb_policy: ROUND_ROBIN
    load_assignment:	
      cluster_name: echo_server
      endpoints:	
      - lb_endpoints:	
        - endpoint:	
            address:	
              socket_address:	
                address: 127.0.0.1
                port_value: 8081

 Dockerfile

FROM uhub.service.ucloud.cn/xk-base/spire-agent:1.4.0  as spire

FROM envoyproxy/envoy-alpine:v1.20.0
RUN mkdir -p /opt/spire/conf/agent
RUN mkdir -p /opt/spire/data/agent
COPY --from=spire /opt/spire/bin/spire-agent /opt/spire/bin/spire-agent
COPY conf/envoy.yaml /etc/envoy/envoy.yaml
COPY conf/spire-agent.conf /opt/spire/conf/agent/agent.conf
COPY conf/agent.key.pem /opt/spire/conf/agent/agent.key.pem
COPY conf/agent.crt.pem /opt/spire/conf/agent/agent.crt.pem
COPY echo-server /usr/local/bin/echo-server

WORKDIR /opt/spire
CMD /usr/local/bin/envoy -l debug -c /etc/envoy/envoy.yaml --log-path /tmp/envoy.log

docker-compose.yml

version: '3.3'

services:
  spire-server:
    build: ./docker/spire-server
    hostname: spire-server
    tty: true
    privileged: true
    networks:
      envoymesh:
        ipv4_address: 172.31.92.7       
    
  echo:
    build: ./docker/echo
    hostname: echo
    tty: true
    privileged: true
    networks:
      envoymesh:
        ipv4_address: 172.31.92.6      
    links:
      - spire-server

  web:
    build: ./docker/web
    hostname: web
    tty: true
    privileged: true
    networks:
      envoymesh:
        ipv4_address: 172.31.92.5
    links:
      - spire-server
      - echo
    ports:
      - 8080:8080

networks:
  envoymesh:
    driver: bridge
    ipam:
      config:
        - subnet: 172.31.92.0/24 

运行服务

# docker-compose build
# docker-compose up -d
# docker ps
CONTAINER ID   IMAGE                        COMMAND                  CREATED          STATUS          PORTS                                                  NAMES
8284c012f9d6   spire-example_web            "/docker-entrypoint.…"   28 seconds ago   Up 23 seconds   0.0.0.0:8080->8080/tcp, :::8080->8080/tcp, 10000/tcp   spire-example-web-1
36827064a257   spire-example_echo           "/docker-entrypoint.…"   28 seconds ago   Up 25 seconds   10000/tcp                                              spire-example-echo-1
7bc97ab24d09   spire-example_spire-server   "/usr/bin/dumb-init …"   28 seconds ago   Up 26 seconds                                                          spire-example-spire-server-1
spire-example-spire-server-1  | time="2022-09-27T10:06:26Z" level=warning msg="Current umask 0022 is too permissive; setting umask 0027"
spire-example-spire-server-1  | time="2022-09-27T10:06:26Z" level=info msg=Configured admin_ids="[]" data_dir=/opt/spire/data/server
spire-example-spire-server-1  | time="2022-09-27T10:06:26Z" level=info msg="Opening SQL database" db_type=sqlite3 subsystem_name=sql
spire-example-spire-server-1  | time="2022-09-27T10:06:26Z" level=info msg="Initializing new database" subsystem_name=sql
spire-example-spire-server-1  | time="2022-09-27T10:06:26Z" level=info msg="Connected to SQL database" read_only=false subsystem_name=sql type=sqlite3 version=3.38.5
spire-example-spire-server-1  | time="2022-09-27T10:06:26Z" level=info msg="Plugin loaded" external=false plugin_name=x509pop plugin_type=NodeAttestor subsystem_name=catalog
spire-example-spire-server-1  | time="2022-09-27T10:06:26Z" level=info msg="Plugin loaded" external=false plugin_name=disk plugin_type=KeyManager subsystem_name=catalog
spire-example-spire-server-1  | time="2022-09-27T10:06:26Z" level=debug msg="Loading journal" path=/opt/spire/data/server/journal.pem subsystem_name=ca_manager
spire-example-spire-server-1  | time="2022-09-27T10:06:26Z" level=info msg="Journal loaded" jwt_keys=0 subsystem_name=ca_manager x509_cas=0
spire-example-spire-server-1  | time="2022-09-27T10:06:26Z" level=debug msg="Preparing X509 CA" slot=A subsystem_name=ca_manager
spire-example-spire-server-1  | time="2022-09-27T10:06:26Z" level=info msg="X509 CA prepared" expiration="2022-09-28T10:06:26Z" issued_at="2022-09-27T10:06:26Z" self_signed=true slot=A subsystem_name=ca_manager
spire-example-spire-server-1  | time="2022-09-27T10:06:26Z" level=info msg="X509 CA activated" expiration="2022-09-28T10:06:26Z" issued_at="2022-09-27T10:06:26Z" slot=A subsystem_name=ca_manager
spire-example-spire-server-1  | time="2022-09-27T10:06:26Z" level=debug msg="Successfully rotated X.509 CA" subsystem_name=ca_manager trust_domain_id="spiffe://wgs.com" ttl=86399.708778217
spire-example-spire-server-1  | time="2022-09-27T10:06:26Z" level=debug msg="Preparing JWT key" slot=A subsystem_name=ca_manager
spire-example-spire-server-1  | time="2022-09-27T10:06:26Z" level=info msg="JWT key prepared" expiration="2022-09-28T10:06:26Z" issued_at="2022-09-27T10:06:26Z" slot=A subsystem_name=ca_manager
spire-example-spire-server-1  | time="2022-09-27T10:06:26Z" level=info msg="JWT key activated" expiration="2022-09-28T10:06:26Z" issued_at="2022-09-27T10:06:26Z" slot=A subsystem_name=ca_manager
spire-example-spire-server-1  | time="2022-09-27T10:06:26Z" level=debug msg="Rotating server SVID" subsystem_name=svid_rotator
spire-example-spire-server-1  | time="2022-09-27T10:06:26Z" level=debug msg="Signed X509 SVID" expiration="2022-09-27T11:06:26Z" spiffe_id="spiffe://wgs.com/spire/server" subsystem_name=svid_rotator
spire-example-spire-server-1  | time="2022-09-27T10:06:26Z" level=info msg="Building in-memory entry cache" subsystem_name=endpoints
spire-example-spire-server-1  | time="2022-09-27T10:06:26Z" level=info msg="Completed building in-memory entry cache" subsystem_name=endpoints
spire-example-spire-server-1  | time="2022-09-27T10:06:26Z" level=debug msg="Initializing API endpoints" subsystem_name=endpoints
spire-example-spire-server-1  | time="2022-09-27T10:06:26Z" level=info msg="Starting Server APIs" address="[::]:9081" network=tcp subsystem_name=endpoints
spire-example-spire-server-1  | time="2022-09-27T10:06:26Z" level=info msg="Starting Server APIs" address=/tmp/spire-server/private/api.sock network=unix subsystem_name=endpoints
spire-example-spire-server-1  | time="2022-09-27T10:06:26Z" level=debug msg="Starting checker" name=catalog.datastore subsystem_name=health
spire-example-spire-server-1  | time="2022-09-27T10:06:26Z" level=debug msg="Starting checker" name=server.ca subsystem_name=health
spire-example-spire-server-1  | time="2022-09-27T10:06:26Z" level=debug msg="Starting checker" name=server.ca.manager subsystem_name=health
spire-example-spire-server-1  | time="2022-09-27T10:06:26Z" level=debug msg="Starting checker" name=server subsystem_name=health

Start Web and Echo Servers

# cat 1-start-services.sh 
#!/bin/bash

set -e

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

bb=$(tput bold)
nn=$(tput sgr0)

# Start up the web server
echo "${bb}Starting web server...${nn}"
docker-compose -f "${DIR}"/docker-compose.yml exec -d web web-server -log /tmp/web-server.log

# Start up the echo server
echo "${bb}Starting echo server...${nn}"
docker-compose -f "${DIR}"/docker-compose.yml exec -d echo echo-server -log /tmp/echo-server.log
# ./1-start-services.sh 
Starting web server...
Starting echo server...

Start SPIRE Agents

# cat 2-start-spire-agents.sh 
#!/bin/bash

set -e

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

bb=$(tput bold)
nn=$(tput sgr0)

# Bootstrap trust to the SPIRE server for each agent by copying over the
# trust bundle into each agent container. Alternatively, an upstream CA could
# be configured on the SPIRE server and each agent provided with the upstream
# trust bundle (see UpstreamAuthority under
# https://github.com/spiffe/spire/blob/master/doc/spire_server.md#plugin-types)
echo "${bb}Bootstrapping trust between SPIRE agents and SPIRE server...${nn}"
docker-compose -f "${DIR}"/docker-compose.yml exec -T spire-server bin/spire-server bundle show |
	docker-compose -f "${DIR}"/docker-compose.yml exec -T web tee conf/agent/bootstrap.crt > /dev/null
docker-compose -f "${DIR}"/docker-compose.yml exec -T spire-server bin/spire-server bundle show |
	docker-compose -f "${DIR}"/docker-compose.yml exec -T echo tee conf/agent/bootstrap.crt > /dev/null

# Start up the web server SPIRE agent.
echo "${bb}Starting web server SPIRE agent...${nn}"
docker-compose -f "${DIR}"/docker-compose.yml exec -d web bin/spire-agent run

# Start up the echo server SPIRE agent.
echo "${bb}Starting echo server SPIRE agent...${nn}"
docker-compose -f "${DIR}"/docker-compose.yml exec -d echo bin/spire-agent run
# ./2-start-spire-agents.sh 
Bootstrapping trust between SPIRE agents and SPIRE server...
Starting web server SPIRE agent...
Starting echo server SPIRE agent...
spire-example-spire-server-1  | time="2022-09-27T10:12:14Z" level=info msg="Agent attestation request completed" address="172.31.92.5:43168" agent_id="spiffe://wgs.com/spire/agent/x509pop/11809aeca9d7f13fe01ea5ce1fa41fd2d4566580" authorized_as=nobody authorized_via= caller_addr="172.31.92.5:43168" method=AttestAgent node_attestor_type=x509pop request_id=8a8270fe-3dec-4868-a41d-b407700465be service=agent.v1.Agent subsystem_name=api
spire-example-spire-server-1  | time="2022-09-27T10:12:14Z" level=info msg="Agent attestation request completed" address="172.31.92.6:36692" agent_id="spiffe://wgs.com/spire/agent/x509pop/2feca4602e5e37f683ef9205a3818d79b3bf7444" authorized_as=nobody authorized_via= caller_addr="172.31.92.6:36692" method=AttestAgent node_attestor_type=x509pop request_id=96483c8a-b615-49fc-912a-d3257fde6154 service=agent.v1.Agent subsystem_name=api

Create Workload Registration Entries

# cat 3-create-registration-entries.sh 
#/bin/bash

set -e

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

bb=$(tput bold)
nn=$(tput sgr0)

fingerprint() {
	# calculate the SHA1 digest of the DER bytes of the certificate using the
	# "coreutils" output format (`-r`) to provide uniform output from
	# `openssl sha1` on macOS and linux.
	cat $1 | openssl x509 -outform DER | openssl sha1 -r | awk '{print $1}'
}

WEB_AGENT_FINGERPRINT=$(fingerprint "${DIR}"/docker/web/conf/agent.crt.pem)
ECHO_AGENT_FINGERPRINT=$(fingerprint "${DIR}"/docker/echo/conf/agent.crt.pem)

echo "${bb}Creating registration entry for the web server...${nn}"
docker-compose -f "${DIR}"/docker-compose.yml exec spire-server bin/spire-server entry create \
	-parentID spiffe://wgs.com/spire/agent/x509pop/${WEB_AGENT_FINGERPRINT} \
	-spiffeID spiffe://wgs.com/web-server \
	-selector unix:user:envoy

echo "${bb}Creating registration entry for the echo server...${nn}"
docker-compose -f "${DIR}"/docker-compose.yml exec spire-server bin/spire-server entry create \
	-parentID spiffe://wgs.com/spire/agent/x509pop/${ECHO_AGENT_FINGERPRINT} \
	-spiffeID spiffe://wgs.com/echo-server \
	-selector unix:user:envoy
# ./3-create-registration-entries.sh 
Creating registration entry for the web server...
Entry ID         : 3c1e4953-83af-45e1-8bcc-2e2c2649fe2f
SPIFFE ID        : spiffe://wgs.com/web-server
Parent ID        : spiffe://wgs.com/spire/agent/x509pop/11809aeca9d7f13fe01ea5ce1fa41fd2d4566580
Revision         : 0
TTL              : default
Selector         : unix:user:envoy

Creating registration entry for the echo server...
Entry ID         : b097d6da-3122-4141-bedb-83a5020c5f44
SPIFFE ID        : spiffe://wgs.com/echo-server
Parent ID        : spiffe://wgs.com/spire/agent/x509pop/2feca4602e5e37f683ef9205a3818d79b3bf7444
Revision         : 0
TTL              : default
Selector         : unix:user:envoy
spire-example-spire-server-1  | time="2022-09-27T10:14:45Z" level=debug msg="Signed X509 SVID" authorized_as=agent authorized_via=datastore caller_addr="172.31.92.5:43172" caller_id="spiffe://wgs.com/spire/agent/x509pop/11809aeca9d7f13fe01ea5ce1fa41fd2d4566580" entry_id=3c1e4953-83af-45e1-8bcc-2e2c2649fe2f expiration="2022-09-27T11:14:45Z" method=BatchNewX509SVID request_id=607fe5e0-19ff-4734-b8d3-c196f6a2d2cb service=svid.v1.SVID spiffe_id="spiffe://wgs.com/web-server" subsystem_name=api
spire-example-spire-server-1  | time="2022-09-27T10:14:46Z" level=debug msg="Signed X509 SVID" authorized_as=agent authorized_via=datastore caller_addr="172.31.92.6:36698" caller_id="spiffe://wgs.com/spire/agent/x509pop/2feca4602e5e37f683ef9205a3818d79b3bf7444" entry_id=b097d6da-3122-4141-bedb-83a5020c5f44 expiration="2022-09-27T11:14:46Z" method=BatchNewX509SVID request_id=86655152-2eca-43be-a29d-0955c4dea57c service=svid.v1.SVID spiffe_id="spiffe://wgs.com/echo-server" subsystem_name=api

通过访问Web Server进行测试

访问宿主机的8080/tcp端口,即可访问到Web Server的UI,它提供了三个不同的测试链接:

Web Server和Echo Server间的直接通信

Web Server和Echo Server基于Envoy进行的mTLS通信

Web和Echo Server之间基于Envoy进行的tls通信

查看Web和Echo Server的证书

web server证书

# curl  172.31.92.5:9901/certs
{
 "certificates": [
  {
   "ca_cert": [
    {
     "path": "wgs.com: \u003cinline\u003e",
     "serial_number": "7311ad031b24289c8aae09b34882a656",
     "subject_alt_names": [
      {
       "uri": "spiffe://wgs.com"
      }
     ],
     "days_until_expiration": "0",
     "valid_from": "2022-09-27T10:06:16Z",
     "expiration_time": "2022-09-28T10:06:26Z"
    }
   ],
   "cert_chain": []
  },
  {
   "ca_cert": [
    {
     "path": "wgs.com: \u003cinline\u003e",
     "serial_number": "7311ad031b24289c8aae09b34882a656",
     "subject_alt_names": [
      {
       "uri": "spiffe://wgs.com"
      }
     ],
     "days_until_expiration": "0",
     "valid_from": "2022-09-27T10:06:16Z",
     "expiration_time": "2022-09-28T10:06:26Z"
    }
   ],
   "cert_chain": [
    {
     "path": "\u003cinline\u003e",
     "serial_number": "9f980202c9de88c22f85531e3b3eba6e",
     "subject_alt_names": [
      {
       "uri": "spiffe://wgs.com/web-server"
      }
     ],
     "days_until_expiration": "0",
     "valid_from": "2022-09-27T10:14:35Z",
     "expiration_time": "2022-09-27T11:14:45Z"
    }
   ]
  }
 ]
}

echo server的证书

# curl  172.31.92.6:9901/certs 
{
 "certificates": [
  {
   "ca_cert": [
    {
     "path": "wgs.com: \u003cinline\u003e",
     "serial_number": "7311ad031b24289c8aae09b34882a656",
     "subject_alt_names": [
      {
       "uri": "spiffe://wgs.com"
      }
     ],
     "days_until_expiration": "0",
     "valid_from": "2022-09-27T10:06:16Z",
     "expiration_time": "2022-09-28T10:06:26Z"
    }
   ],
   "cert_chain": [
    {
     "path": "\u003cinline\u003e",
     "serial_number": "85046824c9c138a5f2a40404f66cbc6d",
     "subject_alt_names": [
      {
       "uri": "spiffe://wgs.com/echo-server"
      }
     ],
     "days_until_expiration": "0",
     "valid_from": "2022-09-27T10:14:36Z",
     "expiration_time": "2022-09-27T11:14:46Z"
    }
   ]
  },
  {
   "ca_cert": [],
   "cert_chain": [
    {
     "path": "\u003cinline\u003e",
     "serial_number": "85046824c9c138a5f2a40404f66cbc6d",
     "subject_alt_names": [
      {
       "uri": "spiffe://wgs.com/echo-server"
      }
     ],
     "days_until_expiration": "0",
     "valid_from": "2022-09-27T10:14:36Z",
     "expiration_time": "2022-09-27T11:14:46Z"
    }
   ]
  }
 ]
}

参考文档

https://github.com/spiffe/spire-examples

https://github.com/spiffe/spire-tutorials/tree/main/docker-compose

https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.proto#extension-envoy-tls-cert-validator-spiffe

 

posted @ 2022-09-27 18:47  小吉猫  阅读(196)  评论(0编辑  收藏  举报