webserver programmieren mit ssl verschlüsselung ???

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
hmikux

Sonntag 27. Februar 2005, 22:08

Hallo Leute,
ich versuche mich gerade in Python einzuarbeiten und benutze hierzu das Buch "Python ge-packt" von M.Weigend. Einen einfachen webserver mit cgi-unterstützung zu programmieren ist ja nicht schwer! Jedoch frage ich mich nun inwieweit man einen "sicheren" webserver programmieren kann, der mit ssl arbeitet - jeglicher traffic zwischen client und server sollte verschlüsselt sein.

Als einfachen Webserver benutze ich das code-Beispiel aus dem Buch:

Code: Alles auswählen

#!/usr/local/bin/python
from BaseHTTPServer import HTTPServer
from CGIHTTPServer import CGIHTTPRequestHandler
serveradresse=("", 8080)
server=HTTPServer(serveradresse,CGIHTTPRequestHand ler)
server.serve_forever()
Mit Hilfe des md5-Moduls baue ich mir eine Startseite mit Authentifizierung! Jedoch bringt mir die Authentifizierung nichts, wenn jeglicher traffic unverschlüsselt ueber das netz geht.

Ist python hierzu auch geeignet, oder sollte ich da gleich auch apache zurückgreifen? Möchte einen webserver auf meinem "MiniLinux" aufbauen um meinen VDR-server zu steuern - dabei lediglich python, bash, html inkl. cgi-scripte benutzen.

hmikux
Benutzeravatar
jens
Moderator
Beiträge: 8483
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Montag 28. Februar 2005, 07:33

SSL Unterstützung wäre schon cool, wünschte ich mir auch. Aber ich hab keinen Plan wie man es realisiert...
Im Prinzip könnte man auf einem Linux Rechner, den Server mit OpenSLL kapseln, oder?

Ansonsten kann ich dir mal raten diesen http://python.sandtner.org/viewtopic.php?t=2741 Thread durch zu lesen... Damit kannst du den Server auf den lokalen IP-Bereich einschränken, wenn du ihn nicht gerade durch's Internet Administrieren willst, ist das schon mal was ;)
Beyond
User
Beiträge: 227
Registriert: Freitag 6. September 2002, 19:06
Kontaktdaten:

Montag 28. Februar 2005, 10:31

Ja. Würde ich auch so machen. Nimm z.B. den Apache (gibt's sogar für Windows), der kann SSL. Dann machst Du einen Forward auf den Python-Server (der nur lokale Zugriffe erlaubt).

cu beyond
Benutzeravatar
jens
Moderator
Beiträge: 8483
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Montag 28. Februar 2005, 10:45

Einfacher wäre es allerdings, wenn SSL direkt mit dem Python-Server gehen würde... Apache ist ja nicht gerade ein kleines Mini-Tool ;)
hmikux

Montag 28. Februar 2005, 11:09

Hi, wenn ich den apache nehme, kann ich auf meinen Python webserver verzichten. Das war ja nicht Sinn der Sache.
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Montag 28. Februar 2005, 13:42

Du kannst:
1) pyopenssl nutzen (ich habe auch aktuelle Windows Binaries gemacht)
2) Stunnel oder SSLWrap nutzen, um deinen Server in SSL verschlüsselung zu kapseln.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Benutzeravatar
jens
Moderator
Beiträge: 8483
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Montag 28. Februar 2005, 14:14

Hast du es selber mal versucht? Hast du Beispielcode, wie man ein CGIHTTPServer einfach erweitern kann?
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Montag 28. Februar 2005, 14:25

Also mit PyOpenSSL müsste das so ähnlich gehen wie mit dem SecureXMLRPCServer Beispiel.

Und stunnel ist eine ganze andere Sache, ist externes kapseln, so dass Python gar nicht weiß, dass die Verbindung über SSL läuft.

Edit: TLS Lite scheint auch gar nicht schlecht zu sein. In dem Fall wäre wohl die Integration über SocketServer angebracht.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Benutzeravatar
jens
Moderator
Beiträge: 8483
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Montag 28. Februar 2005, 14:54

TLS Lite sieht wirklich interessant aus! Es scheint auch völlig ohne andere Pakete zu funktionieren. Allerdings kann es auch verschiedene andere Pakete wie z.B. M2Crypto nutzen, was alles ein wenig schneller machen sollte...

In der Readme: http://trevp.net/tlslite/readme.txt steht unter Punkt 10 ein einfaches Beispiel:

Code: Alles auswählen

  from SocketServer import *
  from BaseHTTPServer import *
  from SimpleHTTPServer import *
  from tlslite.api import *

  s = open("./serverX509Cert.pem").read()
  x509 = X509()
  x509.parse(s)
  certChain = X509CertChain([x509])

  s = open("./serverX509Key.pem").read()
  privateKey = parsePEMKey(s, private=True)

  sessionCache = SessionCache()

  class MyHTTPServer(ThreadingMixIn, TLSSocketServerMixIn, HTTPServer):
      def handshake(self, tlsConnection):
          try:
              tlsConnection.handshakeServer(certChain=certChain,
                                            privateKey=privateKey,
                                            sessionCache=sessionCache)
              tlsConnection.ignoreAbruptClose = True
              return True
          except TLSError, error:
              print "Handshake failure:", str(error)
              return False

  httpd = MyHTTPServer(('localhost', 443), SimpleHTTPRequestHandler)
  httpd.serve_forever()
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Montag 28. Februar 2005, 15:02

Genau. Nur die Performance von pure Python SSL braucht dich dann nicht zu wundern. Ich würde das ja testen, hab nur dummerweise null Ahnung von SSL, müsste mir jemand schnell sagen, wie ich die Certs und Keys erstelle. Am besten du kombinierst es mit pycrypto, dann geht das auch unter Windows (zwei pycrypto py2.4 Binaries Vorhanden) und vermutlich auch entsprechend schneller. M2Crypto soll laut GvR promlematisch sein.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Benutzeravatar
jens
Moderator
Beiträge: 8483
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Montag 28. Februar 2005, 15:50

Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Montag 28. Februar 2005, 16:32

Okay... aber tlslite hat doch scheinbar einige C Module... ich habe den Quellcode mal mit

Code: Alles auswählen

#include <wincrypt.h>
erweitert um auch an HCRYPTPROV ranzukommen, und das Modul entropy auch gleich miterstellt.

Wie immer, Binary ohne Garantie.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Benutzeravatar
jens
Moderator
Beiträge: 8483
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Montag 28. Februar 2005, 16:36

In der readme steht aber was anderes:
TLS Lite is pure python, however it can access OpenSSL [4],
cryptlib [5], pycrypto [9], and GMPY [10] for faster crypto operations.
Naja, vielleicht ist die ja mittlerweile etwas veraltet???
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Montag 28. Februar 2005, 16:44

Vielleicht sind die nicht wirklich nötig, und es lässt sich wie dort geschrieben ohne weitere sachen betreiben.
Aber schau selbst: im Tarball sind unter tlslite/utils zwei C Dateien. Win32prng ist ein Pseudozufallszahlengenerator (wie random und crnd).
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Benutzeravatar
jens
Moderator
Beiträge: 8483
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Montag 28. Februar 2005, 18:20

Hab mal versucht einen Server zu bauen. Allerdings so, das man tlslite nicht installieren muß. Es muß nur im Verz "tlslite" liegen:

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: ISO-8859-1 -*-

import CGIHTTPServer, SocketServer, socket
import BaseHTTPServer
import os, sys

sys.path.append("tlslite")
sys.path.append("tlslite/integration")
sys.path.append("tlslite/utils")

import TLSSocketServerMixIn
import X509
import X509CertChain
import keyfactory
import SessionCache

def getFile( fileName ):
    f = file( fileName, "r")
    c = f.read()
    f.close()
    return c

x509 = X509.X509()
x509.parse( getFile("./cert.pem") )
certChain = X509CertChain.X509CertChain([x509])

privateKey = keyfactory.parsePEMKey( getFile( "./key.pem" ), private=True )

sessionCache = SessionCache.SessionCache()


class MyHTTPServer( SocketServer.ThreadingMixIn,
                TLSSocketServerMixIn.TLSSocketServerMixIn,
                BaseHTTPServer.HTTPServer ):
    def handshake(self, tlsConnection):
        #~ try:
            tlsConnection.handshakeServer( certChain=certChain,
                                   privateKey=privateKey,
                                   sessionCache=sessionCache )
            tlsConnection.ignoreAbruptClose = True
            return True
        #~ except TLSError, error:
            #~ print "Handshake failure:", str(error)
            #~ return False


httpd = MyHTTPServer(("", 443), CGIHTTPServer.CGIHTTPRequestHandler)
print "Server gestartet: https://localhost"
httpd.serve_forever()
Ich bekomme allerdings Fehler, wenn ich im Browser die Seite aufrufen will. Ich hab extra bei handshake() die Fehler-Abfrage auskommentiert, damit man die vollständige Fehlermeldung erhält:

Code: Alles auswählen

Traceback (most recent call last):
  File "D:\Python\Python24\lib\SocketServer.py", line 463, in process_request_thread
    self.finish_request(request, client_address)
  File "D:\Python\HTTPsServer\tlslite\integration\TLSSocketServerMixIn.py", line 52, in finish_request
    if self.handshake(tlsConnection) == True:
  File "SocketServer1.py", line 40, in handshake
    sessionCache=sessionCache )
  File "D:\Python\HTTPsServer\tlslite\TLSConnection.py", line 1009, in handshakeServer
    checker):
  File "D:\Python\HTTPsServer\tlslite\TLSConnection.py", line 1032, in handshakeServerAsync
    for result in self._handshakeWrapperAsync(handshaker, checker):
  File "D:\Python\HTTPsServer\tlslite\TLSConnection.py", line 1537, in _handshakeWrapperAsync
    for result in handshaker:
  File "D:\Python\HTTPsServer\tlslite\TLSConnection.py", line 1075, in _handshakeServerAsyncHelper
    raise ValueError("Unrecognized certificate type")
ValueError: Unrecognized certificate type
Liegt vielleicht auch an den Zertifikaten... Ich habe die beiden Dateien unter Linux mit openssl erstellt:

Code: Alles auswählen

openssl genrsa -out key.pem 2048
openssl req -new -x509 -days 1460  -key key.pem -out cert.pem
EDIT: Achso, ich möchte gern tlslite benutzen ohne installation, damit man es evtl. auch auf dem Web-Server benutzen kann, wo man keine Module nachinstallalieren kann... Da tlslite ja in pures Python geschrieben ist, sollte es möglich sein... Aber dazu muß es erstmal generell funktionieren...
Antworten