/tang-iam-proxy

HTTPS server that parsers X509 client certificate and extracts SVID from subject alternate names extension

Primary LanguageGoMIT LicenseMIT

tang-iam-proxy

License

License: MIT

Status

Golang CI lint
Staticcheck
Shellcheck
Spellcheck

Introduction

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

Certificate generation

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 certificate
  • server_bundle.pem: File that will act as the server certificate
  • server.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

Compilation

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 ...

Proxy execution

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.

Agent certificates

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 that curl would expect, the key has to be extracted to an agent.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.

Client simulation through curl tool

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.

References

Configuring SPIRE for Amazon EC2 Instances
Install Spire Agents
Install the Spire Server
How to generate certificates