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

Serviços próprios e temporizadores

Módulo 6: Serviços e registos · Tempo de leitura: 11 minutos

Objetivo de aprendizagem: Após esta lição, saberá executar um programa próprio como serviço systemd com um utilizador próprio e algumas opções de segurança, e agendar tarefas com um temporizador systemd ou com cron.

Conceitos-chave: ficheiro de unidade, [Unit], [Service], [Install], ExecStart, User=, WorkingDirectory, EnvironmentFile, Restart=, WantedBy, NoNewPrivileges, ProtectSystem, ProtectHome, PrivateTmp, systemd-analyze security, temporizador (timer), OnCalendar, Persistent, crontab

Porque não simplesmente "nohup" ou "screen"?

Quem instala um programa próprio num servidor (uma pequena aplicação web, um bot, um script que faz algo todas as noites) começa muitas vezes por iniciá-lo à mão: node server.js &, ou numa sessão screen. Isso funciona até terminar a sessão, reiniciar o servidor ou o programa falhar. Nessa altura, o programa desaparece e ninguém dá por isso.

Um programa que tem de estar sempre em execução deve ser um serviço systemd. Assim:

  • arranca automaticamente no arranque do sistema;
  • o systemd volta a iniciá-lo se falhar;
  • a saída fica no journal (lição 6.2);
  • é executado com um utilizador à sua escolha, com as permissões que o senhor autorizar.

Um ficheiro de unidade próprio

Suponha que tem uma pequena aplicação Node.js em /opt/factuurapp, que escuta em 127.0.0.1:3000. Mais tarde, o nginx ou o Caddy vão disponibilizá-la para o exterior (módulo 7).

Passo 1: um utilizador próprio sem shell (lição 3.2). A aplicação não precisa de ser root nem de iniciar sessão:

anna@web1:~$ sudo adduser --system --group --home /opt/factuurapp --no-create-home factuurapp
anna@web1:~$ sudo chown -R factuurapp:factuurapp /opt/factuurapp/data

O código propriamente dito pode continuar a pertencer ao root (a aplicação não precisa de se alterar a si própria); só a pasta onde escreve pertence ao utilizador do serviço.

Passo 2: o ficheiro de unidade. As unidades próprias ficam em /etc/systemd/system/:

# /etc/systemd/system/factuurapp.service
[Unit]
Description=Factuurapp (Node.js)
After=network-online.target
Wants=network-online.target

[Service]
User=factuurapp
Group=factuurapp
WorkingDirectory=/opt/factuurapp
EnvironmentFile=/etc/factuurapp/env
ExecStart=/usr/bin/node /opt/factuurapp/server.js
Restart=on-failure
RestartSec=5s

NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true
ReadWritePaths=/opt/factuurapp/data

[Install]
WantedBy=multi-user.target

Os três blocos:

  • [Unit]: descrição e ordem de arranque. After=network-online.target com Wants= garante que o serviço só arranca quando a rede estiver disponível.
  • [Service]: como o programa é executado. ExecStart com o caminho completo (o systemd não usa um caminho de pesquisa como a sua shell). User= e Group= determinam com que utilizador. EnvironmentFile lê definições, como uma palavra-passe de base de dados, a partir de um ficheiro separado, para que não fiquem na unidade.
  • [Install]: o que enable faz. WantedBy=multi-user.target significa: arrancar com um arranque normal do sistema.

Passo 3: segredos à parte, com permissões restritas.

anna@web1:~$ sudo mkdir /etc/factuurapp
anna@web1:~$ sudo install -m 600 -o root -g root /dev/null /etc/factuurapp/env
anna@web1:~$ sudoedit /etc/factuurapp/env

Conteúdo, por exemplo, DATABASE_URL=postgres://factuur:...@127.0.0.1/factuur. O systemd lê o ficheiro como root antes de mudar para o utilizador do serviço, por isso 600 com dono root é suficiente.

Passo 4: carregar, iniciar, verificar.

anna@web1:~$ sudo systemctl daemon-reload
anna@web1:~$ sudo systemctl enable --now factuurapp
anna@web1:~$ systemctl status factuurapp
anna@web1:~$ journalctl -u factuurapp -f

Opções de segurança: pouco esforço, grande diferença

As quatro linhas abaixo de RestartSec no exemplo limitam o que o serviço pode fazer, mesmo que alguém encontre uma falha na sua aplicação:

OpçãoEfeito
NoNewPrivileges=trueo processo e os seus processos filhos nunca podem obter mais permissões (nem através de sudo ou de programas setuid)
ProtectSystem=stricttodo o sistema de ficheiros fica só de leitura para o serviço, exceto o que autorizar com ReadWritePaths=
ProtectHome=true/home, /root e /run/user ficam invisíveis
PrivateTmp=trueum /tmp próprio e vazio, que os outros programas não veem

O systemd pode avaliar a sua unidade:

anna@web1:~$ systemd-analyze security factuurapp
...
→ Overall exposure level for factuurapp.service: 4.9 OK 🙂

Quanto mais baixo o número, melhor. Um serviço sem opções obtém cerca de 9 ("UNSAFE"). Não precisa de chegar a zero: cada opção que acrescenta pode avariar algo de que a aplicação precisa. Acrescente-as uma a uma e teste após cada passo. Se algo deixar de funcionar, a causa está normalmente no journal ("Read-only file system", ou seja, sistema de ficheiros só de leitura; "Permission denied", ou seja, permissão recusada).

Agendar tarefas: temporizadores

Para algo que tem de acontecer a horas fixas (uma cópia de segurança, um script de limpeza, um relatório) precisa de um temporizador (timer). Um temporizador systemd é composto por duas unidades com o mesmo nome: um .service que diz o que deve acontecer e um .timer que diz quando.

# /etc/systemd/system/opruimen.service
[Unit]
Description=Oude exportbestanden opruimen

[Service]
Type=oneshot
User=factuurapp
ExecStart=/usr/bin/find /opt/factuurapp/data/export -type f -mtime +30 -delete
# /etc/systemd/system/opruimen.timer
[Unit]
Description=Dagelijks oude exportbestanden opruimen

[Timer]
OnCalendar=*-*-* 03:15:00
RandomizedDelaySec=10m
Persistent=true

[Install]
WantedBy=timers.target

Type=oneshot significa: o programa é executado e depois termina. OnCalendar é o horário: todos os dias às 03:15. Também pode escrever daily, weekly ou Mon *-*-* 02:00; systemd-analyze calendar "Mon *-*-* 02:00" mostra quando será a próxima execução. Persistent=true é importante: se o servidor estava desligado às 03:15, a tarefa é executada logo após o arranque. RandomizedDelaySec distribui um pouco o momento de início.

A ativação faz-se com o temporizador, não com o serviço:

anna@web1:~$ sudo systemctl daemon-reload
anna@web1:~$ sudo systemctl enable --now opruimen.timer
anna@web1:~$ systemctl list-timers opruimen
NEXT                        LEFT     LAST PASSED UNIT           ACTIVATES
Tue 2026-11-10 03:19:42 CET 15h left -    -      opruimen.timer opruimen.service
anna@web1:~$ sudo systemctl start opruimen.service    # testar agora uma vez manualmente
anna@web1:~$ journalctl -u opruimen.service

E o cron?

O cron é a ferramenta mais antiga e mais simples, e continua a funcionar bem. Uma linha na crontab de um utilizador (crontab -e):

15 3 * * * /usr/local/bin/opruimen.sh

Os cinco campos são minuto, hora, dia do mês, mês e dia da semana. Vantagens e desvantagens lado a lado:

crontemporizador systemd
Configuraçãouma linhadois ficheiros
Execução perdida (servidor desligado)é ignoradacom Persistent=true, é recuperada
Saída e errospor e-mail, se o servidor conseguir enviar e-mail; caso contrário, perdem-seno journal
Opções de segurança, utilizadoratravés do próprio scripttudo o que o systemd oferece (ver acima)
Ver quando foi executadodifícilsystemctl list-timers e o journal

Para um servidor que gere a sério, os temporizadores são a melhor escolha, sobretudo para cópias de segurança (lição 8.2): quer ter a certeza de que foram executadas e do que reportaram. Uma linha cron que falha em silêncio só é notada quando precisar da cópia de segurança.

No AlmaLinux e no Rocky Linux

As unidades e os temporizadores funcionam exatamente da mesma forma. Uma diferença: o SELinux pode bloquear um serviço próprio que leia ou escreva ficheiros num local que o SELinux não espera, ou que escute numa porta invulgar. A mensagem fica em /var/log/audit/audit.log. Não desative o SELinux para resolver o problema; procure a etiqueta ou regra correta (por exemplo, com semanage).

Resumo

  • Um programa que tem de estar sempre em execução deve ser um serviço systemd: arranque automático, reinício após uma falha, registos no journal.
  • Unidades próprias em /etc/systemd/system/, com User= um utilizador próprio sem shell, segredos num EnvironmentFile com permissões 600.
  • NoNewPrivileges, ProtectSystem=strict com ReadWritePaths, ProtectHome e PrivateTmp limitam os danos em caso de falha de segurança; systemd-analyze security avalia a unidade.
  • Um temporizador é um .service mais um .timer com OnCalendar; Persistent=true recupera execuções perdidas. Ative o temporizador, não o serviço.
  • O cron continua a funcionar, mas os temporizadores dão melhores registos e não perdem execuções.

Questionário

1. A sua aplicação é executada como serviço com User=root. Porque é melhor um utilizador próprio?



2. Criou um .service e um .timer. O que ativa com enable --now?



3. O que faz Persistent=true num temporizador?



4. Acrescenta ProtectSystem=strict e, a seguir, a sua aplicação devolve "Read-only file system" ao guardar ficheiros carregados. Qual é a solução correta?



5. Onde coloca a palavra-passe da base de dados do seu serviço próprio?



Exercício

Exercício O6.3: Um serviço próprio com temporizador. Crie no seu servidor um pequeno serviço próprio com um temporizador, por exemplo um script que todas as noites escreve o espaço livre em disco e systemctl --failed num ficheiro ou no journal. Utilize um utilizador próprio, Type=oneshot, pelo menos duas opções de segurança e Persistent=true. Teste com systemctl start, veja a saída no journal e anote a pontuação de systemd-analyze security. Cole o seu .service e o seu .timer e responda às perguntas da lista de verificação.

Exercício O6.3: Um serviço próprio com temporizador

Este exercício faz você mesmo; ninguém o verifica. Assinale o que já fez e marque o exercício como concluído.




As suas marcações e notas ficam apenas neste navegador; não as enviamos para lado nenhum. Se tiver sessão iniciada, guardamos em Os meus cursos apenas que concluiu o exercício.

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…