Secure Connections

지원 대상

 

TsgcWebSocketServer

TsgcWebSocketHTTPServer

TsgcWebSocketClient

웹 브라우저

 

SSL 지원은 Indy 구현을 기반으로 하므로, 이 기능을 사용하려면 openssl 라이브러리를 배포해야 합니다.

TsgcWebSocketClient는 Microsoft SChannel을 지원하므로 WebSocket 클라이언트에서 SChannel 옵션이 선택된 경우 Windows 32 및 64비트용 openssl 라이브러리를 배포할 필요가 없습니다.

 

 

Server Side

 

이 기능을 활성화하려면 다음 속성을 활성화해야 합니다:

 

SSL/ Enable

 

정의해야 하는 다른 속성이 있습니다:

 

SSLOptions/ CertFile/ KeyFile/ RootCertFile: websocket 통신을 암호화하려면 .PEM 형식의 인증서가 필요합니다.

 

SSLOptions/ Password: 이것은 선택 사항이며 인증서에 비밀번호가 있는 경우에만 필요합니다.

 

SSLOptions/ Port: SSL 연결에 사용되는 포트.

 

 

 

클라이언트 측

 

이 기능을 활성화하려면 다음 속성을 활성화해야 합니다:

 

TLS/ Enable

 

 

OpenSSL

 

기본적으로, Indy 기반 클라이언트 및 서버 구성 요소는 보안 websocket 서버에 연결할 때 openSSL 라이브러리를 사용합니다.

Indy는 1.0.2 OpenSSL API만 지원하므로 API 1.1은 지원되지 않습니다. sgcWebSockets를 당사의 사용자 지정 Indy 라이브러리로 컴파일하면 API 1.1을 사용하고 TLS 1.3 버전을 선택할 수 있습니다. OpenSSL_Options 속성에서 사용하려는 OpenSSL API를 선택하기만 하면 됩니다:

 

 

 

Events

 

SSL 설정을 사용자 정의하는 데 사용할 수 있는 2개의 이벤트가 있습니다:

OnSSLGetHandler

이 이벤트는 SSL 핸들러가 생성되기 전에 발생합니다. 여기에서 자체 SSL 핸들러(TIdServerIOHandlerSSLBase 또는 TIdIOHandlerSSLBase에서 상속되어야 함)를 생성하고 필요한 속성을 설정할 수 있습니다


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

OnSSLAfterCreateHandler

사용자 지정 SSL 객체가 생성되지 않은 경우 OpenSSL 핸들러를 사용하여 기본적으로 하나가 생성됩니다. 필요한 경우 SSL 핸들러 속성에 액세스하여 수정할 수 있습니다.


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

 

 

Microsoft SChannel

 

sgcWebSockets 4.2.6부터 openssl 대신 SChannel을 사용할 수 있습니다(Windows 7 이상의 Windows 전용). 이는 openssl 라이브러리를 배포할 필요가 없음을 의미합니다. TLS 1.0은 Windows 7부터 지원되지만, Windows 7에서 TLS 1.2와 같은 더 현대적인 구현이 필요한 경우 Windows 레지스트리에서 TLS 1.1 및 TLS 1.2를 활성화해야 합니다.

Delphi 2010 Professional Edition(또는 Delphi 7, 2007 및 2009의 경우 Enterprise Edition)이 필요합니다.

 

다시 시작하지 않고 인증서 다시 로드

서버 인증서가 갱신되면(예: ACME 또는 Let's Encrypt 클라이언트에 의해) 서버를 중지하지 말고 ReloadCertificates 메서드를 호출하십시오. 새 TLS 핸드셰이크는 새 인증서를 사용하며, 이미 열려 있는 연결은 닫힐 때까지 이전 인증서로 계속 동작합니다. 이 메서드는 TsgcWebSocketServer, TsgcWebSocketHTTPServer, TsgcWebSocketProxyServer 및 TsgcWebSocketServer_HTTPAPI에서 사용할 수 있습니다.

인증서 및 키 파일을 그 자리에서 덮어쓰거나, SSLOptions.CertFile, KeyFile, RootCertFile 및 Password(http.sys 서버에서는 SSLOptions.Hash 및 CertStoreName)에 새 값을 할당한 다음 ReloadCertificates를 호출하십시오. 서버가 활성 상태인 동안 어느 스레드에서든 호출할 수 있으며, 서버가 활성 상태가 아니거나 SSL이 비활성화된 경우에는 아무 작업도 하지 않습니다. 새 인증서와 개인 키는 아무것도 변경되기 전에 로드되고 검사되므로, 둘이 일치하지 않으면 예외가 발생하고 서버는 이전 인증서를 계속 제공합니다. 인증서만 다시 로드됩니다. 나머지 SSLOptions(암호 목록, TLS 버전 등)와 OnSSLAfterCreateHandler에서 변경한 내용은 실행 중인 값을 유지하므로, 이를 변경하려면 여전히 재시작이 필요합니다.

Indy 기반 서버는 OpenSSL(연결당 스레드, Windows의 IOCP 및 Linux의 EPOLL), SChannel 및 sgc 네이티브 TLS(스레드 및 IOCP/EPOLL)로 인증서를 다시 로드합니다. IOCP/EPOLL 엔진에 연결된 사용자 정의 TLS Provider는 DoCreateTLSContext를 통해 다시 로드됩니다. 기본(stock) Indy(sgc Indy 포크가 아님)에서는 기존 OpenSSL 핸들러가 다시 로드할 수 없으며 ReloadCertificates는 "not supported" 예외를 발생시킵니다. 네이티브 TLS에서는 다시 로드하기 전에 발급된 TLS 세션 티켓이 이후에 재개되지 않으므로, 클라이언트는 단순히 전체 핸드셰이크를 수행합니다.

http.sys 서버(TsgcWebSocketServer_HTTPAPI)에서 BindingOptions.ConfigureSSLCertificate가 True(기본값)이면, ReloadCertificates는 Windows가 지원하는 경우 각 SSL 바인딩의 인증서를 원자적으로 다시 바인딩합니다. SSL로 서버를 시작할 때와 동일한 관리자 권한이 필요하며, 이미 수립된 연결은 영향을 받지 않습니다. ConfigureSSLCertificate가 False이면 바인딩이 구성 요소 외부(netsh)에서 관리되므로 ReloadCertificates는 예외를 발생시키며, 바인딩은 netsh로 업데이트해야 합니다. .NET에서는 http.sys 서버가 인증서를 다시 바인딩할 수 없는 HttpListener 위에서 실행되고 바인딩은 항상 netsh로 관리되므로, 서버가 https로 활성 상태인 동안 ReloadCertificates는 NotSupportedException을 발생시키며 인증서는 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;

ReloadCertificates 메서드도 참조하십시오.