Sunday, May 16, 2021

 Writing a Python Flask application to serve content over https. 

 

Problem statement: Python Flask is a framework that serves web API over HTTP. Their documentation suggests running the server over HTTPS so that clients can send requests and receive responses securely. This article is a blog post to describe how to do that. 

Solution:  A Flask application takes command line input parameters in the form: 

python3.5 run -m flask --port=8443 --host=0.0.0.0 --cert=cacert.pem --key=privkey.pem 

This should start the server to serve over https. 

There are a few caveats.  

First, the certificate requested must be trusted for it to be universally accepted by browsers, clients, and mobile device platforms. Getting a trusted certificate from a certificate authority is a well-documented procedure but the input parameters to that method are just as relevant and prone to mistakes as they are to the command line invocation shown above. 

The hostname registration parameter for the certificate request must match that of the server. It is better to use a fully qualified domain name that is registered with name servers so that can be resolved from anywhere in the world. If the server hosts multiple applications, then the certificate is issued to the server and may be trusted for one app but not the other. This is a commonly encountered situation and is resolved in one of two different ways: 

The first way is to use different certificates to be passed in via the command line arguments and each of those certificates points to unique endpoint names for their corresponding applications. These names have alias records in nameservers, so they are mapped to the IP address of the host.  

The second way is to use subdomains within the host endpoint and have a wild card certificate issued for all subdomains from that server registered with the certificate request.  This certificate allows any application to be reached if there is a partial match with the domain part of the subdomain inclusive fully qualified domain name. 

Once the certificate is trusted, the mutual authentication between client and server kicks in and the request-responses work seamlessly over the internet just as if it were over HTTP.  

The use of untrusted certificates is possible but not universally accepted because the untrusted certificates require to be permitted by the host and runtime of the client applications. Even the server host and runtime might demand exclusions and overrides to the security check with the use of untrusted certificates. A certificate helps with the encryption of traffic, so an untrusted certificate may pass for this task as much as a trusted certificate but the default security settings on client and server may warn or reject its use. This might be an option for development use but not for production use because the former control both the client and the server, but the latter can only secure the server. 

Finally, the method to generate a certificate request is facilitated with the use of standard cryptographic tools such as OpenSSL and involves generating a public key and a private key to make a certificate request. 

The invocation for Django applications is: 

django-admin runserver --host=0.0.0.0 runserver --certfile cacert.pem  --keyfile privkey.pem 

If a reverse proxy for HTTPS is configured on the host, running a server with HTTPS is unnecessary 

 

No comments:

Post a Comment