Tutorial SSL com Lets Encrypt: Certificado gratuito e homologado para lojas virtuais

Aprenda neste tutorial como configurar certificados SSL válidos usando a tecnologia Let’s Encrypt, que permite emitir certificações para sites que exigem encriptação SSL usando o protocolo https para navegação, como por exemplo lojas virtuais ou páginas de login.

Let’s Encrypt é um projeto de esforço mundial que visa tornar a internet mais segura e que tem o apoio de grandes empresas do setor de tecnologia. A emissão e a renovação dos certificados são gratuitas e “lifetime”, ou seja, você nunca irá precisar pagar por ele o resto da vida do domínio.

Seguindo os meus tutoriais você deve ter notado que ao navegar pelas páginas  do painel de controle, phpMyAdmin e Webmail usando https o acesso exibe uma aviso dizendo que o certificado não é válido. Isso ocorre porque ao instalar o ISPConfig e os serviços emitimos um certificado genérico a partir do próprio servidor, sem a devida validação por órgãos competentes.

Com a instalação do Let’s Encrypt e a devida configuração do bloco de diretivas no NginX podemos adicionar ao servidor e aos sites certificados válidos, e que inclusive são homologados para uso em lojas virtuais que conectam-se a Cielo por exemplo.

*Eu já utilizo o Let’s Encrypt por aproximadamente um ano instalando em servidores de sites parceiros e clientes para lojas Magento, Opencart e Prestashop, além de sites WordPress que dependem de login com https. Até hoje não tivemos problema algum com ele.

Certificado SSL gratuito com Let’s Encrypt:

* Esta documentação pode servir como base para implementação do Let’s Encrypt em servidores com Apache e outras distros Linux diferentes de Debian 8, porém é altamente recomendável seguir nosso tutorial  de Servidor Linux VPS: Debian 8 Jessie com ISPConfig 3 e NginX + Servidor de Emails, clique aqui e aprenda como instalar.

Instalação do certbot

O nosso tutorial de Debian 8 (ver link acima) já tem os comandos para instalar e ativar o certbot (app usado para instalar e gerenciar os certificados da Let’s Encrypt no servidor). Mas caso você não tenha ele instalado siga os procedimentos abaixo:

*Execute os comandos para instalação e configuração dos certificados logado no servidor com o superusuário root.

Adicione o repositório backports do Debian, atualize a lista de pacotes e instale o aplicativo.

Edite o arquivo /etc/apt/sources.list e verifique se ao final há uma linha parecida com esta, se não houver adicione:

deb http://ftp.debian.org/debian jessie-backports main

Em seguida atualize o repositório e instale o Let’s Encrypt:

> apt-get update

> apt-get -y install -t jessie-backports certbot

*Mas somente execute este primeiro passo caso não tenha o certbot instalado ainda.

2 Passo complementar: Prevenindo Logjam attack

Para prevenir este tipo de ataque ao SSL pode-se configurar um parâmetro nas diretivas do site gerando uma chave de criptografia adicional ao certificado. Execute os comandos abaixo. *Estes comandos só serão necessários uma única vez para o servidor e a encriptação da chave poderá demorar até 3 minutos em alguns casos.

> cd /etc/ssl/private
> openssl dhparam -out dhparams.pem 2048
> chmod 600 dhparams.pem
3 Arquivo com o bloco NginX para servir páginas do painel, phpMyAdmin e Webmail do servidor pelo FQDN (hostname)

Se você seguiu atentamente o meu tutorial provavelmente criou o nome do servidor (hostname) com uma URL válida (FQDN). Por exemplo, ao fazer o deploy do VPS digitou no hostname uma URL válida como esta: server1.SEUDOMINIO.COM e adicionou o subdominio “server1” nos registros da tabela DNS do SEUDOMINIO.COM. Caso não tenha feito isso sempre há tempo para recomeçar da maneira correta.

Considerando que o seu FQDN (URL de acesso ao servidor) seja server1.SEUDOMINIO.COM, crie um novo arquivo no diretório /etc/nginx/sites-available com o nome de vps.vhost e cole as diretivas abaixo dentro dele, substituindo server1.SEUDOMINIO.COM pelo FQDN do servidor:

server {
 listen 80;

 #COMENTAR as linhas SSL para validar o certificado LetsEncrypt e liberar elas apos a emissao
 # listen 443 ssl;
 # ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
 # ssl_certificate /etc/letsencrypt/live/server1.SEUDOMINIO.COM/cert.pem;
 # ssl_certificate_key /etc/letsencrypt/live/server1.SEUDOMINIO.COM/privkey.pem;
 # ssl_trusted_certificate /etc/letsencrypt/live/server1.SEUDOMINIO.COM/fullchain.pem;
 # ssl_stapling on;
 # ssl_stapling_verify on;
 # ssl_dhparam /etc/ssl/private/dhparams.pem;
 # ssl_session_cache shared:ssl_session_cache:10m;
 # ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';

 server_name server1.SEUDOMINIO.COM;
 root /usr/local/ispconfig/interface/web/;
 client_max_body_size 100M;

 location / {
 index index.php index.html;
 }

 # serve static files directly
 location ~* ^.+.(jpg|jpeg|gif|css|png|js|ico|html|xml|txt)$ {
 access_log off;
 }

 location ~ \.php$ {
 try_files $uri =404;
 include /etc/nginx/fastcgi_params;
 fastcgi_pass unix:/var/lib/php5-fpm/ispconfig.sock;
 #Caso tenha instalado o Debian 9 com multiplas versoes de PHP substitua a linha acima por esta (descomente):
 #fastcgi_pass unix:/var/lib/php7.0-fpm/ispconfig.sock;
 fastcgi_index index.php;
 fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
 #fastcgi_param PATH_INFO $fastcgi_script_name;
 fastcgi_buffer_size 128k;
 fastcgi_buffers 256 4k;
 fastcgi_busy_buffers_size 256k;
 fastcgi_temp_file_write_size 256k;
 }

 location ~ /\. {
 deny all;
 }
 location ^~ /.well-known/acme-challenge/ {
 default_type text/plain;
 }

 location /phpmyadmin {
 root /usr/share/;
 index index.php index.html index.htm;
 location ~ ^/phpmyadmin/(.+\.php)$ {
 try_files $uri =404;
 root /usr/share/;
 fastcgi_param QUERY_STRING $query_string;
 fastcgi_param REQUEST_METHOD $request_method;
 fastcgi_param CONTENT_TYPE $content_type;
 fastcgi_param CONTENT_LENGTH $content_length;

 fastcgi_param SCRIPT_FILENAME $request_filename;
 fastcgi_param SCRIPT_NAME $fastcgi_script_name;
 fastcgi_param REQUEST_URI $request_uri;
 fastcgi_param DOCUMENT_URI $document_uri;
 fastcgi_param DOCUMENT_ROOT $document_root;
 fastcgi_param SERVER_PROTOCOL $server_protocol;

 fastcgi_param GATEWAY_INTERFACE CGI/1.1;
 fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;

 fastcgi_param REMOTE_ADDR $remote_addr;
 fastcgi_param REMOTE_PORT $remote_port;
 fastcgi_param SERVER_ADDR $server_addr;
 fastcgi_param SERVER_PORT $server_port;
 fastcgi_param SERVER_NAME $server_name;

 fastcgi_param HTTPS $https;

 # PHP only, required if PHP was built with --enable-force-cgi-redirect
 fastcgi_param REDIRECT_STATUS 200;
 # To access phpMyAdmin, the default user (like www-data on Debian/Ubuntu) must be used
 #fastcgi_pass 127.0.0.1:9000;
 fastcgi_pass unix:/var/run/php5-fpm.sock;
 #Caso tenha instalado o Debian 9 com multiplas versoes de PHP substitua a linha acima por esta (descomente):
 #fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
 fastcgi_index index.php;
 fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
 fastcgi_buffer_size 128k;
 fastcgi_buffers 256 4k;
 fastcgi_busy_buffers_size 256k;
 fastcgi_temp_file_write_size 256k;
 fastcgi_read_timeout 1200;
 }
 location ~* ^/phpmyadmin/(.+\.(jpg|jpeg|gif|css|png|js|ico|html|xml|txt))$ {
 root /usr/share/;
 }
 }
 location /phpMyAdmin {
 rewrite ^/* /phpmyadmin last;
 }

 location /roundcube {
 root /var/lib/;
 index index.php index.html index.htm;
 location ~ ^/roundcube/(.+\.php)$ {
 try_files $uri =404;
 root /var/lib/;
 include /etc/nginx/fastcgi_params;
 fastcgi_pass unix:/var/run/php5-fpm.sock;
 #Caso tenha instalado o Debian 9 com multiplas versoes de PHP substitua a linha acima por esta (descomente):
 #fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
 fastcgi_index index.php;
 fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
 fastcgi_buffer_size 128k;
 fastcgi_buffers 256 4k;
 fastcgi_busy_buffers_size 256k;
 fastcgi_temp_file_write_size 256k;
 }
 location ~* ^/roundcube/(.+\.(jpg|jpeg|gif|css|png|js|ico|html|xml|txt))$ {
 root /var/lib/;
 }
 location ~* /.svn/ {
 deny all;
 }
 location ~* /README|INSTALL|LICENSE|SQL|bin|CHANGELOG$ {
 deny all;
 }
 }
 location /webmail {
 rewrite ^/* /roundcube last;
 }
}

***Observação: Caso tenha seguido o tutorial de Debian 9 com múltiplas versões de PHP veja as anotações no script acima, elas foram feitas em 3 lugares, para os blocos ISPConfig, phpMyAdmin e Roundcube. É necessário apontar o arquivo de sock correto ou receberá uma mensagem de 502 Bad Gateway ao tentar acessar o painel. Naquelas linhas de sock é definido qual a versão PHP usada para o painel, pode-se ainda usar a 7.1 ou qualquer outra.

Salve o arquivo, que deverá ser /etc/nginx/sites-available/vps.vhost, e execute os comandos abaixo:

> ln -s /etc/nginx/sites-available/vps.vhost /etc/nginx/sites-enabled/vps.vhost
> /etc/init.d/nginx restart

Após fazermos isso note que já podemos acessar o painel do ISPConfig pela URL http://server1.SEUDOMINIO.COM, o phpMyAdmin pela URL http://server1.SEUDOMINIO.COM/phpmyadmin e o Roundcube pela URL http://server1.SEUDOMINIO.COM/webmail. Mas ainda falta emitir o certificado para que seja possível acessar as mesmas URLs com https.

4 Emissão do certificado SSL para o FQDN do servidor

Agora que já temos uma URL válida para acessar o servidor podemos solicitar a emissão do certificado SSL para ela. *O emissor de certificados da Let’s Encrypt (ACME) irá verificar se a URL existe e se tem um caminho reverso para a origem, por isso a necessidade de configurar uma URL válida.

*A ACME não permite a emissão de certificados “wildcards” (subdomínios múltiplos), então para cada subdomínio será necessário um novo pedido de emissão. A única exceção é o “www”.

Comando para emitir o certificado para o FQDN de um servidor com ISPConfig e NginX, note o caminho de instalação dos scripts web da página. Substitua o FQDN pelo do seu servidor e [email protected] por um email válido, pois caso haja problemas com o certificado você será notificado:

> certbot certonly --agree-tos --renew-by-default --webroot --email [email protected] -w /usr/local/ispconfig/interface/web -d SERVER1.SEUDOMINIO.COM

Para saber se o certificado foi emitido corretamente uma mensagem de “Congratulations” será exibida indicando o caminho que o certificado foi instalado e que deverá ser /etc/letsencrypt/live/. *Para verificar pode-se também listar o diretório e ver se há um subdiretório com o domínio do site.

Após isso só precisamos descomentar as linhas do certificado no arquivo de diretivas (retirando as “#hashtags das linhas 5 a 14 do vps.vhost), salvar o arquivo e reiniciar o NginX:

> /etc/init.d/nginx restart

Agora o ISPConfig, phpMyAdmin e Webmail já podem ser acessados com https sem dar erro de certificado.

5 Let’s Encrypt para os sites

Muito bem. Agora que já temos o certbot instalado e o método de uso pronto, já podemos emitir certificados para todos os sites no mesmo servidor. O ISPConfig facilita a configuração das diretivas NginX para os sites, irei mostrar abaixo como fazer isso usando ele, mas caso não tenha ISPConfig então verifique na configuração do seu painel como fazer.

Acesse o painel do ISPConfig e selecione o site que deseja emitir o certificado. Clique na aba “Options” do site e adicione as diretivas abaixo ao final das demais diretivas NginX que lá estão:

location ^~ /.well-known/acme-challenge/ {
   default_type text/plain;
}

Clique em salvar e aguarde alguns minutos. Em seguida execute o comando abaixo logado no servidor como superusuário root e substituindo os textos em vermelho pelo email e domínio corretos:

*Note que agora o caminho web para o site é diferente do anterior para o FQDN, nesta emissão você deverá digitar onde cada site está instalado. Para sites adicionados ao ISPConfig basta trocar DOMINIO001.COM pelo seu domínio de site.

*E note que adicionamos um novo parâmetro ao comando para que a emissão seja feita também para o “www”.

> certbot certonly --agree-tos --renew-by-default --webroot --email [email protected] -w /var/www/DOMINIO001.COM/web -d DOMINIO001.COM -d www.DOMINIO001.COM

E para finalizar você deverá colar as diretivas NginX para cada site, na caixa de diretivas NginX da aba “Options” do site. Mas desta vez cole-as no início, antes de todas as outras diretivas lá.

*Lembre-se de substituir o DOMINIO.

listen 443 ssl;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_certificate /etc/letsencrypt/live/DOMINIO001.COM/cert.pem;
ssl_certificate_key /etc/letsencrypt/live/DOMINIO001.COM/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/DOMINIO001.COM/fullchain.pem;
ssl_stapling on;
ssl_stapling_verify on;
ssl_dhparam /etc/ssl/private/dhparams.pem;
ssl_session_cache shared:ssl_session_cache:10m;
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
6 Agendamento do certbot no CRON 

Um último passo irá assegurar que o servidor nunca fique sem o certificado de segurança. Na documentação do Let’s Encrypt esta informação não é clara por isso é bom prevenir. E há vários relatos nos fóruns deles dizendo que é necessário reiniciar o NginX após a reemissão do certificado.

O certificado da Let’s Encrypt é lifetime porém a reemissão e revalidação do mesmo é obrigatória a cada 4 meses em média.

Edite o CRON:

> crontab -e

E cole as seguintes linhas ao final:

15 23 * * * /usr/bin/certbot renew -q
0 5 * * * /etc/init.d/php5-fpm restart > /dev/null
0 5 * * * /etc/init.d/nginx restart > /dev/null

Salve as tarefas (para sair do editor salvando tecle CTRL+X e y).

* OBSERVAÇÃO em 19/05/2017:

Ao emitir o certificado talvez ocorra o erro abaixo:

Starting new HTTPS connection (1): acme-v01.api.letsencrypt.org
An unexpected error occurred:
ClientError: <Response [504]>

O motivo do erro 504 na maioria das vezes é: ou problema de conexão com a Lets Encrypt, ou problema nos servidores deles. Verifique o status do serviço de emissão dos certificados neste link: https://letsencrypt.status.io/

NOTAS:

Domínios com a tabela DNS configurada na CloudFlare e que estejam com a nuvem ativada (laranja) é importante verificar na aba “Crypto” se o certificado está ligado. Na maioria dos casos essa opção deverá estar selecionada como “Flexible” mas para lojas virtuais é recomendável deixar como “Full Strict“.

Mesmo com as diretivas acima configuradas note que o https das páginas não está “forçado”, ou seja, ainda é possível acessar o site com http. Para sites WordPress existe um plugin que resolve isso chamado Really Simple SSL. Se quiser encontrá-lo mais facilmente entre no painel admin do WordPress e clique em Adicionar Novo Plugin e na aba Favoritos digite “fatorbinario“, isso irá exibir todos os plugins que marquei como favoritos no WordPress.org. Instale o plugin e ative-o. Por último será exibida uma mensagem no topo da tela com um botão azul de “Go ahead, activate SSL!“, clique nele e pronto.

Para saber como forçar o SSL em todas as páginas usando outros CMS ou até mesmo para sites em PHP deixe um comentário.

Gerenciamento em infraestrutura de Servidores Cloud VPS e Dedicados. Planos mensais acessíveis e consultoria diferenciada para agências de marketing. Envie um email para [email protected] e solicite uma análise gratuita!