mirror of
https://github.com/laurivosandi/certidude
synced 2024-11-16 18:06:44 +00:00
Merge branch 'master' of github.com:laurivosandi/certidude
This commit is contained in:
commit
5d5a24096c
152
README.rst
152
README.rst
@ -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?)
|
||||||
|
@ -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)
|
||||||
|
@ -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,6 +1174,7 @@ 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
|
||||||
|
if os.getuid() == 0:
|
||||||
import pwd
|
import pwd
|
||||||
_, _, uid, gid, gecos, root, shell = pwd.getpwnam("certidude")
|
_, _, uid, gid, gecos, root, shell = pwd.getpwnam("certidude")
|
||||||
restricted_groups = []
|
restricted_groups = []
|
||||||
|
Loading…
Reference in New Issue
Block a user