webserver programmieren mit ssl verschlüsselung ???

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Leonidas hat geschrieben:Wie immer, Binary ohne Garantie.
Hab gerade gesehen... in der ZIP-Version, die ich mir herrunter geladen hab, sind Windows Installer für Python v2.3 und v2.4 schon dabei! Sie liegen im Verz. "Installers"
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Ja sowas. Darauf muss man erst kommen... ich lad mir meist grundsätzlich die gzips runter wenn ich Quellcode will, auch wenn Zips da sind. Tja, dumm gelaufen. Dann nutz lieber die Installer aus dem ZIP, ist wohl besser.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Also ich komme nicht so recht weiter... Ich erhalte immer den Fehler "Unrecognized certificate type"...

Einen Fingerprint erhalte ich aber mit "certChain.getFingerprint()"...

Hab mit ein wenig die API-Doku http://trevp.net/tlslite/docs/index.html angeschaut, hilft aber auch nicht so ganz...
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Ich bekam immer den Fehler "Incorrect padding", aaaber ich habe mich mal etwas reingehängt:

Code: Alles auswählen

#!/usr/bin/env python
# -*- encoding: latin-1 -*-
import SocketServer, BaseHTTPServer, CGIHTTPServer
import tlslite.api

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

def getfile(filename):
    f = file(filename)
    content = f.read()
    f.close()
    return content
    

def main():
    s = getfile("cacert.pem")
    x509 = tlslite.api.X509()
    x509.parse(s)
    global certChain
    certChain = tlslite.api.X509CertChain([x509])

    s = getfile("cakey.pem")
    global privateKey
    privateKey = tlslite.api.parsePEMKey(s, private=True)

    global sessionCache
    sessionCache = tlslite.api.SessionCache()

    httpd = MyHTTPServer(('localhost', 443), CGIHTTPServer.CGIHTTPRequestHandler)
    httpd.serve_forever()

if __name__ == '__main__':
    main()
Das heißt natürlcih nicht, das der Code gut ist, die globals nerven, ist aber nur ein schneller Hack. Die Zertifikate habe ich mir unter Windows mit OpenSSL 0.9.7e erstellt:

Code: Alles auswählen

openssl genrsa 2048 > cakey.pem
openssl req -new -x509 -days 30  -key private/cakey.pem -out cacert.pem 
wobei ich beim zweiten halt die Werte eingestellt habe. Der Schlüssel hat kein Passwort, aber das sollte irgendwie mit dem passwortCallback von parsePEMKey zu lösen sein.

Und siehe da, Firefox zeigt ein Directory Listning ohne zu murren über HTTPS dar.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Wow! Super, jetzt klappt es bei mir auch! Sogar in meiner nicht installierten tlslite-Version!
Die Verz. Struktur:

Code: Alles auswählen

/MeinServer.py
/tlslite
/tlslite/integration
/tlslite/utils
Ich hab MeinServer.py noch mal umstrukturiert, sodas man kein global verwenden muß... Läuft aber im Prinzip auf's selbe hinaus:

Code: Alles auswählen

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

import sys,os,SocketServer, BaseHTTPServer, CGIHTTPServer
import webbrowser

sys.path.append(os.getcwd()+"\\tlslite")
sys.path.append(os.getcwd()+"\\tlslite\\integration")
sys.path.append(os.getcwd()+"\\tlslite\\utils")

import tlslite.api


def getfile(filename):
    f = file(filename)
    content = f.read()
    f.close()
    return content


x509 = tlslite.api.X509()
x509.parse( getfile("cacert.pem") )
certChain = tlslite.api.X509CertChain([x509])

privateKey = tlslite.api.parsePEMKey( getfile("cakey.pem"), private=True)

sessionCache = tlslite.api.SessionCache()



class MyHTTPServer(SocketServer.ThreadingMixIn,
        tlslite.api.TLSSocketServerMixIn,
        BaseHTTPServer.HTTPServer):

    def handshake(self, tlsConnection):
        try:
            tlsConnection.handshakeServer(certChain=certChain,
                                          privateKey=privateKey,
                                          sessionCache=sessionCache)
            tlsConnection.ignoreAbruptClose = True
            return True
        except tlslite.api.TLSError, error:
            print "Handshake failure:", str(error)
            return False

if __name__ == '__main__':
    httpd = MyHTTPServer(('localhost', 443), CGIHTTPServer.CGIHTTPRequestHandler)
    print "Server gestartet: https://127.0.0.1:443"
    webbrowser.open_new("https://127.0.0.1:443") # Öffne Browser
    httpd.serve_forever()
Jetzt wird die Sache Interessant! Das ganze ein wenig Aufzubohren:
-Einschränken auf IP-Bereich
-Auf ThreadingTCPServer umstellen
8)

Dadurch das man tlslite nicht wirklich installieren muß, könnte man das ganze evtl. auf einen Web-Server einrichten und dort quasi einen Virtuellen HTTPs Server öffnen... Die Sourcen und die *.pem-Dateien per FTP auf den Server packen und fertig...
Naja, ich denke allerdings, das es wahrscheinlich nicht möglich ist, da man bestimmt nicht einfach einen Port "öffnen" darf... Aber Versuchen kann man es ja mal...

EDIT: Gesagt, getan: Schade, ich hab's mir schon gedacht, es geht nicht:
File "/usr/lib/python2.2/SocketServer.py", line 329, in __init__
self.server_bind()
File "/usr/lib/python2.2/BaseHTTPServer.py", line 94, in server_bind
SocketServer.TCPServer.server_bind(self)
File "/usr/lib/python2.2/SocketServer.py", line 340, in server_bind
self.socket.bind(self.server_address)
socket.error: (13, 'Permission denied')
Zuletzt geändert von jens am Dienstag 1. März 2005, 14:11, insgesamt 1-mal geändert.
hmikux

*** ich bin der Gast der dieses Thema ursprünglich eröffnet hat ***

SUPER..danke für eure hilfe!
Jetzt wird die Sache Interessant! Das ganze ein wenig Aufzubohren:
-Einschränken auf IP-Bereich
-Auf ThreadingTCPServer umstellen
so ist es...!!!!

hmikux
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Übrigens, der offizielle tlslite Python 2.4 Installer enthält auch das kompilierte C Modul win32prng.pyd. Ich habe meinen Installer nun gelöscht.

Ich habe den Code deswegen strukturiert und mit globals gearbeitet, weil ich lose rumliegenden Code, den nicht in Methoden ist, nicht besonders mag.

Was man noch überlegen müsste, ist den CA Schlüssel noch mit AES und Passwort zu verschlüsseln, so, dass es immer noch funktioniert. Ich könnte mir aber vorstellen, dass man dazu dann noch einige Zusatzmodule braucht.

TLSLite ist echt eine interessante Implementation von SSL und TLS :)
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

jens hat geschrieben:EDIT: Gesagt, getan: Schade, ich hab's mir schon gedacht, es geht nicht:
File "/usr/lib/python2.2/SocketServer.py", line 329, in __init__
self.server_bind()
File "/usr/lib/python2.2/BaseHTTPServer.py", line 94, in server_bind
SocketServer.TCPServer.server_bind(self)
File "/usr/lib/python2.2/SocketServer.py", line 340, in server_bind
self.socket.bind(self.server_address)
socket.error: (13, 'Permission denied')
Was wäre das sonst für eine Sicherheit in der FTP User einfach ihre Server starten?

Generell zu dem Thema: Also ich würde mir da lieber einen 2er Apachen aufsetzen, bei dem hat man wesentlich höhere Sicherheit und weitaus mehr Features.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Nein, also ich hab ein Paket bei Hosteurope... Natürlich bieten die erst bei den richtig teuren Versionen echte HTTPs Unterstützung an. Ich dachte mir ganz naiv, das man evtl. mit Python sich halt das selber baut ;)
Das ganze wäre ganz hilfreich, wenn es darum geht einen Login mit Passwort zu verschlüßeln...

Naja, dennoch ist die ganze Geschichte super nützlich für mein PyAdmin Ding... So ein kleiner Ableger von Webmin, um den Linux-Server bequem mit dem Browser konfigurieren zu können... Dafür ist es optimal, denn ich möchte dazu kein Apache nutzen...
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

jens hat geschrieben:Nein, also ich hab ein Paket bei Hosteurope... Natürlich bieten die erst bei den richtig teuren Versionen echte HTTPs Unterstützung an. Ich dachte mir ganz naiv, das man evtl. mit Python sich halt das selber baut ;)
Das ganze wäre ganz hilfreich, wenn es darum geht einen Login mit Passwort zu verschlüßeln...
Also auf dem Server wo ich als normaler User Zugriff habe geht es mit Port 8080, also versuch es doch mal mit einem Port über 1024.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Hast recht, damit läuft es... Nur sehen kann ich die Seite nicht... Ich denke das die halt einen Firewall laufen haben und alle nicht benötigten Ports gesperrt haben...
Ich denke das der Server allerdings läuft, weil wenn ich in durch aufruf des Python-Skriptes nochmals starte, kann ich in der Error-Log sehen: "socket.error: (98, 'Address already in use')"... Somit gehe ich mal davon aus, das er laufen wird, zumindest eine Zeit lang...
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Tja, ist halt Hosteurope, die lassen wohl ihre Kunden nicht gerne rumexperimentieren, zumindest nicht sofern sie dafür nicht gezahlt haben.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Zurück zum HTTPs Server... Ich hab nun mal versucht eine CGI (*.py) Datei ausführen zu lassen... Es funktioniert nicht:

Code: Alles auswählen

Exception happened during processing of request from ('127.0.0.1', 1410)
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 53, in finish_request
    self.RequestHandlerClass(tlsConnection, client_address, self)
  File "D:\Python\Python24\lib\SocketServer.py", line 521, in __init__
    self.handle()
  File "D:\Python\Python24\lib\BaseHTTPServer.py", line 314, in handle
    self.handle_one_request()
  File "D:\Python\Python24\lib\BaseHTTPServer.py", line 308, in handle_one_request
    method()
  File "D:\Python\Python24\lib\SimpleHTTPServer.py", line 40, in do_GET
    f = self.send_head()
  File "D:\Python\Python24\lib\CGIHTTPServer.py", line 66, in send_head
    return self.run_cgi()
  File "D:\Python\Python24\lib\CGIHTTPServer.py", line 265, in run_cgi
    while select.select([self.rfile._sock], [], [], 0)[0]:
TypeError: argument must be an int, or have a fileno() method.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Habe nun eine Bestätigung vom Entwickler erhalten:
I see that CGIHTTPServer will have problems. For one thing, it passes file descriptors when it forks a child process, but the SSL connection isn't an OS file descriptor, it's a python object that just behaves like a file. For the same reason, select() will have problems (like you're seeing).

The CGIHTTPRequestHandler class has some variables which control which code-path it takes: (have_fork, have_popen2, have_popen3). If you set these to False, it will launch the script in-process. That's not a very good solution, but it might work a little bit.

To make it *really* work, you'd have to provide a different CGHttpServer implementation so when the child processes read/write through stdin/stdout, it goes through tlslite. If you wanted to write that, I'd love to integrate it. It seems a little intimidating to me, though.

Trevor
Antworten