Connessioni sicure

Supportato da

 

TsgcWebSocketServer

TsgcWebSocketHTTPServer

TsgcWebSocketClient

Browser web

 

Il supporto SSL è basato sull'implementazione di Indy, quindi è necessario distribuire le librerie openssl per utilizzare questa funzionalità.

TsgcWebSocketClient supporta Microsoft SChannel, quindi non è necessario distribuire le librerie openssl per Windows a 32 e 64 bit se l'opzione SChannel è selezionata nel WebSocket Client.

 

 

Lato server

 

Per abilitare questa funzionalità, è necessario abilitare la seguente proprietà:

 

SSL/ Abilita

 

Ci sono altre proprietà che è necessario definire:

 

SSLOptions/ CertFile/ KeyFile/ RootCertFile: è necessario un certificato in formato .PEM per cifrare le comunicazioni WebSocket.

 

SSLOptions/ Password: questo è facoltativo ed è necessario solo se il certificato ha una password.

 

SSLOptions/ Port: porta utilizzata sulle connessioni SSL.

 

 

 

Lato client

 

Per abilitare questa funzionalità, è necessario abilitare la seguente proprietà:

 

TLS/ Abilita

 

 

OpenSSL

 

Per impostazione predefinita, i componenti client e server basati su Indy utilizzano le librerie openSSL per connettersi a server WebSocket sicuri.

Indy supporta solo l'API OpenSSL 1.0.2, pertanto l'API 1.1 non è supportata. Se si compila sgcWebSockets con la nostra libreria Indy personalizzata è possibile utilizzare l'API 1.1 e selezionare la versione TLS 1.3. Basta selezionare nelle proprietà OpenSSL_Options quale API OpenSSL si desidera utilizzare:

 

 

 

Eventi

 

Esistono 2 eventi che possono essere utilizzati per personalizzare le Sue impostazioni SSL:

OnSSLGetHandler

Questo evento viene generato prima che venga creato l'handler SSL; è possibile creare qui il proprio SSL Handler (deve ereditare da TIdServerIOHandlerSSLBase o TIdIOHandlerSSLBase) e impostare le proprietà necessarie.


procedure OnServerSSLGetHandler(Sender: TObject; aType: TwsSSLHandler; var aSSLHandler:
TIdServerIOHandlerSSLBase);
begin
  aSSLHandler := TCustomSSLHandler.Create(nil);
  ...
end;

OnSSLAfterCreateHandler

Se non è stato creato alcun oggetto SSL personalizzato, ne viene creato uno per impostazione predefinita utilizzando il gestore OpenSSL. È possibile accedere alle proprietà del gestore SSL e modificarle se necessario.


procedure OnSSLAfterCreateHandler(Sender: TObject; aType: TwsSSLHandler; aSSLHandler:
TIdServerIOHandlerSSLBase);
begin
  TIdServerIOHandlerSSLOpenSSL(aSSLHandler).SSLOptions.Method := sslvTLSv1_2;
end;

 

 

Microsoft SChannel

 

Da sgcWebSockets 4.2.6 è possibile utilizzare SChannel al posto di openssl (solo per Windows da Windows 7+). Ciò significa che non è necessario distribuire le librerie openssl. TLS 1.0 è supportato da Windows 7, ma se si necessita di implementazioni più moderne come TLS 1.2 su Windows 7 è necessario abilitare TLS 1.1 e TLS 1.2 nel Registro di sistema di Windows.

Richiede Delphi 2010 Professional Edition (o Enterprise Edition per Delphi 7, 2007 e 2009).

 

Ricaricare il certificato senza riavvio

Quando il certificato del server viene rinnovato (ad esempio da un client ACME o Let's Encrypt), chiami il metodo ReloadCertificates invece di arrestare il server. I nuovi handshake TLS utilizzano il nuovo certificato, mentre le connessioni già aperte continuano a funzionare con il vecchio fino alla loro chiusura. È disponibile su TsgcWebSocketServer, TsgcWebSocketHTTPServer, TsgcWebSocketProxyServer e TsgcWebSocketServer_HTTPAPI.

Sovrascriva sul posto i file del certificato e della chiave, oppure assegni nuovi valori a SSLOptions.CertFile, KeyFile, RootCertFile e Password (sul server http.sys, SSLOptions.Hash e CertStoreName), quindi chiami ReloadCertificates. Può essere chiamato da qualsiasi thread mentre il server è attivo e non fa nulla se il server non è attivo o se SSL è disabilitato. Il nuovo certificato e la chiave privata vengono caricati e verificati prima di modificare qualsiasi cosa, quindi se non corrispondono viene sollevata un'eccezione e il server continua a servire il certificato precedente. Viene ricaricato solo il certificato: le altre SSLOptions (elenco dei cifrari, versioni TLS e così via) e le modifiche apportate in OnSSLAfterCreateHandler mantengono i valori in esecuzione, e per modificarli è ancora necessario un riavvio.

I server basati su Indy ricaricano il certificato con OpenSSL (thread per connessione, IOCP su Windows ed EPOLL su Linux), con SChannel e con il TLS nativo di sgc (thread e IOCP/EPOLL). Un TLS Provider personalizzato collegato ai motori IOCP/EPOLL ricarica tramite il proprio DoCreateTLSContext. Con Indy standard (non il fork Indy di sgc) il gestore OpenSSL classico non può ricaricare e ReloadCertificates solleva un'eccezione "not supported". Con il TLS nativo, i ticket di sessione TLS emessi prima del ricaricamento non vengono ripresi dopo di esso, quindi i client eseguono semplicemente un handshake completo.

Sul server http.sys (TsgcWebSocketServer_HTTPAPI), quando BindingOptions.ConfigureSSLCertificate è True (il valore predefinito), ReloadCertificates ricollega in modo atomico il certificato di ciascun binding SSL dove Windows lo supporta. Richiede gli stessi diritti di amministratore necessari per avviare il server con SSL e le connessioni già stabilite non vengono toccate. Quando ConfigureSSLCertificate è False il binding è gestito al di fuori del componente (netsh), quindi ReloadCertificates solleva un'eccezione e il binding deve essere aggiornato con netsh. In .NET il server http.sys funziona su HttpListener, che non può ricollegare il certificato: il binding è sempre gestito con netsh, quindi mentre il server è attivo con https ReloadCertificates solleva NotSupportedException e il certificato deve essere rinnovato con netsh http update sslcert.


// uses sgcWebSocket, Dialogs, SysUtils; field: oServer: TsgcWebSocketHTTPServer;
procedure TForm1.FormCreate(Sender: TObject);
begin
  oServer := TsgcWebSocketHTTPServer.Create(Self);
  oServer.Port := 80;
  oServer.SSL := True;
  oServer.SSLOptions.Port := 443;
  oServer.SSLOptions.CertFile := 'C:\certs\fullchain.pem';
  oServer.SSLOptions.KeyFile := 'C:\certs\privkey.pem';
  oServer.Active := True;
end;

procedure TForm1.btnReloadClick(Sender: TObject);
begin
  try
    oServer.SSLOptions.CertFile := 'C:\certs\renewed\fullchain.pem';
    oServer.SSLOptions.KeyFile := 'C:\certs\renewed\privkey.pem';
    oServer.ReloadCertificates;
  except
    on E: Exception do
      ShowMessage('Certificate reload failed: ' + E.Message);
  end;
end;

Vedere anche il metodo ReloadCertificates.