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.
* 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.
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.
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
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.
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.
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';
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.






