Upgrade to Pro — share decks privately, control downloads, hide ads and more …

SSL All The Things (PyCon NZ 2016)

Markus H
September 10, 2016

SSL All The Things (PyCon NZ 2016)

My talk from PyCon NZ / 🥝🐍📣 2016.

Speaker notes / blog post: https://markusholtermann.eu/2016/09/ssl-all-the-things-in-python/

Markus H

September 10, 2016
Tweet

More Decks by Markus H

Other Decks in Technology

Transcript

  1. SSL All The Things Using SSL in Python Markus Holtermann

    • @m_holtermann • KiwiPyCon 2016
  2. Markus Holtermann Senior Software Engineer at LaterPay Django Core Developer

    @m_holtermann • github.com/MarkusH • markusholtermann.eu
  3. EASY MICROPAYMENTS FOR YOUR FAVORITE CONTENT USE NOW, PAY LATER.

    @laterpay • github.com/laterpay • laterpay.net W e are hiring
  4. Trust Store Intermediate CA 1 Intermediate CA 2 Root CA

    1 Root CA 2 Intermediate CA 3 Certs Certs Certs Root CA 3
  5. The ACME Process new-authz Challenges Certificate Signing Request new-cert Certificate

    Retrieve Certificate Write Challenges Check challenge new-reg Public Account Key Account Key Certificate Key Certificate Signing Request
  6. host { listen [::]:80; server_name example.com; location /.well-known/acme-challenge/ { alias

    /srv/http/acme-challenges/; try_files $uri =404; } location / { try_files $uri =404; } } Webserver config for Challenges
  7. python3 /etc/acme-tiny/acme-tiny.py \ --account-key "/etc/acme-tiny/account.key" \ --csr "/etc/acme-tiny/example.com.csr" \ --acme-dir

    "/srv/www/acme-challenges" \ --output "/etc/nginx/ssl/example.com.crt" \ --combine "https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem" Using Let’s Encrypt
  8. import socket, ssl HOST, PORT = 'example.com', 443 def handle(conn):

    conn.write(b'GET / HTTP/1.1\n') print(conn.recv().decode()) def main(): sock = socket.socket(socket.AF_INET) context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH) context.options |= ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1 # optional conn = context.wrap_socket(sock, server_hostname=HOST) try: conn.connect((HOST, PORT)) handle(conn) finally: conn.close() if __name__ == '__main__': main()
  9. import socket, ssl HOST, PORT, CERT = 'example.com', 443, '/path/to/example.com.pem'

    def handle(conn): print(conn.recv()) conn.write(b'HTTP/1.1 200 OK\n\n%s' % conn.getpeername()[0].encode()) def main(): sock = socket.socket() sock.bind((HOST, PORT)) sock.listen(5) context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) context.load_cert_chain(certfile=CERT) # 1. key, 2. cert, 3. intermediates context.options |= ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1 # optional context.set_ciphers('EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH') while True: conn = None ssock, addr = sock.accept() try: conn = context.wrap_socket(ssock, server_side=True) handle(conn) except ssl.SSLError as e: print(e) finally: if conn: conn.close() if __name__ == '__main__': main()
  10. Sources • https://cipherli.st/ • https://www.ssllabs.com/ssltest/index.html • https://hynek.me/talks/tls/ • https://ssldecoder.org/ •

    https://github.com/ietf-wg-acme/acme/blob/bf34c2a/draft-ietf-acme-acme.md • https://security.googleblog.com/2016/07/experimenting-with-post-quantum.html • https://gist.github.com/MarkusH/2c8818096103c118657eb42e3b1e4563