One App - Two proxies

Application
Application access requirement
This specifc use-case revolves around providing secure and un-secure access to an application. Internal consumption of application API needs bypassing SSL. External consumption of the application API happens over SSL
We demonstrate the use-case using the petstore example.
Application architecture
The customer use-case needs configuration of two proxies to achieve this. One runs the application without the certificate and another one runs it with the certificate.
We’ll walk through the following list of steps to achieve this objective
- Start control plane (For this example, we assume it is already running on https://controller.local:8443
- Create proxies, one for petstore, another for petstore-https
- Create service, one for petstore, another for petstore-https
- Associate route and upstream with petstore and petstore-https service
- Create secret and attach secret to petstore-https
- Associate psetstore service to petstore proxy
- Associate psetstore-https service to petstore-https proxy
- Send test traffic to petstore-http and petstore-https
Control Plane
Control Plane for proxy configuration
We spin up a control plane to create proxies and applications. Each of the data plane components connect to this control plane to read their config.
Control Plane API
The control plane exposes a RESTful API to administer proxies. The API provides complete control over the proxies.
The admin API accepts content type application/json.
Control Plane Abstractions
- Proxy : Proxy defines configuration associated with one proxy.
- Service : Service is configuration associated with a listener. We associate service with a proxy to program it on a proxy.
- Route : Route defines L7 routing rules.
- Upstream : Upstream represents an endpoint to send traffic to
Creating Proxies
Proxy is our high level abstraction that holds configuration related to a proxy. We initially create proxies on the control plane.
Create proxy to serve application over http
Proxy can be created using the following commands -
$ curl -s -X POST https://controller.local:8443/proxy -d '{"Name":"petstore"}' -H "Content-Type: application/json" -H "Authorization: Bearer treeseverywhere" | python -m json.tool
{
"name": "petstore"
}
To get details about the proxy -
$ curl -s https://controller.local:8443/proxy/petstore -H "Authorization: Bearer treeseverywhere" | python -m json.tool
{
"data": {
"saaras_db_proxy": [
{
"create_ts": "2019-09-17T22:03:23.307982+00:00",
"proxy_id": 18,
"proxy_name": "petstore",
"update_ts": "2019-09-17T22:05:12.004973+00:00"
}
]
}
}
Create another proxy to serve traffic over https, check list of proxies
We repeat the steps above with “petstore-https” to create another proxy. Once created, check the list of proxies created -
$ curl -s https://controller.local:8443/proxy -H "Authorization: Bearer treeseverywhere" | python -m json.tool
{
"data": {
"saaras_db_proxy": [
{
"create_ts": "2019-09-17T22:03:23.307982+00:00",
"proxy_id": 18,
"proxy_name": "petstore",
"update_ts": "2019-09-17T22:05:12.004973+00:00"
},
{
"create_ts": "2019-09-17T22:27:35.555514+00:00",
"proxy_id": 20,
"proxy_name": "petstore-https",
"update_ts": "2019-09-17T22:54:26.053712+00:00"
}
]
}
}
Connecting data plane to proxies
Saaras data plane container
The Saaras data plane container comes pre-packaged with Envoy. It is accessible on docker at saarasio/enroute
Running data plane container
Running the data plane requires specifying the IP address and port of the control plane. The data plane container takes three arguments to determine details about the control plane.
- ENROUTE_NAME - this is the name of the proxy created on the control plane
- ENROUTE_CP_IP - this is the IP or the host to connect to the control plane
- ENROUTE_CP_PORT - this is the port of the host to connect to the control plane
- ENROUTE_CP_PROTO - the protocol to use to connect to the control plane
We create the data plane for petstore proxy using the following command -
docker run -e ENROUTE_NAME=petstore -e ENROUTE_CP_IP=controller.local -e ENROUTE_CP_PORT=8443 -e ENROUTE_CP_PROTO=HTTPS -p 80:8080 saarasio/enroute
By default listener inside the container is created on port 8080. This port is published to the host stack using the -p 80:8080
directive. We connect to the control plane over HTTPS.
We create the data plane for petstore-https proxy using the following command -
sudo docker run -e ENROUTE_NAME=petstore-https -e ENROUTE_CP_IP=controller.local -e ENROUTE_CP_PORT=8443 -e ENROUTE_CP_PROTO=HTTPS -p 443:8443 saarasio/enroute
Programming the application on one proxy
An application is built using service -> route(s) -> upstream. The controller has APIs to work with these objects. Here we demonstrate how to work with each of these abstractions.
Under the hood, this configuration is streamed to the corresponding Envoy proxy over xDS APIs.
Create service
We start off by creating a service. A service can be created using the following API -
curl -s -X POST https://controller.local:8443/service -H "Content-Type: application/json" -H "Authorization: Bearer treeseverywhere" -d '{"Service_Name":"petstore", "Fqdn":"petstore.local"}' | python -m json.tool
{
"data": {
"saaras_db_service": [
{
"create_ts": "2019-09-12T00:14:21.68843+00:00",
"fqdn": "petstore.local",
"service_id": 30,
"service_name": "petstore",
"update_ts": "2019-09-17T22:29:31.623226+00:00"
}
]
}
}
Here is how you view all the services -
$ curl -s https://controller.local:8443/service -H "Authorization: Bearer treeseverywhere" | python -m json.tool
{
"data": {
"saaras_db_service": [
{
"create_ts": "2019-09-12T00:14:21.68843+00:00",
"fqdn": "petstore.local",
"service_id": 30,
"service_name": "petstore",
"update_ts": "2019-09-17T22:29:31.623226+00:00"
},
{
"create_ts": "2019-09-17T22:53:27.129213+00:00",
"fqdn": "petstore-https.local",
"service_id": 94,
"service_name": "petstore-https",
"update_ts": "2019-09-17T23:23:37.433466+00:00"
}
]
}
}
To view just one service, qualify the above command with service name -
$ curl -s https://controller.local:8443/service/petstore -H "Authorization: Bearer treeseverywhere" | python -m json.tool
{
"data": {
"saaras_db_service": [
{
"create_ts": "2019-09-12T00:14:21.68843+00:00",
"fqdn": "petstore.local",
"service_id": 30,
"service_name": "petstore",
"update_ts": "2019-09-17T22:29:31.623226+00:00"
}
]
}
}
Create route(s) for service
Routes are rules to provide L7 routing information to Envoy. To create a route for the petstore, use the following command.
$ curl -s -X POST https://controller.local:8443/service/petstore/route -H "Content-Type: application/json" -H "Authorization: Bearer treeseverywhere" -d '{"Route_name":"default", "Route_prefix":"/"}' | python -m json.tool
{
"data": {
"insert_saaras_db_route": {
"affected_rows": 2
}
}
}
You can also see a service, its routes and associated upstream using the dump api for a service. We can look at a service and its associated route using the following command -
curl -s https://controller.local:8443/service/dump/petstore -H "Authorization: Bearer treeseverywhere" | python -m json.tool
{
"data": {
"saaras_db_service": [
{
"create_ts": "2019-09-12T00:14:21.68843+00:00",
"fqdn": "petstore.local",
"routes": [
{
"route_id": 19,
"route_name": "default",
"route_prefix": "/",
},
],
"service_id": 30,
"service_name": "petstore",
"service_secrets": []
}
]
}
}
Create upstream
Next we create an upstream that will serve this traffic -
$ curl -s -X POST https://controller.local:8443/upstream -H "Content-Type: application/json" -H "Authorization: Bearer treeseverywhere" -d '{"Upstream_name":"default", "Upstream_ip":"172.31.18.10", "Upstream_port":"8088", "Upstream_weight":"100", "Upstream_hc_path": "/" }' | python -m json.tool
{
"data": {
"insert_saaras_db_upstream": {
"affected_rows": 1
}
}
}
View the upstream
Use the following command to view the upstream -
$ curl -s https://controller.local:8443/upstream/default -H "Authorization: Bearer treeseverywhere" | python -m json.tool
{
"data": {
"saaras_db_upstream": [
{
"create_ts": "2019-09-12T00:38:05.564381+00:00",
"update_ts": "2019-09-17T22:53:27.139382+00:00",
"upstream_hc_healthythresholdcount": 0,
"upstream_hc_host": "",
"upstream_hc_intervalseconds": 0,
"upstream_hc_path": "/",
"upstream_hc_timeoutseconds": 0,
"upstream_hc_unhealthythresholdcount": 0,
"upstream_id": 16,
"upstream_ip": "172.31.18.10",
"upstream_name": "default",
"upstream_port": 8088,
"upstream_strategy": "",
"upstream_validation_cacertificate": "",
"upstream_validation_subjectname": "",
"upstream_weight": 100
}
]
}
}
Associate upstream with routes
We have created a service, a route for this service. Next we created an upstream. However this upstream is not associated with the route. Here we associate the upstream with the route -
$ curl -s -X POST https://controller.local:8443/service/petstore/route/default/upstream/default -H "Content-Type: application/json" -H "Authorization: Bearer treeseverywhere" | python -m json.tool
{
"data": {
"insert_saaras_db_route_upstream": {
"affected_rows": 4
}
}
}
Dump service to view (service -> route -> upstream)
$ curl -s https://controller.local:8443/service/dump/petstore -H "Authorization: Bearer treeseverywhere" | python -m json.tool
{
"data": {
"saaras_db_service": [
{
"create_ts": "2019-09-12T00:14:21.68843+00:00",
"fqdn": "petstore.local",
"routes": [
{
"route_id": 19,
"route_name": "default",
"route_prefix": "/",
"route_upstreams": [
{
"upstream": {
"upstream_id": 16,
"upstream_ip": "172.31.18.10",
"upstream_name": "default",
"upstream_port": 8088
}
}
]
},
],
"service_id": 30,
"service_name": "petstore",
"service_secrets": []
}
]
}
}
Associate the service with petstore proxy
curl -s -X POST https://controller.local:8443/proxy/petstore/service/petstore -H "Authorization: Bearer treeseverywhere" | python -m json.tool
Dump petstore proxy config
$ curl -s https://controller.local:8443/proxy/dump/petstore -H "Authorization: Bearer treeseverywhere" | python -m json.tool
{
"data": {
"saaras_db_proxy": [
{
"create_ts": "2019-09-17T22:03:23.307982+00:00",
"proxy_id": 18,
"proxy_name": "petstore",
"proxy_services": [
{
"service": {
"create_ts": "2019-09-12T00:14:21.68843+00:00",
"fqdn": "petstore.local",
"routes": [
{
"create_ts": "2019-09-12T00:19:06.462858+00:00",
"route_id": 19,
"route_name": "default",
"route_prefix": "/",
"route_upstreams": [
{
"upstream": {
"create_ts": "2019-09-12T00:38:05.564381+00:00",
"update_ts": "2019-09-17T22:53:27.139382+00:00",
"upstream_hc_healthythresholdcount": 0,
"upstream_hc_host": "",
"upstream_hc_intervalseconds": 0,
"upstream_hc_path": "/",
"upstream_hc_timeoutseconds": 0,
"upstream_hc_unhealthythresholdcount": 0,
"upstream_id": 16,
"upstream_ip": "172.31.18.10",
"upstream_name": "default",
"upstream_port": 8088,
"upstream_strategy": "",
"upstream_validation_cacertificate": "",
"upstream_validation_subjectname": "",
"upstream_weight": 100
}
}
],
"update_ts": "2019-09-23T22:22:09.688875+00:00"
},
{
"create_ts": "2019-09-12T01:50:11.47308+00:00",
"route_id": 22,
"route_name": "proxy_admin",
"route_prefix": "/admin",
"route_upstreams": [
{
"upstream": {
"create_ts": "2019-09-12T01:58:29.441053+00:00",
"update_ts": "2019-09-17T22:53:27.174974+00:00",
"upstream_hc_healthythresholdcount": null,
"upstream_hc_host": null,
"upstream_hc_intervalseconds": null,
"upstream_hc_path": "/admin",
"upstream_hc_timeoutseconds": null,
"upstream_hc_unhealthythresholdcount": null,
"upstream_id": 21,
"upstream_ip": "127.0.0.1",
"upstream_name": "proxy_admin",
"upstream_port": 9001,
"upstream_strategy": null,
"upstream_validation_cacertificate": null,
"upstream_validation_subjectname": null,
"upstream_weight": 100
}
}
],
"update_ts": "2019-09-12T02:01:23.085169+00:00"
},
{
"create_ts": "2019-09-12T02:06:49.882298+00:00",
"route_id": 26,
"route_name": "proxy_listeners",
"route_prefix": "/listeners",
"route_upstreams": [
{
"upstream": {
"create_ts": "2019-09-12T01:58:29.441053+00:00",
"update_ts": "2019-09-17T22:53:27.174974+00:00",
"upstream_hc_healthythresholdcount": null,
"upstream_hc_host": null,
"upstream_hc_intervalseconds": null,
"upstream_hc_path": "/admin",
"upstream_hc_timeoutseconds": null,
"upstream_hc_unhealthythresholdcount": null,
"upstream_id": 21,
"upstream_ip": "127.0.0.1",
"upstream_name": "proxy_admin",
"upstream_port": 9001,
"upstream_strategy": null,
"upstream_validation_cacertificate": null,
"upstream_validation_subjectname": null,
"upstream_weight": 100
}
}
],
"update_ts": "2019-09-12T02:07:32.451421+00:00"
},
{
"create_ts": "2019-09-12T02:08:00.49249+00:00",
"route_id": 28,
"route_name": "proxy_clusters",
"route_prefix": "/clusters",
"route_upstreams": [
{
"upstream": {
"create_ts": "2019-09-12T01:58:29.441053+00:00",
"update_ts": "2019-09-17T22:53:27.174974+00:00",
"upstream_hc_healthythresholdcount": null,
"upstream_hc_host": null,
"upstream_hc_intervalseconds": null,
"upstream_hc_path": "/admin",
"upstream_hc_timeoutseconds": null,
"upstream_hc_unhealthythresholdcount": null,
"upstream_id": 21,
"upstream_ip": "127.0.0.1",
"upstream_name": "proxy_admin",
"upstream_port": 9001,
"upstream_strategy": null,
"upstream_validation_cacertificate": null,
"upstream_validation_subjectname": null,
"upstream_weight": 100
}
}
],
"update_ts": "2019-09-12T02:08:08.684786+00:00"
}
],
"service_id": 30,
"service_name": "petstore",
"service_secrets": [],
"update_ts": "2019-09-23T22:22:09.688875+00:00"
}
}
],
"update_ts": "2019-09-17T22:05:12.004973+00:00"
}
]
}
}
Create service to serve application over HTTPS - use deepcopy
curl -s -X POST https://controller.local:8443/service/deepcopy/petstore/petstore-https -H "Authorization: Bearer treeseverywhere" | python -m json.tool
Create and associate Secret to the newly created service
Next we show how create a secret and upload a key and a cert for that secret
Create a secret
- Create a secret
curl -s -X POST https://controller.local:8443/secret -d '{"Secret_name":"petstore-https-secret"}' -H "Content-Type: application/json" -H "Authorization: Bearer treeseverywhere" | python -m json.tool
- Upload a key
curl -vvv -X POST -F 'Secret_key=@privkey.pem' https://controller.local:8443/secret/petstore-https-secret/key -H "Authorization: Bearer treeseverywhere" | python -m json.tool
- Upload a cert
curl -vvv -X POST -F 'Secret_cert=@fullchain.pem' https://controller.local:8443/secret/petstore-https-secret/cert -H "Authorization: Bearer treeseverywhere" | python -m json.tool
Attach the secret to a service
curl -s -X POST https://controller.local:8443/service/petstore-https/secret/petstore-https-secret -H "Authorization: Bearer treeseverywhere" | python -m json.tool
Associate the service with petstore-https proxy
curl -s -X POST https://controller.local:8443/proxy/petstore-https/service/petstore-https -H "Authorization: Bearer treeseverywhere" | python -m json.tool
Dump petstore-https proxy config
$ curl -s https://controller.local:8443/proxy/dump/petstore-https -H "Authorization: Bearer treeseverywhere" | python -m json.tool
{
"data": {
"saaras_db_proxy": [
{
"create_ts": "2019-09-17T22:27:35.555514+00:00",
"proxy_id": 20,
"proxy_name": "petstore-https",
"proxy_services": [
{
"service": {
"create_ts": "2019-09-17T22:53:27.129213+00:00",
"fqdn": "petstore-https.local",
"routes": [
{
"create_ts": "2019-09-17T22:53:27.133695+00:00",
"route_id": 72,
"route_name": "default",
"route_prefix": "/",
"route_upstreams": [
{
"upstream": {
"create_ts": "2019-09-12T00:38:05.564381+00:00",
"update_ts": "2019-09-17T22:53:27.139382+00:00",
"upstream_hc_healthythresholdcount": 0,
"upstream_hc_host": "",
"upstream_hc_intervalseconds": 0,
"upstream_hc_path": "/",
"upstream_hc_timeoutseconds": 0,
"upstream_hc_unhealthythresholdcount": 0,
"upstream_id": 16,
"upstream_ip": "172.31.18.10",
"upstream_name": "default",
"upstream_port": 8088,
"upstream_strategy": "",
"upstream_validation_cacertificate": "",
"upstream_validation_subjectname": "",
"upstream_weight": 100
}
}
],
"update_ts": "2019-09-17T22:53:27.139382+00:00"
},
{
"create_ts": "2019-09-17T22:53:27.14846+00:00",
"route_id": 74,
"route_name": "proxy_admin",
"route_prefix": "/admin",
"route_upstreams": [
{
"upstream": {
"create_ts": "2019-09-12T01:58:29.441053+00:00",
"update_ts": "2019-09-17T22:53:27.174974+00:00",
"upstream_hc_healthythresholdcount": null,
"upstream_hc_host": null,
"upstream_hc_intervalseconds": null,
"upstream_hc_path": "/admin",
"upstream_hc_timeoutseconds": null,
"upstream_hc_unhealthythresholdcount": null,
"upstream_id": 21,
"upstream_ip": "127.0.0.1",
"upstream_name": "proxy_admin",
"upstream_port": 9001,
"upstream_strategy": null,
"upstream_validation_cacertificate": null,
"upstream_validation_subjectname": null,
"upstream_weight": 100
}
}
],
"update_ts": "2019-09-17T22:53:27.151782+00:00"
},
{
"create_ts": "2019-09-17T22:53:27.162287+00:00",
"route_id": 76,
"route_name": "proxy_listeners",
"route_prefix": "/listeners",
"route_upstreams": [
{
"upstream": {
"create_ts": "2019-09-12T01:58:29.441053+00:00",
"update_ts": "2019-09-17T22:53:27.174974+00:00",
"upstream_hc_healthythresholdcount": null,
"upstream_hc_host": null,
"upstream_hc_intervalseconds": null,
"upstream_hc_path": "/admin",
"upstream_hc_timeoutseconds": null,
"upstream_hc_unhealthythresholdcount": null,
"upstream_id": 21,
"upstream_ip": "127.0.0.1",
"upstream_name": "proxy_admin",
"upstream_port": 9001,
"upstream_strategy": null,
"upstream_validation_cacertificate": null,
"upstream_validation_subjectname": null,
"upstream_weight": 100
}
}
],
"update_ts": "2019-09-17T22:53:27.165597+00:00"
},
{
"create_ts": "2019-09-17T22:53:27.171819+00:00",
"route_id": 78,
"route_name": "proxy_clusters",
"route_prefix": "/clusters",
"route_upstreams": [
{
"upstream": {
"create_ts": "2019-09-12T01:58:29.441053+00:00",
"update_ts": "2019-09-17T22:53:27.174974+00:00",
"upstream_hc_healthythresholdcount": null,
"upstream_hc_host": null,
"upstream_hc_intervalseconds": null,
"upstream_hc_path": "/admin",
"upstream_hc_timeoutseconds": null,
"upstream_hc_unhealthythresholdcount": null,
"upstream_id": 21,
"upstream_ip": "127.0.0.1",
"upstream_name": "proxy_admin",
"upstream_port": 9001,
"upstream_strategy": null,
"upstream_validation_cacertificate": null,
"upstream_validation_subjectname": null,
"upstream_weight": 100
}
}
],
"update_ts": "2019-09-17T22:53:27.174974+00:00"
}
],
"service_id": 94,
"service_name": "petstore-https",
"service_secrets": [
{
"secret": {
"create_ts": "2019-09-17T23:10:48.299743+00:00",
"secret_cert": "-----BEGIN CERTIFICATE-----
MIIFdDCCBFygAwIBAgISA8jvDUl7GQ1VfzT3GBpMpMAdMA0GCSqGSIb3DQEBCwUA
MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQD
ExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMzAeFw0xOTA5MTcyMjA4MjBaFw0x
OTEyMTYyMjA4MjBaMCgxJjAkBgNVBAMTHXBldHN0b3JlLWh0dHBzLmluZ3Jlc3Nw
aXBlLmlvMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvvsGNbgelrwQ
r8x3znQg8GOwae69/FAeUcVwqz+OPieKmvq/Y3OMC5L2gPrEv/yynut3wyxhNRZI
Fm8UV8s1rqiS1LiMumO3FED4etSM3uYRYo7vz6fVWnmdl5Lgw8BH07tS3cC/afI/
ZW6sdnk09PYH/dfYIRf/oyvxXVW5y6gtcU7/ACKKpX5QrIP+0wPyNYftZSley0s7
fV44kZ3LosXWIEILzxvhmNK4OH9yXdvQXL9d30NIydSG2tbwsTWRs6jBaqkMafAN
eypegRwT/sAeOxRe1WSEb6QycyaHYnpF3c45LsSRMgeneq6FphOfwgWYEpzna2iU
ElH06b2QWQIDAQABo4ICdDCCAnAwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQG
CCsGAQUFBwMBBggrBgEFBQcDAjAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBRD7RrZ
Ic9CKq2l47JbFhdAxyV90jAfBgNVHSMEGDAWgBSoSmpjBH3duubRObemRWXv86js
oTBvBggrBgEFBQcBAQRjMGEwLgYIKwYBBQUHMAGGImh0dHA6Ly9vY3NwLmludC14
My5sZXRzZW5jcnlwdC5vcmcwLwYIKwYBBQUHMAKGI2h0dHA6Ly9jZXJ0LmludC14
My5sZXRzZW5jcnlwdC5vcmcvMCgGA1UdEQQhMB+CHXBldHN0b3JlLWh0dHBzLmlu
Z3Jlc3NwaXBlLmlvMEwGA1UdIARFMEMwCAYGZ4EMAQIBMDcGCysGAQQBgt8TAQEB
MCgwJgYIKwYBBQUHAgEWGmh0dHA6Ly9jcHMubGV0c2VuY3J5cHQub3JnMIIBBgYK
KwYBBAHWeQIEAgSB9wSB9ADyAHcAdH7agzGtMxCRIZzOJU9CcMK//V5CIAjGNzV5
5hB7zFYAAAFtQXvg3AAABAMASDBGAiEAsLBIXPgQZL8K86PaKKqN2sDvsWgzw7mT
QhJoI6wkY8UCIQDmp69yj3O2IH8TS89ueMaJbe9Ls+fddpIhqcbIEnfsQAB3ACk8
UZZUyDlluqpQ/FgH1Ldvv1h6KXLcpMMM9OVFR/R4AAABbUF74PQAAAQDAEgwRgIh
APkNCQIDsUM6VY/Q8xsaNjTnSNVa9WwrqUvfOObYgSvjAiEA8SNeKn1D7zyMeQuD
3zU1akhs9UtTi6GNnBvh9tPdPAwwDQYJKoZIhvcNAQELBQADggEBAAaR8tbgr7Sk
eF2nHPKvKL1GHVjhH/DRWWyUA1e+EGznXBFCeYJNnfsDtbnF9X6T7IkIqDkvVI5G
QTi6SKNtj/IXOmgibtoCYKSrv7gbxA8t0+4C7H7PyS/+ApO4gHJqG81PdTtQSvIa
G+vJ7EynKASXvj1jpWsRAbws63XVzXvZN4IZPVWWs32FxWTbiNfL8iylbRmoWpr5
iTfvLa+Oh+nGqBtwGMlnTjjwoGIz7lshhGOdhr7tMkf5BS/zOOxRGWaE57eIvQi8
9l3WIRzrrPRKRIqwB72ITg87hCy9DJSwYmtfwe1l4JtWWyrFfXVhhV5kcheSuf5a
Yef9y9ufFZ4=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2oLheynCDANBgkqhkiG9w0BAQsFADA/
MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
DkRTVCBSb290IENBIFgzMB4XDTE2MDMxNzE2NDA0NloXDTIxMDMxNzE2NDA0Nlow
SjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxIzAhBgNVBAMT
GkxldCdzIEVuY3J5cHQgQXV0aG9yaXR5IFgzMIIBIjANBgkqhkiG9w0BAQEFAAOC
AQ8AMIIBCgKCAQEAnNMM8FrlLke3cl03g7NoYzDq1zUmGSXhvb418XCSL7e4S0EF
q6meNQhY7LEqxGiHC6PjdeTm86dicbp5gWAf15Gan/PQeGdxyGkOlZHP/uaZ6WA8
SMx+yk13EiSdRxta67nsHjcAHJyse6cF6s5K671B5TaYucv9bTyWaN8jKkKQDIZ0
Z8h/pZq4UmEUEz9l6YKHy9v6Dlb2honzhT+Xhq+w3Brvaw2VFn3EK6BlspkENnWA
a6xK8xuQSXgvopZPKiAlKQTGdMDQMc2PMTiVFrqoM7hD8bEfwzB/onkxEz0tNvjj
/PIzark5McWvxI0NHWQWM6r6hCm21AvA2H3DkwIDAQABo4IBfTCCAXkwEgYDVR0T
AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwfwYIKwYBBQUHAQEEczBxMDIG
CCsGAQUFBzABhiZodHRwOi8vaXNyZy50cnVzdGlkLm9jc3AuaWRlbnRydXN0LmNv
bTA7BggrBgEFBQcwAoYvaHR0cDovL2FwcHMuaWRlbnRydXN0LmNvbS9yb290cy9k
c3Ryb290Y2F4My5wN2MwHwYDVR0jBBgwFoAUxKexpHsscfrb4UuQdf/EFWCFiRAw
VAYDVR0gBE0wSzAIBgZngQwBAgEwPwYLKwYBBAGC3xMBAQEwMDAuBggrBgEFBQcC
ARYiaHR0cDovL2Nwcy5yb290LXgxLmxldHNlbmNyeXB0Lm9yZzA8BgNVHR8ENTAz
MDGgL6AthitodHRwOi8vY3JsLmlkZW50cnVzdC5jb20vRFNUUk9PVENBWDNDUkwu
Y3JsMB0GA1UdDgQWBBSoSmpjBH3duubRObemRWXv86jsoTANBgkqhkiG9w0BAQsF
AAOCAQEA3TPXEfNjWDjdGBX7CVW+dla5cEilaUcne8IkCJLxWh9KEik3JHRRHGJo
uM2VcGfl96S8TihRzZvoroed6ti6WqEBmtzw3Wodatg+VyOeph4EYpr/1wXKtx8/
wApIvJSwtmVi4MFU5aMqrSDE6ea73Mj2tcMyo5jMd6jmeWUHK8so/joWUoHOUgwu
X4Po1QYz+3dszkDqMp4fklxBwXRsW10KXzPMTZ+sOPAveyxindmjkW8lGy+QsRlG
PfZ+G6Z6h7mjem0Y+iWlkYcV4PIWL1iwBi8saCbGS5jN2p8M+X+Q7UNKEkROb3N6
KOqkqm57TH2H3eDJAkSnh6/DNFu0Qg==
-----END CERTIFICATE-----
",
"secret_id": 5,
"secret_key": "-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC++wY1uB6WvBCv
zHfOdCDwY7Bp7r38UB5RxXCrP44+J4qa+r9jc4wLkvaA+sS//LKe63fDLGE1FkgW
bxRXyzWuqJLUuIy6Y7cUQPh61Ize5hFiju/Pp9VaeZ2XkuDDwEfTu1LdwL9p8j9l
bqx2eTT09gf919ghF/+jK/FdVbnLqC1xTv8AIoqlflCsg/7TA/I1h+1lKV7LSzt9
XjiRncuixdYgQgvPG+GY0rg4f3Jd29Bcv13fQ0jJ1Iba1vCxNZGzqMFqqQxp8A17
Kl6BHBP+wB47FF7VZIRvpDJzJodiekXdzjkuxJEyB6d6roWmE5/CBZgSnOdraJQS
UfTpvZBZAgMBAAECggEAI81vZpaztVJgVnSgaSXAHxCxO8qz9x8V8AJxkskBY4mK
JG+pfX1l3a2ZZKieRdebrMs70mz5dDhPH1WHnMXNtIaJsDNAvph+898SNgSuvAKp
c66UKnuuNZ3i+01fsZLUZE8Tw9qkh7oQRHWxAyzJzrpo2R+jtuCG3hIY14SApjr4
EoBddLvaC6GXb2wfzeX2GGw4TBTTaxqeV9sbloq6WyekP3VSvt9Plkc/CoPN0Gab
0bnENEDbX5c6zklItBpVgb+sS/D9au1F8SkyElYutSpiwt7hgSbd+QLSghhcpQL6
U0o4wMc40UggxfdsHeVJuP6s7ygEYsLeDsg3r8IamQKBgQDdWpKa0vDRobky4b6j
jHyxch7WiqrNJCzYXZzb5VHpzHVufs9fCEAjxoHTe4pSdVezgCj010FFVqRG+fCP
eilS2VC0s/VPFl4VmR6cgbaINd+Y0XdyFbaD4Z8do7yg0cscizT+yss1qT4hQs3r
J39uYMaeuAT8lpGHF3j7sczI5wKBgQDc320WbsLQPNQYunxcW8ljjXp+Z954URqb
P5BIQqXLdgG83yIzAL3aIFpeGJ8akd4/cZQpT+oEcNeaEefxVaf8wdC8KrxhGtaW
G6gXRXHGuXoMMzHmSecc79pAQaoFSqOXCxNUlRDeq5CY4tFZaivZvBX4Bhn9XCCr
rf74TV10vwKBgQCW+rk2axyhD9r/TqS2bxN6AOnx0eFQTRVdevSLtC2b9749YLdX
DYyaGkLhGcmuFqV8JLVK0yuM/NzOIJqpclyPSvTWXEy85ffEaY1MmNkErSJW3MDJ
CvBToefi0pTNaGtOi9DY3T+f2VEsZKGJfIZZph6zkbatBpI6f5MgshSJDwKBgFHG
RtUvXOFMJBqjsLdhJEa/csKqIivZm0gvWHPoeQnDPxF2a2sGs0O3Br4fz4g+yVIj
8v74n2PVg31/c6heVju2ZlnEWMp67UfWJX24ME+rDAzIR4lDg1WrV9rCdPhQkhCy
AQ4nwn8udfKkx22baXDLujaBy82J9m6ZlPTJb/hxAoGBAJCJgdL1qrqae6wuq9jW
ua+yN+EAmdsGwKJ7Z47et/nAW5JQcDInmxeyOZcgnd/8NnqBCY2J+niRo+fJhNEk
GS7XA/g4/qciPreAEqRZ1tROVqfHcgFkM3DCAIU5S4qDBAOFmEF/7o9UzN3DH/XP
vRgHw3tvqapryvZcZwujhDvk
-----END PRIVATE KEY-----
",
"secret_name": "petstore-https-secret",
"update_ts": "2019-09-17T23:23:37.433466+00:00"
}
}
],
"update_ts": "2019-09-17T23:23:37.433466+00:00"
}
}
],
"update_ts": "2019-09-17T22:54:26.053712+00:00"
}
]
}
}
Test traffic
Test petstore app
$ curl -vvv petstore.local
* Rebuilt URL to: petstore.local/
* Trying 13.52.165.162...
* TCP_NODELAY set
* Connected to petstore.local (13.52.165.162) port 80 (#0)
> GET / HTTP/1.1
> Host: petstore.local
> User-Agent: curl/7.54.0
> Accept: */*
>
< HTTP/1.1 200 OK
< last-modified: Mon, 13 Aug 2018 06:26:44 GMT
< accept-ranges: bytes
< content-type: text/html;charset=UTF-8
< content-language: en-US
< content-length: 1832
< date: Mon, 23 Sep 2019 23:02:18 GMT
< x-envoy-upstream-service-time: 2
< server: envoy
<
<!-- HTML for static distribution bundle build -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Swagger UI</title>
<link href="https://fonts.googleapis.com/css?family=Open+Sans:400,700|Source+Code+Pro:300,600|Titillium+Web:400,600,700" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="./swagger-ui/swagger-ui.css" >
<link rel="icon" type="image/png" href="./swagger-ui/favicon-32x32.png" sizes="32x32" />
<link rel="icon" type="image/png" href="./swagger-ui/favicon-16x16.png" sizes="16x16" />
<style>
html
{
box-sizing: border-box;
overflow: -moz-scrollbars-vertical;
overflow-y: scroll;
}
*,
*:before,
*:after
{
box-sizing: inherit;
}
body
{
margin:0;
background: #fafafa;
}
</style>
</head>
<body>
<div id="swagger-ui"></div>
<script src="./swagger-ui/swagger-ui-bundle.js"> </script>
<script src="./swagger-ui/swagger-ui-standalone-preset.js"> </script>
<script>
window.onload = function() {
// Build a system
const ui = SwaggerUIBundle({
url: "/openapi.json",
dom_id: '#swagger-ui',
deepLinking: true,
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIStandalonePreset
],
plugins: [
SwaggerUIBundle.plugins.DownloadUrl
],
layout: "StandaloneLayout",
oauth2RedirectUrl: "/swagger-ui/oauth2-redirect.html"
})
ui.initOAuth({
clientId: "sample-client-id",
clientSecret: "secret",
scopeSeparator: " "
})
window.ui = ui
}
</script>
</body>
* Connection #0 to host petstore.local left intact
</html>
Test petstore https app
$ curl -vvv https://petstore-https.local
* Rebuilt URL to: https://petstore-https.local/
* Trying 13.52.165.162...
* TCP_NODELAY set
* Connected to petstore-https.local (13.52.165.162) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
* CAfile: /etc/ssl/cert.pem
CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server accepted to use h2
* Server certificate:
* subject: CN=petstore-https.local
* start date: Sep 17 22:08:20 2019 GMT
* expire date: Dec 16 22:08:20 2019 GMT
* subjectAltName: host "petstore-https.local" matched cert's "petstore-https.local"
* issuer: C=US; O=Let's Encrypt; CN=Let's Encrypt Authority X3
* SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x7fdf42009c00)
> GET / HTTP/2
> Host: petstore-https.local
> User-Agent: curl/7.54.0
> Accept: */*
>
* Connection state changed (MAX_CONCURRENT_STREAMS updated)!
< HTTP/2 200
< last-modified: Mon, 13 Aug 2018 06:26:44 GMT
< accept-ranges: bytes
< content-type: text/html;charset=UTF-8
< content-language: en-US
< content-length: 1832
< date: Mon, 23 Sep 2019 23:02:31 GMT
< x-envoy-upstream-service-time: 2
< server: envoy
<
<!-- HTML for static distribution bundle build -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Swagger UI</title>
<link href="https://fonts.googleapis.com/css?family=Open+Sans:400,700|Source+Code+Pro:300,600|Titillium+Web:400,600,700" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="./swagger-ui/swagger-ui.css" >
<link rel="icon" type="image/png" href="./swagger-ui/favicon-32x32.png" sizes="32x32" />
<link rel="icon" type="image/png" href="./swagger-ui/favicon-16x16.png" sizes="16x16" />
<style>
html
{
box-sizing: border-box;
overflow: -moz-scrollbars-vertical;
overflow-y: scroll;
}
*,
*:before,
*:after
{
box-sizing: inherit;
}
body
{
margin:0;
background: #fafafa;
}
</style>
</head>
<body>
<div id="swagger-ui"></div>
<script src="./swagger-ui/swagger-ui-bundle.js"> </script>
<script src="./swagger-ui/swagger-ui-standalone-preset.js"> </script>
<script>
window.onload = function() {
// Build a system
const ui = SwaggerUIBundle({
url: "/openapi.json",
dom_id: '#swagger-ui',
deepLinking: true,
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIStandalonePreset
],
plugins: [
SwaggerUIBundle.plugins.DownloadUrl
],
layout: "StandaloneLayout",
oauth2RedirectUrl: "/swagger-ui/oauth2-redirect.html"
})
ui.initOAuth({
clientId: "sample-client-id",
clientSecret: "secret",
scopeSeparator: " "
})
window.ui = ui
}
</script>
</body>
* Connection #0 to host petstore-https.local left intact