Skip to content

Commit d63c0cd

Browse files
authored
Merge pull request #1539 from tkan145/dev-env-mtls
[dev-environments] Introduce MTLS dev environment
2 parents 47a7d99 + 352791a commit d63c0cd

File tree

9 files changed

+492
-0
lines changed

9 files changed

+492
-0
lines changed

dev-environments/mtls/Makefile

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
SHELL = /usr/bin/env bash -o pipefail
2+
.SHELLFLAGS = -ec
3+
.DEFAULT_GOAL := gateway
4+
MKFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST)))
5+
WORKDIR := $(patsubst %/,%,$(dir $(MKFILE_PATH)))
6+
DOCKER ?= $(shell which docker 2> /dev/null || echo "docker")
7+
8+
gateway: ## run gateway configured to access upstream powered with TLS
9+
$(DOCKER) compose -f docker-compose.yml up --attach gateway
10+
11+
clean:
12+
$(DOCKER) compose down --volumes --remove-orphans
13+
$(DOCKER) compose -f docker-compose.yml down --volumes --remove-orphans
14+
$(MAKE) clean -C $(WORKDIR)/cert -f $(WORKDIR)/cert/Makefile
15+
16+
certs:
17+
$(MAKE) clean -C $(WORKDIR)/cert -f $(WORKDIR)/cert/Makefile
18+
$(MAKE) all -C $(WORKDIR)/cert -f $(WORKDIR)/cert/Makefile
19+
20+
template: export WHITELIST=$(shell cat cert/intermediate.cert.pem | tr '\n' ' ')
21+
template: export CRL=$(shell cat cert/intermediate.crl.pem | tr '\n' ' ')
22+
template:
23+
yq -i '.services[0].proxy.policy_chain[0].configuration.whitelist[0].pem_certificate="$(WHITELIST)"' apicast-config.json
24+
yq -i '.services[0].proxy.policy_chain[0].configuration.revoke_list[0].pem_certificate="$(CRL)"' apicast-config.json
25+
yq -i '.services[1].proxy.policy_chain[0].configuration.whitelist[0].pem_certificate="$(WHITELIST)"' apicast-config.json
26+

dev-environments/mtls/README.md

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# Making APIcast listen on HTTPS
2+
3+
## Create the SSL Certificates
4+
5+
```sh
6+
make certs
7+
```
8+
9+
## Prepare apicast-config.json
10+
11+
```sh
12+
make template
13+
```
14+
15+
## Run the gateway
16+
17+
Running local `apicast-test` docker image
18+
19+
```sh
20+
make gateway
21+
```
22+
23+
Running custom apicast image
24+
25+
```sh
26+
make gateway IMAGE_NAME=quay.io/3scale/apicast:latest
27+
```
28+
29+
## Testing CRL
30+
31+
Send request with valid cert
32+
33+
```
34+
curl --resolve example.com:8443:127.0.0.1 -H "Host: crl.example.com" --cacert cert/rootCA.cert.pem --cert cert/client-chain.cert.pem --key cert/client.key.pem "https://example.com:8443/?user_key=123" --http1.1 -v
35+
```
36+
37+
Request with revoked cert
38+
39+
```sh
40+
curl --resolve example.com:8443:127.0.0.1 -H "Host: crl.example.com" --cacert cert/rootCA.cert.pem --cert cert/revoked_client-chain.cert.pem --key cert/revoked_client.key.pem "https://example.com:8443/?user_key=123" --http1.1 -v
41+
```
42+
43+
## Testing OCSP
44+
45+
Send request with valid cert
46+
47+
```
48+
curl --resolve example.com:8443:127.0.0.1 -H "Host: ocsp.example.com" --cacert cert/rootCA.cert.pem --cert cert/client-chain.cert.pem --key cert/client.key.pem "https://example.com:8443/?user_key=123" --http1.1 -v
49+
```
50+
51+
Request with revoked cert
52+
53+
```sh
54+
curl --resolve example.com:8443:127.0.0.1 -H "Host: ocsp.example.com" --cacert cert/rootCA.cert.pem --cert cert/revoked_client-chain.cert.pem --key cert/revoked_client.key.pem "https://example.com:8443/?user_key=123" --http1.1 -v
55+
```
56+
57+
## Clean env
58+
59+
```sh
60+
make clean
61+
```
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
{
2+
"services": [
3+
{
4+
"id": "1",
5+
"backend_version": "1",
6+
"proxy": {
7+
"hosts": [
8+
"crl.example.com"
9+
],
10+
"api_backend": "http://one.upstream/get",
11+
"backend": {
12+
"endpoint": "http://127.0.0.1:8081",
13+
"host": "backend"
14+
},
15+
"policy_chain": [
16+
{
17+
"name": "tls_validation",
18+
"version": "builtin",
19+
"configuration": {
20+
"whitelist": [
21+
{
22+
"pem_certificate": ""
23+
}
24+
],
25+
"allow_partial_chain": true,
26+
"revocation_check_type": "crl",
27+
"revoke_list": [
28+
{
29+
"pem_certificate": ""
30+
}
31+
]
32+
}
33+
},
34+
{
35+
"name": "apicast.policy.apicast"
36+
}
37+
],
38+
"proxy_rules": [
39+
{
40+
"http_method": "GET",
41+
"pattern": "/",
42+
"metric_system_name": "hits",
43+
"delta": 1,
44+
"parameters": [],
45+
"querystring_parameters": {}
46+
}
47+
]
48+
}
49+
},
50+
{
51+
"id": "2",
52+
"backend_version": "1",
53+
"proxy": {
54+
"hosts": [
55+
"ocsp.example.com"
56+
],
57+
"api_backend": "http://one.upstream/get",
58+
"backend": {
59+
"endpoint": "http://127.0.0.1:8081",
60+
"host": "backend"
61+
},
62+
"policy_chain": [
63+
{
64+
"name": "tls_validation",
65+
"version": "builtin",
66+
"configuration": {
67+
"whitelist": [
68+
{
69+
"pem_certificate": ""
70+
}
71+
],
72+
"allow_partial_chain": true,
73+
"revocation_check_type": "ocsp"
74+
}
75+
},
76+
{
77+
"name": "apicast.policy.apicast"
78+
}
79+
],
80+
"proxy_rules": [
81+
{
82+
"http_method": "GET",
83+
"pattern": "/",
84+
"metric_system_name": "hits",
85+
"delta": 1,
86+
"parameters": [],
87+
"querystring_parameters": {}
88+
}
89+
]
90+
}
91+
}
92+
]
93+
}
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
DOMAIN=example.com
2+
3+
clean:
4+
- rm *.crt *.key *.pem *.csr index.* crlnumber crlnumber.* serial serial.* *.srl
5+
6+
all: index ca intermediate ca-chain ocsp server client revoked_client crl client-chain revoked-client-chain
7+
8+
index:
9+
touch index.txt
10+
echo 1000 > serial
11+
echo 1000 > crlnumber
12+
13+
ca:
14+
openssl genrsa -out rootCA.key.pem 2048
15+
openssl req -config root-ca.cnf \
16+
-key rootCA.key.pem \
17+
-new -x509 -days 3650 -sha256 -extensions v3_ca \
18+
-out rootCA.cert.pem \
19+
-subj "/C=US/CN=ca.$(DOMAIN)"
20+
21+
intermediate:
22+
openssl genrsa -out intermediate.key.pem 2048
23+
openssl req -config intermediate.cnf \
24+
-key intermediate.key.pem \
25+
-new -sha256 \
26+
-out intermediate.csr.pem \
27+
-subj "/CN=intermediate-cert.$(DOMAIN)"
28+
openssl ca -config root-ca.cnf \
29+
-extensions v3_intermediate_ca -days 2650 -notext -batch \
30+
-in intermediate.csr.pem \
31+
-out intermediate.cert.pem
32+
33+
ca-chain:
34+
cat intermediate.cert.pem rootCA.cert.pem > ca-chain.cert.pem
35+
36+
crl:
37+
openssl ca -config intermediate.cnf \
38+
-gencrl -out intermediate.crl.pem
39+
40+
ocsp:
41+
openssl genrsa -out ocsp.$(DOMAIN).key.pem 2048
42+
openssl req -config intermediate.cnf -new -sha256 \
43+
-key ocsp.$(DOMAIN).key.pem \
44+
-out ocsp.$(DOMAIN).csr.pem \
45+
-nodes \
46+
-subj "/CN=ocsp.$(DOMAIN)"
47+
openssl ca -config intermediate.cnf \
48+
-extensions v3_ocsp -days 2650 -notext -batch \
49+
-in ocsp.$(DOMAIN).csr.pem \
50+
-out ocsp.$(DOMAIN).cert.pem
51+
52+
server:
53+
openssl req -subj '/CN=$(DOMAIN)' -newkey rsa:4096 -nodes \
54+
-sha256 \
55+
-days 3650 \
56+
-keyout $(DOMAIN).key \
57+
-out $(DOMAIN).csr
58+
chmod +r $(DOMAIN).key
59+
openssl x509 -req -in $(DOMAIN).csr -CA rootCA.cert.pem -CAkey rootCA.key.pem -CAcreateserial -out $(DOMAIN).crt -days 500 -sha256
60+
openssl ca -config root-ca.cnf \
61+
-extensions v3_intermediate_ca -days 2650 -notext -batch \
62+
-in $(DOMAIN).csr \
63+
-out $(DOMAIN).pem
64+
65+
client:
66+
openssl genrsa -out client.key.pem 2048
67+
openssl req -config intermediate.cnf -new -sha256 \
68+
-key client.key.pem \
69+
-out client.csr.pem \
70+
-nodes \
71+
-subj "/CN=client-cert.$(DOMAIN)"
72+
echo -e "y\ny\n" | openssl ca -config intermediate.cnf \
73+
-extensions v3_leaf -days 375 -notext -md sha256 \
74+
-in client.csr.pem \
75+
-out client.cert.pem
76+
77+
revoked_client:
78+
openssl genrsa -out revoked_client.key.pem 2048
79+
openssl req -config intermediate.cnf -new -sha256 \
80+
-key revoked_client.key.pem \
81+
-out revoked_client.csr.pem \
82+
-nodes \
83+
-subj "/CN=revoked_client-cert.$(DOMAIN)"
84+
echo -e "y\ny\n" | openssl ca -config intermediate.cnf \
85+
-extensions v3_leaf -days 375 -notext -md sha256 \
86+
-in revoked_client.csr.pem \
87+
-out revoked_client.cert.pem
88+
openssl ca -config intermediate.cnf -revoke revoked_client.cert.pem
89+
90+
client-chain:
91+
cat client.cert.pem intermediate.cert.pem > client-chain.cert.pem
92+
93+
revoked-client-chain:
94+
cat revoked_client.cert.pem intermediate.cert.pem > revoked_client-chain.cert.pem
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
[ ca ]
2+
default_ca = CA_default
3+
4+
[ CA_default ]
5+
dir = .
6+
certificate = $dir/intermediate.cert.pem
7+
database = $dir/index.txt
8+
new_certs_dir = $dir
9+
serial = $dir/serial
10+
crlnumber = $dir/crlnumber
11+
12+
private_key = $dir/intermediate.key.pem
13+
14+
name_opt = ca_default
15+
cert_opt = ca_default
16+
17+
default_days = 365
18+
default_crl_days= 30
19+
default_md = sha256
20+
preserve = no
21+
policy = policy_anything
22+
23+
[ policy_match ]
24+
organizationalUnitName = optional
25+
commonName = supplied
26+
emailAddress = optional
27+
28+
[ policy_anything ]
29+
countryName = optional
30+
stateOrProvinceName = optional
31+
localityName = optional
32+
organizationName = optional
33+
organizationalUnitName = optional
34+
commonName = supplied
35+
emailAddress = optional
36+
37+
[ req ]
38+
default_bits = 4096
39+
default_md = sha256
40+
default_keyfile = privkey.pem
41+
distinguished_name = req_distinguished_name
42+
x509_extensions = v3_ca
43+
string_mask = nombstr
44+
45+
[ req_distinguished_name ]
46+
countryName = Country Name (2 letter code)
47+
countryName_default = US
48+
countryName_min = 2
49+
countryName_max = 2
50+
stateOrProvinceName = State or Province Name (full name)
51+
stateOrProvinceName_default = CA
52+
localityName = Locality Name (eg, city)
53+
localityName_default = Testland
54+
0.organizationName = Organization Name (eg, company)
55+
0.organizationName_default = Testers
56+
organizationalUnitName = Organizational Unit Name (eg, section)
57+
commonName = Common Name (eg, your name or your server\'s hostname)
58+
commonName_max = 64
59+
emailAddress = Email Address
60+
emailAddress_max = 64
61+
emailAddress_default = [email protected]
62+
63+
[ v3_ca ]
64+
subjectKeyIdentifier=hash
65+
authorityKeyIdentifier=keyid:always,issuer
66+
basicConstraints = critical,CA:true
67+
68+
[ v3_intermediate_ca ]
69+
subjectKeyIdentifier = hash
70+
authorityKeyIdentifier = keyid:always,issuer
71+
basicConstraints = critical, CA:true, pathlen:0
72+
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
73+
extendedKeyUsage = OCSPSigning
74+
75+
[ v3_ocsp ]
76+
basicConstraints = CA:FALSE
77+
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
78+
extendedKeyUsage = OCSPSigning
79+
80+
[ v3_leaf ]
81+
extendedKeyUsage = serverAuth, clientAuth
82+
authorityInfoAccess = OCSP;URI:http://ocsp:2560

0 commit comments

Comments
 (0)