Simple REST Api for automatic SSL certificate generation.
Note: This tool is currently targeting development like environments. It's not recommended to use cacophony for anything sensitive or production related yet.
Use nosetests -v --with-cover --cover-package cacophony test/ from the main directory to execute unittests. This will use the test/Test-CA/ CA.
Configuration of the server is done in JSON and is by default kept in the current directories settings.json file.
You can override the location by setting CACOPHONY_CONFIG
environment variable.
Name | Type | Parent | Value |
---|---|---|---|
AUTH_DECORATOR | str | None | cacophony.decorators:remote_user_required (module.name:decorator) |
LOGFILE | str | None | File name for the application level log |
LOGLEVEL | str | None | Log level to use (DEBUG, INFO, WARN, FATAL). Unset defaults to INFO |
CA | dict | None | A dictionary holding CA configuration data |
"ENVIRONMENT" | dict | CA | Configuration info for the CA to be used in "ENVIRONMENT" |
privKey | str | "ENVIRONMENT" | Path to the CA's private key. |
privPass | str | "ENVIRONMENT" | Password for CA. |
pubCert | str | "ENVIRONMENT" | Path to the public cert. |
serial | str | "ENVIRONMENT" | Path to the CA's serial file. |
index | str | "ENVIRONMENT" | Path to the CA's index file. |
keySize | int | "ENVIRONMENT" | Key size to use |
validTime | int | "ENVIRONMENT" | Length of time the certificates will be valid for. |
certStore | str | "ENVIRONMENT" | Path to write out certificates after generation. |
altnames | str | "ENVIRONMENT" | Path to the file which holds altname\tparent host |
reqStore | str | "ENVIRONMENT" | Path to write out requests after generation. |
{
"DEBUG": false,
"PREFERRED_URL_SCHEME": "https",
"LOGGER_NAME": "cacophony",
"AUTH_DECORATOR": "cacophony.decorators:remote_user_required",
"CA": {
"Test": {
"privKey": "test/Test-CA/private/cakey.pem",
"privPass": "test",
"pubCert": "test/Test-CA/cacert.pem",
"serial": "test/Test-CA/serial",
"index": "test/Test-CA/index.txt",
"keySize": 4096,
"validTime": 31536000,
"certStore": "test/Test-CA/certs/by-name/",
"altnames": "test/Test-CA/altnames",
"reqStore": "test/Test-CA/requests/"
}
}
}
Further configuration items can be found at http://flask.pocoo.org/docs/config/#builtin-configuration-values
cacophony uses a simple decorater system for authentication.
This decorator assumes that cacophony is running behind another web server which is taking care of authentication. If REMOTE_USER is passed to cacophony from the web server cacophony assumes authentication has succeeded. If it is not passed through cacophony treats the users as unauthenticated.
WARNING: When using this decorator it is very important that cacophony not be reachable by any means other than through the front end webserver!!
- Response Type: json
- Auth Required: Yes
- Input Format: None
- Inputs: None
- Response Type: json on error, text pem on cert creation
- Auth Required: Yes
- Input Format: json
- Inputs:
Name | Type | Description | Example |
---|---|---|---|
str | Email of the owner | [email protected] | |
alt_names | list | List of other domains the cert is for | ["test.example.com", "another.example.com"] |
Note: However you deploy cacophony make sure the application server can read and write to the files listed in the CA section. If the appserver can not read or write to the files errors will occur.
WARNING: DO NOT USE THE Test-CA FOR ANYTHING OTHER THAN TESTING!!!!
mod_wsgi can be used with Apache to mount cacophony. Example mod_wsgi files are located in contrib/mod_wsgi.
- cacophony.conf: The mod_wsgi configuration file. This should be modified and placed in /etc/httpd/conf.d/.
- cacophony.wsgi: The WSGI file that mod_wsgi will use. This should be modified and placed in the location noted in cacophony.conf
Note: When using mod_wsgi you will still need to set up authentication such as mod_auth_kerb.
Note: Makes ure that Apache has access to the CA files. You should check both normal permissions as well as SELinux!
Gunicorn (http://gunicorn.org/) is a popular open source Python WSGI server. It's still recommend to use Apache (or another web server) to handle auth before gunicorn since gunicorn itself is not set up for it.
$ gunicorn --user=YOUR_WORKER_USER --group=YOUR_WORKER_GROUP -D -b 127.0.0.1:5000 --access-logfile=/your/access.log --error-logfile=/your/error.log -e CACOPHONY_CONFIG=/full/path/to/settings.json cacophony:app
The authentication mechanism used in the front end webserver could be set up to use vastly different schemes. Instead of covering every possible authentication style which could be used we will work with two common ones in usage examples: htacces and kerberos.
The first command will look up to see if a known certificate already exists for an ENVIRONMENT/HOSTNAME. If it does it will return some basic json metadata. If it does not exist a 404 will be returned.
The second command will attempt to create a new certificate. If the certificate doesn't exist it will be created and returned, with the key, in pem format to the client. If a certificate has already been created for the host then a 409 with an error message will be returned.
Note: Setting up the front end proxy server for authentication is out of scope for this documentation.
$ curl -X GET --user "USERNAME" https://cacophony.example.com/api/v1/certificate/ENVIRONMENT/HOSTNAME/
Password:
... # 200 and json data if exists, otherwise 404 and error json
$ curl -X PUT --user "USERNAME" -H "Content-Type: application/json" -d '{"email": "[email protected]"}' https://cacophony.example.com/api/v1/certificate/ENVIRONMENT/NEWHOST/
Password:
... # 201 and a pem (key + cert) returned
$ kinit -f USERNAME
Password for USERNAME@DOMAIN:
$ curl --negotiate -u 'a:a' policy -X GET https://cacophony.example.com/api/v1/certificate/ENVIRONMENT/HOSTNAME/
... # 200 and json data if exists, otherwise 404 and error json
$ curl --negotiate -u 'a:a' -X PUT -H "Content-Type: application/json" -d '{"email": "[email protected]"}' https://cacophony.example.com/api/v1/certificate/ENVIRONMENT/NEWHOST/
... # 201 and a pem (key + cert) returned