2016-03-30 9 views
0

Meine Sentry-Instanz befindet sich hinter dem Proxy, der die Authentifizierung mit dem clientseitigen Zertifikat erfordert. Wie mache ich meine Twisted-Anwendung, die Raven verwendet, um diesen Proxy erfolgreich zu übergeben? Ich sehe nichts in raven.transport.Transport, das mir erlauben könnte, Client Cert, Schlüssel und Vertrauenskette zu spezifizieren. Was sind meine Möglichkeiten?SSL-Optionen für die Raven Twisted-Integration

Antwort

0

OK, ich habe es gefunden. Nicht die sauberste Lösung, aber es funktioniert.

Es stellt sich heraus, dass Sie Ihre eigene Transportklasse mit benutzerdefiniertem Schema registrieren können. Um diese Arbeit mit Client Geheimnisse zu machen (cert, schlüssel) Sie müssen sie als Abfrageparameter zu Sentry DSN-URL angeben, wie:

https://url/project?client_cert=f1&client_key=f2 

und so weiter. Diese Parameter werden dann an den Transport-Konstruktor in Kwargs übergeben. . Twisted v 16.0.0 kann dies wie folgt aussehen:

class InstancePolicy(BrowserLikePolicyForHTTPS): 

    def __init__(self, trustRoot=None, 
      client_cert=None, client_key=None, client_trust_chain=None, 
      server_ca_cert=None): 
     if None in (client_cert, client_key): 
      raise ValueError('When using client side SSL both certificate and key are required') 
     super(InstancePolicy, self).__init__(trustRoot) 
     self.client_cert_file = client_cert 
     self.client_key_file = client_key 
     self.client_trust_chain_file = client_trust_chain 
     self.server_ca_cert_file = server_ca_cert 

    @property 
    def trust_source(self): 
     src = self._trustRoot 
     if self.server_ca_cert_file is not None: 
      src = ssl.Certificate.loadPEM(FilePath(self.server_ca_cert_file).getContent()) 
     return src 

    def creatorForNetloc(self, hostname, port): 
     if self.client_cert_file is not None: 
      key_pair = ssl.KeyPair.load(FilePath(self.client_key_file).getContent(), crypto.FILETYPE_PEM) 
      client_cert = ssl.PrivateCertificate.load(FilePath(self.client_cert_file).getContent(), 
       key_pair, crypto.FILETYPE_PEM) 
     else: 
      client_cert = None 
     extra = {} 
     if self.client_trust_chain_file is not None: 
      chain = [ssl.Certificate.loadPEM(str(x)) for x in pem.parse_file(self.client_trust_chain_file)] 
      extra['extraCertificateOptions'] = dict(extraCertChain=[x.original for x in chain]) 
     return ssl.optionsForClientTLS(
      hostname.decode('ascii'), 
      trustRoot=self.trust_source, 
      clientCertificate=client_cert, 
      **extra 
     ) 

Dann können Sie folgende Funktion verwenden, um Agenten Instanz nach Ihren Wünschen zu bauen:

def make_agent(reactor, policy=None): 
    kw = {} 
    if policy is not None: 
     kw['contextFactory'] = policy 
    return Agent(reactor, pool=HTTPConnectionPool(reactor), **kw) 

Mit diesen Komponenten, die Sie jetzt Ihre eigene definieren Transportunterklasse:

class TwistedHTTPSClientSSLTransport(TwistedHTTPTransport): 
    scheme = ['twisted_clientssl+https'] 

    def __init__(self, parsed_url, *args, **kwargs): 
     client_cert = kwargs.pop('client_cert', None) 
     client_key = kwargs.pop('client_key', None) 
     client_trust_chain = kwargs.pop('client_trust_chain', None) 
     server_ca_cert = kwargs.pop('server_ca_cert', None) 
     super(TwistedHTTPSClientSSLTransport, self).__init__(parsed_url, *args, **kwargs) 
     policy = InstancePolicy(client_cert=client_cert, 
      client_key=client_key, client_trust_chain=client_trust_chain, 
      server_ca_cert=server_ca_cert) 
     from twisted.internet import reactor 
     self._agent = make_agent(reactor, policy) 

Nun, bevor Raven-Client-Instanz Erstellen Sie Ihre Transport-Klasse für Ihr eigenes Schema registrieren kann:

for sc in TwistedHTTPSClientSSLTransport.scheme: 
    Client.register_scheme(sc, TwistedHTTPSClientSSLTransport) 

Und das funktioniert.

Verwandte Themen