Conexões Seguras

Suportado por

 

TsgcWebSocketServer

TsgcWebSocketHTTPServer

TsgcWebSocketClient

Navegadores Web

 

O suporte a SSL é baseado na implementação do Indy, portanto você precisa implantar as bibliotecas openssl para utilizar este recurso.

O TsgcWebSocketClient suporta o Microsoft SChannel, então não há necessidade de implantar as bibliotecas openssl para windows 32 e 64 bits se a opção SChannel for selecionada no WebSocket Client.

 

 

Server Side

 

Para habilitar este recurso, você precisa habilitar a seguinte propriedade:

 

SSL/ Enable

 

Há outras propriedades que você precisa definir:

 

SSLOptions/ CertFile/ KeyFile/ RootCertFile: você precisa de um certificado no formato .PEM para criptografar as comunicações websocket.

 

SSLOptions/ Password: isto é opcional e só é necessário se o certificado tiver uma senha.

 

SSLOptions/ Port: porta usada em conexões SSL.

 

 

 

Lado do Cliente

 

Para habilitar este recurso, você precisa habilitar a seguinte propriedade:

 

TLS/ Enable

 

 

OpenSSL

 

Por padrão, os componentes de cliente e servidor baseados em Indy utilizam as bibliotecas openSSL ao conectar a servidores websocket seguros.

O Indy suporta apenas a API OpenSSL 1.0.2, então a API 1.1 não é suportada. Se você compilar o sgcWebSockets com nossa biblioteca Indy personalizada, você pode fazer uso da API 1.1 e selecionar a versão TLS 1.3. Basta selecionar nas propriedades OpenSSL_Options qual API OpenSSL você gostaria de usar:

 

 

 

Eventos

 

Há 2 eventos que podem ser usados para personalizar suas configurações SSL:

OnSSLGetHandler

Este evento é gerado antes do handler SSL ser criado; você pode criar aqui seu próprio SSL Handler (precisa ser herdado de TIdServerIOHandlerSSLBase ou TIdIOHandlerSSLBase) e definir as propriedades necessárias


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

OnSSLAfterCreateHandler

Se nenhum objeto SSL personalizado tiver sido criado, um é criado por padrão usando o handler OpenSSL. Você pode acessar as propriedades do SSL Handler e modificá-las se necessário.


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

 

 

Microsoft SChannel

 

A partir do sgcWebSockets 4.2.6 você pode usar SChannel em vez do openssl (apenas para windows a partir do Windows 7+). Isso significa que não há necessidade de implantar as bibliotecas openssl. O TLS 1.0 é suportado a partir do windows 7, mas se você precisar de implementações mais modernas como TLS 1.2 no Windows 7, deve habilitar TLS 1.1 e TLS 1.2 no Registro do Windows.

Requer a Edição Professional do Delphi 2010 (ou a Edição Enterprise para Delphi 7, 2007 e 2009).

 

Recarregando o certificado sem reiniciar

Quando o certificado do servidor é renovado (por exemplo, por um cliente ACME ou Let's Encrypt), chame o método ReloadCertificates em vez de parar o servidor. Os novos handshakes TLS usam o novo certificado, e as conexões que já estão abertas continuam funcionando com o antigo até serem fechadas. Está disponível em TsgcWebSocketServer, TsgcWebSocketHTTPServer, TsgcWebSocketProxyServer e TsgcWebSocketServer_HTTPAPI.

Sobrescreva os arquivos de certificado e de chave no próprio local, ou atribua novos valores a SSLOptions.CertFile, KeyFile, RootCertFile e Password (no servidor http.sys, SSLOptions.Hash e CertStoreName) e, em seguida, chame ReloadCertificates. Ele pode ser chamado a partir de qualquer thread enquanto o servidor estiver ativo, e não faz nada se o servidor não estiver ativo ou se o SSL estiver desabilitado. O novo certificado e a chave privada são carregados e verificados antes de qualquer alteração; se não corresponderem, uma exceção é gerada e o servidor continua servindo o certificado anterior. Somente o certificado é recarregado: as demais SSLOptions (lista de cifras, versões do TLS e assim por diante) e as alterações feitas em OnSSLAfterCreateHandler mantêm seus valores em execução, e alterá-las ainda exige uma reinicialização.

Os servidores baseados em Indy recarregam o certificado com OpenSSL (uma thread por conexão, IOCP no Windows e EPOLL no Linux), com SChannel e com o Native TLS do sgc (thread e IOCP/EPOLL). Um TLS Provider personalizado conectado aos motores IOCP/EPOLL recarrega por meio de seu DoCreateTLSContext. Com o Indy original (e não o fork Indy do sgc), o handler OpenSSL clássico não consegue recarregar e ReloadCertificates gera uma exceção "not supported". Com o Native TLS, os tickets de sessão TLS emitidos antes do recarregamento não são retomados depois dele, de modo que os clientes simplesmente fazem um handshake completo.

No servidor http.sys (TsgcWebSocketServer_HTTPAPI), quando BindingOptions.ConfigureSSLCertificate é True (o padrão), ReloadCertificates refaz o binding do certificado de cada binding SSL de forma atômica nos casos em que o Windows oferece suporte. Ele exige os mesmos direitos de administrador necessários para iniciar o servidor com SSL, e as conexões estabelecidas não são afetadas. Quando ConfigureSSLCertificate é False, o binding é gerenciado fora do componente (netsh); portanto, ReloadCertificates gera uma exceção e o binding deve ser atualizado com netsh. No .NET, o servidor http.sys é executado sobre HttpListener, que não pode revincular o certificado: o binding é sempre gerenciado com netsh, portanto, enquanto o servidor estiver ativo com https, ReloadCertificates gera NotSupportedException e o certificado deve ser renovado com 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;

Veja também o método ReloadCertificates.