Bezpieczne połączenia

Obsługiwane przez

 

TsgcWebSocketServer

TsgcWebSocketHTTPServer

TsgcWebSocketClient

Przeglądarki internetowe

 

Obsługa SSL jest oparta na implementacji Indy, dlatego w celu korzystania z tej funkcji należy wdrożyć biblioteki openssl.

TsgcWebSocketClient obsługuje Microsoft SChannel, dlatego nie ma potrzeby wdrażania bibliotek OpenSSL dla systemów Windows 32 i 64-bitowych, jeśli w kliencie WebSocket wybrana jest opcja SChannel.

 

 

Strona serwera

 

Aby włączyć tę funkcję, należy włączyć następującą właściwość:

 

SSL / Włącz

 

Istnieją inne właściwości, które należy zdefiniować:

 

SSLOptions/ CertFile/ KeyFile/ RootCertFile: do szyfrowania komunikacji WebSocket wymagany jest certyfikat w formacie .PEM.

 

SSLOptions/ Password: parametr opcjonalny, wymagany jedynie wówczas, gdy certyfikat jest chroniony hasłem.

 

SSLOptions/ Port: port używany w połączeniach SSL.

 

 

 

Strona klienta

 

Aby włączyć tę funkcję, należy włączyć następującą właściwość:

 

TLS / Włącz

 

 

OpenSSL

 

Domyślnie komponenty klienta i serwera oparte na Indy korzystają z bibliotek OpenSSL podczas łączenia się z bezpiecznymi serwerami WebSocket.

Indy obsługuje wyłącznie API OpenSSL 1.0.2, dlatego API 1.1 nie jest obsługiwane. Jeśli sgcWebSockets zostanie skompilowane z naszą niestandardową biblioteką Indy, można korzystać z API 1.1 i wybrać wersję TLS 1.3. Wystarczy wybrać w właściwościach OpenSSL_Options, której wersji API OpenSSL należy użyć:

 

 

 

Zdarzenia

 

Istnieją 2 zdarzenia, których można użyć do dostosowania ustawień SSL:

OnSSLGetHandler

To zdarzenie jest wywoływane przed utworzeniem procedury obsługi SSL. Można tu utworzyć własną procedurę obsługi SSL (musi dziedziczyć po TIdServerIOHandlerSSLBase lub TIdIOHandlerSSLBase) i ustawić wymagane właściwości.


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

OnSSLAfterCreateHandler

Jeśli żaden niestandardowy obiekt SSL nie został utworzony, jest on tworzony domyślnie przy użyciu procedury obsługi OpenSSL. Można uzyskać dostęp do właściwości procedury obsługi SSL i w razie potrzeby je zmodyfikować.


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

 

 

Microsoft SChannel

 

Począwszy od wersji sgcWebSockets 4.2.6, zamiast biblioteki openssl można używać interfejsu SChannel (tylko dla systemu Windows 7 i nowszych). Oznacza to brak konieczności wdrażania bibliotek openssl. TLS 1.0 jest obsługiwany od systemu Windows 7, jednak jeśli wymagane są nowsze implementacje, takie jak TLS 1.2 w systemie Windows 7, należy włączyć TLS 1.1 i TLS 1.2 w rejestrze systemu Windows.

Wymaga Delphi 2010 Professional Edition (lub Enterprise Edition dla Delphi 7, 2007 i 2009).

 

Przeładowanie certyfikatu bez restartu

Gdy certyfikat serwera zostanie odnowiony (na przykład przez klienta ACME lub Let's Encrypt), zamiast zatrzymywać serwer wywołaj metodę ReloadCertificates. Nowe uzgodnienia TLS używają nowego certyfikatu, a połączenia już otwarte działają dalej ze starym certyfikatem do momentu ich zamknięcia. Metoda jest dostępna w TsgcWebSocketServer, TsgcWebSocketHTTPServer, TsgcWebSocketProxyServer i TsgcWebSocketServer_HTTPAPI.

Nadpisz pliki certyfikatu i klucza w miejscu albo przypisz nowe wartości do SSLOptions.CertFile, KeyFile, RootCertFile i Password (w serwerze http.sys do SSLOptions.Hash i CertStoreName), a następnie wywołaj ReloadCertificates. Metodę można wywołać z dowolnego wątku, gdy serwer jest aktywny; nic nie robi, jeśli serwer nie jest aktywny lub SSL jest wyłączone. Nowy certyfikat i klucz prywatny są wczytywane i sprawdzane, zanim cokolwiek się zmieni, więc jeśli do siebie nie pasują, zgłaszany jest wyjątek, a serwer nadal używa poprzedniego certyfikatu. Przeładowywany jest tylko certyfikat: pozostałe SSLOptions (lista szyfrów, wersje TLS itd.) oraz zmiany wprowadzone w OnSSLAfterCreateHandler zachowują swoje działające wartości, a ich zmiana nadal wymaga restartu.

Serwery oparte na Indy przeładowują certyfikat z użyciem OpenSSL (wątek na połączenie, IOCP w systemie Windows i EPOLL w systemie Linux), SChannel oraz natywnego TLS sgc (Natywny TLS; wątki i IOCP/EPOLL). Własny dostawca TLS (TLS Provider) podłączony do silników IOCP/EPOLL przeładowuje certyfikat przez swoje DoCreateTLSContext. Przy standardowym Indy (nie forku Indy sgc) klasyczny moduł OpenSSL nie potrafi przeładować certyfikatu, a ReloadCertificates zgłasza wyjątek "not supported". W przypadku natywnego TLS bilety sesji TLS wydane przed przeładowaniem nie są po nim wznawiane, więc klienci po prostu wykonują pełne uzgodnienie.

W serwerze http.sys (TsgcWebSocketServer_HTTPAPI), gdy BindingOptions.ConfigureSSLCertificate ma wartość True (domyślnie), ReloadCertificates atomowo wiąże ponownie certyfikat każdego powiązania SSL, o ile Windows to obsługuje. Wymaga tych samych uprawnień administratora co uruchomienie serwera z SSL, a nawiązane połączenia pozostają nietknięte. Gdy ConfigureSSLCertificate ma wartość False, powiązanie jest zarządzane poza komponentem (netsh), więc ReloadCertificates zgłasza wyjątek, a powiązanie trzeba zaktualizować za pomocą netsh. W .NET serwer http.sys działa na HttpListener, który nie może ponownie powiązać certyfikatu: powiązanie jest zawsze zarządzane za pomocą netsh, więc gdy serwer jest aktywny z https, ReloadCertificates zgłasza NotSupportedException, a certyfikat trzeba odnowić za pomocą 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;

Zobacz także metodę ReloadCertificates.