|
|
x |
|
|
\ No newline at end of file |
|
|
# What is CertCache?
|
|
|
|
|
|
A client certificate can only be one of 3 states: not yet valid, valid, and no longer valid (expired). The issuing CA can add a fourth state - revoked - which can be determined by checking a [CRL](https://en.wikipedia.org/wiki/Certificate_revocation_list), or querying the CA's [OCSP](https://en.wikipedia.org/wiki/Online_Certificate_Status_Protocol) endpoint. CRLs can become very large, and there's always a lag between certificate revocation and downloading an updated CRL. OCSP is always up to date, but it requires an HTTP call which can have variable performance.
|
|
|
|
|
|
Additionally, Stanford only allows certificates to be used if they are associated with a compliant device, as determined by the Device Registry (based on data from BigFix or VLRE agents, AirWatch MDM, and other sources). Rather than require users to re-enroll for a new certificate anytime their device becomes non-compliant, we want to track when certificates cannot be used.
|
|
|
|
|
|
For these reasons, and to prevent multiple calls to OCSP and the Device Registry API for every authentication, we use a separate cache of certificate information - CertCache.
|
|
|
|
|
|
# CertCache Documentation
|
|
|
|
|
|
CertCache is a [Node](https://nodejs.org/) application, providing a set of processes, and an API, a webhook endpoint, and a database for maintaining extra information acout client certs issued by CloudPath. It is designed to integrate with the following services:
|
|
|
|
|
|
* [CloudPath](http://cloudpath.net/), via webhook (POST) notifications through the [AWS](https://aws.amazon.com/) [API Gateway](https://aws.amazon.com/api-gateway/) to an AWS [SQS](https://aws.amazon.com/sqs/) queue.
|
|
|
* Device Registry, via a RESTful [API]([API](https://certcache.itlab.stanford.edu/api-docs/)
|
|
|
* [MyDevices](https://mydevices.stanford.edu), via the same RESTful API
|
|
|
* Stanford's IdP, via SQL queries (as an Attribute Resolver)
|
|
|
* Stanford's RADIUS servers, via SQL queries
|
|
|
|
|
|
## Architecture
|
|
|
|
|
|
There is a separate page describing the overall [architecture](architecture).
|
|
|
|
|
|
## Configuring CloudPath
|
|
|
|
|
|
There are separate [instructions](cloudpath) for configuring CloudPath certificate templates and notifications.
|
|
|
|
|
|
## Testing
|
|
|
|
|
|
See the [testing instructions](testing).
|
|
|
|
|
|
## Building CertCache
|
|
|
|
|
|
As described in the [architecture](architecture) page, there are several components to CertCache, and those are spread across several projects.
|
|
|
|
|
|
The Node application (API and queue processing) is the [certcache](https://code.stanford.edu/et/certcache/) repository.
|
|
|
|
|
|
The AWS API Gateway and SQS configuration is handled by [Terraform](https://terraform.io) using a custom [certcache](https://code.stanford.edu/tf_modules/certcache) module. The definition in our various environments should look like:
|
|
|
|
|
|
### `itlab` certcache
|
|
|
|
|
|
module "certcache" {
|
|
|
source = "git::ssh://git@code.stanford.edu/tf_modules/certcache.git"
|
|
|
stages = [ "itlab" ]
|
|
|
role_name = "hosting"
|
|
|
}
|
|
|
|
|
|
### `authnz-x` certcache
|
|
|
|
|
|
module "certcache" {
|
|
|
source = "git::ssh://git@code.stanford.edu/tf_modules/certcache.git"
|
|
|
stages = [ "dev", "test", "int", "uat" ]
|
|
|
role_name = "authnz-x-worker"
|
|
|
}
|
|
|
|
|
|
### `authnz` certcache
|
|
|
|
|
|
module "certcache" {
|
|
|
source = "git::ssh://git@code.stanford.edu/tf_modules/certcache.git"
|
|
|
stages = [ "prod" ]
|
|
|
role_name = "authnz-prod-worker"
|
|
|
}
|
|
|
|
|
|
The container image is built on a base Debian Stretch + NodeJS [image](https://code.stanford.edu/et/core-node/), using a [Packer](https://packer.io/) [build project](https://code.stanford.edu/et/core-certcache/).
|
|
|
|
|
|
## Unit Definition
|
|
|
|
|
|
The CertCache image is currently run as a container using [fleet](https://github.com/coreos/fleet) unit; it will migrate to [Kubernetes](https://kubernetes.io/) in the near future. The unit file is used to start and stop the container, and to register the container with a load balancer (the LB is also used for SSL offload).
|
|
|
|
|
|
*NOTE*: certcache has not yet been tested in a load balanced pool, so only one instance should be run in each environment.
|
|
|
|
|
|
The unit definition is in the [itlab-apps](https://code.stanford.edu/et/itlab-apps) project as [certcache/units/certcache.service](https://code.stanford.edu/et/itlab-apps/blob/master/certcache/units/certache.service), along with an [envvars](https://code.stanford.edu/et/itlab-apps/blob/master/certcache/envvars) file to define the runtime environment.
|
|
|
|
|
|
CertCache uses the following environment variables
|
|
|
|
|
|
|Name|Value|Description|
|
|
|
|----|-----|-----------|
|
|
|
|IMAGE|localhost:5000/core/certcache:nightly|Docker image to run|
|
|
|
|CONFIG_FILE|/app/config.json|path to the config file, inside the container|
|
|
|
|RUN_ENV|prod|runtime environment|
|
|
|
|LOG_FORMAT|combined|log format (Apache combined-style)
|
|
|
|ENV_PORT|8020|port to expose on the Docker host|
|
|
|
|HTTP_PORT|8080|port to use inside the container|
|
|
|
|
|
|
|
|
|
## Configuration
|
|
|
|
|
|
The configuration file should be mounted into the container as `/app/config.json`; the JSON file has "sections" (sub-objects) to define various settings:
|
|
|
|
|
|
### Example Configuration
|
|
|
|
|
|
{
|
|
|
"numProcs": 1,
|
|
|
"aws": {
|
|
|
"region": "us-west-2"
|
|
|
},
|
|
|
"cloudpath": {
|
|
|
"url": "https://onboard.cloudpath.net/admin/api/",
|
|
|
"key": "SECRET",
|
|
|
"prefix": "/certificate/Pk/"
|
|
|
},
|
|
|
"db": {
|
|
|
"host": "mysql.rds-zone.us-west-2.rds.amazonaws.com",
|
|
|
"ssl": "Amazon RDS",
|
|
|
"user": "certcache",
|
|
|
"password": "SECRET",
|
|
|
"port": 3306,
|
|
|
"database": "certcache"
|
|
|
},
|
|
|
"introspection": {
|
|
|
"url": "https://authz.itlab.stanford.edu/introspect",
|
|
|
"client_id": "certcache.itlab.stanford.edu",
|
|
|
"client_secret": "SECRET"
|
|
|
},
|
|
|
"scopes": {
|
|
|
"read": "certcache:read",
|
|
|
"write": "certcache:write"
|
|
|
},
|
|
|
"redis": false,
|
|
|
"revoker": {
|
|
|
"interval": 900
|
|
|
},
|
|
|
"sqs": {
|
|
|
"main": "certcache.fifo",
|
|
|
"dl": "certcache_dl.fifo",
|
|
|
"visibilityTimeout": 60,
|
|
|
"maxMessages": 1,
|
|
|
"checkInterval": 40,
|
|
|
"checkDLInterval": 40,
|
|
|
"waitSeconds": 20
|
|
|
}
|
|
|
}
|
|
|
|
|
|
### Top Level Configuration
|
|
|
|
|
|
|Key|Value|Description|
|
|
|
|---|-----|-----------|
|
|
|
|numProces|1|Numer of API processes to run|
|
|
|
|
|
|
### `aws` Configuration
|
|
|
|
|
|
|Key|Value|Description|
|
|
|
|---|-----|-----------|
|
|
|
|region|us-west-2|AWS Region in which certcache is running|
|
|
|
|profile|-|(Optional) AWS profile to use, if not using instance profiles|
|
|
|
|
|
|
Other AWS settings are obtained from the environment or from EC2 instance roles.
|
|
|
|
|
|
### `cloudpath` Configuration
|
|
|
|
|
|
|Key|Value|Description|
|
|
|
|---|-----|-----------|
|
|
|
|url|https://onboard.cloudpath.net/admin/api/|Base CloudPath API URL - trailing slash is required|
|
|
|
|key|SECRET|CloudPath API key, which access to query and revoke certificates|
|
|
|
|prefix|/certificate/Pk/|prefix to use before the CloudPath PK in API URLs - trailing slash is required|
|
|
|
|
|
|
### `db` Configuration
|
|
|
|
|
|
CertCache requires a MySQL database; we're using AWS [RDS](https://aws.amazon.com/rds/mysql/).
|
|
|
|
|
|
|Key|Value|Description|
|
|
|
|---|-----|-----------|
|
|
|
|host|mysql.xxx.us-west-2.rds.amazonaws.com|server hostname|
|
|
|
|ssl|Amazon RDS|SSL configuration, using Amazon RDS profile; can also be an object ([docs](https://github.com/mysqljs/mysql#ssl-options))|
|
|
|
|port|3306|database server port|
|
|
|
|database|certcache|database name|
|
|
|
|user|certcache|database username|
|
|
|
|password|SECRET|database password|
|
|
|
|
|
|
*NOTE* We did try using the new RDS IAM functionality, but it does not work with current NodeJS MySQL client pooling.
|
|
|
|
|
|
### `introspection` Configuration
|
|
|
|
|
|
Access to the CertCache API is controlled using [OAuth 2.0](https://tools.ietf.org/html/rfc6749); the API must be configured to use [Token Introspection](https://tools.ietf.org/html/rfc7662) to obtain information about client tokens.
|
|
|
|
|
|
|Key|Value|Description|
|
|
|
|---|-----|-----------|
|
|
|
|url|https://authz.itlab.stanford.edu/introspect|Introspection endpoint on the OAuth 2.0 Authorization Server|
|
|
|
|client_id|certcache.itlab.stanford.edu|client ID for introspection|
|
|
|
|client_secret|SECRET|client secret for introspection|
|
|
|
|
|
|
### `scopes` Configuration
|
|
|
|
|
|
CertCache supports separate read and write OAuth 2.0 scopes, which are configurable.
|
|
|
|
|
|
|Key|Value|Description|
|
|
|
|---|-----|-----------|
|
|
|
|read|certcache:read|scope that grants clients read access|
|
|
|
|write|certcache:write|scope that grants clients write access|
|
|
|
|
|
|
### `redis` Configuration
|
|
|
|
|
|
If `redis` is `false`, CertCache will use an in-memory token cache to prevent excessive introspection calls, otherwise the settings are used to configure a REDIS cache.
|
|
|
|
|
|
|Key|Value|Description|
|
|
|
|---|-----|-----------|
|
|
|
|host|redis.x.y.usw2.cache.amazonaws.com|server hostname|
|
|
|
|port|6379|server port|
|
|
|
|
|
|
Other options from the NPM [redis](https://www.npmjs.com/package/redis#options-object-properties) module can also be used.
|
|
|
|
|
|
### `revoker` Configuration
|
|
|
|
|
|
CertCache runs a `revoker` process to handle delayed / post-dated certificate revocations.
|
|
|
|
|
|
|Key|Value|Description|
|
|
|
|---|-----|-----------|
|
|
|
|interval|900|# of seconds between `revoker` runs|
|
|
|
|
|
|
### `sqs` Configuration
|
|
|
|
|
|
Notifications from CloudPath are pushed onto an SQS queue. CertCache has an SQS process that periodically
|
|
|
|
|
|
|Key|Value|Description|
|
|
|
|---|---|---|
|
|
|
|main|certcache.fifo|main queue, where notifications arrive|
|
|
|
|dl|certcache_dl.fifo|dead letter queue, where failed notifications are held|
|
|
|
|visibilityTimeout|60|how long messages are hidden while they are processed|
|
|
|
|maxMessages|1|maximum number of messages to receive in each SQS query|
|
|
|
|checkInterval|40|# of seconds between queue runs|
|
|
|
|checkDLInterval|40|# of seconds between dead letter runs|
|
|
|
|waitSeconds|20|# of seconds to wait on an empty queue|
|
|
|
|