181 lines
5.6 KiB
Plaintext
181 lines
5.6 KiB
Plaintext
================================
|
|
Enable SSL Client authentication
|
|
================================
|
|
|
|
Intro
|
|
=====
|
|
Tested with Apache 2 and mod_ssl.
|
|
Django over mod_wsgi. From http://docs.djangoproject.com/en/dev/howto/deployment/modwsgi/
|
|
"Deploying Django with Apache and mod_wsgi is the recommended way to get Django into production."
|
|
|
|
Generate Keys
|
|
=============
|
|
* Create a CA (passphrase)
|
|
openssl genrsa -des3 -out ca.key 2048
|
|
openssl req -new -x509 -days 3650 -key ca.key -out ca.crt
|
|
openssl x509 -in ca.crt -text -noout
|
|
* Server key material (challenge)
|
|
openssl genrsa -des3 -out server.key 1024
|
|
openssl req -new -key server.key -out server.csr
|
|
openssl x509 -req -in server.csr -out server.crt -sha1 -CA ca.crt -CAkey ca.key -CAcreateserial -days 3650
|
|
openssl x509 -in server.crt -text -noout
|
|
* User Key material (challenge/password)
|
|
openssl genrsa -des3 -out c.key 1024
|
|
openssl req -new -key c.key -out c.csr
|
|
openssl x509 -req -in c.csr -out c.crt -sha1 -CA ca.crt -CAkey ca.key -CAcreateserial -days 3650
|
|
openssl pkcs12 -export -in c.crt -inkey c.key -name "Mikael Ates" -out c.p12
|
|
openssl pkcs12 -in c.p12 -clcerts -nokeys -info
|
|
|
|
Configure Apache and WSGI
|
|
=========================
|
|
Add a file django.wsgi, e.g.:
|
|
"""
|
|
import os
|
|
import sys
|
|
|
|
sys.path.append("/usr/local/lib/python2.6/site-packages/")
|
|
try:
|
|
import lasso
|
|
except:
|
|
print("Unable to import Lasso.", file=sys.stderr)
|
|
|
|
apache_configuration= os.path.dirname(__file__)
|
|
project = os.path.dirname(apache_configuration)
|
|
sys.path.append(project)
|
|
try:
|
|
import authentic2.settings
|
|
os.environ['DJANGO_SETTINGS_MODULE'] = 'authentic2.settings'
|
|
except:
|
|
print("Unable to import settings.", file=sys.stderr)
|
|
|
|
import django.core.handlers.wsgi
|
|
application = django.core.handlers.wsgi.WSGIHandler()
|
|
"""
|
|
|
|
Activate apache2 modules:
|
|
* a2enmod wsgi
|
|
* a2enmod ssl
|
|
|
|
Add a Apache vhost for SSL.
|
|
"""
|
|
<IfModule mod_ssl.c>
|
|
<VirtualHost *:443>
|
|
|
|
LimitInternalRecursion 1000
|
|
ServerAdmin webmaster@entrouvert.org
|
|
ServerName localhost
|
|
|
|
Alias /media/admin/ /usr/local/lib/python2.6/dist-packages/django/contrib/admin/media/
|
|
|
|
WSGIScriptAlias / /Donnees/devs/authentic/apache/django.wsgi
|
|
|
|
<Directory /Donnees/devs/authentic/>
|
|
SSLVerifyClient optional_no_ca
|
|
Options Indexes MultiViews FollowSymLinks
|
|
AllowOverride None
|
|
Order deny,allow
|
|
Allow from all
|
|
</Directory>
|
|
|
|
SSLEngine on
|
|
SSLCipherSuite HIGH:MEDIUM
|
|
SSLProtocol all -SSLv2
|
|
|
|
SSLCertificateFile /Donnees/devs/authentic/apache/key_mat/server.crt
|
|
SSLCertificateKeyFile /Donnees/devs/authentic/apache/key_mat/server.key
|
|
|
|
SSLCertificateChainFile /Donnees/devs/authentic/apache/key_mat/ca.crt
|
|
SSLCACertificateFile /Donnees/devs/authentic/apache/key_mat/ca.crt
|
|
|
|
SSLOptions +StdEnvVars +ExportCertData
|
|
|
|
BrowserMatch "MSIE [2-6]" \
|
|
nokeepalive ssl-unclean-shutdown \
|
|
downgrade-1.0 force-response-1.0
|
|
BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown
|
|
|
|
</VirtualHost>
|
|
</IfModule>
|
|
"""
|
|
|
|
Give rights to Apache on your Authentic directory.
|
|
Reload Apache.
|
|
|
|
Configure Authentic
|
|
===================
|
|
|
|
Key Description
|
|
-------------------------- ----------------------------------------
|
|
ACCEPT_SELF_SIGNED accept certificate for which the validation failed,
|
|
default: False
|
|
STRICT_MATCH do a binary compare to match certificate and users,
|
|
default: False
|
|
SUBJECT_MATCH_KEYS SSL information to use to match recorded
|
|
certificates. default: ('subject_dn', 'issuer_dn'),
|
|
possible values: serial, subject_dn, issuer_dn, cert.
|
|
CREATE_USERNAME_CALLBACK function receiving a SSLInfo object as first
|
|
parameter and returning a username, default: None
|
|
CREATE_USER function receiving a SSLInfo object as first
|
|
parameter and returning a user, default: None
|
|
USE_COOKIE to be described
|
|
|
|
in settings.py:
|
|
Set AUTH_SSL = True
|
|
To create a user with the mail adress as identifier:
|
|
SSLAUTH_CREATE_USER = True
|
|
To use another identifier:
|
|
def myusernamegen(ssl_info):
|
|
import re
|
|
if(ssl_info.subject_cn):
|
|
return return re.sub('[^a-zA-Z0-9]', '_', ssl_info.subject_cn)
|
|
else:
|
|
return return re.sub('[^a-zA-Z0-9]', '_', ssl_info.serial)
|
|
SSLAUTH_CREATE_USERNAME_CALLBACK = myusernamegen
|
|
|
|
|
|
Nginx configuration
|
|
===================
|
|
|
|
You must be able to retrieve SSL environment variable, for example with the
|
|
SCGI backend you must add those lines to /etc/nginx/scgi_params::
|
|
|
|
scgi_param SSL_CLIENT_CERT $ssl_client_cert;
|
|
scgi_param SSL_CLIENT_RAW_CERT $ssl_client_raw_cert;
|
|
scgi_param SSL_CLIENT_S_DN $ssl_client_s_dn;
|
|
scgi_param SSL_CLIENT_I_DN $ssl_client_i_dn;
|
|
scgi_param SSL_CLIENT_SERIAL $ssl_client_serial;
|
|
scgi_param SSL_CLIENT_M_SERIAL $ssl_client_serial;
|
|
scgi_param SSL_CLIENT_VERIFY $ssl_client_verify;
|
|
|
|
It would be the same with FCGI but using the fcgi_param directive in the
|
|
fcgi_params file. It does not currently work when using proxy_pass.
|
|
|
|
A virtualhost configuration example::
|
|
|
|
server {
|
|
listen 80;
|
|
server_name authentic.localhost;
|
|
|
|
rewrite ^ https://$server_name$request_uri? permanent;
|
|
}
|
|
|
|
server {
|
|
listen 443;
|
|
server_name authentic.localhost;
|
|
|
|
ssl on;
|
|
ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
|
|
ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
|
|
ssl_verify_client optional_no_ca;
|
|
|
|
location / {
|
|
include scgi_params;
|
|
scgi_pass localhost:8000;
|
|
}
|
|
}
|
|
|
|
The serveur must be run using the SCGI protocol, with this command line for
|
|
example::
|
|
|
|
./manage.py runfcgi protocol=scgi method=threaded daemonize=false host=localhost port=8000
|