Múltiplos virtual hosts com SSL em Apache

Configurar um servidor HTTP para HTTPS nunca foi uma tarefa tão fácil como configurá-lo para apenas HTTP. Além das configurações básicas temos também de nos preocupar com certificados, chaves privadas e afins. Além de mais, utilizando o tradicional mod_ssl precisamos de um endereço IP diferente para cada virtual host, o que nem sempre é possível.

Mas agora temos o RFC 3546 (Transport Layer Security (TLS) Extensions). Este RFC define extensões ao TLS (Transport Layer Security) que permite utilizar virtual hosts em SSL sem necessidade de vários endereços IP.

O problema com o mod_ssl

O problema com o mod_ssl e virtual hosts é simples de explicar: não se pode utilizar virtual hosts baseados em nome. Isto por que este tipo de virtual host depende de informação presente no pedido HTTP. Ora, o cabeçalho do pedido HTTP está encriptado numa ligação HTTPS e é necessário saber qual o virtual host para se conseguir obter a chave de descodificação do próprio cabeçalho.

Neste momento o mod_ssl não suporta o RFC 3546, mas, felizmente, existe uma alternativa: o mod_gnutls.

Com este módulo é possível utilizar virtual hosts baseados em nome com um único endereço IP.

Nas linhas seguintes, explicarei como configurar dois virtual hosts com SSL.

O cenário

Quero configurar dois virtual hosts com SSL: www.darklair.homeunix.net e trindade.myphotos.cc. Estes dois servidores virtuais estão alojados no mesmo servidor físico e dispõem apenas de um endereço IP externo.

Para configurar o mod_gnutls para este cenário, vão ser precisos, no mínimo, dois certificados SSL e modificações nos ficheiros de configuração do Apache.

Criação dos certificados

Teremos que criar um certificado assinado por cada servidor virtual que queremos configurar. Podemos optar por criar certificados auto-assinados (self-signed certificates), ou podemos utilizar o certificado de uma CA (Certificate Authority) para assinar os certificados. Estes certificados não serão confiados pelo browser a não ser que se comprem a uma CA oficial, o que implica gastar cerca de €200 por ano (preço baseado no preço dos certificados emitidos pela Thawte). De qualquer forma, são perfeitamente funcionais. Basta que o utilizador confirme que o certificado é válido para que ele funcione.

O certificado de um servidor HTTP servirá igualmente para encriptar a comunicação entre o browser e o servidor.

Certificado da CA (Certificate Authority)

Para constituir a nossa própria CA teremos que criar uma chave secreta para o certificado e o certificado propriamente dito:

$ certtool --generate-privkey --outfile myca.key
Generating a 2432 bit RSA private key...
$ certtool --generate-self-signed --load-privkey myca.key --outfile myca.pem
Generating a self signed certificate...
Please enter the details of the certificate's distinguished name. Just press enter to ignore a field.
Country name (2 chars): PT
Organization name: Antonio Trindade
Organizational unit name: CA
Locality name: Coimbra
State or province name: Beira Litoral
Common name: MyCA
UID: trindade
This field should not be used in new certificates.
E-mail: Antonio.Trindade@gmail.com
Enter the certificate's serial number in decimal (default: 1331422737): 

Activation/Expiration time.
The certificate will expire in (days): 3650

Extensions.
Does the certificate belong to an authority? (y/N): y
Path length constraint (decimal, -1 for no constraint): -1
Is this a TLS web client certificate? (y/N):
Will the certificate be used for IPsec IKE operations? (y/N):
Is this also a TLS web server certificate? (y/N):
Enter the e-mail of the subject of the certificate: Antonio.Trindade@gmail.com
Will the certificate be used to sign other certificates? (y/N): y
Will the certificate be used to sign CRLs? (y/N): y
Will the certificate be used to sign code? (y/N):
Will the certificate be used to sign OCSP requests? (y/N):
Will the certificate be used for time stamping? (y/N):
Enter the URI of the CRL distribution point:
X.509 Certificate Information:
	Version: 3
	Serial Number (hex): 4f5be611
	Validity:
		Not Before: Sat Mar 10 23:38:58 UTC 2012
		Not After: Tue Mar 08 23:39:01 UTC 2022
	Subject: C=PT,O=Antonio Trindade,OU=CA,L=Coimbra,ST=Beira Litoral,CN=MyCA,UID=trindade,EMAIL=Antonio.Trindade@gmail.com
	Subject Public Key Algorithm: RSA
	Certificate Security Level: Normal
		Modulus (bits 2432):
			.
			.
			.
		Exponent (bits 24):
			01:00:01
	Extensions:
		Basic Constraints (critical):
			Certificate Authority (CA): TRUE
		Subject Alternative Name (not critical):
			RFC822name: Antonio.Trindade@gmail.com
		Key Usage (critical):
			Certificate signing.
			CRL signing.
		Subject Key Identifier (not critical):
			604d874c172a52e02047ab47d7277d53113572b7
Other Information:
	Public Key Id:
		604d874c172a52e02047ab47d7277d53113572b7

Is the above information ok? (y/N): y

Signing certificate...

A chave secreta fica guardada no ficheiro myca.key e o certificado no ficheiro myca.pem. A chave secreta deverá ser guardada com permissões restritivas para que nenhum utilizador, excepto o super-utilizador (root), possam ler o ficheiro.

Criação dos certificados para os virtual hosts

De seguida, criar as chaves secretas e os CSR (Certificate Signing Request) para os virtual hosts.

$ certtool --generate-privkey --outfile www.key
Generating a 2432 bit RSA private key...
$ certtool --generate-privkey --outfile trindade_myphotos_cc.key
Generating a 2432 bit RSA private key...
$ certtool --generate-request --load-privkey trindade_myphotos_cc.key --outfile trindade_myphotos_cc.csr
Generating a PKCS #10 certificate request...
Country name (2 chars): PT
Organization name: Antonio Trindade
Organizational unit name: Servidor www.darklair.homeunix.net
Locality name: Coimbra
State or province name: Beira Litoral
Common name: www.darklair.homeunix.net
UID: trindade
Enter a dnsName of the subject of the certificate: www.darklair.homeunix.net
Enter a dnsName of the subject of the certificate:
Enter the IP address of the subject of the certificate: 10.0.0.1
Enter the e-mail of the subject of the certificate: Antonio.Trindade@gmail.com
Enter a challenge password:Does the certificate belong to an authority? (y/N):
Will the certificate be used for signing (DHE and RSA-EXPORT ciphersuites)? (y/N):
Will the certificate be used for encryption (RSA ciphersuites)? (y/N):
Is this a TLS web client certificate? (y/N):
Is this also a TLS web server certificate? (y/N): y
$ certtool --generate-request --load-privkey www.key --outfile www.csr
Generating a PKCS #10 certificate request...
Country name (2 chars): PT
Organization name: Antonio Trindade
Organizational unit name: Servidor www.darklair.homeunix.net
Locality name: Coimbra
State or province name: Beira Litoral
Common name: trindade.myphotos.cc
UID: trindade
Enter a dnsName of the subject of the certificate: trindade.myphotos.cc
Enter a dnsName of the subject of the certificate:
Enter the IP address of the subject of the certificate: 10.0.0.1
Enter the e-mail of the subject of the certificate: Antonio.Trindade@gmail.com
Enter a challenge password:
Does the certificate belong to an authority? (y/N):
Will the certificate be used for signing (DHE and RSA-EXPORT ciphersuites)? (y/N):
Will the certificate be used for encryption (RSA ciphersuites)? (y/N):
Is this a TLS web client certificate? (y/N):
Is this also a TLS web server certificate? (y/N): y

Todos os parâmetros são opcionais, excepto os common name, dnsName e IP address. Estes três campos devem corresponder ao nome do virtual host e ao endereço IP do servidor.

Finalmente, assinar os CSR com o certificado da CA criada anteriormente.

$ certtool --generate-certificate --load-request trindade_myphotos_cc.csr --load-ca-certificate myca.pem --load-ca-privkey myca.key --outfile trindade_myphotos_cc.pem
Generating a signed certificate...
Enter the certificate's serial number in decimal (default: 1331424281):

Activation/Expiration time.The certificate will expire in (days): 3650

Extensions.
Do you want to honour the extensions from the request? (y/N): y
Does the certificate belong to an authority? (y/N):
Is this a TLS web client certificate? (y/N):
Will the certificate be used for IPsec IKE operations? (y/N):
Is this also a TLS web server certificate? (y/N): y
Enter a dnsName of the subject of the certificate: trindade.myphotos.cc
Enter a dnsName of the subject of the certificate:
Enter the IP address of the subject of the certificate: 10.0.0.1
Will the certificate be used for signing (DHE and RSA-EXPORT ciphersuites)? (y/N):
Will the certificate be used for encryption (RSA ciphersuites)? (y/N):
X.509 Certificate Information:
        Version: 3
        Serial Number (hex): 4f5bec19
        Validity:
                Not Before: Sun Mar 11 00:04:42 UTC 2012
                Not After: Wed Mar 09 00:04:44 UTC 2022
        Subject: C=PT,O=Antonio Trindade,OU=Servidor trindade.myphotos.cc,L=Coimbra,ST=Beira Litoral,CN=trindade.myphotos.cc,UID=trindade
        Subject Public Key Algorithm: RSA
        Certificate Security Level: Normal
        Modulus (bits 2432):
                .
                .
                .
        Exponent (bits 24):
                01:00:01
        Extensions:
        Subject Alternative Name (not critical):
                DNSname: trindade.myphotos.cc
                IPAddress: 10.0.0.1
                RFC822name: Antonio.Trindade@gmail.com
                DNSname: trindade.myphotos.cc
                IPAddress: 10.0.0.1
        Basic Constraints (critical):
                Certificate Authority (CA): FALSE
        Key Usage (critical):
                Digital signature.
        Key Purpose (not critical):
                TLS WWW Server.
                TLS WWW Server.
        Subject Key Identifier (not critical):
                736bc20732546e794a859bbd9448809579c9fa69
        Authority Key Identifier (not critical):
                604d874c172a52e02047ab47d7277d53113572b7
Other Information:
        Public Key Id:
                736bc20732546e794a859bbd9448809579c9fa69
Is the above information ok? (y/N): y
Signing certificate...
$ certtool --generate-certificate --load-request www.csr --load-ca-certificate myca.pem --load-ca-privkey myca.key --outfile www.pem
Generating a signed certificate...
Enter the certificate's serial number in decimal (default: 1331424281):

Activation/Expiration time.
The certificate will expire in (days): 3650

Extensions.
Do you want to honour the extensions from the request? (y/N): y
Does the certificate belong to an authority? (y/N):
Is this a TLS web client certificate? (y/N):
Will the certificate be used for IPsec IKE operations? (y/N):
Is this also a TLS web server certificate? (y/N): y
Enter a dnsName of the subject of the certificate: www.darklair.homeunix.net
Enter a dnsName of the subject of the certificate:
Enter the IP address of the subject of the certificate: 10.0.0.1
Will the certificate be used for signing (DHE and RSA-EXPORT ciphersuites)? (y/N):
Will the certificate be used for encryption (RSA ciphersuites)? (y/N):
X.509 Certificate Information:
        Version: 3
        Serial Number (hex): 4f5bec19
        Validity:
                Not Before: Sun Mar 11 00:04:42 UTC 2012
                Not After: Wed Mar 09 00:04:44 UTC 2022
        Subject: C=PT,O=Antonio Trindade,OU=Servidor www.darklair.homeunix.net,L=Coimbra,ST=Beira Litoral,CN=www.darklair.homeunix.net,UID=trindade
        Subject Public Key Algorithm: RSA
        Certificate Security Level: Normal
        Modulus (bits 2432):
                .
                .
                .
        Exponent (bits 24):
                01:00:01
        Extensions:
        Subject Alternative Name (not critical):
                DNSname: www.darklair.homeunix.net
                IPAddress: 10.0.0.1
                RFC822name: Antonio.Trindade@gmail.com
                DNSname: www.darklair.homeunix.net
                IPAddress: 10.0.0.1
        Basic Constraints (critical):
                Certificate Authority (CA): FALSE
        Key Usage (critical):
                Digital signature.
        Key Purpose (not critical):
                TLS WWW Server.
                TLS WWW Server.
        Subject Key Identifier (not critical):
                894e5399ec41a924542d8a762d4d1e37e762abd6
        Authority Key Identifier (not critical):
                604d874c172a52e02047ab47d7277d53113572b7
Other Information:
        Public Key Id:
                894e5399ec41a924542d8a762d4d1e37e762abd6
Is the above information ok? (y/N): y
Signing certificate...

Ficaremos assim com 8 ficheiros no nosso directório de trabalho:

  • myca.key
  • myca.pem
  • www.key
  • www.csr
  • www.pem
  • trindade_myphotos_cc.key
  • trindade_myphotos_cc.csr
  • trindade_myphotos_cc.pem

Os ficheiros csr podem ser apagados, pois não são mais necessários. Também se podem criar os certificados sem ter que os assinar com a nossa CA, eliminando assim dois passos: a criação da CA e a criação dos CSR. O método é semelhante à criação do certificado da CA. Apenas se responde de forma diferente às perguntas finais, especificando que se quer criar um TLS web server certificate.

Configuração do Apache

Copiar os ficheiros key e pem para o directorio onde se encontra a configuração do Apache.

Depois de instalar o mod_gnutls, Basta acrescentar as seguintes linhas ao ficheiro principal de configuração (normalmente httpd.conf):

Listen 443
NameVirtualHost 10.0.0.1:443

Depois, em cada virtual host:


  GnuTLSEnable on
  GnuTLSCertificateFile /usr/local/etc/apache22/www.pem
  GnuTLSKeyFile /usr/local/etc/apache22/www.key
  GnuTLSPriorities NORMAL
  ServerAdmin webmaster@www.darklair.homeunix.net
  DocumentRoot /home/www/www
  ServerName www.darklair.homeunix.net
  ServerAlias 10.0.0.1
  .
  .
  .

Depois destes passos todos (ufff!!!) teremos dois virtual hosts com SSL num único endereço IP.

Em caso de dúvidas, não hesite em contactar-me. No entanto, posso garantir que foi assim que consegui a configuração proposta e funciona!

Esta entrada foi publicada em Configuração com as tags , , , , , . ligação permanente.

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *