Obsługiwane przez
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ć:
oslAPI_1_0: jest to domyślne API Indy; można używać standardowego pakietu Indy z bibliotekami openssl 1.0.2.
oslAPI_1_1: wybierz tylko wtedy, gdy kompilujesz sgcWebSockets z naszą niestandardową biblioteką Indy (wydanie Enterprise). Zostaną użyte biblioteki OpenSSL 1.1.1.
oslAPI_3_0: należy wybrać tylko w przypadku kompilowania sgcWebSockets z naszą niestandardową biblioteką Indy (Enterprise Edition). Korzysta z bibliotek openssl 3.0.0.
ECDHE: umożliwia włączenie ECDHE dla TLS 1.2 (bezpieczniejsze połączenia).
Zdarzenia
Istnieją 2 zdarzenia, których można użyć do dostosowania ustawień SSL:
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;
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.