Skip to content

Commit

Permalink
Merge pull request #29 from grahamgilbert/emails
Browse files Browse the repository at this point in the history
Emails
  • Loading branch information
grahamgilbert committed Apr 20, 2016
2 parents 0164791 + 21d690c commit b108000
Show file tree
Hide file tree
Showing 11 changed files with 208 additions and 43 deletions.
33 changes: 26 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,43 @@
Crypt-Server
============
This is the server component for [Crypt](https://github.com/grahamgilbert/Crypt).
__[Crypt][1]__ is a system for centrally storing FileVault 2 recovery keys. It is made up of a client app, and a Django web app for storing the keys.

##Installation instructions
Installation instructions are over on the in the [docs directory](https://github.com/grahamgilbert/Crypt-Server/blob/master/docs/Installation_on_Ubuntu_12.md)
This Docker image contains the fully configured Crypt Django web app. A default admin user has been preconfigured, use admin/password to login.
If you intend on using the server for anything semi-serious it is a good idea to change the password or add a new admin user and delete the default one.

__Changes in this version__
=================

- 10.7 is no longer supported.
- Improved logging on errors.
- Improved user feedback during long operations (such as enabling FileVault).

__Client__
====
The client is written in Pyobjc, and makes use of the built in fdesetup on OS X 10.8 and higher. An example login hook is provided to see how this could be implemented in your organisation.

__Features__
=======
- If escrow fails for some reason, the recovery key is stored on disk and a Launch Daemon will attempt to escrow the key periodically.
- If the app cannot contact the server, it can optionally quit.
- If FileVault is already enabled, the app will quit.

##Acknowledgements
Many thanks to my lovely employers at [pebble.it](http://pebbleit.com) for letting me release this.

[1]: https://github.com/grahamgilbert/Crypt

##Installation instructions
It is recommended that you use [Docker](Docker.md) to run this, but if you wish to run directly on a host, installation instructions are over on the in the [docs directory](https://github.com/grahamgilbert/Crypt-Server/blob/master/docs/Installation_on_Ubuntu_12.md)

##New features in latest release
- Records Bonjour Name of Macs submitting keys
- Introduces the can_approve permission - users must have this permission to authorise key retrieval
- Key retrievals are logged

##Todo
- Email approvers when a new request is submitted
- Email user when their request is approved or denied
- Move 7 day allowance into settings.py so it can be changed


##Screenshots
Main Page:
![Crypt Main Page](https://raw.github.com/grahamgilbert/Crypt-Server/master/docs/images/home.png)
Expand All @@ -39,4 +59,3 @@ Approve Request:

Key Retrieval:
![Key Retrieval](https://raw.github.com/grahamgilbert/Crypt-Server/master/docs/images/key_retrieval.png)

2 changes: 0 additions & 2 deletions docker/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,4 @@ chmod go+x $APP_DIR
mkdir -p /var/log/gunicorn
export PYTHONPATH=$PYTHONPATH:$APP_DIR
export DJANGO_SETTINGS_MODULE='fvserver.settings'
#export SECRET_KEY='no-so-secret' # Fix for your own site!
# chdir /var/www/django/sd_sample_project/sd_sample_project
supervisord --nodaemon -c $APP_DIR/supervisord.conf
20 changes: 16 additions & 4 deletions docker/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,30 @@
'PORT': '', # Set to empty string for default. Not used with sqlite3.
}
}
# PG Database
if os.environ.has_key('DB_PORT_5432_TCP_ADDR'):

host = None
port = None

if os.environ.has_key('DB_HOST'):
host = os.environ('DB_HOST')
port = os.environ.get('DB_PORT')

elif os.environ.has_key('DB_PORT_5432_TCP_ADDR'):
host = os.environ('DB_PORT_5432_TCP_ADDR')
port = os.environ.get('DB_PORT_5432_TCP_PORT', '5432')

if host and port:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': os.environ['DB_NAME'],
'USER': os.environ['DB_USER'],
'PASSWORD': os.environ['DB_PASS'],
'HOST': os.environ['DB_PORT_5432_TCP_ADDR'],
'PORT': os.environ['DB_PORT_5432_TCP_PORT'],
'HOST': host,
'PORT': port,
}
}

SITE_ID = 1

# If you set this to False, Django will make some optimizations so as not
Expand Down
15 changes: 15 additions & 0 deletions docker/settings_import.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,21 @@
else:
LANGUAGE_CODE = 'en_US'

if getenv('DOCKER_CRYPT_EMAIL_HOST'):
EMAIL_HOST = getenv('DOCKER_CRYPT_EMAIL_HOST')

if getenv('DOCKER_CRYPT_EMAIL_PORT'):
EMAIL_PORT = getenv('DOCKER_CRYPT_EMAIL_PORT')

if getenv('DOCKER_CRYPT_EMAIL_USER'):
EMAIL_USER = getenv('DOCKER_CRYPT_EMAIL_USER')

if getenv('DOCKER_CRYPT_EMAIL_PASSWORD'):
EMAIL_PASSWORD = getenv('DOCKER_CRYPT_EMAIL_PASSWORD')

if getenv('DOCKER_CRYPT_HOST_NAME'):
HOST_NAME = getenv('DOCKER_CRYPT_HOST_NAME')

# Read the list of allowed hosts from the $DOCKER_CRYPT_ALLOWED env var, or
# allow all hosts if none was set.
if getenv('DOCKER_CRYPT_ALLOWED'):
Expand Down
34 changes: 34 additions & 0 deletions docs/Docker.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Using Docker

## Basic usage

``` bash
docker run -d --name="Crypt" \
--restart="always" \
-v /somewhere/on/the/host:/home/docker/crypt/keyset \
-v /somewhere/else/on/the/host:/home/docker/crypt/crypt.db \
-p 8000:8000 \
macadmins/crypt-server
```

The secrets are encrypted, with the encryption keys stored at ``/home/docker/crypt/keyset``. You should back this up as the keys are not recoverable without them.

## Emails

If you would like Crypt to send emails when keys are requested and approved, you should set the following environment variables:

```
docker run -d --name="Crypt" \
--restart="always" \
-v /somewhere/on/the/host:/home/docker/crypt/keyset \
-v /somewhere/else/on/the/host:/home/docker/crypt/crypt.db \
-p 8000:8000 \
-e DOCKER_CRYPT_EMAIL_HOST='mail.yourdomain.com' \
-e DOCKER_CRYPT_EMAIL_PORT='25' \
-e DOCKER_CRYPT_EMAIL_USER='youruser' \
-e DOCKER_CRYPT_EMAIL_PASSWORD='yourpassword' \
-e DOCKER_CRYPT_HOST_NAME='https://crypt.myorg.com' \
macadmins/crypt-server
```

If your SMTP server doesn't need a setting (username and password for example), you should omit it. The `DOCKER_CRYPT_HOST_NAME` setting should be the hostname of your server - this will be used to generate links in emails.
14 changes: 14 additions & 0 deletions docs/Installation_on_Ubuntu_12.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,20 @@ Edit settings.py:
* Set TIME_ZONE to the appropriate timezone
* Change ALLOWED_HOSTS to be a list of hosts that the server will be accessible from (e.g. ``ALLOWED_HOSTS=['crypt.grahamgilbert.dev']``

If you wish to use email notifications, add the following to your settings.py:

``` python
# This is the host and port you are sending email on
EMAIL_HOST = 'localhost'
EMAIL_PORT = '25'

# If your email server requires Authentication
EMAIL_HOST_USER = 'youruser'
EMAIL_HOST_PASSWORD = 'yourpassword'
# This is the URL at the front of any links in the emails
HOST_NAME = 'http://localhost'
```

###More Setup
We need to use Django's manage.py to initialise the app's database and create an admin user. Running the syncdb command will ask you to create an admin user - make sure you do this!

Expand Down
58 changes: 36 additions & 22 deletions docs/Installation_on_Ubuntu_1404.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Installation on Ubuntu 14.04 LTS
=====================
This document assumes a bare install of Ubuntu 14.04 LTS server.
This document assumes a bare install of Ubuntu 14.04 LTS server.

All commands should be run as root, unless specified

Expand Down Expand Up @@ -33,7 +33,7 @@ All commands should be run as root, unless specified

virtualenv --version

###If is isn't, install it with
###If is isn't, install it with

easy_install virtualenv

Expand All @@ -51,10 +51,10 @@ Add cryptuser to the cryptgroup group:
usermod -g cryptgroup cryptuser

##Create the virtual environment
When a virtualenv is created, pip will also be installed to manage a
virtualenv's local packages. Create a virtualenv which will handle
installing Django in a contained environment. In this example we'll
create a virtualenv for Crypt at /usr/local. This should be run from
When a virtualenv is created, pip will also be installed to manage a
virtualenv's local packages. Create a virtualenv which will handle
installing Django in a contained environment. In this example we'll
create a virtualenv for Crypt at /usr/local. This should be run from
Bash, as this is what the virtualenv activate script expects.

Go to where we're going to install the virtualenv:
Expand Down Expand Up @@ -83,7 +83,7 @@ Now we can activate the virtualenv:
source bin/activate

##Install and configure Crypt
Still inside the crypt_env virtualenv, use git to clone the current
Still inside the crypt_env virtualenv, use git to clone the current
version of Crypt-Server

git clone https://github.com/grahamgilbert/Crypt-Server.git crypt
Expand All @@ -97,7 +97,7 @@ Now we need to generate some encryption keys (make sure these go in crypt/keyset
cd crypt
python ./generate_keyczart.py

Next we need to make a copy of the example_settings.py file and put
Next we need to make a copy of the example_settings.py file and put
in your info:

cd ./fvserver
Expand All @@ -107,24 +107,38 @@ Edit settings.py:

* Set ADMINS to an administrative name and email
* Set TIME_ZONE to the appropriate timezone
* Change ALLOWED_HOSTS to be a list of hosts that the server will be
* Change ALLOWED_HOSTS to be a list of hosts that the server will be
accessible from (e.g. ``ALLOWED_HOSTS=['crypt.grahamgilbert.dev']``

If you wish to use email notifications, add the following to your settings.py:

``` python
# This is the host and port you are sending email on
EMAIL_HOST = 'localhost'
EMAIL_PORT = '25'

# If your email server requires Authentication
EMAIL_HOST_USER = 'youruser'
EMAIL_HOST_PASSWORD = 'yourpassword'
# This is the URL at the front of any links in the emails
HOST_NAME = 'http://localhost'
```

## Using with MySQL
In order to use Crypt-Server with MySQL, you need to configure it to connect to
In order to use Crypt-Server with MySQL, you need to configure it to connect to
a MySQL server instead of the default sqlite3. To do this, locate the DATABASES
section of settings.py, and change ENGINE to 'django.db.backends.mysql'. Set the
NAME as the database name, USER and PASSWORD to your user and password, and
either leave HOST as blank for localhost, or insert an IP or hostname of your
section of settings.py, and change ENGINE to 'django.db.backends.mysql'. Set the
NAME as the database name, USER and PASSWORD to your user and password, and
either leave HOST as blank for localhost, or insert an IP or hostname of your
MySQL server. You will also need to install the correct python and apt packages.

apt-get install libmysqlclient-dev python-dev mysql-client
pip install mysql-python


## More Setup
We need to use Django's manage.py to initialise the app's database and
create an admin user. Running the syncdb command will ask you to create
We need to use Django's manage.py to initialise the app's database and
create an admin user. Running the syncdb command will ask you to create
an admin user - make sure you do this!

cd ..
Expand All @@ -136,15 +150,15 @@ Stage the static files (type yes when prompted)
python manage.py collectstatic

##Installing mod_wsgi and configuring Apache
To run Crypt in a production environment, we need to set up a suitable
webserver. Make sure you exit out of the crypt_env virtualenv and the
To run Crypt in a production environment, we need to set up a suitable
webserver. Make sure you exit out of the crypt_env virtualenv and the
cryptuser user (back to root) before continuing).

##Set up an Apache virtualhost
You will probably need to edit most of these bits to suit your
environment, especially to add SSL encryption. There are many different
options, especially if you prefer nginx, the below example is for apache
with an internal puppet CA. Make a new file at
You will probably need to edit most of these bits to suit your
environment, especially to add SSL encryption. There are many different
options, especially if you prefer nginx, the below example is for apache
with an internal puppet CA. Make a new file at
/etc/apache2/sites-available (call it whatever you want)

vim /etc/apache2/sites-available/crypt.conf
Expand Down Expand Up @@ -176,7 +190,7 @@ And then enter something like:
WSGISocketPrefix /var/run/wsgi
WSGIPythonHome /usr/local/crypt_env

Now we just need to enable our site, and then your can go and configure
Now we just need to enable our site, and then your can go and configure
your clients:

a2ensite crypt.conf
Expand Down
26 changes: 26 additions & 0 deletions server/smtp.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from datetime import datetime
import asyncore
from smtpd import SMTPServer

class EmlServer(SMTPServer):
no = 0
def process_message(self, peer, mailfrom, rcpttos, data):
filename = '%s-%d.eml' % (datetime.now().strftime('%Y%m%d%H%M%S'),
self.no)
f = open(filename, 'w')
f.write(data)
f.close
print '%s saved.' % filename
self.no += 1


def run():
foo = EmlServer(('localhost', 25), None)
try:
asyncore.loop()
except KeyboardInterrupt:
pass


if __name__ == '__main__':
run()
2 changes: 1 addition & 1 deletion server/templates/server/approve.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
{% load bootstrap3 %}
{% block content %}
<h1>Approve Request</h1>
<p>{{ the_request.computer.computername }} ({{ the_request.computer.serial }})</p>
<p>{{ the_request.secret.computer.computername }} ({{ the_request.secret.computer.serial }})</p>
{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
<form action="{% url 'approve' the_request.id %}" method="post">{% csrf_token %}

Expand Down
Loading

0 comments on commit b108000

Please sign in to comment.