0
点赞
收藏
分享

微信扫一扫

Envoy TLS基础

Envoy Mesh中TLS常用场景

  • Front Proxy面向下游客户端提供https服务,但Front Proxy、Mesh内部的各服务间依然使用http协议;
  • https (下游) → http (上游)
  • Front Proxy面向下游客户端提供https服务,而且Front Proxy、Mesh内部的各服务间也使用https协议;
  • https (下游) → https (上游)
  • 但是内部各Service间的通信也有如下两种情形
  • 仅客户端验证服务端证书
  • 客户端与服务端之间互相验证彼此的证书(mTLS)
  • 注意:对于容器化的动态环境来说,证书预配和管理将成为显著难题
  • Front Proxy直接以TCP Proxy的代理模式,在下游客户端与上游服务端之间透传tls协议;
  • https-passthrough
  • 集群内部的东西向流量同样工作于https协议模型

TLS配置位置说明

Listener

Listener面向DownStream(下游客户端)通信,与下游建立tls通信时通常配置在Listener上;

与下游建立tls通信时Listener作为server端,需要提供证书和私钥;

Cluster

Cluster面向上游通信,与上游建立tls通信时通常配置在Cluster上;

与上游建立tls通信时Cluster作为客户端;

  • 单向tls通信时;
  • 需要ca证书,验证上游服务器证书;
  • 双向tls通信时;
  • 需要ca证书,验证上游服务器证书;
  • 需要client端证书和私钥;

TLS环境配置实例

环境说明

  • envoy:Front Proxy,地址为172.31.7.2,监听于443端口
  • webserver_http-01:第一个后端服务   http
  • webserver_http-01-sidecar:第一个后端服务的Sidecar Proxy,地址为172.31.7.11,监听于80端口
  • webserver_http-02:第二个后端服务  http
  • webserver_http-02-sidecar:第二个后端服务的Sidecar Proxy,地址为172.31.7.12, 监听于80端口
  • webserver_tls-01:第三个后端服务  tls
  • webserver_tls-01-sidecar:第三个后端服务的Sidecar Proxy,地址为172.31.7.13,监听于443端口
  • webserver_tls-02:第四个后端服务 tls
  • webserver_tls-02-sidecar:第四个后端服务的Sidecar Proxy,地址为172.31.7.14, 监听于443端口
  • webserver_mtls-01:第五个后端服务  mtls
  • webserver_mtls-01-sidecar:第五个后端服务的Sidecar Proxy,地址为172.31.7.15,监听于443端口
  • webserver_mtls-02:第六个后端服务 mtls
  • webserver_mtls-02-sidecar:第六个后端服务的Sidecar Proxy,地址为172.31.7.16, 监听于443端口

拓扑结构

Envoy TLS基础_客户端

创建证书目录

# mkdir -pv certs/{CA,front-envoy}
# 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

准备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

创建证书

创建ca证书

# openssl genrsa -out certs/CA/ca.key 4096
# openssl req -config openssl.conf -new -x509 -days 3650 -sha256 -key certs/CA/ca.key -extensions v3_ca -out certs/CA/ca.crt -subj /CN=envoy-ca

创建front-proxy server证书

# openssl genrsa -out certs/front-envoy/server.key 2048
# openssl req -config openssl.conf -new -sha256 -key certs/front-envoy/server.key -out certs/front-envoy/server.csr -subj /CN=front-proxy
# openssl ca -batch -config openssl.conf -extensions server_cert -days 3650 -notext -md sha256 -in certs/front-envoy/server.csr -out certs/front-envoy/server.crt -cert certs/CA/ca.crt -keyfile certs/CA/ca.key

创建front-proxy client证书

# openssl genrsa -out certs/front-envoy/client.key 2048
# openssl req -config openssl.conf -new -sha256 -key certs/front-envoy/client.key -out certs/front-envoy/client.csr -subj /CN=front-proxy
# openssl ca -batch -config openssl.conf -extensions client_cert -days 3650 -notext -md sha256 -in certs/front-envoy/client.csr -out certs/front-envoy/client.crt -cert certs/CA/ca.crt -keyfile certs/CA/ca.key

修改证书权限

# docker run -it  --rm envoyproxy/envoy:v1.23-latest id envoy
uid=101(envoy) gid=101(envoy) groups=101(envoy)
# chown -R 101.101 certs/

front-envoy.yaml

查看代码

node:
id: front-envoy
cluster: front-envoy

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

layered_runtime:
layers:
- name: admin
admin_layer: {}

static_resources:
secrets:
- name: server_cert
tls_certificate:
certificate_chain:
filename: "/etc/envoy/certs/server.crt"
private_key:
filename: "/etc/envoy/certs/server.key"
- name: client_cert
tls_certificate:
certificate_chain:
filename: "/etc/envoy/certs/client.crt"
private_key:
filename: "/etc/envoy/certs/client.key"
- name: validation_context
validation_context:
trusted_ca:
filename: "/etc/envoy/ca/ca.crt"

listeners:
- name: listener_http
address:
socket_address:
address: 0.0.0.0
port_value: 80
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
codec_type: auto
stat_prefix: ingress_http
access_log:
- name: envoy.access_loggers.file
typed_config:
"@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
path: "/dev/stdout"
route_config:
name: local_route
virtual_hosts:
- name: backend
domains: ["*"]
routes:
- match:
prefix: "/"
redirect:
https_redirect: true
port_redirect: 443
http_filters:
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router

- name: listener_https
address:
socket_address: { address: 0.0.0.0, port_value: 443 }
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
stat_prefix: ingress_https
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"
route_config:
name: https_route
virtual_hosts:
- name: https_route
domains: ["*"]
routes:
- match:
prefix: "/http/"
route:
prefix_rewrite: "/"
cluster: http
- match:
prefix: "/tls/"
route:
prefix_rewrite: "/"
cluster: tls
- match:
prefix: "/mtls/"
route:
prefix_rewrite: "/"
cluster: mtls
http_filters:
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
transport_socket: # DownstreamTlsContext
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: server_cert

clusters:
- name: http
connect_timeout: 0.25s
type: STRICT_DNS
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: http
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: http
port_value: 80

- name: tls
connect_timeout: 0.25s
type: STRICT_DNS
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: tls
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: tls
port_value: 443
transport_socket:
name: envoy.transport_sockets.tls
typed_config:
"@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
common_tls_context:
validation_context_sds_secret_config:
name: validation_context

- name: mtls
connect_timeout: 0.25s
type: STRICT_DNS
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: mtls
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: mtls
port_value: 443
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: client_cert
validation_context_sds_secret_config:
name: validation_context

envoy-sidecar-proxy_http.yaml

查看代码

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_0
address:
socket_address: { address: 0.0.0.0, port_value: 80 }
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
stat_prefix: ingress_http
codec_type: AUTO
route_config:
name: local_route
virtual_hosts:
- name: local_service
domains: ["*"]
routes:
- match: { prefix: "/" }
route: { cluster: local_cluster }
http_filters:
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router

clusters:
- name: local_cluster
connect_timeout: 0.25s
type: STATIC
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: local_cluster
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address: { address: 127.0.0.1, port_value: 8080 }

envoy-sidecar-proxy_tls.yaml

查看代码

admin:
access_log_path: "/dev/null"
address:
socket_address:
address: 0.0.0.0
port_value: 9901

static_resources:
listeners:
- name: listener_http
address:
socket_address:
address: 0.0.0.0
port_value: 80
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
codec_type: auto
stat_prefix: ingress_http
access_log:
- name: envoy.access_loggers.file
typed_config:
"@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
path: "/dev/stdout"
route_config:
name: local_route
virtual_hosts:
- name: service
domains:
- "*"
routes:
- match:
prefix: "/"
route:
cluster: local_service
http_filters:
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router

- name: listener_https
address:
socket_address: { address: 0.0.0.0, port_value: 443 }
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
stat_prefix: ingress_https
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"
route_config:
name: https_route
virtual_hosts:
- name: https_route
domains: ["*"]
routes:
- match:
prefix: "/"
route:
cluster: local_service
http_filters:
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.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_certificates:
certificate_chain:
filename: "/etc/envoy/certs/server.crt"
private_key:
filename: "/etc/envoy/certs/server.key"

clusters:
- name: local_service
connect_timeout: 0.25s
type: STATIC
lb_policy: round_robin
load_assignment:
cluster_name: local_service
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: 127.0.0.1
port_value: 8080

envoy-sidecar-proxy_mtls.yaml

查看代码

admin:
access_log_path: "/dev/null"
address:
socket_address:
address: 0.0.0.0
port_value: 9901

static_resources:
listeners:
- name: listener_http
address:
socket_address:
address: 0.0.0.0
port_value: 80
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
codec_type: auto
stat_prefix: ingress_http
access_log:
- name: envoy.access_loggers.file
typed_config:
"@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
path: "/dev/stdout"
route_config:
name: local_route
virtual_hosts:
- name: service
domains:
- "*"
routes:
- match:
prefix: "/"
redirect:
https_redirect: true
port_redirect: 443
http_filters:
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router

- name: listener_https
address:
socket_address: { address: 0.0.0.0, port_value: 443 }
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
stat_prefix: ingress_https
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"
route_config:
name: https_route
virtual_hosts:
- name: https_route
domains: ["*"]
routes:
- match:
prefix: "/"
route:
cluster: local_service
http_filters:
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
transport_socket: # DownstreamTlsContext
name: envoy.transport_sockets.tls
typed_config:
"@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
common_tls_context:
tls_certificates: # 基于DataSource,直接给出证书和私钥文件
certificate_chain:
filename: "/etc/envoy/certs/server.crt"
private_key:
filename: "/etc/envoy/certs/server.key"
require_client_certificate: true # 强制验证客户端证书

clusters:
- name: local_service
connect_timeout: 0.25s
type: STATIC
lb_policy: round_robin
load_assignment:
cluster_name: local_service
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: 127.0.0.1
port_value: 8080

docker-compose.yaml

查看代码

version: '3.3'

services:
envoy:
image: envoyproxy/envoy:v1.23-latest
volumes:
- ./front-envoy.yaml:/etc/envoy/envoy.yaml
- ./certs/front-envoy:/etc/envoy/certs/
- ./certs/CA/:/etc/envoy/ca/
networks:
envoymesh:
ipv4_address: 172.31.7.2
aliases:
- front-proxy
expose:
- "80"
- "443"
- "9901"
ports:
- "8080:80"
- "8443:443"
- "9901:9901"
depends_on:
- webserver_http-01-sidecar
- webserver_http-02-sidecar
- webserver_tls-01-sidecar
- webserver_tls-02-sidecar
- webserver_mtls-01-sidecar
- webserver_mtls-02-sidecar

webserver_http-01-sidecar:
image: envoyproxy/envoy:v1.23-latest
volumes:
- ./envoy-sidecar-proxy_http.yaml:/etc/envoy/envoy.yaml
hostname: webserver_http-01
networks:
envoymesh:
ipv4_address: 172.31.7.11
aliases:
- webserver_http-01-sidecar
- front-proxy
- http

webserver_http-01:
image: ikubernetes/demoapp:v1.0
environment:
- PORT=8080
- HOST=127.0.0.1
network_mode: "service:webserver_http-01-sidecar"
depends_on:
- webserver_http-01-sidecar

webserver_http-02-sidecar:
image: envoyproxy/envoy:v1.23-latest
volumes:
- ./envoy-sidecar-proxy_http.yaml:/etc/envoy/envoy.yaml
hostname: webserver_http-02
networks:
envoymesh:
ipv4_address: 172.31.7.12
aliases:
- webserver_http-02-sidecar
- front-proxy
- http

webserver_http-02:
image: ikubernetes/demoapp:v1.0
environment:
- PORT=8080
- HOST=127.0.0.1
network_mode: "service:webserver_http-02-sidecar"
depends_on:
- webserver_http-02-sidecar

webserver_tls-01-sidecar:
image: envoyproxy/envoy:v1.23-latest
volumes:
- ./envoy-sidecar-proxy_tls.yaml:/etc/envoy/envoy.yaml
- ./certs/front-envoy/:/etc/envoy/certs/
hostname: webserver_tls-01
networks:
envoymesh:
ipv4_address: 172.31.7.13
aliases:
- webserver_tls-03-sidecar
- tls

webserver_tls-01:
image: ikubernetes/demoapp:v1.0
environment:
- PORT=8080
- HOST=0.0.0.0
network_mode: "service:webserver_tls-01-sidecar"
depends_on:
- webserver_tls-01-sidecar

webserver_tls-02-sidecar:
image: envoyproxy/envoy:v1.23-latest
volumes:
- ./envoy-sidecar-proxy_tls.yaml:/etc/envoy/envoy.yaml
- ./certs/front-envoy/:/etc/envoy/certs/
hostname: webserver_tls-02
networks:
envoymesh:
ipv4_address: 172.31.7.14
aliases:
- webserver_tls-02-sidecar
- tls

webserver_tls-02:
image: ikubernetes/demoapp:v1.0
environment:
- PORT=8080
- HOST=0.0.0.0
network_mode: "service:webserver_tls-02-sidecar"
depends_on:
- webserver_tls-02-sidecar

webserver_mtls-01-sidecar:
image: envoyproxy/envoy:v1.23-latest
volumes:
- ./envoy-sidecar-proxy_mtls.yaml:/etc/envoy/envoy.yaml
- ./certs/front-envoy/:/etc/envoy/certs/
hostname: webserver_mtls-01
networks:
envoymesh:
ipv4_address: 172.31.7.15
aliases:
- webserver_mtls-01-sidecar
- mtls

webserver_mtls-01:
image: ikubernetes/demoapp:v1.0
environment:
- PORT=8080
- HOST=0.0.0.0
network_mode: "service:webserver_mtls-01-sidecar"
depends_on:
- webserver_mtls-01-sidecar

webserver_mtls-02-sidecar:
image: envoyproxy/envoy:v1.23-latest
volumes:
- ./envoy-sidecar-proxy_mtls.yaml:/etc/envoy/envoy.yaml
- ./certs/front-envoy/:/etc/envoy/certs/
hostname: webserver_mtls-02
networks:
envoymesh:
ipv4_address: 172.31.7.16
aliases:
- webserver_mtls-02-sidecar
- mtls

webserver_mtls-02:
image: ikubernetes/demoapp:v1.0
environment:
- PORT=8080
- HOST=0.0.0.0
network_mode: "service:webserver_mtls-02-sidecar"
depends_on:
- webserver_mtls-02-sidecar

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

运行并测试

启动服务

docker-compose up

查看证书

查看代码

 # curl 172.31.7.2:9901/certs
{
"certificates": [
{
"ca_cert": [
{
"path": "/etc/envoy/ca/ca.crt",
"serial_number": "51d6bb31f33491a0c776fb6534c4c2f7794aaee0",
"subject_alt_names": [],
"days_until_expiration": "3649",
"valid_from": "2022-08-20T03:10:25Z",
"expiration_time": "2032-08-17T03:10:25Z"
}
],
"cert_chain": [
{
"path": "/etc/envoy/certs/client.crt",
"serial_number": "1001",
"subject_alt_names": [],
"days_until_expiration": "3649",
"valid_from": "2022-08-20T03:17:16Z",
"expiration_time": "2032-08-17T03:17:16Z"
}
]
},
{
"ca_cert": [],
"cert_chain": [
{
"path": "/etc/envoy/certs/server.crt",
"serial_number": "1000",
"subject_alt_names": [],
"days_until_expiration": "3649",
"valid_from": "2022-08-20T03:16:15Z",
"expiration_time": "2032-08-17T03:16:15Z"
}
]
},
{
"ca_cert": [
{
"path": "/etc/envoy/ca/ca.crt",
"serial_number": "51d6bb31f33491a0c776fb6534c4c2f7794aaee0",
"subject_alt_names": [],
"days_until_expiration": "3649",
"valid_from": "2022-08-20T03:10:25Z",
"expiration_time": "2032-08-17T03:10:25Z"
}
],
"cert_chain": []
}
]
}

查看front-envoy启动的Listener

# curl 172.31.7.2:9901/listeners
listener_http::0.0.0.0:80
listener_https::0.0.0.0:443

测试访问服务

我们可在curl命令上为其提供私有CA证书文件,或者使用“-k”选项忽略提示的风险,从而访问https服务。

http请求自动跳转至https服务上

# curl -I 172.31.7.2
HTTP/1.1 301 Moved Permanently
location: https://172.31.7.2:443/
date: Sat, 20 Aug 2022 08:14:44 GMT
server: envoy
transfer-encoding: chunked

访问http

# curl -k https://172.31.7.2/http/
iKubernetes demoapp v1.0 !! ClientIP: 127.0.0.1, ServerName: webserver_http-01, ServerIP: 172.31.7.11!
# curl -k https://172.31.7.2/http/
iKubernetes demoapp v1.0 !! ClientIP: 127.0.0.1, ServerName: webserver_http-02, ServerIP: 172.31.7.12!

访问tls

# curl -k https://172.31.7.2/tls/
iKubernetes demoapp v1.0 !! ClientIP: 127.0.0.1, ServerName: webserver_tls-01, ServerIP: 172.31.7.13!
# curl -k https://172.31.7.2/tls/
iKubernetes demoapp v1.0 !! ClientIP: 127.0.0.1, ServerName: webserver_tls-02, ServerIP: 172.31.7.14!

 访问mtls

# curl -k https://172.31.7.2/mtls/
iKubernetes demoapp v1.0 !! ClientIP: 127.0.0.1, ServerName: webserver_mtls-01, ServerIP: 172.31.7.15!
# curl -k https://172.31.7.2/mtls/
iKubernetes demoapp v1.0 !! ClientIP: 127.0.0.1, ServerName: webserver_mtls-02, ServerIP: 172.31.7.16!

查看访问日志

tls-wgs-2-envoy-1                                   | [2022-08-20T09:24:43.445Z] "GET /http/ HTTP/1.1" 200 - 0 103 2 2 "-" "curl/7.68.0" "bc0b5abb-2be1-4aaf-b146-b223ce330bbf" "172.31.7.2" "172.31.7.11:80"
tls-wgs-2-envoy-1 | [2022-08-20T09:24:45.006Z] "GET /http/ HTTP/1.1" 200 - 0 103 2 1 "-" "curl/7.68.0" "04b259d7-0e8a-45ff-aeea-023b6f8c0bf8" "172.31.7.2" "172.31.7.12:80"
tls-wgs-2-envoy-1 | [2022-08-20T09:24:48.928Z] "GET /tls/ HTTP/1.1" 200 - 0 102 5 4 "-" "curl/7.68.0" "b71bd17d-9fb6-42ff-bd66-166a7366215d" "172.31.7.2" "172.31.7.14:443"
tls-wgs-2-envoy-1 | [2022-08-20T09:24:51.585Z] "GET /tls/ HTTP/1.1" 200 - 0 102 3 2 "-" "curl/7.68.0" "076b3ec7-5a83-49b8-a663-e1bcaa560153" "172.31.7.2" "172.31.7.13:443"
tls-wgs-2-webserver_tls-01-sidecar-1 | [2022-08-20T09:24:51.586Z] "GET /tls/ HTTP/1.1" 200 - 0 102 2 1 "-" "curl/7.68.0" "076b3ec7-5a83-49b8-a663-e1bcaa560153" "172.31.7.2" "127.0.0.1:8080"
tls-wgs-2-webserver_mtls-01-sidecar-1 | [2022-08-20T09:24:54.662Z] "GET /mtls/ HTTP/1.1" 200 - 0 103 3 2 "-" "curl/7.68.0" "8532ac7a-aaba-4e47-a5d0-63d444a7a6e8" "172.31.7.2" "127.0.0.1:8080"
tls-wgs-2-webserver_mtls-01-sidecar-1 | [2022-08-20T09:24:55.801Z] "GET /mtls/ HTTP/1.1" 200 - 0 103 1 1 "-" "curl/7.68.0" "af41c174-c7a0-4227-8340-f161af0af4e1" "172.31.7.2" "127.0.0.1:8080"
tls-wgs-2-webserver_mtls-02-sidecar-1 | [2022-08-20T09:24:56.981Z] "GET /mtls/ HTTP/1.1" 200 - 0 103 2 2 "-" "curl/7.68.0" "49e4cbfa-f13f-4085-8866-b03a29b611d9" "172.31.7.2" "127.0.0.1:8080"
tls-wgs-2-envoy-1 | [2022-08-20T09:24:54.659Z] "GET /mtls/ HTTP/1.1" 200 - 0 103 7 6 "-" "curl/7.68.0" "8532ac7a-aaba-4e47-a5d0-63d444a7a6e8" "172.31.7.2" "172.31.7.15:443"
tls-wgs-2-envoy-1 | [2022-08-20T09:24:55.800Z] "GET /mtls/ HTTP/1.1" 200 - 0 103 2 2 "-" "curl/7.68.0" "af41c174-c7a0-4227-8340-f161af0af4e1" "172.31.7.2" "172.31.7.15:443"
tls-wgs-2-envoy-1 | [2022-08-20T09:24:56.981Z] "GET /mtls/ HTTP/1.1" 200 - 0 103 3 3 "-" "curl/7.68.0" "49e4cbfa-f13f-4085-8866-b03a29b611d9" "172.31.7.2" "172.31.7.16:443"

openssl s_client命令

查看代码

# openssl s_client -connect 172.31.7.2:443
# 如下命令结果显示,tls传话已然能正常建立,但curl命令无法任何服务端证书的CA,除非我们给命令指定相应的私有CA的证书,以便于验证服务端证书
CONNECTED(00000003)
Can't use SSL_get_servername
depth=0 CN = front-proxy
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 CN = front-proxy
verify error:num=21:unable to verify the first certificate
verify return:1
---
Certificate chain
0 s:CN = front-proxy
i:CN = envoy-ca
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIEkDCCAnigAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwEzERMA8GA1UEAwwIZW52
b3ktY2EwHhcNMjIwODIwMDMxNjE1WhcNMzIwODE3MDMxNjE1WjAWMRQwEgYDVQQD
DAtmcm9udC1wcm94eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMcj
jvCXA7P9S02uI8rZSVqbOegtz39ssPQ9bGkbtZjjBUGysqYs1VKdtR00Gy+eJ55F
1LwGA3fs8nBFNIo2eSAEMkr8tOQFELCbj7kJbMKFqCKBO2i61T4cP++uUM8QzlYw
rQNaLdZcdPPk6uZffd5Gt5N2DoakMt5O3OFV+EGQgbSb9LBdju3zQCkfwZNpewhs
RpMNzdT4m4pbM1dBnhq04sOHwsjwgApeLeTxWrV6DGCBkx6TXOPadnxrI+I7bChZ
65EO4WKHADqlTvlHtMfU+qB6qCHIRxP/k1dYA95PINZ9dB0gqqesah8x5f3soC2V
mQgw/cO8xvbbj4kx7JECAwEAAaOB6jCB5zAJBgNVHRMEAjAAMBEGCWCGSAGG+EIB
AQQEAwIGQDAzBglghkgBhvhCAQ0EJhYkT3BlblNTTCBHZW5lcmF0ZWQgU2VydmVy
IENlcnRpZmljYXRlMB0GA1UdDgQWBBRsX1uAWFyCxOOKG+tuSOH+W7ssyjBOBgNV
HSMERzBFgBRDVByyc+OZZC6ivLr2ujfpTFgT2KEXpBUwEzERMA8GA1UEAwwIZW52
b3ktY2GCFFHWuzHzNJGgx3b7ZTTEwvd5Sq7gMA4GA1UdDwEB/wQEAwIFoDATBgNV
HSUEDDAKBggrBgEFBQcDATANBgkqhkiG9w0BAQsFAAOCAgEAE5OiviTeeelTRYSZ
w6ml0xiPEm9VGfGvgV/hhrVimlRoLV/rjz52z+ZO2hpvgdEBlaRIheKz38EieDgo
QGZAUIgMZA2F2iVnhtPX3R5lGVClzfPq1pvZb30WH5ukMY7MGY82bfoUgzuCz9jS
h5sNrsGgI/qI9yAp/memgPCmEhInHhnpsq/RHJuF+HnX9F8GvG3xy3TOAZl1Fz05
WqlXustuMy9y0fb+wAwmSGX82bWwbgsRlmSy3ZfnVAG5DaZ+/gvljg/rxR9n2Xuq
59SbTqjlmskN7SohpmAmgF6wClz7AgpaKkXN9+wJ9t9fn3IUUC3PD9ETSuB7FAlT
stGiKz1ZdGcSnCkFaqJT3XIfGeT5W4Ujj6oKzNHr9rZ43g5IRHIscEx010nVatX9
Zr+zNoVivhhthuiA7CJvkvHJIMFCeadRmugVu2O23XhAde4vcIXymeXFtrGSBUW3
GUtByhEpOG0KiInHqHTr+DaZuAiXcfb3MjaPqyJ6Onth5hHDhK2VWGXrsWlFjJ6P
10mZzwjX8rNXx78oMWdU4frZNBarSEoVbeBvR+SEt19vVwhXZZOED5EUb8jBsLpl
t48Natd11R05RT57EWCl+1QPrvBCO3R64sj3KmWl1PPzpyUtlP1yov1pdbfXt+aQ
L785fuyO0FHXha61ldCmAhnMYAE=
-----END CERTIFICATE-----
subject=CN = front-proxy

issuer=CN = envoy-ca

---
No client certificate CA names sent
Peer signing digest: SHA256
Peer signature type: RSA-PSS
Server Temp Key: X25519, 253 bits
---
SSL handshake has read 1662 bytes and written 363 bytes
Verification error: unable to verify the first certificate
---
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Server public key is 2048 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 21 (unable to verify the first certificate)
---

TLS环境TCP Proxy模式配置实例

环境说明

五个Service:

  • envoy:Front Proxy,地址为172.31.9.2,监听于8443端口
  • webserver01:第一个后端服务
  • webserver01-sidecar:第一个后端服务的Sidecar Proxy,地址为172.31.9.11,监听于443端口
  • webserver02:第二个后端服务
  • webserver02-sidecar:第二个后端服务的Sidecar Proxy,地址为172.31.9.12, 监听于443端口

front-envoy.yaml

查看代码

 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_http
address:
socket_address: { address: 0.0.0.0, port_value: 8443 }
filter_chains:
- filters:
- name: envoy.filters.network.tcp_proxy
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
cluster: web_cluster_01
stat_prefix: https_passthrough

clusters:
- name: web_cluster_01
connect_timeout: 0.25s
type: STATIC
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: web_cluster_01
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address: { address: 172.31.9.11, port_value: 443 }
- endpoint:
address:
socket_address: { address: 172.31.9.12, port_value: 443 }

envoy-sidecar-proxy_https-passthrough.yaml

查看代码

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_0
address:
socket_address: { address: 0.0.0.0, port_value: 443 }
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
stat_prefix: ingress_http
codec_type: AUTO
route_config:
name: local_route
virtual_hosts:
- name: local_service
domains: ["*"]
routes:
- match: { prefix: "/" }
route: { cluster: local_cluster }
http_filters:
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.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_certificates:
- certificate_chain:
filename: "/etc/envoy/certs/server.crt"
private_key:
filename: "/etc/envoy/certs/server.key"

clusters:
- name: local_cluster
connect_timeout: 0.25s
type: STATIC
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: local_cluster
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address: { address: 127.0.0.1, port_value: 8080 }

docker-compose.yaml

查看代码

version: '3.3'

services:
envoy:
image: envoyproxy/envoy:v1.23-latest
volumes:
- ./front-envoy.yaml:/etc/envoy/envoy.yaml
networks:
envoymesh:
ipv4_address: 172.31.9.2
aliases:
- front-proxy
depends_on:
- webserver01-sidecar
- webserver02-sidecar

webserver01-sidecar:
image: envoyproxy/envoy:v1.23-latest
volumes:
- ./envoy-sidecar-proxy_https-passthrough.yaml:/etc/envoy/envoy.yaml
- ./certs/front-envoy/:/etc/envoy/certs/
hostname: webserver01
networks:
envoymesh:
ipv4_address: 172.31.9.11
aliases:
- webserver01-sidecar

webserver01:
image: ikubernetes/demoapp:v1.0
environment:
- PORT=8080
- HOST=127.0.0.1
network_mode: "service:webserver01-sidecar"
depends_on:
- webserver01-sidecar

webserver02-sidecar:
image: envoyproxy/envoy:v1.23-latest
volumes:
- ./envoy-sidecar-proxy_https-passthrough.yaml:/etc/envoy/envoy.yaml
- ./certs/front-envoy/:/etc/envoy/certs/
hostname: webserver02
networks:
envoymesh:
ipv4_address: 172.31.9.12
aliases:
- webserver02-sidecar

webserver02:
image: ikubernetes/demoapp:v1.0
environment:
- PORT=8080
- HOST=127.0.0.1
network_mode: "service:webserver02-sidecar"
depends_on:
- webserver02-sidecar

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

运行和测试

创建

docker-compose up

测试服务

# curl -k  https://172.31.9.2:8443/
iKubernetes demoapp v1.0 !! ClientIP: 127.0.0.1, ServerName: webserver02, ServerIP: 172.31.9.12!
# curl -k https://172.31.9.2:8443/
iKubernetes demoapp v1.0 !! ClientIP: 127.0.0.1, ServerName: webserver01, ServerIP: 172.31.9.11!

 停止后清理

docker-compose down

参考文档

​​https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/transport_socket/transport_socket​​

​​https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/base.proto#envoy-v3-api-msg-config-core-v3-transportsocket​​

​​https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/transport_sockets/tls/v3/tls.proto#extension-envoy-transport-sockets-tls​​

​​https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/transport_sockets/tls/v3/tls.proto#envoy-v3-api-msg-extensions-transport-sockets-tls-v3-downstreamtlscontext​​

​​https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/transport_sockets/tls/v3/tls.proto#envoy-v3-api-msg-extensions-transport-sockets-tls-v3-upstreamtlscontext​​

 



举报

相关推荐

0 条评论