Ir diretamente para o conteúdo

Definições de cookies

Escolha que tipos de cookies permite. Pode alterar a sua escolha a qualquer momento em Definições de cookies, no fundo de cada página. Política de privacidade

Necessários

Sempre ativos

Necessários para iniciar sessão, manter o seu carrinho e memorizar as suas escolhas. Estão sempre ativos.

Que cookies?
  • weboke_sessie, weboke_klant, weboke_remember: a sua sessão e manter a sessão iniciada
  • weboke_basket: o seu carrinho
  • wkBtwIncl: mostrar preços com ou sem IVA
  • wok_cookies: a sua escolha de cookies, 12 meses

Mede que anúncio leva a uma visita ou encomenda, para não pagarmos por anúncios que não dão resultado.

Que cookies?
  • Google Ads via Google Tag Manager (_gcl_au, _gcl_aw), até 90 dias
  • OpenAI Ads, anúncios no ChatGPT
  • wok_aff: através de que parceiro chegou até nós (programa de afiliados), 60 dias

4,6

País e idioma

Cada país tem o seu próprio site, com os preços e o IVA desse país.

Ver

Caddy, HSTS e security.txt

Módulo 7: Domínio, servidor web e https · Tempo de leitura: 12 minutos

Objetivo de aprendizagem: Depois desta lição, será capaz de utilizar o Caddy como servidor web simples com https automático, definir o HSTS e os principais cabeçalhos de segurança (no Caddy e no nginx) sem tornar o seu site inacessível, e publicar um security.txt válido.

Conceitos-chave: Caddy, Caddyfile, https automático, reverse_proxy, file_server, header, HSTS (Strict-Transport-Security), max-age, includeSubDomains, preload, X-Content-Type-Options, frame-ancestors, Referrer-Policy, security.txt, Contact, Expires, /.well-known/

Caddy: https sem preocupações

Nas lições 7.2 e 7.3 criou um site com https utilizando o nginx e o certbot. São dois programas, alguns ficheiros e um temporizador. O Caddy faz tudo num só: é um servidor web com um cliente ACME integrado. Se um nome constar da configuração, apontar para o servidor e as portas 80 e 443 estiverem acessíveis, o Caddy obtém ele próprio um certificado, renova-o a tempo e redireciona http para https.

O Caddy está disponível no repositório de pacotes do Debian e do Ubuntu (numa versão um pouco mais antiga); os criadores oferecem também um repositório apt próprio com a versão mais recente, com uma chave própria e Signed-By, tal como na lição 4.1. No módulo 9, o Caddy é executado como contentor para os seus serviços Docker (lição 9.4). Aqui, utiliza-o como um serviço normal.

anna@web1:~$ sudo apt install caddy
anna@web1:~$ systemctl status caddy

Utilize o nginx ou o Caddy nas portas 80 e 443, não ambos: apenas um programa pode escutar numa porta.

O Caddyfile

A configuração encontra-se em /etc/caddy/Caddyfile. Um site estático e uma aplicação por detrás de um proxy inverso:

example.com, www.example.com {
	root * /var/www/example.com
	file_server
	encode zstd gzip
}

app.example.com {
	reverse_proxy 127.0.0.1:3000
}

É tudo. O Caddy escuta automaticamente em IPv4 e IPv6, pede certificados para os três nomes, redireciona http para https e, com reverse_proxy, transmite automaticamente os cabeçalhos X-Forwarded-For e X-Forwarded-Proto (o que no nginx fazia manualmente, lição 7.2).

Testar e recarregar faz-se como no nginx:

anna@web1:~$ caddy validate --config /etc/caddy/Caddyfile
Valid configuration
anna@web1:~$ sudo systemctl reload caddy
anna@web1:~$ sudo journalctl -u caddy -f

No journal pode ver a obtenção dos certificados. Se algo correr mal, o motivo aparece aí: normalmente o mesmo que no certbot (porta 80 fechada, nome a apontar para outro sítio, IPv6 com problemas; lição 7.3).

HSTS: fazer o navegador lembrar-se de que é https

O redirecionamento de http para https tem um momento fraco: o primeiríssimo pedido por http ainda segue sem cifra. Alguém na mesma rede pode intercetá-lo e manter o visitante em http. O HSTS (HTTP Strict Transport Security, RFC 6797) resolve isso. O seu site envia, por https, este cabeçalho:

Strict-Transport-Security: max-age=31536000

O navegador memoriza então, durante um ano (31.536.000 segundos), que este nome só pode ser utilizado por https. Se o visitante escrever mais tarde http://, o próprio navegador converte o endereço para https, antes de qualquer dado passar pela rede. Um cabeçalho HSTS recebido por http é ignorado pelo navegador; só conta por https.

Há um reverso. Se um navegador tiver memorizado o HSTS e encontrar um erro de certificado (expirado, nome errado), o visitante não recebe nenhum botão para continuar mesmo assim. O seu site fica então inacessível para esses visitantes até o certificado estar correto. Por isso:

  1. Ative o HSTS apenas quando o https funcionar em todo o lado e a renovação for automática (lição 7.3).
  2. Comece com um max-age curto, por exemplo um dia (86400), e aumente gradualmente até um ano.
  3. Tenha cuidado com includeSubDomains: aplica-se a todos os subdomínios, incluindo um subdomínio antigo com um equipamento ou serviço sem certificado válido.
  4. preload pede a inclusão numa lista integrada nos navegadores (hstspreload.org). Para isso exigem, entre outros requisitos, um max-age de pelo menos um ano, includeSubDomains e https em todos os subdomínios. Sair da lista demora meses. Faça-o apenas se tiver a certeza de que todo o domínio fica definitivamente em https.

Os outros cabeçalhos de segurança

Além do HSTS, há alguns cabeçalhos que, com pouco esforço, ajudam muito:

CabeçalhoContra o quêValor inicial
X-Content-Type-Optionso navegador tenta adivinhar o tipo de um ficheiro, pelo que uma "imagem" carregada pode ser executada como scriptnosniff
Content-Security-Policy: frame-ancestors (ou o mais antigo X-Frame-Options)clickjacking: outro site carrega a sua página de forma invisível numa frameframe-ancestors 'self' (ou X-Frame-Options: SAMEORIGIN)
Referrer-Policyo endereço da sua página (com termos de pesquisa ou números de encomenda) é divulgado a outros sitesstrict-origin-when-cross-origin

Um Content-Security-Policy completo (que scripts e estilos podem ser carregados) é feito à medida de cada site e está fora do âmbito deste curso; comece apenas com frame-ancestors.

No Caddy, define-os com a diretiva header no bloco de um site:

example.com, www.example.com {
	root * /var/www/example.com
	file_server
	header {
		Strict-Transport-Security "max-age=31536000"
		X-Content-Type-Options "nosniff"
		Content-Security-Policy "frame-ancestors 'self'"
		Referrer-Policy "strict-origin-when-cross-origin"
		-Server
	}
}

O Caddy não define o HSTS nem estes cabeçalhos por si só; tem mesmo de os acrescentar. -Server remove o cabeçalho Server. Na lição 9.4, define num bloco do mesmo tipo o seu próprio cabeçalho X-Weboke-Cursus para o exercício.

No nginx, coloca as mesmas regras no bloco server da porta 443:

add_header Strict-Transport-Security "max-age=31536000" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Content-Security-Policy "frame-ancestors 'self'" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;

always garante que também são enviados com as páginas de erro. Atenção a uma armadilha conhecida do nginx: se um bloco location tiver ele próprio um add_header, as regras add_header do bloco server deixam de se aplicar a essa location. Por isso, verifique sempre o resultado:

anna@laptop:~$ curl -sI https://example.com | grep -iE 'strict|nosniff|frame|referrer'
strict-transport-security: max-age=31536000
x-content-type-options: nosniff
content-security-policy: frame-ancestors 'self'
referrer-policy: strict-origin-when-cross-origin

security.txt: assim alguém lhe pode comunicar uma falha

Imagine que alguém encontra uma falha no seu servidor, como uma pasta aberta ou um serviço desatualizado. Como sabe essa pessoa quem deve avisar? É para isso que serve o security.txt (RFC 9116): um pequeno ficheiro de texto num local fixo, https://<jouwdomein>/.well-known/security.txt.

Contact: mailto:security@example.com
Expires: 2027-10-31T23:00:00Z
Preferred-Languages: nl, en
Canonical: https://example.com/.well-known/security.txt

As regras:

  • Contact é obrigatório: um endereço mailto:, https:// ou tel: para onde vão as comunicações. Utilize um endereço que alguém leia realmente.
  • Expires é obrigatório e só pode aparecer uma vez: a data a partir da qual o ficheiro é considerado desatualizado. O RFC recomenda uma data no prazo de um ano. Assim, não fica publicado um ficheiro com um endereço há muito esquecido. Anote na sua agenda quando o deve renovar.
  • Preferred-Languages, Canonical e Policy (uma ligação para a sua política de comunicações) são opcionais.
  • O ficheiro tem de ser servido por https, como texto simples (text/plain, UTF-8). O local antigo /security.txt pode existir como extra, mas /.well-known/ tem prioridade.

Colocá-lo num site estático:

anna@web1:~$ sudo mkdir -p /var/www/example.com/.well-known
anna@web1:~$ sudoedit /var/www/example.com/.well-known/security.txt
anna@laptop:~$ curl -sI https://example.com/.well-known/security.txt | grep -i content-type
content-type: text/plain; charset=utf-8

Se utilizar no nginx a regra de recurso location ~ /\. { deny all; } da lição 7.2, coloque antes dela uma exceção: location ^~ /.well-known/ { }. Para uma aplicação por detrás de um proxy inverso, pode no Caddy fazer o caminho /.well-known/security.txt apontar para um ficheiro com um bloco handle e file_server.

Um erro frequente: um site ou aplicação que responde a qualquer caminho desconhecido com a página inicial e o estado 200. Nesse caso, o security.txt "existe", mas é HTML. Verifique, portanto, também o conteúdo.

No AlmaLinux e no Rocky Linux

Aí, o Caddy vem do repositório dos criadores ou do EPEL/COPR. Tal como no nginx, o SELinux tem de permitir um proxy inverso (setsebool -P httpd_can_network_connect 1). O Caddyfile e os cabeçalhos são iguais.

Resumo

  • O Caddy trata sozinho dos certificados, da renovação e do redirecionamento para https; reverse_proxy transmite automaticamente os cabeçalhos corretos.
  • O HSTS faz os navegadores memorizarem que o seu site é apenas https; aumente o max-age gradualmente, tenha cuidado com includeSubDomains e muito cuidado com preload.
  • Defina também X-Content-Type-Options: nosniff, frame-ancestors 'self' e um Referrer-Policy; no Caddy com header, no nginx com add_header ... always, e verifique com curl -I.
  • O security.txt fica em /.well-known/security.txt, por https, como texto simples, com Contact obrigatório e um único Expires no prazo de um ano.

Questionário

1. Porque é que o HSTS ajuda, se já redireciona http para https?



2. Define o HSTS com max-age=31536000; includeSubDomains. Uma semana depois, verifica-se que camera.example.com não tem um certificado válido. O que notam os visitantes que já visitaram o seu site?



3. Que campos são obrigatórios num security.txt?



4. No nginx, colocou os cabeçalhos de segurança no bloco server, mas não são enviados para /api/. No bloco location /api/ existe um add_header próprio. O que se passa?



5. O que deve fazer antes de acrescentar preload ao seu cabeçalho HSTS?



Exercício

Exercício Z7.4: HSTS, cabeçalhos e security.txt. Defina para o seu site o HSTS (pelo menos 180 dias, depois de o https funcionar bem durante algum tempo), X-Content-Type-Options: nosniff e frame-ancestors 'self' (ou X-Frame-Options), e publique um security.txt com Contact e um Expires no prazo de um ano. Introduza o nome do seu servidor. O programa obtém https://<hostnaam>/ e verifica os cabeçalhos, e obtém https://<hostnaam>/.well-known/security.txt e verifica os campos. Não guarda nada além do resultado e da data de Expires.

Exercício Z7.4: HSTS, cabeçalhos e security.txt

Apenas para formandos inscritos. Obtemos https://<naam>/ e /.well-known/security.txt (apenas GET).




O que preenche e o que encontramos não ficam guardados. O seu navegador memoriza as suas respostas e se concluiu o exercício com sucesso. Se tiver sessão iniciada, guardamos apenas que concluiu o exercício (quase) com sucesso em Os meus cursos; aí também o pode eliminar.

Para saber mais

Um momento…

Configurar os seus domínios

Para cada domínio, defina os servidores de nomes, a ligação ao seu alojamento e quem fica como titular.

A carregar os seus domínios…