mirror of
https://github.com/laurivosandi/certidude
synced 2024-12-22 08:15:18 +00:00
Added diagrams and improved docs
This commit is contained in:
parent
e2f27078d1
commit
f92853bedb
21
README.rst
21
README.rst
@ -5,9 +5,10 @@ Introduction
|
||||
------------
|
||||
|
||||
Certidude is a novel X.509 Certificate Authority management tool
|
||||
with privilege isolation mechanism aiming to
|
||||
with privilege isolation mechanism and Kerberos authentication aiming to
|
||||
eventually support PKCS#11 and in far future WebCrypto.
|
||||
|
||||
.. figure:: doc/usecase-diagram.png
|
||||
|
||||
Features
|
||||
--------
|
||||
@ -106,19 +107,19 @@ Use web interface or following to sign a certificate on Certidude server:
|
||||
Production deployment
|
||||
---------------------
|
||||
|
||||
Install uWSGI:
|
||||
Install ``nginx`` and ``uwsgi``:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
apt-get install nginx uwsgi uwsgi-plugin-python3
|
||||
|
||||
To set up ``nginx`` and ``uwsgi`` is suggested:
|
||||
For easy setup following is reccommended:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
certidude setup production
|
||||
|
||||
Otherwise manually configure uUWSGI application in ``/etc/uwsgi/apps-available/certidude.ini``:
|
||||
Otherwise manually configure ``uwsgi`` application in ``/etc/uwsgi/apps-available/certidude.ini``:
|
||||
|
||||
.. code:: ini
|
||||
|
||||
@ -136,8 +137,12 @@ Otherwise manually configure uUWSGI application in ``/etc/uwsgi/apps-available/c
|
||||
callable = app
|
||||
chmod-socket = 660
|
||||
chown-socket = certidude:www-data
|
||||
buffer-size = 32768
|
||||
env = PUSH_PUBLISH=http://localhost/event/publish/%(channel)s
|
||||
env = PUSH_SUBSCRIBE=http://localhost/event/subscribe/%(channel)s
|
||||
env = LANG=C.UTF-8
|
||||
env = LC_ALL=C.UTF-8
|
||||
env = KRB5_KTNAME=/etc/certidude.keytab
|
||||
|
||||
Also enable the application:
|
||||
|
||||
@ -272,11 +277,11 @@ to generate user whitelist via LDAP:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
ldapsearch -H ldap://dc1.id.stipit.com -s sub -x -LLL \
|
||||
-D 'cn=certidude,cn=Users,dc=id,dc=stipit,dc=com' \
|
||||
ldapsearch -H ldap://dc1.example.com -s sub -x -LLL \
|
||||
-D 'cn=certidude,cn=Users,dc=example,dc=com' \
|
||||
-w 'certidudepass' \
|
||||
-b 'ou=sso,dc=id,dc=stipit,dc=com' \
|
||||
'(objectClass=user)' sAMAccountName userPrincipalName givenName sn \
|
||||
-b 'dc=example,dc=com' \
|
||||
'(&(objectClass=user)(memberOf=cn=Domain Admins,cn=Users,dc=example,dc=com))' sAMAccountName userPrincipalName givenName sn \
|
||||
| python3 -c "import ldif3; import sys; [sys.stdout.write('%s:%s:%s:%s\n' % (a.pop('sAMAccountName')[0], a.pop('userPrincipalName')[0], a.pop('givenName')[0], a.pop('sn')[0])) for _, a in ldif3.LDIFParser(sys.stdin.buffer).parse()]" \
|
||||
> /run/certidude/user.whitelist
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
import re
|
||||
import falcon
|
||||
import ipaddress
|
||||
import os
|
||||
import json
|
||||
import types
|
||||
@ -23,9 +24,25 @@ def omit(**kwargs):
|
||||
|
||||
def authorize_admin(func):
|
||||
def wrapped(self, req, resp, *args, **kwargs):
|
||||
authority = kwargs.get("ca")
|
||||
|
||||
# Parse remote IPv4/IPv6 address
|
||||
remote_addr = ipaddress.ip_network(req.env["REMOTE_ADDR"])
|
||||
|
||||
# Check for administration subnet whitelist
|
||||
print("Comparing:", authority.admin_subnets, "To:", remote_addr)
|
||||
for subnet in authority.admin_subnets:
|
||||
if subnet.overlaps(remote_addr):
|
||||
break
|
||||
else:
|
||||
raise falcon.HTTPForbidden("Forbidden", "Remote address %s not whitelisted" % remote_addr)
|
||||
|
||||
# Check for username whitelist
|
||||
kerberos_username, kerberos_realm = kwargs.get("user")
|
||||
if kerberos_username not in kwargs.get("ca").admin_users:
|
||||
raise falcon.HTTPForbidden("User %s not whitelisted" % kerberos_username)
|
||||
if kerberos_username not in authority.admin_users:
|
||||
raise falcon.HTTPForbidden("Forbidden", "User %s not whitelisted" % kerberos_username)
|
||||
|
||||
# Retain username, TODO: Better abstraction with username, e-mail, sn, gn?
|
||||
kwargs["user"] = kerberos_username
|
||||
return func(self, req, resp, *args, **kwargs)
|
||||
return wrapped
|
||||
@ -34,7 +51,6 @@ def authorize_admin(func):
|
||||
def pop_certificate_authority(func):
|
||||
def wrapped(self, req, resp, *args, **kwargs):
|
||||
kwargs["ca"] = self.config.instantiate_authority(kwargs["ca"])
|
||||
print(func)
|
||||
return func(self, req, resp, *args, **kwargs)
|
||||
return wrapped
|
||||
|
||||
@ -86,7 +102,6 @@ def templatize(path):
|
||||
def wrapper(func):
|
||||
def wrapped(instance, req, resp, *args, **kwargs):
|
||||
assert not req.get_param("unicode") or req.get_param("unicode") == u"✓", "Unicode sanity check failed"
|
||||
print("templatize would call", func, "with", args, kwargs)
|
||||
r = func(instance, req, resp, *args, **kwargs)
|
||||
r.pop("self")
|
||||
if not resp.body:
|
||||
@ -212,7 +227,7 @@ class RequestListResource(CertificateAuthorityBase):
|
||||
Submit certificate signing request (CSR) in PEM format
|
||||
"""
|
||||
# Parse remote IPv4/IPv6 address
|
||||
remote_addr = ipaddress.ip_address(req.env["REMOTE_ADDR"])
|
||||
remote_addr = ipaddress.ip_network(req.env["REMOTE_ADDR"])
|
||||
|
||||
# Check for CSR submission whitelist
|
||||
if ca.request_subnets:
|
||||
@ -220,7 +235,7 @@ class RequestListResource(CertificateAuthorityBase):
|
||||
if subnet.overlaps(remote_addr):
|
||||
break
|
||||
else:
|
||||
raise falcon.HTTPForbidden("IP address %s not whitelisted" % remote_addr)
|
||||
raise falcon.HTTPForbidden("Forbidden", "IP address %s not whitelisted" % remote_addr)
|
||||
|
||||
if req.get_header("Content-Type") != "application/pkcs10":
|
||||
raise falcon.HTTPUnsupportedMediaType(
|
||||
@ -308,6 +323,7 @@ class CertificateAuthorityResource(CertificateAuthorityBase):
|
||||
class IndexResource(CertificateAuthorityBase):
|
||||
@login_required
|
||||
@pop_certificate_authority
|
||||
@authorize_admin
|
||||
@templatize("index.html")
|
||||
def on_get(self, req, resp, ca, user):
|
||||
return locals()
|
||||
|
BIN
doc/usecase-diagram.dia
Normal file
BIN
doc/usecase-diagram.dia
Normal file
Binary file not shown.
BIN
doc/usecase-diagram.png
Normal file
BIN
doc/usecase-diagram.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 38 KiB |
Loading…
Reference in New Issue
Block a user