1
0
mirror of https://github.com/laurivosandi/certidude synced 2024-09-28 21:11:42 +00:00

Merge branch 'master' of github.com:laurivosandi/certidude

This commit is contained in:
Lauri Võsandi 2017-01-26 21:59:37 +00:00
commit 5d5a24096c
3 changed files with 112 additions and 55 deletions

View File

@ -17,9 +17,10 @@ eventually support PKCS#11 and in far future WebCrypto.
.. figure:: doc/usecase-diagram.png .. figure:: doc/usecase-diagram.png
Certidude is mainly designed for VPN gateway operators to make Certidude is mainly designed for StrongSwan and OpenVPN gateway operators to make
desktop/laptop VPN setup as easy as possible. VPN client setup on laptops, desktops and mobile devices as painless as possible.
User certificate management eg. for HTTPS is also made reasonably simple. Certidude can also be used to manage HTTPS client certificates for
eg. maintaining an extra layer of protection for intranet websites.
For a full-blown CA you might want to take a look at For a full-blown CA you might want to take a look at
`EJBCA <http://www.ejbca.org/features.html>`_ or `EJBCA <http://www.ejbca.org/features.html>`_ or
`OpenCA <https://pki.openca.org/>`_. `OpenCA <https://pki.openca.org/>`_.
@ -105,18 +106,29 @@ TODO
Install Install
------- -------
To install Certidude server: To install Certidude server you need certain system libraries in addition to
regular Python dependencies.
System dependencies for Ubuntu 16.04:
.. code:: bash .. code:: bash
apt-get install -y python python-pip python-dev cython \ apt install -y python python-pip python-dev cython \
python-cffi python-configparser \ python-cffi python-configparser \
python-pysqlite2 python-mysql.connector python-ldap \ python-pysqlite2 python-mysql.connector python-ldap \
build-essential libffi-dev libssl-dev libkrb5-dev \ build-essential libffi-dev libssl-dev libkrb5-dev \
ldap-utils krb5-user \ ldap-utils krb5-user \
libsasl2-modules-gssapi-mit \ libsasl2-modules-gssapi-mit \
libsasl2-dev libldap2-dev libsasl2-dev libldap2-dev
pip install simplepam pykerberos certidude
System dependencies for Fedora 24+:
.. code:: bash
yum install redhat-rpm-config python-devel openssl-devel openldap-devel
At the moment package at PyPI is rather outdated.
Please proceed down to Development section to install Certidude from source.
Setting up authority Setting up authority
@ -139,15 +151,6 @@ If necessary tweak machine's fully qualified hostname in ``/etc/hosts``:
127.0.0.1 localhost 127.0.0.1 localhost
127.0.1.1 ca.example.com ca 127.0.1.1 ca.example.com ca
Then proceed to install `nchan <https://nchan.slact.net/>`_:
.. code:: bash
wget https://nchan.slact.net/download/nginx-common.deb \
https://nchan.slact.net/download/nginx-extras.deb
dpkg -i nginx-common.deb nginx-extras.deb
apt-get -f install
Certidude can set up certificate authority relatively easily. Certidude can set up certificate authority relatively easily.
Following will set up certificate authority in ``/var/lib/certidude/hostname.domain.tld``, Following will set up certificate authority in ``/var/lib/certidude/hostname.domain.tld``,
configure systemd service for your platform, configure systemd service for your platform,
@ -166,27 +169,27 @@ and start the services:
systemctl restart certidude systemctl restart certidude
Certificate management Setting up PAM authentication
---------------------- -----------------------------
Use following command to request a certificate on a machine: Following assumes the OS user accounts are used to authenticate users.
This means users can be easily managed with OS tools such as ``adduser``, ``usermod``, ``userdel`` etc.
.. code:: Make sure you insert `AllowUsers administrator-account-username`
to SSH server configuration if you have SSH server installed on the machine
to prevent regular users from accessing the command line of certidude.
Note that in future we're planning to add command-line interaction
in which case SSH access makes sense.
certidude setup client ca.example.com If you're planning to use PAM for authentication you need to install corresponding
Python modules:
Use following to list signing requests, certificates and revoked certificates on server: .. code:: bash
.. code:: pip install simplepam
certidude list
Use web interface or following to sign a certificate on server:
.. code::
certidude sign client-hostname-or-common-name
The default configuration generated by ``certidude setup`` should make use of the
PAM.
Setting up Active Directory authentication Setting up Active Directory authentication
------------------------------------------ ------------------------------------------
@ -199,6 +202,7 @@ Install dependencies:
.. code:: bash .. code:: bash
apt-get install samba-common-bin krb5-user ldap-utils apt-get install samba-common-bin krb5-user ldap-utils
pip install pykerberos
Reset Samba client configuration in ``/etc/samba/smb.conf``, adjust Reset Samba client configuration in ``/etc/samba/smb.conf``, adjust
workgroup and realm accordingly: workgroup and realm accordingly:
@ -274,33 +278,58 @@ Common pitfalls:
the CA machine to domain, eg when you're running CA behind SSL terminating web server: the CA machine to domain, eg when you're running CA behind SSL terminating web server:
Bad credentials: Unspecified GSS failure. Minor code may provide more information (851968) Bad credentials: Unspecified GSS failure. Minor code may provide more information (851968)
Automating certificate setup
----------------------------
Ubuntu 14.04 based desktops come with NetworkManager installed. Setting up services
Create ``/etc/NetworkManager/dispatcher.d/certidude`` with following content: -------------------
Set up services as usual (OpenVPN, Strongswan, etc), when setting up certificates
generate signing request with TLS server flag set.
Paste signing request into the Certidude web interface and hit the submit button.
Since signing requests with custom flags are not allowed to be signed
from the interface due to security concerns, sign the certificate at Certidude command line:
.. code:: bash .. code:: bash
#!/bin/sh -e certidude sign gateway.example.com
# Set up certificates for IPSec connection
case "$2" in Download signed certificate from the web interface or ``wget`` it into the service machine.
up) Fetch also CA certificate and finish configuring the service.
LANG=C.UTF-8 /usr/local/bin/certidude request spawn -k
;;
esac
Finally make it executable:
Setting up clients
------------------
This example works for Ubuntu 16.04 desktop with corresponding plugins installed
for NetworkManager.
Configure Certidude client in ``/etc/certidude/client.conf``:
.. code:: ini
[ca.example.com]
insecure = true
trigger = interface up
Configure services in ``/etc/certidude/services.conf``:
.. code:: bash .. code:: bash
chmod +x /etc/NetworkManager/dispatcher.d/certidude [gateway.example.com]
authority = ca.example.com
service = network-manager/openvpn
remote = gateway.example.com
Whenever a wired or wireless connection is brought up, To request certificate:
the dispatcher invokes ``certidude`` in order to generate RSA keys,
submit CSR, fetch signed certificate, .. code:: bash
create NetworkManager configuration for the VPN connection.
certidude request
The keys, signing requests, certificates and CRL-s are placed under
/var/lib/certidude/ca.example.com/
The VPN connection should immideately become available under network connections.
Development Development
@ -323,7 +352,7 @@ To generate templates:
.. code:: bash .. code:: bash
apt-get install npm nodejs apt install npm nodejs
sudo ln -s nodejs /usr/bin/node # Fix 'env node' on Ubuntu 14.04 sudo ln -s nodejs /usr/bin/node # Fix 'env node' on Ubuntu 14.04
npm install -g nunjucks@2.5.2 npm install -g nunjucks@2.5.2
nunjucks-precompile --include "\\.html$" --include "\\.svg$" certidude/static/ > certidude/static/js/templates.js nunjucks-precompile --include "\\.html$" --include "\\.svg$" certidude/static/ > certidude/static/js/templates.js
@ -340,3 +369,30 @@ To install the package from the source:
.. code:: bash .. code:: bash
python setup.py install --single-version-externally-managed --root / python setup.py install --single-version-externally-managed --root /
To uninstall:
pip uninstall certidude
Certificate attributes
----------------------
Certificates have a lot of fields that can be filled in.
In any case country, state, locality, organization, organizational unit are not filled in
as this information will already exist in AD and duplicating it in the certificate management
doesn't make sense. Additionally the information will get out of sync if
attributes are changed in AD but certificates won't be updated.
If machine is enrolled, eg by running certidude request:
* If Kerberos credentials are presented machine is automatically enrolled
* Common name is set to short hostname/machine name in AD
* E-mail is not filled in (maybe we can fill in something from AD?)
* Given name and surname are not filled in
If user enrolls, eg by clicking generate bundle button in the web interface:
* Common name is either set to username or username@device-identifier depending on the 'user certificate enrollment' setting
* Given name and surname are filled in based on LDAP attributes of the user
* E-mail not filled in (should it be filled in? Can we even send mail to user if it's in external domain?)

View File

@ -1,7 +1,6 @@
import click import click
import falcon import falcon
import kerberos # If this fails pip install kerberos
import logging import logging
import os import os
import re import re
@ -13,6 +12,7 @@ from certidude import config, const
logger = logging.getLogger("api") logger = logging.getLogger("api")
if "kerberos" in config.AUTHENTICATION_BACKENDS: if "kerberos" in config.AUTHENTICATION_BACKENDS:
import kerberos # If this fails pip install kerberos
ktname = os.getenv("KRB5_KTNAME") ktname = os.getenv("KRB5_KTNAME")
if not ktname: if not ktname:
@ -186,7 +186,7 @@ def authenticate(optional=False):
if not simplepam.authenticate(user, passwd, "sshd"): if not simplepam.authenticate(user, passwd, "sshd"):
logger.critical(u"Basic authentication failed for user %s from %s", logger.critical(u"Basic authentication failed for user %s from %s",
repr(user), req.context.get("remote_addr")) repr(user), req.context.get("remote_addr"))
raise falcon.HTTPForbidden("Forbidden", "Invalid password") raise falcon.HTTPUnauthorized("Forbidden", "Invalid password", ("Basic",))
req.context["user"] = User.objects.get(user) req.context["user"] = User.objects.get(user)
return func(resource, req, resp, *args, **kwargs) return func(resource, req, resp, *args, **kwargs)

View File

@ -239,7 +239,7 @@ def certidude_request(fork):
nm_config.set("vpn", "connection-type", "tls") nm_config.set("vpn", "connection-type", "tls")
nm_config.set("vpn", "comp-lzo", "yes") nm_config.set("vpn", "comp-lzo", "yes")
nm_config.set("vpn", "cert-pass-flags", "0") nm_config.set("vpn", "cert-pass-flags", "0")
nm_config.set("vpn", "tap-dev", "yes") nm_config.set("vpn", "tap-dev", "no")
nm_config.set("vpn", "remote-cert-tls", "server") # Assert TLS Server flag of X.509 certificate nm_config.set("vpn", "remote-cert-tls", "server") # Assert TLS Server flag of X.509 certificate
nm_config.set("vpn", "remote", service_config.get(endpoint, "remote")) nm_config.set("vpn", "remote", service_config.get(endpoint, "remote"))
nm_config.set("vpn", "key", endpoint_key_path) nm_config.set("vpn", "key", endpoint_key_path)
@ -1174,10 +1174,11 @@ def certidude_serve(port, listen):
from certidude import config from certidude import config
# Fetch UID, GID of certidude user # Fetch UID, GID of certidude user
import pwd if os.getuid() == 0:
_, _, uid, gid, gecos, root, shell = pwd.getpwnam("certidude") import pwd
restricted_groups = [] _, _, uid, gid, gecos, root, shell = pwd.getpwnam("certidude")
restricted_groups.append(gid) restricted_groups = []
restricted_groups.append(gid)
""" """
Spawn signer process Spawn signer process