Prerequisites
Generate self signed certificate
Generate the server's private key using a secret, which is
SuperSecretPassword in this case.
openssl genrsa -aes256 -passout pass:SuperSecretPassword -out server.key 2048
Perform a CSR (certificate signing request). Ensure the FQDN (fully qualified domain name) matches the hostname of the server, otherwise the server won't be properly validated.
openssl req -new -key server.key -passin pass:SuperSecretPassword -out server.csr
# Common Name (e.g. server FQDN or YOUR name) []:localhost
openssl x509 -req -passin pass:SuperSecretPassword -days 1024 -in server.csr -signkey server.key -out server.crt
For development purposes, remove the password from the certificate.
openssl rsa -in server.key -out server_no_pass.key -passin pass:SuperSecretPassword
mv server_no_pass.key server.key
Although not necessary, it's convenient to have the key and certificate in the same PEM file and the
official Twisted TLS tutorial uses this method.
cat server.crt server.key > server.pem
TLS Server
A special object, called a contextFactory, is required for TLS connections.
They can be generated in multiple ways.
Generate a
PrivateCertificate using a single PEM file.
Notice the
options()
call, this produces a contextFactory object.
from twisted.internet import ssl
with open('./keys/server.pem') as f:
certData = f.read()
certificate = ssl.PrivateCertificate.loadPEM(certData).options()
Alternatively, a contextFactory could be created using the certificate file and private key separately.
certificate = ssl.DefaultOpenSSLContextFactory('keys/server.key', 'keys/server.crt')
Finally, create and start a server.
from twisted.internet import endpoints, reactor, ssl
tls_server = endpoints.SSL4ServerEndpoint(reactor, 8000, certificate, interface='0.0.0.0')
# or
tls_server = endpoints.serverFromString(reactor, 'ssl:8000:interface=0.0.0.0:certKey=keys/server.crt:privateKey=keys/server.key')
tls_server.listen(my_factory)
reactor.start()
Example: TLS Server
import sys
from twisted.internet import endpoints, reactor, ssl
from twisted.web import server, resource
from twisted.python import log
from twisted.python.modules import getModule
class Example(resource.Resource):
isLeaf = True
def render_GET(self, request):
return u'Hello World'.encode('ascii')
# create SSL server from string
https_server = endpoints.serverFromString(
reactor,
'ssl:8000:interface=0.0.0.0:certKey=keys/server.crt:privateKey=keys/server.key')
# start server
site = server.Site(Example())
https_server.listen(site)
log.startLogging(sys.stdout)
reactor.run()
The TLS site can be accessed at
https://localhost:8000.
If a web browser is used, then a warning prompt should appear to add the self signed certificate to a whitelist.
Using curl:
curl --cacert keys/server.crt https://localhost:8000
TLS Client using treq
import treq
from twisted.internet import defer, ssl, task
from twisted.web import client
@task.react
@defer.inlineCallbacks
def custom_trust(_reactor):
# get root cert from pem file
with open('keys/server.crt') as cert_file:
trust_root = yield ssl.Certificate.loadPEM(cert_file.read())
# ready made browser-like policy
policy = client.BrowserLikePolicyForHTTPS(trustRoot=trust_root)
agent = client.Agent(_reactor, policy)
treqish = treq.client.HTTPClient(agent)
response = yield treqish.get('https://localhost:8000')
content = yield response.content()
print(content)
While most "requests-like" libraries allow ignoring of invalid certificates, treq and twisted do not.
In conjunction with
BrowserLikePolicyForHTTPS, treq can very easily handle self signed certificates by imitating how a browser handles such certificates.
Final Thoughts
Understanding and implementing a basic TLS server has been a very valuable experience.
Some might be saying,
"Why not use verify=False (requests) or -k (curl) to ignore certificates?"
Although it's more convenient to ignore certificates when making HTTP requests, it's a very good habit to utilize TLS, even in development, and it's more secure.
An unsafe side effect of ignoring certificates is that
ALL certificates go unvalidated, which can lead users to unsafe sites.
Nice post. Thanks for sharing such a worthy information.
ReplyDeleteIELTS Coaching in Mulund
IELTS Training in Mulund West
IELTS Courses in Mulund
Best IELTS Coaching Institute in Mulund
IELTS Classes in Mulund
Best IELTS Training Centres in Mulund East
IELTS Classes near me
The USD TO INR FORECASTConverter Is Updated Every 15 Minutes. You Can Set It To Alert You Whenever The Rate Changes.
ReplyDeletess hoses & ss bellows
ReplyDeletepest exterminator new york
ReplyDelete