Giter VIP home page Giter VIP logo

certidude's People

Contributors

laurivosandi avatar plaes avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

certidude's Issues

Auditing script

Currently activities at CA leave trace in:

  • Mailbox at a separate machine
  • System logs
  • SQL logs possibly at a separate machine
  • Signed, revoked folders at server
  • CRL at server

Auditing tool would have to fetch all the bits and pieces and verify that data hasn't been tampered with.

Autosign for domain computers

Since we are authenticating Certidude server users against Kerberos anyway, it would be relatively easy to authenticate machines as well. This way we can leverage the system keytab which is already in place once computer is joined to domain. See examples how to make requests on behalf of a computer account instead of a regular user.

Make missing directories

Currently following directories are not created on the fly:

  • /run/certidude when Kerberos TGT cronjob runs, Certidude server or signer is started. This should be solved with systemd instead.
  • /var/lib/certidude/ca.example.com/{signed,keys,requests} are not created on the client side when certidude request runs

Migrate to nchan

https://nchan.slact.net/ is a nice competitor to the streaming push module we're using currently. It properly forwards content type to long polling request and deleting the channel causes 404 to be returned.

Investigate FastCGI/uWSGI support

Currently the certidude serve spawns signer processes as root and then switches to user certitude to serve HTTP API. In order to use Kerberos authentication on the server we could serve the API on UNIX domain socket and let the web server do the heavy lifting. Currently there is no elegant way to start API as root and then have it's privileges dropped (UNIX domain socket binding is done once event loop starts), moreover FastCGI implementations seem to be somwhat behind for Python3. It might make sense to modify code to permit uWSGI usage from web server context (as user www-data), this assumes the certidude spawn is run during boot.

kinit won't run during boot

One of the systemd service files is being generated with incorrect contents:

Unknown lvalue 'Before' in section 'Service' for certidude-ldap-kinit.service

Python 3 blockers

To even get started with Python3 port some things need to be clarified first - what is the current status of following dependencies:

  • LDAP support - it seems widely used ldap3 doesn't support GSSAPI encryption the way it's used right now, so we need to switch to TLS with GSSAPI authentication only
  • Requests Kerberos
  • cryptography.io
  • P12 bundles are generated with PyOpenSSL, can we switch to cryptography.io for more consitent dependencies
  • MySQL connector
  • falcon

Group membership or delegation check via LDAP

Currently the domain admins group membership check is not performed within Python code. AD-compatible domain controllers also supply PAC, which can be used to check group membership avoiding additional LDAP query.

Support HTTP Strict Transport Security

Currently insecure flag in /etc/certidude/client.conf specifies whether CA should be contacted over HTTP or HTTPS. Instead of such static configuration we should support HSTS.

Possible implementation on the client side would perform first request over HTTP and if server redirects to HTTPS and returns with HSTS headers create a file eg /var/lib/certidude/ca.example.com/secure. If such file exists further requests would be performed over HTTPS by default.

Add ACME support

This would allow auotmatically obtaining certificate for a server with certbot

Optional timestamp check during CSR submission

Clock skew issues are common, it would be convenient to supply client timestamp with CSR so server could inform CA administrator about the clock skew on client side eg. simply via log entry.

HTTP request header Date should be suitable for this purpose.

Certificate renewal

A cron job could be scheduled 2 weeks before the certificate expiration so Certidude could also perform certificate renewal. Certidude server could automatic allow certificate renewal in certain timeframe, exact implementation details need more investigation.

Provision fails with jinja2.exceptions.UndefinedError: 'session' is undefined

Hi,

I've hit an error when trying to provision with sudo -H /usr/local/bin/certidude provision authority:

Traceback (most recent call last):
  File "/usr/local/bin/certidude", line 6, in <module>
    exec(compile(open(__file__).read(), __file__, 'exec'))
  File "/srv/certidude/misc/certidude", line 6, in <module>
    entry_point()
  File "/usr/local/lib/python3.5/dist-packages/click/core.py", line 722, in __call__
    return self.main(*args, **kwargs)
  File "/usr/local/lib/python3.5/dist-packages/click/core.py", line 697, in main
    rv = self.invoke(ctx)
  File "/usr/local/lib/python3.5/dist-packages/click/core.py", line 1066, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/local/lib/python3.5/dist-packages/click/core.py", line 1066, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/local/lib/python3.5/dist-packages/click/core.py", line 895, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/local/lib/python3.5/dist-packages/click/core.py", line 535, in invoke
    return callback(*args, **kwargs)
  File "/srv/certidude/certidude/cli.py", line 1193, in certidude_provision_authority
    verbose_render_systemd_service("snippets/nginx-ocsp-cache.service", "certidude-ocsp-cache.service", vars())
  File "/srv/certidude/certidude/cli.py", line 1179, in verbose_render_systemd_service
    buf = env.get_template(template).render(context)
  File "/usr/lib/python3/dist-packages/jinja2/environment.py", line 989, in render
    return self.environment.handle_exception(exc_info, True)
  File "/usr/lib/python3/dist-packages/jinja2/environment.py", line 754, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/lib/python3/dist-packages/jinja2/_compat.py", line 37, in reraise
    raise value.with_traceback(tb)
  File "/srv/certidude/certidude/templates/snippets/nginx-ocsp-cache.service", line 7, in top-level template code
    ExecStart=-/usr/bin/curl --cert-status https://{{ common_name }}:8443/ --cacert /etc/certidude/authority/{{ session.authority.hostname }}/ca_cert.pem
  File "/usr/lib/python3/dist-packages/jinja2/environment.py", line 408, in getattr
    return getattr(obj, attribute)
jinja2.exceptions.UndefinedError: 'session' is undefined

I haven't found this error on the net, so after a bit digging I think this is related to nginx not starting, this is the output from sudo systemctl status nginx.service:

nginx.service - A high performance web server and a reverse proxy server
   Loaded: loaded (/lib/systemd/system/nginx.service; disabled; vendor preset: enabled)
   Active: failed (Result: exit-code) since vie 2018-09-21 10:53:08 CEST; 11s ago
     Docs: man:nginx(8)
  Process: 29186 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process on; (code=exited, status=1/FAILURE)

sep 21 10:53:07 soporte systemd[1]: Starting A high performance web server and a reverse proxy server...
sep 21 10:53:08 soporte nginx[29186]: nginx: [emerg] BIO_new_file("/var/lib/certidude/signed/ca.mainsip.com.pem") failed (SSL: error:02001002:system library:fopen:No such file or directory:fopen('/var/lib/certidude/signed/ca.mainsip.com.pemsep 21 10:53:08 soporte nginx[29186]: nginx: configuration file /etc/nginx/nginx.conf test failed
sep 21 10:53:08 soporte systemd[1]: nginx.service: Control process exited, code=exited status=1
sep 21 10:53:08 soporte systemd[1]: Failed to start A high performance web server and a reverse proxy server.
sep 21 10:53:08 soporte systemd[1]: nginx.service: Unit entered failed state.
sep 21 10:53:08 soporte systemd[1]: nginx.service: Failed with result 'exit-code'.

So it seems it doesn't find a certificate on /var/lib/certidude/signed/ca.mainsip.com.pem but /var/lib/certidude/ doesn't even exists. Is there anything I'm missing?

Renew over TLS

Migrate whole certificate renewal procedure to mutually authenticated TLS connection.

New port assignment:

80 - Certidude API-s over HTTP
443 - Certidude API-s over HTTPS, no client auth
8443 - Certidude API-s over HTTPS with mandatory client auth

Database backed tokens

Currently hashing algorithm is used for tokening systems. Not having to save stuff to database is a pro of this approach, but if server's secrets are compromised attacker can generate a valid token. Also such token can be reused.

Certidude should support a database backed token system where token identifier is genuinely random and relevant information is looked up on the server side from the database.

Save enrollment IP address

Currently CSR submission originating IP address is not saved. It could be saved in the filesystem attributes and shown in the user interface as well.

Apply correct selinux context

When certidude client places certificates and keys under /var/lib/certidude NetworkManager/OpenVPN/Fedora combo doesn't like it. A quick hack right now seems to be following:

chcon -Rv --type=home_cert_t /var/lib/certidude

Support other systems than Ubuntu

Trying to install Certidude on CentOS 7, in a virtual env. The install went fine, but provisioning fails with

[root@rad ~]# /opt/certidude/bin/certidude provision authority
Traceback (most recent call last):
  File "/opt/certidude/bin/certidude", line 4, in <module>
    __import__('pkg_resources').run_script('certidude==0.1.21', 'certidude')
  File "/opt/certidude/lib/python2.7/site-packages/pkg_resources/__init__.py", line 743, in run_script
    self.require(requires)[0].run_script(script_name, ns)
  File "/opt/certidude/lib/python2.7/site-packages/pkg_resources/__init__.py", line 1498, in run_script
    exec(code, namespace, namespace)
  File "/opt/certidude/lib/python2.7/site-packages/certidude-0.1.21-py2.7.egg/EGG-INFO/scripts/certidude", line 6, in <module>
    entry_point()
  File "/opt/certidude/lib/python2.7/site-packages/click/core.py", line 722, in __call__
    return self.main(*args, **kwargs)
  File "/opt/certidude/lib/python2.7/site-packages/click/core.py", line 697, in main
    rv = self.invoke(ctx)
  File "/opt/certidude/lib/python2.7/site-packages/click/core.py", line 1066, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/opt/certidude/lib/python2.7/site-packages/click/core.py", line 1066, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/opt/certidude/lib/python2.7/site-packages/click/core.py", line 895, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/opt/certidude/lib/python2.7/site-packages/click/core.py", line 535, in invoke
    return callback(*args, **kwargs)
  File "/opt/certidude/lib/python2.7/site-packages/certidude-0.1.21-py2.7.egg/certidude/cli.py", line 1024, in certidude_provision_authority
    assert subprocess.check_output(["/usr/bin/lsb_release", "-cs"]) in (b"trusty\n", b"xenial\n", b"bionic\n"), "Only Ubuntu 16.04 supported at the moment"
  File "/usr/lib64/python2.7/subprocess.py", line 568, in check_output
    process = Popen(stdout=PIPE, *popenargs, **kwargs)
  File "/usr/lib64/python2.7/subprocess.py", line 711, in __init__
    errread, errwrite)
  File "/usr/lib64/python2.7/subprocess.py", line 1327, in _execute_child
    raise child_exception
OSError: [Errno 2] No such file or directory

I only Ubuntu trusty, xenial or bionic supported ? It should be made more clear in the doc in that case

Add Windows packaging

Certidude client could be packaged as MSI for Windows, installed as a service and it could allow automatic installation of OpenVPN as a service once the certificates are in place. Graphical user interface can be omitted at first.

Add OpenVPN support

strongSwan support is almost there so adding OpenVPN support using strongSwan snippets is pretty trivial.

Customizable server title and description

Currently window title in the certidude web server view is simply Certidude server, instead it could be something more descripive and specific to organization, hence it should be configurable via /etc/certidude/server.conf for example by placing title = Foo Bar LLC VPN certificates under [authority] section.

Similarily description = /var/lib/certidude/ca.example.com/help.md could be used to specify Markdown formatted file which gets rendered to HTML and displayed as landing page.

User interface chokes with 200+ certificates

Current approach is pretty naive - all signed certificates and accompanying metadata and code snippets are inserted into DOM tree which makes even Chrome choke.

For development/testing run this with autosign allowed from localhost:

for j in $(seq 1 500); do
  openssl genrsa -out /tmp/host_key.pem 1024
  openssl req -new -sha384 -subj "/CN=$(cat /dev/urandom | tr -dc 'a-z0-9' | fold -w 15 | head -n 1)" \
    -key /tmp/host_key.pem \
    -out /tmp/host_req.pem
  curl --cert-status -f -L -H "Content-type: application/pkcs10" \
    --data-binary @/tmp/host_req.pem \
    -o /tmp/host_cert.pem \
    'http://127.0.1.1:8080/api/request/?wait=yes\&autosign=yes'
done

Generate bundle secret using WebCrypto

Currently if .ovpn or .p12 bundle is downloaded the RSA private key is generated on the server and served for the web browser.

To do it technically correctly the private key would have to be generated on the client side. Using WebCrypto and pki.js we should be able to generate RSA keypair and bundle file in the browser and have it signed by server since the user is already logged in.

The .ovpn could be generated using JavaScript blobs.

Client woes if revocation list is empty

File "/usr/lib/python2.7/site-packages/certidude-0.1.21-py2.7.egg/certidude/helpers.py", line 73, in certidude_request_certificate
    for revocation in revocation_list.get_revoked():
TypeError: 'NoneType' object is not iterable

Remove/refactor command line helpers

In the beginning we tried to configure services with certidude setup service-blah, this approach failed because bits and pieces of the information has to be persistent for example for certificate renewal and in some cases request has to be initiated later (when interface goes up or machine is joined to domain).

Instead now we're using /etc/certidude/client.conf and /etc/certidude/services.conf configuration files. This makes it more manageable also with configuration management software.

In fact in the future we should migrate to /etc/certidude/client.d/blah.conf and /etc/certidude/service.d/blah.conf schema. This makes it easier to reconfigure services with a simple copypastable command instead of having to update fragments of an .ini style file.

So - certidude setup service-blah command either should be removed completely or refactored to generate /etc/certidude/serivced/blah.conf files

Customizable certificate expiration

When certificate is going to be signed UI could show a popup where following can be adjusted:

  • Certificate expires in X years, as predefined in /etc/certidude/server.conf
  • Certificate expires when user account expires in AD
  • Certificate expires at particular date handpicked by the

When automatic enrollment is possible certificate expiration policy could be defined in /etc/certidude/server.conf.

Cronjob for automatically revoking certificates for disabled/deleted computer/user accounts should be added. To consistently map users to certificates perhaps SID should be added into the certificate somehow?

Error 404 immediately after install on clean VM

Hi, I'm trying to use this to manage my certificates for Samba domain controllers and OpenVPN. I have followed the source install steps for a source install, but get an error 404 page when loading the https page.
The logs show no error:

Aug 25 16:01:31 ca certidude[7615]: Executing log_insert_entry.sql with (datetime.datetime(2019, 8, 25, 16, 1, 31, 519141), 'certidude.api.session', 20, 'info', 'Served CA certificate to 192.168.48.69', 'session', 'on_get', 17, '', 7623, 139841744570176, 'MainThread') Aug 25 16:01:31 ca certidude[7615]: Publishing log-entry event '{"created": "2019-08-25T16:01:31.519Z", "message": "Served CA certificate to 192.168.48.69", "severity": "info"}' on http://localhost/ev/pub/lidJVVGSKNSEgV5cJ5YzmFjIYLSBatKk

Is there something obvious that I am missing ?

Thanks very much

Certificate renewal breaks if e-mail can't be delivered

Example stack trace:

Mar 31 06:26:02 ca certidude[16379]: Connecing to ldap://dc1.example.com using Kerberos ticket cache from /run/certidude/krb5cc
Mar 31 06:26:02 ca /usr/bin/python[17271]: python /usr/local/bin/certidude serve -l 0.0.0.0 -p 80: GSSAPI client step 1
Mar 31 06:26:02 ca /usr/bin/python[17271]: python /usr/local/bin/certidude serve -l 0.0.0.0 -p 80: GSSAPI client step 1
Mar 31 06:26:02 ca /usr/bin/python[17271]: python /usr/local/bin/certidude serve -l 0.0.0.0 -p 80: GSSAPI client step 1
Mar 31 06:26:02 ca /usr/bin/python[17271]: python /usr/local/bin/certidude serve -l 0.0.0.0 -p 80: GSSAPI client step 2
Mar 31 06:26:02 ca certidude[16379]: Sending e-mail certificate-renewed.md to Lauri Võsandi <[email protected]>
Mar 31 06:26:03 ca certidude[16379]: Traceback (most recent call last):
Mar 31 06:26:03 ca certidude[16379]:   File "/usr/lib/python2.7/wsgiref/handlers.py", line 85, in run
Mar 31 06:26:03 ca certidude[16379]:     self.result = application(self.environ, self.start_response)
Mar 31 06:26:03 ca certidude[16379]:   File "/usr/local/lib/python2.7/dist-packages/falcon/api.py", line 209, in __call__
Mar 31 06:26:03 ca certidude[16379]:     responder(req, resp, **params)
Mar 31 06:26:03 ca certidude[16379]:   File "/root/certidude/certidude/auth.py", line 50, in kerberos_authenticate
Mar 31 06:26:03 ca certidude[16379]:     return func(resource, req, resp, *args, **kwargs)
Mar 31 06:26:03 ca certidude[16379]:   File "/root/certidude/certidude/firewall.py", line 24, in wrapped
Mar 31 06:26:03 ca certidude[16379]:     return func(self, req, resp, *args, **kwargs)
Mar 31 06:26:03 ca certidude[16379]:   File "/root/certidude/certidude/firewall.py", line 33, in wrapped
Mar 31 06:26:03 ca certidude[16379]:     return func(self, req, resp, *args, **kwargs)
Mar 31 06:26:03 ca certidude[16379]:   File "/root/certidude/certidude/api/request.py", line 100, in on_post
Mar 31 06:26:03 ca certidude[16379]:     _, resp.body = authority._sign(csr, body, overwrite=True)
Mar 31 06:26:03 ca certidude[16379]:   File "/root/certidude/certidude/authority.py", line 351, in _sign
Mar 31 06:26:03 ca certidude[16379]:     certificate=cert,
Mar 31 06:26:03 ca certidude[16379]:   File "/root/certidude/certidude/mailer.py", line 96, in send
Mar 31 06:26:03 ca certidude[16379]:     conn.sendmail(config.OUTBOX_MAIL, recipients, msg.as_string())
Mar 31 06:26:03 ca certidude[16379]:   File "/usr/lib/python2.7/smtplib.py", line 747, in sendmail
Mar 31 06:26:03 ca certidude[16379]:     raise SMTPRecipientsRefused(senderrs)
Mar 31 06:26:03 ca certidude[16379]: SMTPRecipientsRefused: {u'Lauri V\xf5sandi <[email protected]>': (451, '4.3.5 <[email protected]>: Recipient address rejected: Server configuration error')}
Mar 31 06:26:03 ca certidude[16379]: 192.168.12.1 - - [31/Mar/2017 06:26:03] "POST /api/request/?autosign=true&wait=30 HTTP/1.1" 500 59

Feature Request: Custom attributes

When uploading a CSR, all custom extensions are removed.

There should be a feature that if the adminstrator approves, the extensions are included in the certificate. For example, this software can't currently be used to issue certificates for smart cards for windows logon, as they require special attributes to be set (certidude removes them on issuance).

Even if these weren't exposed in the GUI, it would be great if this was an option for advanced users (e.g. adding multiple SANs).

Add syslog integration

On the VPN gateway interesting traffic could be logged to syslog and then forwarded to Certidude:

  • Rejected traffic logged with rate limiting
  • Start/stop of TCP/UDP sessions

Certidude could have another syslog server facilities, possibly use already deployed certificates to authenticate TLS tunnel for syslog and parse the messages coming in.

Parsed messages could be stored in SQL database with all relevant metadata decoded - who was the user/computer initiating the connections etc

Relevant OCSP response if user account disabled in AD

Currently OCSP responder returns ok regardless of user account status in AD. Certidude should have config to handle this

  • By default return not ok response on OCSP if certificate was issued to a user (CN=user@machine-id) and user is disabled (UserAccountControl flags)
  • Optionally revoke certificate as soon as user is disabled
  • Do not check user status

Fix network-manager/openvpn generated configuration file

On Ubuntu 16.04 NetworkManager seems to shut down VPN connection after certain time of inactivity. Quick fix is to add ping option.

Currently confguration file gets generated with TAP interface but we should switch to TUN.

Bootstrapping API call

To automate VPN setup even more the server could export basically the client's services.conf file which tells clients which services to configure once the certificates have been deployed to basically make it possible to acquire the certificate and configure related services with single command:

certidude bootstrap ca.example.lan

By default assume clients to have sort of dumb config which accepts anything that eg VPN gateway suggests during negotiation.

However in certain cases it makes sense to constrain config on the client side:

  • Which VPN client software is to be configured (OpenVPN or StrongSwan)
  • How is the service configured eg as a service running in the background or user controlled (eg via NetworkManager)
  • Which ciphers are used
  • Which DNS domains are forwarded and to which IP address
  • Which subnets are routed to VPN tunnel

Fedora issues

Currently adduser command fails during certidude setup authority on Fedora. This should be replaced with something more universal - useradd perhaps

Mailbox interaction

Certidude server could be set up so it would fetch certidude@hostname mailbox content automatically. Preliminary implementation could avoid IMAP altogether and simply parse /var/mail contents directly. Sending mail could be implemented with smtplib

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.