Tang IAM proxy is an HTTPS proxy that parses X509 client certificate and
extracts SVID from Subject Alternate Names extension.
Main purpose of the proxy is to show how to extract previous information
from certificates generated by an SPIRE agent.
In this document it is explained how to generate required scripts for
the proxy server, and how to run curl
application to act
as a client that sends the agent certificate.
The HTTPS server will parse client certificate, and will dump the
corresponding parsed information. It will also check in database
if receiving SPIRE ID is registered and, if so, it will forward the request
to the Tang server specified as parameter.
Database supported is SQLite,
essentially due to two aspects:
- It provides a very simple mechanism to be configured
- It has a very small footprint, which makes it suitable to be used in ConsoleDot
The script generate-signed-certificate.sh
has been included to generate
the corresponding certificates.
It can be provided a parameter to name the certificates.
Otherwise, the naming used will be server.
Usage of the script is as follows:
$ ./generate-signed-certificate.sh -h
./generate-signed-certificate.sh [-n name] [-s subAlternateName] [-h] [-v]
Examples:
./generate-signed-certificate.sh -n server -s tang-iam-proxy-passthrough
Options:
-n "name": Base name for generated files
-s "subAlternateName": extra Subject Alternate Name for server certificate
-h: help
-v: verbose
To generate the certificates, execute the script:
$ ./generate-signed-certificate.sh
*************************
certname:server
sub_alternate_name:tang-server-deployment
*************************
Certificate request self-signature ok
subject=C = ES, ST = Madrid, L = Madrid, O = Red Hat, OU = org, CN = www.redhat.com
The script will generate a collection of certificates. The ones that will be used are:
ca_server_cert.pem
: This file will be used as the CA certificateserver_bundle.pem
: File that will act as the server certificateserver.key
: File that will be used as the server private key
The script can be provided a different subject alternate name to store in server's certificate:
$ ./generate-signed-certificate.sh -s tang-iam-proxy-passthrough-ephemeral-012345.apps.c-rh-c-eph.1a0b.p1.openshiftapps.com
*****************************************
certname:server
sub_alternate_name:tang-iam-proxy-passthrough-ephemeral-012345.apps.c-rh-c-eph.1a0b.p1.openshiftapps.com
*****************************************
Certificate request self-signature ok
subject=C = ES, ST = Madrid, L = Madrid, O = Red Hat, OU = org, CN = www.redhat.com
Tang IAM proxy can be compiled through make
tool.
Makefile
exists so that it eases the compilation,
required certificates and the container generation:
$ make
mkdir -p root/usr/bin
echo "0.0.1" > root/version.txt
cp tang-iam-entrypoint.sh root/usr/bin
cp tang-iam-health-check.sh root/usr/bin
cp tang_bindings.db root/usr/bin
go build -o root/usr/bin/tang-iam-proxy tang_iam_proxy.go
./generate-signed-certificate.sh -s "tang-iam-proxy-passthrough"
*****************************************
certname:server
sub_alternate_name:tang-iam-proxy-passthrough
*****************************************
...
--> 2d54bac76533
Successfully tagged quay.io/sec-eng-special/tang-iam-proxy-deehms-sqlite:v0.0.1
2d54bac765330435f1d2564810f2d262393d9ef1f0ab5086b3bd78fa84470254
echo "Building all ..."
Building all ...
As shown previously, current version is 0.0.1
.
Makefile
can be parameterized with two parameters:
- VERSION: To generate a different version
- SUB_ALT_NAME: To include an additional Subject Alternate Name in the server certificate. An example of a full parameterized compilation execution is shown below:
$ VERSION=0.0.2 SUB_ALT_NAME=tang-iam-proxy-passthrough-ephemeral-123-456-789.openshiftapps.com make
mkdir -p root/usr/bin
echo "0.0.2" > root/version.txt
...
./generate-signed-certificate.sh -s "tang-iam-proxy-passthrough"
*****************************************
certname:server
sub_alternate_name: tang-iam-proxy-passthrough-ephemeral-123-456-789.openshiftapps.com
*****************************************
...
--> 7dabf6a2d65a
Successfully tagged quay.io/sec-eng-special/tang-iam-proxy-deehms-sqlite:v0.0.2
7dabf6a2d65a92ee02ab49b4467007ea12abd28cd5f9dbf971a5e4bff6fbe054
echo "Building all ..."
Building all ...
The proxy has next usage:
$ ./tang-iam-proxy -help
usage:
tang_iam_proxy -serverCert <serverCertificateFile> -serverKey <serverPrivateKeyFile> -tangServer <tangServer>
[-port <port>] [-dbFile <dbfile>] [-httpUser <httpuser>] [-httpPass <httppass>] [-insecure] [-internal] [-help] [-verbose]
Options:
-help Optional, prints help message
-dbFile Optional, defaults to /var/lib/sqlite/tang_bindings.db
-httpUser Optional, http user, defaults to jdoe
-httpPass Optional, http password, defaults to jdoe123
-insecure Optional, insecure more
-internal Optional, disabled by default
-port Optional, the HTTPS port for the server to listen on, defaults to 443
-serverCert Mandatory (except for insecure mode), server's certificate file
-serverKey Mandatory (except for insecure mode), server's private key certificate file
-tangServer Mandatory, tang server location in form host:port
-verbose Optional, be more verbose
Taking into account the certificates generated in section Certificate generation, the server will be executed as follows:
$ ./tang-iam-proxy -internal -dbFile /var/lib/sqlite/tang_bindings.db -port 8887 -serverCert server_bundle.pem --serverKey server.key -tangServer tang-server-deployment:8000
...
2023/07/28 17:15:08 Connected to DB!
2023/07/28 17:15:08 Sending requests to tang-server-deployment:8000
2023/07/28 17:15:08 URL:[http://tang-server-deployment:8000]
...
It must be highlighted that server certificate (server_bundle.pem
) already contains the CA certificate, so it is not necessary
to provide it to the server in an additional parameter.
The main purpose of this server application is to show how SVID in an SPIRE agent certificate can be parsed. The agent private key and certificate is generated by the SPIRE agent once server attests its correctly. It is not the aim of this document to document the whole SPIRE server attestation. To do so, refer to the References) section.
SPIRE agent generates the certificate and the keys normally in data
directory:
$ spire-agent run -config spire-1.6.4/conf/agent/agent.conf
...
$ tree data/agent/
data/agent/
├── agent-data.json
├── agent_svid.der
├── bundle.der
└── keys.json
From previous directory, the files to used in client will be:
agent_svid.der
: This file will be used as it appears.keys.json
: This file contains the private key of the agent. However, as it is not in the format thatcurl
would expect, the key has to be extracted to anagent.key
file with the corresponding prefix and suffix.keys.json
has next format:
$ cat data/agent/keys.json
{
"keys": {
"agent-svid-A": "MIGHAgE...LoNg_KeY_HeRe_123a_...LuymQw"
}
}
The agent key provided to curl will be of the format:
$ cat agent.key
-----BEGIN PRIVATE KEY-----
MIGHAgE...LoNg_KeY_HeRe_123a_...LuymQw
-----END PRIVATE KEY-----
## SVID identification
To check if server is parsing SVID correctly, agent certificate can be read with `openssl` tool, so that
Subject Alternate Name URI is obtained:
```bash
openssl x509 -inform der -in ./agent_svid.der --text | grep -i "Subject Alternative Name:" -A1
X509v3 Subject Alternative Name:
URI:spiffe://example.org/spire/agent/aws_iid/12977789345/us-east-1/i-1234d7bdff825678
The URI string spiffe://example.org/spire/agent/aws_iid/12977789345/us-east-1/i-1234d7bdff825678
is the
one that needs to be obtained in server. In case that line can be parsed, it will be demonstrated that the
information can be programmatically parsed. Next section covers how to use curl
tool to use SPIRE agent
private key and certificate to access the HTTPS server.
Previous section showed how to obtain curl
required files to access HTTPS server, so that it can parse
the SVID that was assigned to an agent.
For curl
to access the HTTPS server that was started as described in Section Server execution,
the command to use will be next:
$ curl --cert agent_svid.der --cert-type der --cacert ca_server_cert.pem --key ./agent.key --verbose https://localhost:8082
...
* SSL certificate verify ok.
...
< HTTP/2 200
...
A description on how to get each of the files used by curl
was performed on the previous sections.
As it can be observed in previous command, curl will dump SSL certificate verification works appropriately, and server will send
a 200 OK response with no content.
If everything works as expected HTTPS server will dump the information of the agent certificate, and print the SVID in the console:
2023/01/02 03:06:09
2023/01/02 03:06:18 Starting HTTPS server, port:[8082]
2023/01/02 03:06:18 Received GET request for host localhost:8082 from IP address 127.0.0.1:45738
2023/01/02 03:06:18 **************** Connection State *****************
2023/01/02 03:06:18 Version: 304
2023/01/02 03:06:18 HandshakeComplete: true
2023/01/02 03:06:18 DidResume: false
2023/01/02 03:06:18 CipherSuite: 1301
2023/01/02 03:06:18 NegotiatedProtocol: h2
2023/01/02 03:06:18 Certificate chain:
2023/01/02 03:06:18 0 s:/C=[US]/ST=[]/L=[]/O=[SPIRE]/OU=[]/CN=
2023/01/02 03:06:18 i:/C=[US]/ST=[]/L=[]/O=[SPIFFE]/OU=[]/CN=
2023/01/02 03:06:18 SAN URL:[spiffe://example.org/spire/agent/aws_iid/12977789345/us-east-1/i-1234d7bdff825678]
2023/01/02 03:06:18 **************** /Connection State ****************
This way, forward implementation of a proxy that uses SVID to forward agent requests can be implemented.
Configuring SPIRE for Amazon EC2 Instances
Install Spire Agents
Install the Spire Server
How to generate certificates