Home Comunidade Eventos YouTube Networks Desafios // produtos Academy News CTI | CVE Contato

02 - Localização (-etc-systemd-system, -usr-lib-systemd-system)

video explicativo
Video explicativoEspaco reservado para o video desta anotação — adicione video: https://youtu.be/... no frontmatter da nota.

A arquitetura do systemd aboliu o modelo monolítico e caótico do SysVinit, onde todos os scripts de controle residiam em um único diretório (/etc/init.d/), misturando indiscriminadamente o código original do fornecedor (vendor) com as customizações do administrador local. Em seu lugar, o systemd introduziu um Caminho de Resolução de Unidades (Unit Load Path) rigorosamente estratificado.

Esta estratificação baseia-se no princípio de Statelessness (ausência de estado local por padrão) e na imutabilidade do código do fornecedor. O PID 1 não busca arquivos de unidade de forma aleatória; ele obedece a uma hierarquia de precedência determinística baseada na origem do arquivo. Quando uma unidade é referenciada (por exemplo, nginx.service), o analisador (parser) do systemd vasculha diretórios específicos em uma ordem estrita. O primeiro arquivo encontrado interrompe a busca e dita o estado do objeto na memória.

Esta pasta disseca os três domínios principais de localização de unidades de sistema, os mecanismos de injeção parcial (Drop-ins) e a aniquilação estrutural (Masking).


1. O Domínio do Fornecedor (/usr/lib/systemd/system/)

O diretório /usr/lib/systemd/system/ (ou /lib/systemd/system/ em distribuições que ainda não completaram o UsrMerge) é o território exclusivo dos desenvolvedores de software e dos empacotadores da distribuição (RPM/DEB).

  • Imutabilidade Semântica: Os arquivos contidos neste diretório representam as configurações padrão, testadas e homologadas (upstream defaults). Sob nenhuma circunstância um administrador de sistemas deve editar arquivos neste diretório.
  • Volatilidade de Atualização: Qualquer alteração manual feita aqui será impiedosamente aniquilada pelo gerenciador de pacotes (apt, dnf, pacman) durante a próxima atualização do software. Quando um pacote é atualizado, o arquivo .service antigo em /usr/lib/ é sobrescrito pelo novo.
  • Baixa Precedência: Na hierarquia de busca do PID 1, este diretório possui a menor prioridade absoluta. Ele atua como o "estado de fallback". Se nenhuma customização local existir, o systemd carregará a unidade a partir daqui.

2. O Domínio Efêmero (/run/systemd/system/)

O diretório /run/ é montado pelo kernel como um sistema de arquivos em memória RAM (tmpfs). Consequentemente, o diretório /run/systemd/system/ atua como o domínio de unidades transientes, cujo ciclo de vida está estritamente atrelado ao uptime atual da máquina.

  • Precedência Intermediária: Arquivos alocados neste diretório sobrepõem as configurações do fornecedor (/usr/lib/), mas são subordinados às configurações estáticas do administrador (/etc/).
  • Geração Dinâmica (Generators): Durante os primeiros milissegundos do boot, o systemd executa pequenos binários chamados Generators (localizados em /usr/lib/systemd/system-generators/). Um exemplo clássico é o systemd-fstab-generator, que lê o arquivo legado /etc/fstab e escreve as unidades .mount e .swap dinamicamente dentro de /run/systemd/system/. Isso permite que o systemd gerencie partições legadas usando sua lógica de grafos moderna, sem tocar no disco físico.
  • Unidades Transientes de API: Quando o administrador executa comandos como systemd-run (para agendar um job temporário ou rodar um comando em um cgroup isolado), o systemd não escreve no disco. Ele cria uma unidade transiente .service ou .timer em /run/systemd/system/. Ao término da execução, ou após um reboot, esses arquivos evaporam sem deixar resíduos de configuração.

3. O Domínio do Administrador (/etc/systemd/system/)

O diretório /etc/systemd/system/ é o santuário do administrador do sistema (SysAdmin). Ele reflete o estado customizado e persistente da infraestrutura.

  • Precedência Absoluta: O parser do PID 1 verifica este diretório primeiro. Se o arquivo apache2.service existir simultaneamente em /usr/lib/ e em /etc/, o arquivo em /etc/ será carregado na íntegra, e o arquivo do fornecedor será sumariamente ignorado. Este mecanismo é conhecido como Full Override (Sobreposição Completa).
  • Unidades Customizadas: É o local correto para a criação de daemons corporativos proprietários ou scripts locais que não vieram de um pacote oficial da distribuição.
  • Ancoragem de Estado (Enablement): A função mais crítica deste diretório não é apenas hospedar arquivos, mas hospedar Links Simbólicos de Dependência Inversa. Quando o administrador executa systemctl enable nginx.service, o systemd lê a seção [Install] (especificamente WantedBy=multi-user.target) e cria um symlink em /etc/systemd/system/multi-user.target.wants/nginx.service apontando para o binário em /usr/lib/. É a mera existência deste symlink no diretório /etc/ que instrui o Grafo de Inicialização a puxar o serviço do Nginx durante o boot.

4. O Paradigma da Composição: Diretórios Drop-in (*.d/)

A técnica de Full Override (copiar um arquivo inteiro de /usr/lib/ para /etc/ e alterá-lo) introduz uma vulnerabilidade silenciosa de manutenção (Configuration Drift). Se o fornecedor atualizar o software e precisar adicionar uma nova variável de ambiente crítica ou alterar o comando de inicialização no arquivo padrão, o administrador nunca receberá essa atualização, pois seu arquivo estático em /etc/ sobreporá completamente o arquivo novo do fornecedor.

Para resolver este conflito arquitetural, o systemd introduziu a sobreposição parcial através de Diretórios Drop-in.

Se o administrador deseja apenas alterar a política de reinicialização de um serviço (ex: mudar Restart=on-failure para Restart=always), ele não deve copiar a unidade. Em vez disso, ele invoca o utilitário systemctl edit <unidade>.service.
Isso gera a seguinte estrutura em disco:
/etc/systemd/system/<unidade>.service.d/override.conf

A Mecânica de Merge Sintático

Quando o PID 1 resolve a unidade na memória, ele opera em duas fases:

  1. Ele lê o arquivo base, tipicamente de /usr/lib/systemd/system/.
  2. Ele busca por qualquer diretório nomeado com o sufixo .d/ correspondente ao nome da unidade.
  3. Ele aplica os arquivos .conf contidos nesse diretório (em ordem alfabética) como um patch sobre o objeto em memória.

O Efeito de Limpeza de Lista (List Clearing)

Uma idiossincrasia técnica vital dos Drop-ins ocorre ao manipular diretivas baseadas em listas, como ExecStart=.
Se o arquivo do fornecedor declara ExecStart=/usr/bin/daemon -a, e o administrador deseja alterar a flag para -b via Drop-in, simplesmente declarar um novo ExecStart= causará um erro sintático (pois unidades .service do tipo simples não aceitam múltiplos comandos de início simultâneos).
A arquitetura exige a redefinição de lista através de uma atribuição vazia. O arquivo override.conf deve conter estritamente:

[Service]
ExecStart=
ExecStart=/usr/bin/daemon -b

O primeiro ExecStart= instrui o compilador do systemd a esvaziar o vetor de comandos previamente carregado da unidade do fornecedor, permitindo que a linha subsequente injete o comando final com sucesso.


5. Aniquilação Estrutural: O Mascaramento (Masking)

Em ecossistemas complexos de dependências cruzadas (Grafo Acíclico Dirigido), simplesmente desabilitar um serviço (systemctl disable) não garante que ele não será executado. Se o serviço A estiver desabilitado (nenhum symlink no alvo de boot), mas o serviço B declarar Requires=A, o início do serviço B forçará o systemd a buscar e iniciar o serviço A, ignorando a vontade de "desabilitação" do administrador.

Para banir permanentemente um binário da execução sob qualquer circunstância, o systemd implementa a técnica de Masking (Mascaramento).

Ao executar o comando systemctl mask <unidade>.service, o sistema não edita arquivos internos. Ele utiliza o princípio de precedência absoluta do diretório /etc/ criando um link simbólico venenoso:
ln -s /dev/null /etc/systemd/system/<unidade>.service

Quando o parser do PID 1 tenta carregar a unidade (mesmo que requisitada por Requires= de outra unidade vital), ele atinge /etc/systemd/system/, encontra o arquivo e tenta abri-lo. Como o arquivo aponta para o buraco negro estrutural do kernel (/dev/null), a leitura retorna um EOF (End-of-File) instantâneo sem dados.
O systemd interpreta intencionalmente um arquivo de unidade vazio apontando para /dev/null como um estado de masked. A tentativa de carga falha com o código de erro arquitetural Unit is masked. A aniquilação é total, derrotando qualquer gatilho de socket, dependência forte de unidade ou comando manual de ativação.


6. O Escopo de Usuário (systemd --user)

Embora o foco principal seja a orquestração do sistema (systemd --system), a arquitetura isola completamente os processos de daemons dos processos atrelados a usuários humanos.

Quando um usuário realiza um login via PAM, o PID 1 gera uma instância secundária do systemd executando sob os privilégios daquele usuário (PID não-root, gerenciado pelo user@<UID>.service). Esta instância de usuário obedece a um caminho de carga de unidades inteiramente distinto, replicando a mesma hierarquia de precedência do sistema, mas operando sobre diretórios focados no utilizador:

  1. Fornecedor (Usuário): /usr/lib/systemd/user/ (Configurações globais padrão de software gráfico, como pulseaudio.socket ou dbus.service).
  2. Administrador Global (Usuário): /etc/systemd/user/ (Políticas aplicadas pelo SysAdmin a todas as sessões de usuário).
  3. Local do Usuário (Precedência Absoluta): ~/.config/systemd/user/ (Diretório Home restrito ao utilizador específico).

Esta separação estrutural permite que desenvolvedores criem unidades .service independentes em seus diretórios Home e iniciem daemons pessoais (systemctl --user start app) sem necessidade de interagir com as permissões restritivas de /etc/ ou requerer intervenção direta do superusuário.