error-message
success-message
saving-message
warning-message
JavaScript must be enabled.
There was an error retrieving this content.
The content could not be found.
Simple Certificate Authority for MITM proxies
.. image:: https://travis-ci.org/ikreymer/certauth.svg?branch=master :target: https://travis-ci.org/ikreymer/certauth .. image:: https://coveralls.io/repos/ikreymer/certauth/badge.svg?branch=master :target: https://coveralls.io/r/ikreymer/certauth?branch=master
This package provides a small library, built on top of pyOpenSSL
, which allows for creating a custom certificate authority certificate,
and genereating on-demand dynamic host certs using that CA certificate.
It is most useful for use with a man-in-the-middle HTTPS proxy, for example, for recording or replaying web content.
Trusting the CA created by this tool should be used with caution in a controlled setting to avoid security risks.
The CertificateAuthority
class provides an interface to manage a root CA and generate dynamic host certificates suitable
for use with the native Python ssl
library as well as pyOpenSSL SSL
module.
The class provides several options for storing the root CA and generated host CAs.
File-based Certificate Cache ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. code:: python
ca = CertificateAuthority('My Custom CA', 'my-ca.pem', certcache='/tmp/certs') filename = ca.certfor_host('example.com')
In this configuration, the root CA is stored at my-ca.pem
and dynamically generated certs
are placed in /tmp/certs
. The filename
returned would be /tmp/certs/example.com.pem
in this example.
This filename can then be used with the Python ssl.load_cert_chain(certfile) <https://docs.python.org/3/library/ssl.html#ssl.SSLContext.load_cert_chain>
_ command.
Note that the dynamically created certs are never deleted by certauth
, it remains up to the user to handle cleanup occasionally if desired.
In-memory Certificate Cache ~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. code:: python
ca = CertificateAuthority('My Custom CA', 'my-ca.pem', certcache=50) cert, key = ca.loadcert('example.com')
This configuration stores the root CA at my-ca.pem
but uses an in-memory certificate cache for dynamically created certs.
These certs are stored in an LRU cache, configured to keep at most 50 certs.
The cert
and key
can then be used with OpenSSL.SSL.Context.use_certificate <http://www.pyopenssl.org/en/stable/api/ssl.html#OpenSSL.SSL.Context.use_certificate>
_
.. code:: python
context = SSl.Context(...)
context.use_privatekey(key)
context.use_certificate(cert)
Custom Cache ~~~~~~~~~~~~
A custom cache implementations which stores and retrieves per-host certificates can also be provided:
.. code:: python
ca = CertificateAuthority('My Custom CA', 'my-ca.pem', certcache=CustomCache()) cert, key = ca.loadcert('example.com')
class CustomCache: def setitem(self, host, certstring): # store certstring for host
def get(self, host):
# return cached cert_string, if available
cert_string = ...
return cert_string
Wildcard Certs ~~~~~~~~~~~~~~
To reduce the number of certs generated, it is convenient to generate wildcard certs.
.. code:: python
cert, key = ca.load_cert('example.com', wildcard=True)
This will generate a cert for *.example.com
.
To automatically generate a wildcard cert for parent domain, use:
.. code:: python
cert, key = ca.loadcert('test.example.com', wildcard=True, wildcardfor_parent=True)
This will also generate a cert for *.example.com
Starting with 1.3.0, certauth
uses tldextract
to determine the tld for a given host,
and will not use a parent domain if it is itself a tld suffix.
For example, calling:
.. code:: python
cert, key = ca.loadcert('example.co.uk', wildcard=True, wildcardfor_parent=True)
will now result in a cert for *.example.co.uk
, not *.co.uk
.
certauth
also includes a simple command-line API for certificate creation and management.
::
usage: certauth [-h] [-c CERTNAME] [-n HOSTNAME] [-d CERTSDIR] [-f] [-w] rootca_cert
positional arguments: rootcacert Path to existing or new root CA file
optional arguments:
-h, --help show this help message and exit
-c CERTNAME, --certname CERTNAME
Name for root certificate
-n HOSTNAME, --hostname HOSTNAME
Hostname certificate to create
-d CERTSDIR, --certs-dir CERTSDIR
Directory for host certificates
-f, --force Overwrite certificates if they already exist
-w, --wildcard_cert add wildcard SAN to host: *.
To create a new root CA certificate:
certauth myrootca.pem --certname "My Test CA"
To create a host certificate signed with CA certificate in directory certs_dir
:
certauth myrootca.pem --hostname "example.com" -d ./certs_dir
If the root cert doesn't exist, it'll be created automatically.
If certs_dir
, doesn't exist, it'll be created automatically also.
The cert for example.com
will be created as certs_dir/example.com.pem
.
If it already exists, it will not be overwritten (unless -f
option is used).
The -w
option can be used to create a wildcard cert which has subject alternate names (SAN) for example.com
and *.example.com
The CertificateAuthority functionality has evolved from certificate management originally found in the man-in-the-middle proxy pymiproxy <https://github.com/allfro/pymiproxy>
_ by Nadeem Douba.
It was also extended in warcprox <https://github.com/internetarchive/warcprox>
_ by Noah Levitt <https://github.com/nlevitt>
_ of Internet Archive.
The CA functionality was also reused in pywb <https://github.com/ikreymer/pywb>
_ and finally factored out into this separate package for modularity.
It is now also used by wsgiprox <https://github.com/webrecorder/wsgiprox>
_ to provide a generalized HTTPS proxy wrapper to any WSGI application.
This section shows a list of objects the current object is dependent upon in order to be used.
For dependencies that are only relevant as part of the build or runtime of the object, it is best to describe those local to those sections.
This section tracks information useful to describing how to build this object.
certauth-1.3.0-py2.py3-none-any.whl
application/zip
Python Source for certauth 1.3.0
https://files.pythonhosted.org/packages/18/6a/748f61932188f9bfc7685089d9a83b36e239b828aeb610661871d4342917/certauth-1.3.0-py2.py3-none-any.whl
QmcagHNiiWKR4cBvVcSHXmx2DtjBKSc848nLZLU6M7JCeg
QmWRLxQPg1qY7zUpBzQobR7hVfMLT28jAEG4PFiGyKXSSm
Qmf3tdjVsWK4TtkE7NjYNEbMXfEKj5GH3ESWGDBntu1QyY
downloadargparse-1.4.0.tar.gz
application/gzip
Python Source for argparse 1.4.0
https://files.pythonhosted.org/packages/18/dd/e617cfc3f6210ae183374cd9f6a26b20514bbb5a792af97949c5aacddf0f/argparse-1.4.0.tar.gz
QmVMjtpCHUfoKdHkNdqDCry1Ck6P8Tk9bJaHmrH7a35oXr
QmYhLtiLR6hamZiy5TL3vf5d6fA1z2eq4iGn4EmeJywkFs
QmUyto3kPC3XY43kf9bh6VoSJnEVvUCX32XX5EPXZCFCNw
download/bin/bash
{{ paths.mount }}/build.sh
certauth-1.3.0-py2.py3-none-any.whl
3
certauth
argparse-1.4.0.tar.gz
linux
x86-64
Objects have a set of files that comprise that object, as seen in the Files tab. When an object is built, they have a set of files that are the result of that build. In each case, these sets of files are the ones that are accessible within a virtual machine when running the object.
This section describes how those files are accessible and visible to that machine. When a virtual machine is created, the data is always accessible read-only within a particular mounted directory. However, applications may expect to be located at particular directories. This section allows one to place files in different directories when the virtual machine is launched.
There are two types of access. One is a link where the file is not copied from its original location. Instead, it creates what is called a symbolic link which is a "shortcut" that acts like a normal file but allows the actual data to be in a different directory. The other type is a traditional copy which copies the data explicitly to the provided destination. This takes more time, but the copy can be modified, unlike the read-only link type.
Action | Source | Destination | Summary | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Link | usr | /usr | N/A | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
No files will be installed. |
JavaScript must be enabled.
There was an error retrieving this content.
The content could not be found.
JavaScript must be enabled.
There was an error retrieving this content.
The content could not be found.
JavaScript must be enabled.
There was an error retrieving this content.
The content could not be found.
Confirm message?