diff --git a/README.md b/README.md index d641896..9694d47 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,32 @@ 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 @@ -14,10 +34,10 @@ Many thanks to my lovely employers at [pebble.it](http://pebbleit.com) for letti - 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) @@ -39,4 +59,3 @@ Approve Request: Key Retrieval: ![Key Retrieval](https://raw.github.com/grahamgilbert/Crypt-Server/master/docs/images/key_retrieval.png) - diff --git a/docker/run.sh b/docker/run.sh index 97cb367..f588dcd 100755 --- a/docker/run.sh +++ b/docker/run.sh @@ -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 diff --git a/docker/settings.py b/docker/settings.py index 4c3b4d5..158231b 100644 --- a/docker/settings.py +++ b/docker/settings.py @@ -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 diff --git a/docker/settings_import.py b/docker/settings_import.py index a009b0c..639e8ef 100644 --- a/docker/settings_import.py +++ b/docker/settings_import.py @@ -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'): diff --git a/docs/Docker.md b/docs/Docker.md new file mode 100644 index 0000000..604e388 --- /dev/null +++ b/docs/Docker.md @@ -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. diff --git a/docs/Installation_on_Ubuntu_12.md b/docs/Installation_on_Ubuntu_12.md index fac13a8..d3b57cb 100644 --- a/docs/Installation_on_Ubuntu_12.md +++ b/docs/Installation_on_Ubuntu_12.md @@ -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! diff --git a/docs/Installation_on_Ubuntu_1404.md b/docs/Installation_on_Ubuntu_1404.md index f122414..31d47bd 100644 --- a/docs/Installation_on_Ubuntu_1404.md +++ b/docs/Installation_on_Ubuntu_1404.md @@ -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 @@ -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 @@ -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: @@ -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 @@ -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 @@ -107,15 +107,29 @@ 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 @@ -123,8 +137,8 @@ MySQL server. You will also need to install the correct python and apt packages. ## 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 .. @@ -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 @@ -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 diff --git a/server/smtp.py b/server/smtp.py new file mode 100644 index 0000000..9d48627 --- /dev/null +++ b/server/smtp.py @@ -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() diff --git a/server/templates/server/approve.html b/server/templates/server/approve.html index 9e80cc7..ff5fc7c 100755 --- a/server/templates/server/approve.html +++ b/server/templates/server/approve.html @@ -3,7 +3,7 @@ {% load bootstrap3 %} {% block content %}
{{ the_request.computer.computername }} ({{ the_request.computer.serial }})
+{{ the_request.secret.computer.computername }} ({{ the_request.secret.computer.serial }})
{% if error_message %}{{ error_message }}
{% endif %}