Tutorial

Como hospedar um site com o Caddy no Ubuntu 18.04

GoLet's EncryptUbuntu 18.04

O autor selecionou o Free and Open Source Fund para receber uma doação como parte do programa Write for DOnations.

Introdução

O Caddy é um servidor Web projetado em torno da simplicidade e segurança que vem com um conjunto de recursos úteis para o hospedagem de sites. Por exemplo, ele pode obter e gerenciar automaticamente os certificados TLS do Let’s Encrypt para habilitar o HTTPS e inclui o suporte para o HTTP/2. O HTTPS é um sistema criado para proteger o tráfego entre seus usuários e seu servidor, e rapidamente se tornou uma expectativa básica de qualquer site em execução na produção — sem ele, o Chrome e o Firefox alertarão que seu site “não é seguro”, caso usuários tentem enviar informações de login.

Anteriormente, o método recomendado para a instalação do Caddy era de baixar os binários pré-compilados do site do projeto do Caddy. No entanto, devido a alterações na forma como o licenciamento do Caddy funciona, você não tem mais permissão para usar esses binários pré-compilados para fins comerciais, a menos que você pague uma taxa de licença, mesmo que esteja usando o Caddy internamente dentro de uma empresa. Felizmente, o código de origem do Caddy ainda está totalmente em código aberto e você mesmo pode compilar o Caddy para evitar problemas de licenciamento.

Neste tutorial, você compilará o Caddy a partir da fonte e o utilizará para hospedar um site protegido com o HTTPS. Isso implica compilá-lo, configurá-lo usando um Caddyfile e instalar plug-ins. No final, você aprenderá como atualizar sua instalação quando uma nova versão for liberada.

Pré-requisitos

Passo 1 — Compilação do Caddy

Neste passo, você compilará o Caddy a partir da fonte com a habilidade de adicionar plug-ins mais tarde, tudo sem alterar o código-fonte do Caddy.

Para fins deste tutorial, você armazenará o código-fonte em ~/caddy. Crie o diretório executando o seguinte comando:

  • mkdir ~/caddy

Navegue até ele:

  • cd ~/caddy

Você armazenará o código-fonte para executar e personalizar o Caddy em um arquivo chamado caddy.go. Crie-o usando o seguinte comando:

  • nano caddy.go

Adicione as linhas a seguir:

~/caddy/caddy.go
package main

import (
    "github.com/caddyserver/caddy/caddy/caddymain"
)

func main() {
    // caddymain.EnableTelemetry = false
    caddymain.Run()
}

Este código importa o Caddy diretamente do Github (usando o Git) e o inicia a partir da função main de entrada. Caso queira habilitar a telemetria, descomente a linha caddymain.EnableTelemetry e configure o valor para true. Quando terminar, salve e feche o arquivo.

Para que o caddy.go consiga utilizar as dependências importadas, será necessário inicializá-lo como um módulo:

  • go mod init caddy
Output
go: creating new go.mod: module caddy

Neste ponto, você está pronto para compilar a versão de estoque do Caddy a partir do código-fonte acima, executando:

  • go install

Haverá várias saídas, detalhando quais bibliotecas o Go baixou como dependências necessárias para a compilação. O executável resultante é armazenado em $GOPATH/bin, como explicado nos pré-requisitos.

Quando terminar, tente executar o Caddy:

  • caddy

Você verá um resultado similar ao seguinte:

Output
Activating privacy features... done. Serving HTTP on port 2015 http://:2015 WARNING: File descriptor limit 1024 is too low for production servers. At least 8192 is recommended. Fix with `ulimit -n 8192`.

Isso significa que o Caddy foi iniciado com sucesso e está disponível na porta 2015. Você pode ignorar a mensagem de aviso, pois isso será ajustado em passos mais adiante sem sua intervenção. Para sair, pressione CTRL + C.

Você compilou e executou o Caddy. Nos próximo passo, você instalará o Caddy como um serviço para que ele seja iniciado automaticamente ao inicializar o sistema e ajustará suas configurações de propriedade e de permissão para garantir a segurança do servidor.

Passo 2 — Instalando o Caddy

Agora que você viu que consegue compilar e executar o Caddy, é hora de configurar um serviço systemd para que o Caddy seja iniciado automaticamente na inicialização do sistema. Para entender melhor a respeito do systemd, visite nosso tutorial Essenciais do Systemd.

Para começar, mova o binário do Caddy para /usr/local/bin, o local padrão para os binários que não são gerenciados pelo gerenciador de pacotes do Ubuntu e não são chaves para a operação do sistema:

  • sudo mv $GOPATH/bin/caddy /usr/local/bin/

Em seguida, mude a propriedade do binário do Caddy para o usuário root:

  • sudo chown root:root /usr/local/bin/caddy

Isso impedirá que outras contas modifiquem o executável. No entanto, embora o usuário root seja proprietário do Caddy, é recomendável executá-lo apenas usando outras contas não raiz presentes no sistema. Isso garante que, em um evento do Caddy (ou outro programa) ficar comprometido, o invasor não conseguirá modificar o binário ou executar comandos como root.

Em seguida, defina as permissões do arquivo binário para 755 — isso dá ao root permissões totais de leitura/escrita/execução para o arquivo, enquanto outros usuários poderão apenas ler e executá-lo.

  • sudo chmod 755 /usr/local/bin/caddy

Como o processo do Caddy não está em execução como root, o Lunix impedirá que ele se vincule às portas 80 e 443 (as portas padrão para o HTTP e o HTTPS, respectivamente), pois estas são operações privilegiadas. Para seu domínio ficar mais acessível, o Caddy precisa ficar ligado a uma dessas portas, dependendo do protocolo. Caso contrário, seria necessário adicionar um número de porta específico à URL do domínio em seu navegador para visualizar o conteúdo que será exibido.

Execute o seguinte comando para permitir que o Caddy se associe a portas inferiores sem ser executado como root:

  • sudo setcap 'cap_net_bind_service=+ep' /usr/local/bin/caddy

O utilitário setcap define as capacidades do arquivo. Neste comando, ele atribui a capacidade CAP_NET_BIND_SERVICE ao binário do Caddy, que permite que um executável se associe a uma porta menor que 1024.

Agora, você acabou de configurar o binário do Caddy e está pronto para começar a escrever a configuração do Caddy Crie um diretório onde você armazenará os arquivos de configuração do Caddy executando o seguinte comando:

  • sudo mkdir /etc/caddy

Em seguida, defina as permissões do usuário e do grupo corretos para ele:

  • sudo chown -R root:www-data /etc/caddy

Definir o usuário como root e o grupo como www-data garante que o Caddy terá o acesso de leitura e escrita à pasta (via grupo www-data) e que apenas a conta do superuser terá os mesmos direitos de ler e modificar. O www-data é o usuário e o grupo padrão para os servidores Web no Ubuntu.

Em um passo mais adiante, você habilitará o fornecimento automático do certificado TLS do Let’s Encrypt. Para nos prepararmos para isso, crie um diretório para armazenar todos os certificados TLS que o Caddy receberá e dê a ele as mesmas regras de propriedade do diretório /etc/caddy:

  • sudo mkdir /etc/ssl/caddy
  • sudo chown -R root:www-data /etc/ssl/caddy

O Caddy deve conseguir escrever certificados para este diretório e ler a partir dele para criptografar solicitações. Por este motivo, modifique as permissões do diretório /etc/ssl/caddy, para que ele seja acessível apenas pelo root e pelo www-data:

  • sudo chmod 0770 /etc/ssl/caddy

Em seguida, crie um diretório para armazenar os arquivos que o Caddy hospedará:

  • sudo mkdir /var/www

Então, defina o proprietário e o grupo do diretório para www-data:

  • sudo chown www-data:www-data /var/www

O Caddy lê suas configurações a partir de um arquivo chamado Caddyfile, armazenado em /etc/caddy. Crie o arquivo no disco executando:

  • sudo touch /etc/caddy/Caddyfile

Para instalar o serviço Caddy, baixe o arquivo de unidade do systemd no repositório Caddy Github para /etc/systemd/system, executando:

  • sudo sh -c 'curl https://raw.githubusercontent.com/caddyserver/caddy/master/dist/init/linux-systemd/caddy.service > /etc/systemd/system/caddy.service'

Modifique as permissões do arquivo de serviço para que ele só possa ser modificado pelo seu proprietário, o root:

  • sudo chmod 644 /etc/systemd/system/caddy.service

Então, recarregue o systemd para detectar o serviço do Caddy:

  • sudo systemctl daemon-reload

Verifique se o systemd detectou o serviço Caddy executando systemctl status:

  • sudo systemctl status caddy

Você verá um resultado parecido com este:

Output
● caddy.service - Caddy HTTP/2 web server Loaded: loaded (/etc/systemd/system/caddy.service; disabled; vendor preset: e Active: inactive (dead) Docs: https://caddyserver.com/docs

Caso veja este mesmo resultado, então o novo serviço foi detectado corretamente pelo systemd.

Como parte do pré-requisito da configuração inicial do servidor, você habilitou o ufw, um firewall descomplicado e permitiu conexões do tipo SSH. Para que o Caddy possa exibir tráfegos HTTP e HTTPS de seu servidor, será necessário permiti-los no ufw, executando o seguinte comando:

  • sudo ufw allow proto tcp from any to any port 80,443

O resultado será:

Output
Rule added Rule added (v6)

Utilize o ufw status para verificar se suas alterações funcionaram:

  • sudo ufw status

Você verá o seguinte resultado:

Output
Status: active To Action From -- ------ ---- OpenSSH ALLOW Anywhere 80,443/tcp ALLOW Anywhere OpenSSH (v6) ALLOW Anywhere (v6) 80,443/tcp (v6) ALLOW Anywhere (v6)

Sua instalação do Caddy está completa, mas ela não está configurada para exibição. No próximo passo, você configurará o Caddy para exibir arquivos a partir do diretório /var/www.

Passo 3 — Configurando o Caddy

Nesta seção, você escreverá a configuração básica do Caddy para exibir arquivos estáticos do seu servidor.

Comece criando um arquivo HTML básico em /var/www, chamado index.html:

  • sudo nano /var/www/index.html

Adicione as linhas a seguir:

/var/www/index.html
<!DOCTYPE html>
<html>
<head>
  <title>Hello from Caddy!</title>
</head>
<body>
  <h1 style="font-family: sans-serif">This page is being served via Caddy</h1>
</body>
</html>

Este arquivo, quando for mostrado em um navegador Web, exibirá um cabeçalho com o texto This page is being served via Caddy. Salve e feche o arquivo.

Abra o arquivo de configuração Caddyfile que você criou mais cedo para a edição:

  • sudo nano /etc/caddy/Caddyfile

Adicione as linhas a seguir:

/etc/caddy/Caddyfile
:80 {
  root /var/www
  gzip
}

Esta é uma configuração básica do Caddy, e ela declara que a porta 80 do seu servidor deve ser exibida com os arquivos da /var/www e eles devem ser compactados usando o gzip, para reduzir o tempo de carregamento da página no lado do cliente.

Na maioria dos casos, o Caddy permite que você personalize as diretivas de configuração ainda mais. Por exemplo, você pode limitar a compactação do gzip apenas para os arquivos HTML e PHP e definir o nível de compactação para 6 (1 sendo o mais baixo e 9 sendo o mais alto), estendendo a diretiva com chaves e listando as sub-diretivas abaixo:

/etc/caddy/Caddyfile
:80 {
  root /var/www
  gzip {
      ext .html .htm .php
      level 6
  }
}

Quando terminar, salve e feche o arquivo.

O Caddy possui um grande número de diretivas diferentes para muitos casos de uso. Por exemplo, a diretiva fastcgi poderia ser útil para habilitar o PHP. A diretiva markdown poderia ser usada para converter automaticamente os arquivos Markdown para HTML antes de exibi-los. Isso poderia ser útil para a criação de um blog simples.

Para testar se tudo está funcionando corretamente, inicie o serviço Caddy:

  • sudo systemctl start caddy

Em seguida, execute systemctl status para encontrar informações sobre o status do serviço do Caddy:

  • sudo systemctl status caddy

Você verá o seguinte:

Output
● caddy.service - Caddy HTTP/2 web server Loaded: loaded (/etc/systemd/system/caddy.service; disabled; vendor preset: enabled) Active: active (running) since Thu 2020-03-12 11:17:49 UTC; 11s ago Docs: https://caddyserver.com/docs Main PID: 3893 (caddy) Tasks: 7 (limit: 1152) CGroup: /system.slice/caddy.service └─3893 /usr/local/bin/caddy -log stdout -log-timestamps=false -agree=true -conf=/etc/caddy/Caddyfile -root=/var/tmp Mar 12 11:17:49 caddy-article-update systemd[1]: Started Caddy HTTP/2 web server. Mar 12 11:17:49 caddy-article-update caddy[3893]: [INFO] Caddy version: v1.0.5 Mar 12 11:17:49 caddy-article-update caddy[3893]: Activating privacy features... done. Mar 12 11:17:49 caddy-article-update caddy[3893]: Serving HTTP on port 80 Mar 12 11:17:49 caddy-article-update caddy[3893]: http:// Mar 12 11:17:49 caddy-article-update caddy[3893]: [INFO] Serving http:// Mar 12 11:17:49 caddy-article-update caddy[3893]: [INFO][cache:0xc00007a7d0] Started certificate maintenance routine Mar 12 11:17:49 caddy-article-update caddy[3893]: [WARNING] Sending telemetry (attempt 1): Post "https://telemetry.caddyserver.com/v1/update/6a8159c4-3427-42 Mar 12 11:17:57 caddy-article-update caddy[3893]: [WARNING] Sending telemetry (attempt 2): Post "https://telemetry.caddyserver.com/v1/update/6a8159c4-3427-42 ...

Agora, você pode ir para o IP do seu servidor em um navegador Web. Sua página de amostra Web exibirá:

Mensagem do Caddy

Você configurou o Caddy para exibir arquivos estáticos do seu servidor. No próximo passo, você ampliará a funcionalidade do Caddy através do uso de plug-ins.

Passo 4 — Usando plug-ins

Os plug-ins oferecem uma maneira de alterar e ampliar o comportamento do Caddy. Geralmente, eles oferecem mais diretivas de configuração para você usar, de acordo com seu caso de uso. Nesta seção, você adicionará e utilizará plug-ins instalando o plug-in minify, que remove o excesso de espaços em branco e arruma o código que será enviado para o cliente, reduzindo ainda mais o volume e o tempo de carregamento.

O repositório GitHub do plug-in minify é o hacdias/caddy-minify.

Vá até o diretório com o código-fonte que você criou no passo um:

  • cd ~/caddy

Para adicionar um plug-in ao Caddy, será necessário importá-lo no arquivo caddy.go que você usou para compilar o Caddy. Abra o caddy.go​​​ para edição:

  • nano caddy.go

Importe o plug-in minify, adicionando a linha destacada, desta forma:

~/caddy/caddy.go
package main

import (
    "github.com/caddyserver/caddy/caddy/caddymain"

    _ "github.com/hacdias/caddy-minify"
)

func main() {
    // caddymain.EnableTelemetry = false
    caddymain.Run()
}

Salve e feche o arquivo.

Alguns plug-ins podem precisar de pequenos ajustes de configuração. Certifique-se de ler a documentação dos plug-ins que instalar. É possível encontrar uma lista dos plug-ins mais populares no painel esquerdo da documentação do Caddy, embaixo de Plugins.

Sempre que adicionar um novo plug-in, você terá que compilar o Caddy novamente. Isso acontece porque o Go é uma linguagem de programação compilada, o que significa que o código-fonte é transformado em código de máquina antes da execução. Sua mudança para a declaração de importação alterou o código-fonte, mas não afetará o binário até que ele seja compilado.

Use o comando go install para compilar o Caddy:

  • go install

Quando ele terminar de compilar, mova o binário gerado para /usr/local/bin e configure as permissões para o binário como você fez anteriormente. Você deve executar esses passos sempre que você for compilar o Caddy novamente, para garantir sua funcionalidade e segurança:

  • sudo mv $GOPATH/bin/caddy /usr/local/bin/
  • sudo chown root:root /usr/local/bin/caddy
  • sudo chmod 755 /usr/local/bin/caddy
  • sudo setcap 'cap_net_bind_service=+ep' /usr/local/bin/caddy

Para começar a utilizar o plug-in minify, será necessário adicionar a diretiva minify para seu Caddyfile. Abra o Caddyfile​​​ para edição:

  • sudo nano /etc/caddy/Caddyfile

Habilite o plug-in adicionando a seguinte linha ao bloco de configuração:

/etc/caddy/Caddyfile
:80 {
  root /var/www
  gzip
  minify
}

Agora, reinicie seu servidor usando systemctl:

  • sudo systemctl restart caddy

O Caddy está agora em execução e diminuirá todos os arquivos que ele exibir, incluindo o arquivo index.html que você criou mais cedo. Você pode observar a ‘diminuição’ em trabalho buscando o conteúdo do seu domínio usando o curl:

  • curl http://your_domain

Você verá o seguinte resultado: Note que todo o espaço em branco desnecessário foi removido, mostrando que o plug-in minify está funcionando.

Output
<!doctype html><title>Hello from Caddy!</title><h1 style=font-family:sans-serif>This page is being served via Caddy</h1>

Neste passo, você aprendeu como estender o Caddy com plug-ins. Em seguida, você habilitará o HTTPS instalando o plug-in tls.dns.digitalocean.

Passo 5 — Habilitando o TLS automático com o Let’s Encrypt

Nesta seção, você habilitará o fornecimento e renovação automáticos de certificados do Let’s Encrypt usando registros DNS TXT para verificação.

Para verificar o uso de registro TXT DNS, será necessário instalar um plug-in para interagir com a API da Digital Ocean chamado tls.dns.digitalocean. O processo de instalação dele é quase idêntico ao modo como você instalou o plug-in minify no passo anterior. Para começar, abra o caddy.go:

  • nano caddy.go

Adicione o repositório do plug-in às importações:

~/caddy/caddy.go
package main

import (
    "github.com/caddyserver/caddy/caddy/caddymain"

    _ "github.com/hacdias/caddy-minify"

    _ "github.com/caddyserver/dnsproviders/digitalocean"
)

func main() {
    // caddymain.EnableTelemetry = false
    caddymain.Run()
}

Compile-o executando:

  • go install

Certifique-se de que o Caddy está parado através do systemctl e, em seguida, termine de instalar o plug-in copiando o binário do Caddy recém compilado e, mais uma vez, configure a propriedade e permissões dele:

  • sudo systemctl stop caddy
  • sudo mv $GOPATH/bin/caddy /usr/local/bin/
  • sudo chown root:root /usr/local/bin/caddy
  • sudo chmod 755 /usr/local/bin/caddy
  • sudo setcap 'cap_net_bind_service=+ep' /usr/local/bin/caddy

Em seguida, configure o Caddy para trabalhar com a API da DigitalOcean para definir registros de DNS. O Caddy precisa acessar este token como uma variável de ambiente para configurar o DNS da DigitalOcean. Assim sendo, você editará o arquivo de unidade systemd:

  • sudo nano /etc/systemd/system/caddy.service

Encontre a linha que começa com o Environment= na seção [Service]. Essa linha define as variáveis de ambiente que devem ser enviadas para o processo do Caddy. Adicione um espaço no final desta linha e então, adicione uma variável DO_AUTH_TOKEN, seguida pelo token que acabou de gerar:

/etc/systemd/system/caddy.service
[Service]
Restart=on-abnormal

; User and group the process will run as.
User=www-data
Group=www-data

; Letsencrypt-issued certificates will be written to this directory.
Environment=CADDYPATH=/etc/ssl/caddy DO_AUTH_TOKEN=your_token_here

Salve e feche este arquivo e, em seguida, recarregue o daemon do systemd como fez anteriormente para garantir que a configuração esteja atualizada:

  • sudo systemctl daemon-reload

Execute o systemctl status para verificar que suas alterações de configuração estavam OK:

  • sudo systemctl status caddy

O resultado deve ficar parecido com este:

Output
● caddy.service - Caddy HTTP/2 web server Loaded: loaded (/etc/systemd/system/caddy.service; disabled; vendor preset: enabled) Active: inactive (dead) Docs: https://caddyserver.com/docs ...

Será necessário fazer algumas pequenas alterações no seu Caddyfile, então abra-o para edição:

  • sudo nano /etc/caddy/Caddyfile

Adicione as linhas destacadas ao Caddyfile, certificando-se de substituir o your_domain pelo seu domínio (em vez de apenas a porta :80) e de comentar o gzip:

/etc/caddy/Caddyfile
your_domain {
  root /var/www
  #gzip
  minify
  tls {
      dns digitalocean
  }
}

Usar um domínio em vez de apenas uma porta para o nome do host fará com que o Caddy atenda solicitações por HTTPS. A diretiva tls configura o comportamento do Caddy ao usar o TLS, e a sub-diretiva dns especifica que o Caddy deve usar o sistema DNS-01, em vez de HTTP-01.

Com isso, seu site está pronto para ser implantado. Inicie o Caddy com o systemctl e, em seguida, use enable para habilitá-lo para que ele seja executado na inicialização do sistema:

  • sudo systemctl start caddy
  • sudo systemctl enable caddy

Se você for para seu domínio, será automaticamente redirecionado para o HTTPS, com a mesma mensagem mostrada.

Sua instalação do Caddy está completa e protegida, e você pode personalizar ainda mais de acordo com seu caso de uso.

Caso queira atualizar o Caddy quando uma nova versão sair, será necessário atualizar o arquivo go.mod (armazenado no mesmo diretório), que se parece com isto:

~/caddy/go.mod
module caddy

go 1.14

require (
        github.com/caddyserver/caddy v1.0.5
        github.com/caddyserver/dnsproviders v0.4.0
        github.com/hacdias/caddy-minify v1.0.2
)

A parte destacada é a versão do Caddy que você está usando. Quando uma nova versão for lançada no Github (veja a página de lançamentos de tags), você pode substituir a versão existente no go.mod por ela e compilar o Caddy, de acordo com os dois primeiros passos. Faça o mesmo em todos os plug-ins importados.

Conclusão

Agora, você tem o Caddy instalado e configurado em seu servidor, atendendo páginas estáticas em seu domínio desejado, protegido com certificados do Let’s Encrypt gratuitos.

Um bom próximo passo seria encontrar uma maneira de ser notificado quando novas versões do Caddy fossem liberadas. Por exemplo, você pode utilizar o feed do Atom para lançamentos do Caddy, ou um serviço dedicado, como o dependencies.io.

Explore a documentação do Caddy para obter maiores informações a respeito da configuração do Caddy.

0 Comments

Creative Commons License