Múltiplos virtual hosts com SSL em Apache

Con­fig­u­rar um servi­dor HTTP para HTTPS nun­ca foi uma tare­fa tão fácil como con­fig­urá-lo para ape­nas HTTP. Além das con­fig­u­rações bási­cas temos tam­bém de nos pre­ocu­par com cer­ti­fi­ca­dos, chaves pri­vadas e afins. Além de mais, uti­lizan­do o tradi­cional mod_ssl pre­cisamos de um endereço IP difer­ente para cada vir­tu­al host, o que nem sem­pre é possível.

Mas ago­ra temos o RFC 3546 (Trans­port Lay­er Secu­ri­ty (TLS) Exten­sions). Este RFC define exten­sões ao TLS (Trans­port Lay­er Secu­ri­ty) que per­mite uti­lizar vir­tu­al hosts em SSL sem neces­si­dade de vários endereços IP.

O problema com o mod_ssl

O prob­le­ma com o mod_ssl e vir­tu­al hosts é sim­ples de explicar: não se pode uti­lizar vir­tu­al hosts basea­d­os em nome. Isto por que este tipo de vir­tu­al host depende de infor­mação pre­sente no pedi­do HTTP. Ora, o cabeçal­ho do pedi­do HTTP está encrip­ta­do numa lig­ação HTTPS e é necessário saber qual o vir­tu­al host para se con­seguir obter a chave de descod­i­fi­cação do próprio cabeçalho.

Neste momen­to o mod_ssl não supor­ta o RFC 3546, mas, feliz­mente, existe uma alter­na­ti­va: o mod_gnutls.

Com este módu­lo é pos­sív­el uti­lizar vir­tu­al hosts basea­d­os em nome com um úni­co endereço IP.

Nas lin­has seguintes, expli­carei como con­fig­u­rar dois vir­tu­al hosts com SSL.

O cenário

Quero con­fig­u­rar dois vir­tu­al hosts com SSL: www.darklair.homeunix.net e trindade.myphotos.cc. Estes dois servi­dores vir­tu­ais estão alo­ja­dos no mes­mo servi­dor físi­co e dis­põem ape­nas de um endereço IP externo.

Para con­fig­u­rar o mod_gnutls para este cenário, vão ser pre­cisos, no mín­i­mo, dois cer­ti­fi­ca­dos SSL e mod­i­fi­cações nos ficheiros de con­fig­u­ração do Apache.

Criação dos certificados

Ter­e­mos que cri­ar um cer­ti­fi­ca­do assi­na­do por cada servi­dor vir­tu­al que quer­e­mos con­fig­u­rar. Podemos optar por cri­ar cer­ti­fi­ca­dos auto-assi­na­dos (self-signed cer­tifi­cates), ou podemos uti­lizar o cer­ti­fi­ca­do de uma CA (Cer­tifi­cate Author­i­ty) para assi­nar os cer­ti­fi­ca­dos. Estes cer­ti­fi­ca­dos não serão con­fi­a­dos pelo brows­er a não ser que se com­prem a uma CA ofi­cial, o que impli­ca gas­tar cer­ca de €200 por ano (preço basea­do no preço dos cer­ti­fi­ca­dos emi­ti­dos pela Thawte). De qual­quer for­ma, são per­feita­mente fun­cionais. Bas­ta que o uti­lizador con­firme que o cer­ti­fi­ca­do é váli­do para que ele funcione.

O cer­ti­fi­ca­do de um servi­dor HTTP servirá igual­mente para encrip­tar a comu­ni­cação entre o brows­er e o servidor.

Certificado da CA (Certificate Authority)

Para con­sti­tuir a nos­sa própria CA ter­e­mos que cri­ar uma chave sec­re­ta para o cer­ti­fi­ca­do e o cer­ti­fi­ca­do pro­pri­a­mente 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 sec­re­ta fica guarda­da no ficheiro myca.key e o cer­ti­fi­ca­do no ficheiro myca.pem. A chave sec­re­ta dev­erá ser guarda­da com per­mis­sões restri­ti­vas para que nen­hum uti­lizador, excep­to o super-uti­lizador (root), pos­sam ler o ficheiro.

Criação dos certificados para os virtual hosts

De segui­da, cri­ar as chaves sec­re­tas e os CSR (Cer­tifi­cate Sign­ing Request) para os vir­tu­al 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âmet­ros são opcionais, excep­to os common name, dnsName e IP address. Estes três cam­pos devem cor­re­spon­der ao nome do vir­tu­al host e ao endereço IP do servidor.

Final­mente, assi­nar os CSR com o cer­ti­fi­ca­do da CA cri­a­da 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...

Ficare­mos assim com 8 ficheiros no nos­so direc­tó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 apa­ga­dos, pois não são mais necessários. Tam­bém se podem cri­ar os cer­ti­fi­ca­dos sem ter que os assi­nar com a nos­sa CA, elim­i­nan­do assim dois pas­sos: a cri­ação da CA e a cri­ação dos CSR. O méto­do é semel­hante à cri­ação do cer­ti­fi­ca­do da CA. Ape­nas se responde de for­ma difer­ente às per­gun­tas finais, especi­f­i­can­do que se quer cri­ar um TLS web serv­er cer­tifi­cate.

Configuração do Apache

Copi­ar os ficheiros key e pem para o direc­to­rio onde se encon­tra a con­fig­u­ração do Apache.

Depois de insta­lar o mod_gnutls, Bas­ta acres­cen­tar as seguintes lin­has ao ficheiro prin­ci­pal de con­fig­u­ração (nor­mal­mente httpd.conf):

Listen 443
NameVirtualHost 10.0.0.1:443

Depois, em cada vir­tu­al 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 pas­sos todos (ufff!!!) ter­e­mos dois vir­tu­al hosts com SSL num úni­co endereço IP.

Em caso de dúvi­das, não hes­ite em con­tac­tar-me. No entan­to, pos­so garan­tir que foi assim que con­segui a con­fig­u­ração pro­pos­ta e funciona!

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

Deixe um comentário

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

Este site utiliza o Akismet para reduzir spam. Fica a saber como são processados os dados dos comentários.