uwsgi/nginx/django client certificate authentication elevation at runtime - django

Preamble
I have a django application set up to run under uwsgi proxy passed by nginx. In Iceland we have a smart card client certificate system in place, embedded in debet cards, distributed free by the debet card issuers, i.e. banks. I am attempting to support this environment for authentication, while retaining the ability to issue logic when authenticating, making the process interactive for the user. Currently we use Apache/mod_wsgi to host the application and use a location directive /auth/smartcard where we require client certificate handshakes. The root of the site is just plain https. This relegates the process to the server only, denying us the ability to interact with the user in a constructive manner.
The configuration so far
uWSGI ini:
[uwsgi]
chdir=/home/vagrant/gimli/src
socket=localhost:5000
processes=1
module=application_name.wsgi:application
env DJANGO_SETTINGS_MODULE=application_name.settings
max-requests=5000
home=/home/vagrant/virtualenvs/gimli
py-autoreload=True
nginx settings
server {
<snip>
ssl on;
ssl_protocols SSLv3 TLSv1;
ssl_certificate ssl/host.domain.is.crt;
ssl_certificate_key ssl/host.domain.is.key;
ssl_client_certificate ssl/ca_chain.crt;
ssl_verify_client optional;
ssl_verify_depth 2;
error_log /var/log/nginx/host.domain.error.log debug; # debug for debugging ssl
access_log /var/log/nginx/host.domain.is.access.log;
location / {
include uwsgi_params;
# Client cert support
uwsgi_param SSL_CLIENT_ID $ssl_client_s_dn;
# Bind parameters
uwsgi_pass localhost:5000;
}
</snip>
} # /server
These configurations enable SSL and optional client certificates if supplied to the browser by the smartcard reader (usb dongle). Therefore the ssl_verify_client optional directive. We are not married to Nginx, though we would prefer not to run uwsgi naked.
The question
Is it possible - at runtime - to issue a directive back from the application to the server to elevate the ssl connection to require a client certificate, using either uwsgi or nginx? Is it possible, essentially, to alter the state of the ssl_verify_client setting, renegotiating the ssl handshake?

Related

Prevent Nginx from changing host

I am building an application which is right now working on localhost. I have my entire dockerized application up and running at https://localhost/.
HTTP request is being redirected to HTTPS
My nginx configuration in docker-compose.yml is handling all the requests as it should.
I want my application accessible from anywhere hence i tried using Ngrok to route the request to my localhost. Actually i have a mobile app in development so need a local server for apis.
Now, when i enter ngrok's url like abc123.ngrok.io in the browser, the nginx converts it to https://localhost/. That works for my host system's browser, as my web app is working there only, but when i open the same in my mobile emulator. It doesn't work.
I am newbie to nginx. Any suggestions will be welcomed.
Here's my nginx configuration.
nginx.conf
upstream web {
ip_hash;
server web:443;
}
# Redirect all HTTP requests to HTTPS
server {
listen 80;
server_name localhost;
return 301 https://$server_name$request_uri;
}
# for https requests
server {
# Pass request to the web container
location / {
proxy_pass https://web/;
}
location /static/ {
root /var/www/mysite/;
}
listen 443 ssl;
server_name localhost;
# SSL properties
# (http://nginx.org/en/docs/http/configuring_https_servers.html)
ssl_certificate /etc/nginx/conf.d/certs/localhost.crt;
ssl_certificate_key /etc/nginx/conf.d/certs/localhost.key;
root /usr/share/nginx/html;
add_header Strict-Transport-Security "max-age=31536000" always;
}
This configuration i got from a tutorial.
First of all, you set redirection from every HTTP request to HTTPS:
# Redirect all HTTP requests to HTTPS
server {
listen 80;
server_name localhost;
return 301 https://$server_name$request_uri;
}
You are using $server_name variable here, so every /some/path?request_string HTTP request to your app would be redirected to https://localhost/some/path?request_string. At least change the return directive to
return 301 https://$host$request_uri;
Check this question for information about difference between $host and $server_name variables.
If these are your only server blocks in your nginx config, you can safely remove the server_name localhost; directive at all, those blocks still remains the default blocks for all incoming requests on 80 and 443 TCP ports.
The second one, if you are using self-signed certificate for localhost be ready for browser complains about mismatched certificate (issued for localhost, appeared at abc123.ngrok.io). If it doesn't break your mobile app, its ok, but if it is, you can get the certificate for your abc123.ngrok.io domain from Lets Encrypt for free after you start your ngrok connection, check this page for available ACME clients and options. Or you can disable HTTPS at all if it isn't strictly requred for your debug process, just use this single server block:
server {
listen 80;
# Pass request to the web container
location / {
proxy_pass https://web/;
}
location /static/ {
root /var/www/mysite/;
}
}
Of course this should not be used in production, only for debugging.
And the last one. I don't see any sense encrypting traffic between nginx and web containers inside docker itself, especially if you already setup HTTP-to-HTTPS redirection with nginx. It gives you nothing in the terms of security but only some extra overhead. Use plain HTTP protocol on port 80 for communications between nginx and web container:
upstream web {
ip_hash;
server web:80;
}
server {
...
location / {
proxy_pass http://web;
}
}

Django & Certbot - unauthorized, Invalid response (HTTPS)

I'm trying to configure Certbot (Letsencrypt) with Nginx.
I get this error :
- The following errors were reported by the server:
Domain: koomancomputing.com
Type: unauthorized
Detail: Invalid response from
http://koomancomputing.com/.well-known/acme-challenge/xvDuo8MqaKvUhdDMjE3FFbnP1fqbp9R66ah5_uLdaZk
[2600:3c03::f03c:92ff:fefb:794b]: "<html>\r\n<head><title>404 Not
Found</title></head>\r\n<body bgcolor=\"white\">\r\n<center><h1>404
Not Found</h1></center>\r\n<hr><center>"
Domain: www.koomancomputing.com
Type: unauthorized
Detail: Invalid response from
http://www.koomancomputing.com/.well-known/acme-challenge/T8GQaufb9qhKIRAva-_3IPfdu6qsDeN5wQPafS0mKNA
[2600:3c03::f03c:92ff:fefb:794b]: "<html>\r\n<head><title>404 Not
Found</title></head>\r\n<body bgcolor=\"white\">\r\n<center><h1>404
Not Found</h1></center>\r\n<hr><center>"
To fix these errors, please make sure that your domain name was
entered correctly and the DNS A/AAAA record(s) for that domain
contain(s) the right IP address.
- Your account credentials have been saved in your Certbot
configuration directory at /etc/letsencrypt. You should make a
secure backup of this folder now. This configuration directory will
also contain certificates and private keys obtained by Certbot so
making regular backups of this folder is ideal.
in /etc/nginx/sites-available/koomancomputing :
server {
listen 80;
server_name koomancomputing.com www.koomancomputing.com;
location = /favicon.ico { access_log off; log_not_found off; }
location /staticfiles/ {
root /home/kwaku/koomancomputing;
}
location /media/ {
root /home/kwaku/koomancomputing;
}
location / {
include proxy_params;
proxy_pass http://unix:/run/gunicorn.sock;
}
}
my DNS A/AAAA records :
I didn't know what to do, so I did a search and find django-letsencrypt app, but I don't know hot to use :
Your domain has a proper AAAA record configured to your server over IPv6, and certbot chose that to validate your server.
However, your server block as configured under nginx only listens to port 80 on IPv4 for your domain. When certbot requests Let's Encrypt to access your challenge and issue a certificate, nginx isn't configured to properly respond with the challenge on IPv6. It often in this case returns other things (such as a 404 in your case, or a default site).
You can resolve this by modifying the first two lines to also listen on all IPv6 addresses for your server:
server {
listen 80;
listen [::]:80;
# other configuration
}
After editing, restart nginx and run certbot again.
Your Nginx server is responding with a 404 error because it does not define a route to /.well-known needed by certbot to verify challenges. You need to modify the Nginx config file to tell it how to respond to certbot's challenges.
Certbot can update the Nginx config file for you.
First, make sure your config file is enabled. Run sudo service nginx reload and check for the presence of a file called /etc/nginx/sites-enabled/koomancomputing.
Then, run certbot --nginx -d koomancomputing.com -d www.koomancomputing.com
The --nginx flag tells certbot to find an Nginx config file with a matching server name and update that file with SSL info.
server {
listen 80;
listen [::]:80;
# other configuration
}
Works for both IPV4 and IPV6 after adding this restart nginx.
For me, it worked after I removed and installed the latest certbot version using snapd.
I use cloudflare proxy option and it failed for certbot 0.31.0.
After installing certbot 1.27 and configuring the cert newly, it works fine even proxy toggle is on in cloudflare.

Django won't get https header

Intro
I am building a web app using the latest Django version along with python3.7. The app is dockerized and I plan to deploy with docker-compose. Inside the container, I use nginx to proxy traffic to the application and not expose it directly. Also, I use apache in server level to proxy traffic to various other containers hosted on the same machine.
In the Django application, I use oauth2 to authenticate to Fitbit Web API and the issue I am facing is that the django-social-auth is passing the hostname automatically as a redirect_uri which now, after a lot of configuration with all those proxies, works perfectly in HTTP but when I use HTTPS although the app responds normally the redirect_uri is still http which obviously is not allowed by fitbit and very risky.
Although it is very hard for me to locate in which level the problem occurs I have tried various things but nothing seems to work out.
What I have tried
First
I tried to make my container listen to https request which seemed the most appropriate solution to me but ended getting 502 errors from the Apache.
I tried to find a solution on this by adding some configuration to the virtual host file like
#Solution 1
SSLProxyEngine on
SSLProxyVerify none
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
SSLProxyCheckPeerExpire off
ProxyPass / https://localhost:83/ Keepalive=On #Solution 2 (keep alive)
ProxyPassReverse / https://localhost:83
But at last, I found out that it was not an apache issue but that the nginx inside the container was not responding although the traffic was routed to 443 port using HTTPS
Second
I tried to route traffic from the apache https to containerd nginx HTTP ( which does not make so much sense to me ) which makes the application respond normally but and results the redirect_uri error I mentioned above
As you can see I more or less confused and any kind of hint or help could be very useful
Update 1
The nginx configuration as requested in the comments
server {
listen 80;
listen 443 default_server ssl;
server_name localhost;
charset utf-8;
location /static {
alias /app/static/;
}
location /upload {
alias /app/media/;
}
location / {
proxy_pass http://web:8000;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
I was able to fix the issue by adding the following configuration on the settings.py. I also added a control conditional in order to be able to run the container in development.
# Was already present before the issue resolved but is also needed
USE_X_FORWARDED_HOST = True
# The actual solution
if eval(os.environ.get('DEPLOY', default=False)):
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
SECURE_SSL_REDIRECT = True
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True

Can't deploy to Tomcat - no httpd process

I am trying to implement encryption a Tomcat Server on AWS Elastic Beanstalk.
I follow this advise, and in the .ebextensions directory, I add the following files:
https-instance.config, which contains the certificate file and private key contents.
ssl.conf, which contains:
SSLCertificateKeyFile "/etc/pki/tls/certs/server.key"
SSLCertificateChainFile "/etc/pki/tls/certs/gd_bundle.crt"
SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH
but on the server in /etc/pki/tls/certs:
(In ssl.conf I tried changing "/etc/pki/tls/certs/gd_bundle.crt" to "/etc/pki/tls/certs/ca-bundle.crt", but no difference)
https-instance-single.config, which contains:
Resources:
sslSecurityGroupIngress:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: {"Fn::GetAtt" : ["AWSEBSecurityGroup", "GroupId"]}
IpProtocol: tcp
ToPort: 443
FromPort: 443
CidrIp: 0.0.0.0/0
I then try deploy my war file, but get:
Error
[Instance: i-04a9fa826b9d8e0a3] Command failed on instance. Return
code: 1 Output: httpd: no process found. container_command killhttpd
in .ebextensions/https-instance.config failed. For more detail, check
/var/log/eb-activity.log using console or EB CLI.
eb-activity.log
[Application update
thewhozoo-1.0.0.39#121/AppDeployStage0/EbExtensionPostBuild/Infra-EmbeddedPostBuild/postbuild_0_theWhoZoo_java/Command
killhttpd] : Activity execution failed, because: httpd: no process
found (ElasticBeanstalk::ExternalInvocationError)
As you can see, it's complaining about in https-instance.config there is httpd: no process found. Which suggests that there is a problem with:
...
-----END RSA PRIVATE KEY-----
container_commands:
killhttpd:
command: "killall httpd"
waitforhttpddeath:
command: "sleep 3"
i.e. there is no httpd process.
I then read that I need to set up a proxy server on Tomcat, so I follow these instructions, Extending the Default nginx Configuration.
So I add the following:
.ebextensions/nginx/conf.d/https.conf
# HTTPS server
server {
listen 443;
server_name localhost;
ssl on;
ssl_certificate /etc/pki/tls/certs/server.crt;
ssl_certificate_key /etc/pki/tls/certs/server.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://localhost:80;
proxy_set_header Connection "";
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
But I still get the same above error (no httpd process).
More info
I don't really know what this means, but it looks like something is running on the server:
and
where on the server /etc/httpd/conf.d/ssl.conf:
#
# This is the Apache server configuration file providing SSL support.
# It contains the configuration directives to instruct the server how to
# serve pages over an https connection. For detailing information about these
# directives see <URL:http://httpd.apache.org/docs/2.2/mod/mod_ssl.html>
#
# Do NOT simply read the instructions in here without understanding
# what they do. They're here only as hints or reminders. If you are unsure
# consult the online docs. You have been warned.
#
LoadModule ssl_module modules/mod_ssl.so
#
# When we also provide SSL we have to listen to the
# the HTTPS port in addition.
#
Listen 443
##
## SSL Global Context
##
## All SSL configuration in this context applies both to
## the main server and all SSL-enabled virtual hosts.
##
# Pass Phrase Dialog:
# Configure the pass phrase gathering process.
# The filtering dialog program (`builtin' is a internal
# terminal dialog) has to provide the pass phrase on stdout.
SSLPassPhraseDialog builtin
# Inter-Process Session Cache:
# Configure the SSL Session Cache: First the mechanism
# to use and second the expiring timeout (in seconds).
SSLSessionCache shmcb:/var/cache/mod_ssl/scache(512000)
SSLSessionCacheTimeout 300
# Semaphore:
# Configure the path to the mutual exclusion semaphore the
# SSL engine uses internally for inter-process synchronization.
SSLMutex default
# Pseudo Random Number Generator (PRNG):
# Configure one or more sources to seed the PRNG of the
# SSL library. The seed data should be of good random quality.
# WARNING! On some platforms /dev/random blocks if not enough entropy
# is available. This means you then cannot use the /dev/random device
# because it would lead to very long connection times (as long as
# it requires to make more entropy available). But usually those
# platforms additionally provide a /dev/urandom device which doesn't
# block. So, if available, use this one instead. Read the mod_ssl User
# Manual for more details.
SSLRandomSeed startup file:/dev/urandom 256
SSLRandomSeed connect builtin
#SSLRandomSeed startup file:/dev/random 512
#SSLRandomSeed connect file:/dev/random 512
#SSLRandomSeed connect file:/dev/urandom 512
#
# Use "SSLCryptoDevice" to enable any supported hardware
# accelerators. Use "openssl engine -v" to list supported
# engine names. NOTE: If you enable an accelerator and the
# server does not start, consult the error logs and ensure
# your accelerator is functioning properly.
#
SSLCryptoDevice builtin
#SSLCryptoDevice ubsec
##
## SSL Virtual Host Context
##
<VirtualHost _default_:443>
# General setup for the virtual host, inherited from global configuration
#DocumentRoot "/var/www/html"
#ServerName www.example.com:443
# Use separate log files for the SSL virtual host; note that LogLevel
# is not inherited from httpd.conf.
ErrorLog logs/ssl_error_log
TransferLog logs/ssl_access_log
LogLevel warn
# SSL Engine Switch:
# Enable/Disable SSL for this virtual host.
SSLEngine on
# SSL Protocol support:
# List the enable protocol levels with which clients will be able to
# connect. Disable SSLv3 access by default:
SSLProtocol all -SSLv3
SSLProxyProtocol all -SSLv3
# SSL Cipher Suite:
# List the ciphers that the client is permitted to negotiate.
# See the mod_ssl documentation for a complete list.
SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW
# Server Certificate:
# Point SSLCertificateFile at a PEM encoded certificate. If
# the certificate is encrypted, then you will be prompted for a
# pass phrase. Note that a kill -HUP will prompt again. A new
# certificate can be generated using the genkey(1) command.
SSLCertificateFile /etc/pki/tls/certs/localhost.crt
# Server Private Key:
# If the key is not combined with the certificate, use this
# directive to point at the key file. Keep in mind that if
# you've both a RSA and a DSA private key you can configure
# both in parallel (to also allow the use of DSA ciphers, etc.)
SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
# Server Certificate Chain:
# Point SSLCertificateChainFile at a file containing the
# concatenation of PEM encoded CA certificates which form the
# certificate chain for the server certificate. Alternatively
# the referenced file can be the same as SSLCertificateFile
# when the CA certificates are directly appended to the server
# certificate for convinience.
#SSLCertificateChainFile /etc/pki/tls/certs/server-chain.crt
# Certificate Authority (CA):
# Set the CA certificate verification path where to find CA
# certificates for client authentication or alternatively one
# huge file containing all of them (file must be PEM encoded)
#SSLCACertificateFile /etc/pki/tls/certs/ca-bundle.crt
# Client Authentication (Type):
# Client certificate verification type and depth. Types are
# none, optional, require and optional_no_ca. Depth is a
# number which specifies how deeply to verify the certificate
# issuer chain before deciding the certificate is not valid.
#SSLVerifyClient require
#SSLVerifyDepth 10
# Access Control:
# With SSLRequire you can do per-directory access control based
# on arbitrary complex boolean expressions containing server
# variable checks and other lookup directives. The syntax is a
# mixture between C and Perl. See the mod_ssl documentation
# for more details.
#<Location />
#SSLRequire ( %{SSL_CIPHER} !~ m/^(EXP|NULL)/ \
# and %{SSL_CLIENT_S_DN_O} eq "Snake Oil, Ltd." \
# and %{SSL_CLIENT_S_DN_OU} in {"Staff", "CA", "Dev"} \
# and %{TIME_WDAY} >= 1 and %{TIME_WDAY} <= 5 \
# and %{TIME_HOUR} >= 8 and %{TIME_HOUR} <= 20 ) \
# or %{REMOTE_ADDR} =~ m/^192\.76\.162\.[0-9]+$/
#</Location>
# SSL Engine Options:
# Set various options for the SSL engine.
# o FakeBasicAuth:
# Translate the client X.509 into a Basic Authorisation. This means that
# the standard Auth/DBMAuth methods can be used for access control. The
# user name is the `one line' version of the client's X.509 certificate.
# Note that no password is obtained from the user. Every entry in the user
# file needs this password: `xxj31ZMTZzkVA'.
# o ExportCertData:
# This exports two additional environment variables: SSL_CLIENT_CERT and
# SSL_SERVER_CERT. These contain the PEM-encoded certificates of the
# server (always existing) and the client (only existing when client
# authentication is used). This can be used to import the certificates
# into CGI scripts.
# o StdEnvVars:
# This exports the standard SSL/TLS related `SSL_*' environment variables.
# Per default this exportation is switched off for performance reasons,
# because the extraction step is an expensive operation and is usually
# useless for serving static content. So one usually enables the
# exportation for CGI and SSI requests only.
# o StrictRequire:
# This denies access when "SSLRequireSSL" or "SSLRequire" applied even
# under a "Satisfy any" situation, i.e. when it applies access is denied
# and no other module can change it.
# o OptRenegotiate:
# This enables optimized SSL connection renegotiation handling when SSL
# directives are used in per-directory context.
#SSLOptions +FakeBasicAuth +ExportCertData +StrictRequire
<Files ~ "\.(cgi|shtml|phtml|php3?)$">
SSLOptions +StdEnvVars
</Files>
<Directory "/var/www/cgi-bin">
SSLOptions +StdEnvVars
</Directory>
# SSL Protocol Adjustments:
# The safe and default but still SSL/TLS standard compliant shutdown
# approach is that mod_ssl sends the close notify alert but doesn't wait for
# the close notify alert from client. When you need a different shutdown
# approach you can use one of the following variables:
# o ssl-unclean-shutdown:
# This forces an unclean shutdown when the connection is closed, i.e. no
# SSL close notify alert is send or allowed to received. This violates
# the SSL/TLS standard but is needed for some brain-dead browsers. Use
# this when you receive I/O errors because of the standard approach where
# mod_ssl sends the close notify alert.
# o ssl-accurate-shutdown:
# This forces an accurate shutdown when the connection is closed, i.e. a
# SSL close notify alert is send and mod_ssl waits for the close notify
# alert of the client. This is 100% SSL/TLS standard compliant, but in
# practice often causes hanging connections with brain-dead browsers. Use
# this only for browsers where you know that their SSL implementation
# works correctly.
# Notice: Most problems of broken clients are also related to the HTTP
# keep-alive facility, so you usually additionally want to disable
# keep-alive for those clients, too. Use variable "nokeepalive" for this.
# Similarly, one has to force some clients to use HTTP/1.0 to workaround
# their broken HTTP/1.1 implementation. Use variables "downgrade-1.0" and
# "force-response-1.0" for this.
SetEnvIf User-Agent ".*MSIE.*" \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0
# Per-Server Logging:
# The home of a custom SSL log file. Use this when you want a
# compact non-error SSL logfile on a virtual host basis.
CustomLog logs/ssl_request_log \
"%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
</VirtualHost>
(Unfortunately I cannot deploy to the server and I am under time pressure - should I delete the entire environment and start again on AWS?)
UPDATE
On the advise below, I add Elastic Load Balancing to my server, set up https with a certificate issued by Amazon. I test my app, and the url is accessible under https...Yay!
However, when I access it, it shows:
Why is it "Not Secure"?
If you're using Elastic Beanstalk I'd totally recommend you to use the Elastic Load balancer to take care of the encryption. Use HTTP layer between the VM and ELB and then from the ELB to the client, use HTTPS.
You can generate the certificates for free on AWS and upload them in the ELB.
http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/configuring-https.html

How can I serve a Django application using the SPDY protocol?

What is the best way to serve a Django application over the SPDY [1] protocol?
[1] http://www.chromium.org/spdy
One way is to run Django on Jython with Jetty - http://www.evonove.it/blog/en/2012/12/28/django-jetty-spdy-blazing-fast/
Also, apparently nginx has some draft module for SPDY
It works with nginx > 1.5.10 and Django run as fastcgi server.
Recent versions of Chrome and Firefox dropped support for SPDY v2. So you need at least SPDY3 support on the server side. Nginx versions higher than 1.5.10 support version 3 of the protocol.
Django Mainline Installation
Currently (as of Feb 2014) Nginx > 1.5.10 is only available from the mainline branch, not from stable. On most Linux distributions, it is easiest to install mainline packages provided by the nginx project.
Nginx and Django configuration
The Django documentation explains how to run Django with Nginx through fastcgi. The configuration that is provided there can be used as a starting point.
In addition, you need SSL certificates for your host and extend the Nginx configuration in the following ways:
The listen configuration options needs to be modified to:
from listen 80; to listen 443 ssl spdy;.
You need to add basic ssl configuration options, most importantly a certificate and key.
So, both modifications combined, the configuration may look as follows:
server {
listen 443 ssl spdy;
server_name yourhost.example.com;
ssl_certificate <yourhostscertificate>.pem;
ssl_certificate_key <yourhostskey>.key;
ssl_prefer_server_ciphers on;
location / {
include fastcgi_params;
fastcgi_pass 127.0.0.1:8080;
}
}
Then run your Django as in fastcgi mode, as follows:
python ./manage.py runfcgi host=127.0.0.1 port=8080
Testing your setup
Point your browser to https://yourhost.example.com
You should be able to verify that the connection is done via SPDY in:
Chrome: Look for an active SPDY session in chrome://net-internals/#spdy
Firefox: Check the Firebug Network tab and look for the X-Firefox-Spdy:"3.1" response header.