Específicos · Infraestrutura em TI
Linux: FHS, permissões (rwx, octal, chmod/chown), processos, systemd, cron, pipes
Tudo é arquivo, e todo arquivo tem dono, grupo e três permissões — mas o que decide o item quase nunca é o conceito, e sim uma letra: a opção do comando, o bit da permissão, o nome do diretório.
Altíssima77 itens no tópico
A ideia que organiza o assunto
O Unix nasceu de uma máquina cara com muita gente usando ao mesmo tempo, e
respondeu a isso com uma decisão que organiza tudo o que vem depois: tudo é
arquivo. Disco, terminal, placa de rede, e até o estado dos processos em
/proc — tudo aparece como um caminho que se abre, lê e escreve com as mesmas
chamadas de sistema.
Dessa decisão sai o resto por dedução. Se tudo é arquivo, basta um modelo de
proteção: cada arquivo tem um dono (UID), um grupo (GID) e três ternos rwx, e
o kernel confere isso a cada abertura. Se tudo é arquivo, a configuração do
sistema é texto, guardada num lugar previsível — daí o FHS, que é norma
publicada e não capricho de distribuição. E se tudo é arquivo, programas
pequenos podem ser encadeados pela saída e pela entrada padrão, que é o pipe.
Para a prova há uma segunda metade dessa ideia, e é a que realmente decide
itens: o tópico quase nunca erra o conceito — ele erra a menor unidade da
frase. A finalidade descrita está certa, e o que está trocado é a opção do
comando (tail sem -f), o bit (w no arquivo em vez de no diretório), o
diretório (/usr no lugar de /home) ou o verbo (reload no lugar de
restart). Leia o item de trás para a frente: primeiro a letra, depois a
afirmação.
Por que se usa (e o que custa)
Ganha-se uniformidade e composição. O mesmo grep vasculha um log e a saída
de um comando; o mesmo script de becape que salva /etc funciona em Red Hat e
em Ubuntu; a permissão é verificada pelo kernel, e não pela aplicação, de modo
que nenhum programa consegue esquecer de conferi-la.
Paga-se na pobreza do modelo. Nove bits não expressam “este usuário e mais
aquele”, e todo o remendo — SUID, SGID, sticky, ACL, SELinux — é justamente a
parte cheia de exceção que a banca explora. Paga-se também em vocabulário: o
systemd trouxe paralelismo e dependências explícitas ao custo de um jogo novo
de termos (unit, target, socket) que convive na prova com o jogo antigo
dos runlevels.
A formulação honesta: o Linux não esconde a complexidade de um sistema multiusuário, ele a expõe em arquivos de texto e em opções de uma letra. É por isso que o tópico é tão produtivo para a CEBRASPE.
Como funciona
A hierarquia (FHS). Há uma raiz só, /, e todo volume novo é enxertado nela
pelo mount — não existem letras de unidade. Cada diretório tem finalidade
definida em norma, e é isso que faz um administrador achar o que procura em
qualquer distribuição.
Permissões. O ls -l mostra dez caracteres: o primeiro é o tipo (-
arquivo, d diretório, l link simbólico) e os nove seguintes são dono, grupo
e outros, nessa ordem. O valor octal soma r=4, w=2 e x=1 por classe. O
chmod aceita as duas formas, octal (chmod 640 arq) e simbólica
(chmod u+x, chmod go-w); o chown muda dono e grupo (chown root:apache arq), e mudar o dono é privilégio do root. O umask não define permissão:
subtrai da máxima de criação, 666 para arquivos e 777 para diretórios — com
umask 022, arquivo nasce 644 e diretório nasce 755. Como é herdado do shell,
escrevê-lo no .bashrc de alguém muda o padrão só daquele usuário.
Em diretório os bits mudam de sentido, e é a sutileza mais cobrada: r
lista os nomes, w cria e apaga entradas, x atravessa o diretório. Daí a
consequência incômoda: apagar um arquivo depende da permissão de escrita no
diretório, não no arquivo — e é por isso que o sticky bit precisa existir.
Processos. Todo processo tem PID, pai (PPID) e uma identidade efetiva (UID e
GID) que é o que o kernel confronta com os bits do arquivo. Um processo nasce de
um fork do pai e troca de programa com exec; o PID 1 é o systemd, que adota
os órfãos. ps aux dá a visão instantânea, top a contínua, /proc/<pid> o
detalhe. kill envia SIGTERM (15), que pode ser tratado; kill -9 envia
SIGKILL, que não pode. Prioridade se ajusta com nice na largada e com
renice depois. comando & joga para segundo plano, nohup desliga do terminal.
systemd. Ele gerencia units, cada uma um arquivo de texto cujo sufixo diz
o tipo: .service, .socket, .timer, .mount, .target (que substituiu os
runlevels). Os arquivos da distribuição ficam em /usr/lib/systemd/system e
são sobrepostos pelos de /etc/systemd/system. O log central é o journalctl,
convivendo com o rsyslog e seus arquivos em /var/log.
cron. O usuário edita a própria tabela com crontab -e, lista com -l e
apaga com -r — sem confirmação. A linha tem cinco campos de tempo e o comando;
em /etc/crontab e /etc/cron.d há um sexto campo, o usuário, antes do
comando. Operadores: * todos, , lista, - intervalo, / passo. Então
*/30 * * * * roda a cada 30 minutos e 0 3 * * 1 às 3h de segunda. O script
agendado precisa de chmod +x e de caminhos absolutos, porque o ambiente do
cron é mínimo.
Pipes e redirecionamento. Todo processo nasce com entrada padrão (0), saída
padrão (1) e erro padrão (2). O shell reposiciona esses descritores antes de
executar: > trunca, >> acrescenta, < alimenta, 2> desvia só o erro e
2>&1 funde o erro na saída. A barra vertical liga a saída de um processo à
entrada do seguinte através de um canal em memória mantido pelo kernel — e é
isso, e não sinal, que transporta um fluxo de bytes. mkfifo cria um pipe
nomeado, visível no sistema de arquivos, para processos sem parentesco.
O que decide os itens
Diretórios do FHS — trocar um pelo outro é item pronto:
| diretório | é | não é |
|---|---|---|
/etc | configuração do sistema, em texto | binários, nem logs |
/var | dados que variam: /var/log, /var/spool, /var/lib | configuração |
/home | arquivos pessoais dos usuários | do sistema |
/root | diretório pessoal do superusuário | a raiz /, nem onde ficam programas |
/usr | programas, bibliotecas e dados do sistema | área de usuário |
/bin, /sbin | binários essenciais; /sbin os de administração | de terceiros |
/opt, /usr/local | software de terceiros e instalado à mão | do pacote base |
/boot | vmlinuz e initrd/initramfs | configuração de serviço |
/dev | arquivos de dispositivo | diretório comum |
/proc, /sys | sistemas de arquivos virtuais do kernel | arquivos em disco |
/tmp | temporários, com sticky bit | persistente |
O que cada bit faz — depende de onde ele está:
| bit | em arquivo | em diretório |
|---|---|---|
r | ler o conteúdo | listar os nomes |
w | alterar o conteúdo | criar e apagar entradas |
x | executar | atravessar para chegar ao conteúdo |
Os três bits especiais:
| bit | octal | onde vale | efeito | no ls |
|---|---|---|---|---|
| SUID | 4000 | executável | roda com o UID do dono do arquivo | s no x do dono |
| SGID | 2000 | executável e diretório | roda com o GID do arquivo; em diretório, o arquivo criado herda o grupo | s no x do grupo |
| sticky | 1000 | diretório | só o dono do arquivo (ou o root) apaga, mesmo com o diretório 777 | t no x de outros |
Pares de comando que a banca troca:
| par | quem faz o quê |
|---|---|
nice × renice | lança com prioridade × altera a de processo já em execução |
du × df | tamanho de arquivos e diretórios × ocupação do sistema de arquivos |
getfacl × setfacl | consulta ACL × define ACL |
find × which | varre a árvore por critério × acha o caminho do executável no PATH |
grep × find | procura dentro dos arquivos × procura os arquivos |
tail × tail -f | dez últimas linhas e sai × acompanha em tempo real |
> × >> | trunca × acrescenta ao final |
su × sudo | pede a senha do destino × pede a sua e consulta o sudoers |
systemctl start × enable | sobe agora × faz subir no próximo boot |
systemctl restart × reload | derruba e sobe × só relê a configuração |
crontab -e × -r | edita × remove tudo, sem perguntar |
Estados de processo:
| estado | letra | significa |
|---|---|---|
| executando / pronto | R | na CPU ou na fila por ela |
| dormindo | S / D | bloqueado à espera de recurso (E/S, rede) |
| parado | T | suspenso por sinal (SIGSTOP, Ctrl+Z) — não é espera por recurso |
| zumbi | Z | já terminou; o pai ainda não leu o código de saída |
Modos do SELinux — enforcing nega e registra; permissive só registra;
disabled nem avalia. Enforcing é o padrão.
Camadas que não se confundem — o shell interpreta comandos, o kernel
gerencia recursos; o nftables programa o netfilter (filtro de pacotes), e o
NFS é compartilhamento de arquivos; o firewalld é a administração, o netfilter
é quem filtra; o tar agrupa, o gzip comprime; o pipe transporta
bytes, o sinal apenas interrompe.
Números que caem
r · w · x | 4 · 2 · 1 |
| SUID · SGID · sticky | 4000 · 2000 · 1000 (quarto dígito octal) |
755 · 644 · 600 · 777 | rwxr-xr-x · rw-r--r-- · rw------- · rwxrwxrwx |
640 · 664 | rw-r----- · rw-rw-r-- |
| máximo na criação: arquivo · diretório | 666 · 777 |
umask 022 produz | arquivo 644, diretório 755 |
| UID do root | 0 |
| UIDs de sistema × de usuário comum | < 1000 × ≥ 1000 |
| campos do cron | 5 (minuto 0-59, hora 0-23, dia 1-31, mês 1-12, semana 0-7) |
| domingo no cron | 0 e 7 |
/etc/crontab e /etc/cron.d | 6 campos — o extra é o usuário |
SIGHUP · SIGKILL · SIGTERM | 1 · 9 · 15 |
| faixa de niceness | −20 (mais prioritário) a +19 |
head e tail sem opção | 10 linhas |
| runlevel 3 · 5 | multi-user.target · graphical.target |
lvcreate -L sem sufixo | o valor é lido em megabytes |
Como a CEBRASPE derruba você aqui
Uma palavra errada na linha de comando — 59% dos itens errados. É a
assinatura do tópico, e o rótulo não ajuda: o que se repete é uma opção, um
verbo ou um nome de binário trocado numa frase que, no resto, está correta.
“tail /var/log/meu_arquivo.log” apresentado como leitura contínua — sem -f ele
imprime dez linhas e termina. “systemctl reload nfs-server.service” apresentado
como reinício — reload manda reler a configuração sem derrubar o processo;
reiniciar é restart. “com o uso do comando nice” para mudar a prioridade de um
processo já em execução — o nice só lança processo novo, quem mexe em PID
existente é o renice. “df -h /home/usuario/” para justificar uma saída que
lista o tamanho de cada arquivo — aquilo é du. Leia a linha de comando antes
da justificativa: diga o que ela faz de fato e só então compare com o que o item
afirma que ela faz.
A opção ou o subcomando não existe. Mesma família, e mais barato ainda de
escrever: “yum find pacote1” (a busca é yum search), “timedatectl list —zone”
(o subcomando é list-timezones, palavra única), “systemctl list-units —type
target —anyway” (--anyway não existe — quem inclui as unidades inativas é
--all — e --type target lista alvos, não serviços). Se você nunca digitou
aquela opção, ela é a suspeita principal; subcomando partido em duas palavras é
quase sempre invenção.
O mecanismo descrito certo, assinado com o nome do vizinho. Fora da linha de
comando o formato é o mesmo. “por interrupções de software”, dito de um canal em
que um processo escreve um fluxo de bytes e o outro lê — isso é pipe; sinal não
transporta dado. O “carregador de boot de primeiro estágio” que lê o sistema de
arquivos, encontra o vmlinuz e o descompacta — o primeiro estágio cabe num
setor e só sabe chamar o segundo. “as tabelas internas do sistema de arquivos
NFS” para explicar o nftables — as tabelas são do netfilter, e a semelhança
das siglas é todo o disfarce. “o operador > acrescenta informações ao final de
um arquivo existente” — > trunca; quem acrescenta é >>. Batize a descrição
antes de olhar o nome: leia o mecanismo, diga qual é, e só depois confira a
etiqueta que o item colou nele.
Inversão — um em cada cinco itens errados. Dois dos seis são o mesmo par: “as
regras do SELinux são desativadas” e “impede o log das ações realizadas no
sistema”, ambos ditos do modo enforcing — enforcing bloqueia e registra,
permissive só registra, disabled não faz nem um nem outro. “o primeiro localiza o
caminho (path) onde o comando está instalado”, dito do find — quem percorre o
PATH é o which. “não sendo permitido que esse arquivo contenha diretórios com
outros arquivos”, dito do tar — empacotar uma árvore inteira é exatamente o que
ele faz. E “O Linux impede que dois usuários diferentes tenham o mesmo UID” — não
impede, e o useradd -o aceita isso explicitamente. Monte o par antes de julgar,
e desconfie de todo verbo de proibição: o Linux quase nunca impede, ele permite e
responsabiliza.
Generalização — 9%, e sempre desmentida por uma opção. “não é necessária
nenhuma configuração” depois de o kernel reconhecer a placa sem fio —
reconhecer o hardware não informa SSID nem senha. “cada usuário consegue ter
apenas um processo ativo por vez”, num sistema multitarefa em que um único login
já sustenta o shell e tudo o que ele dispara. “Qualquer leitura feita em arquivos
no GNU/Linux provoca uma operação de escrita” — com relatime, que é o padrão, o
atime só é regravado em casos específicos; com noatime, nunca. Achado o
absoluto, procure a opção que o desmente.
O que sobra, e em que proporção. Atribuição errada de componente aparece duas
vezes: “O kernel do sistema operacional Linux tem a função de interpretar os
comandos” — interpretar a linha, expandir curinga e montar pipe é trabalho do
shell, que é processo comum de espaço de usuário. Permissão esticada para a
classe errada, uma vez: de um arquivo -rw-rw-r--, “todos os usuários do
computador poderão ler e escrever nesse arquivo” — os outros só leem; converta
para octal e compare classe por classe. E número alterado, também uma vez só, num
laço de shell cuja saída bastava simular mentalmente. Vale registrar o que a
medição não mostra: este tópico não derruba por número. Derruba por uma letra
na opção.
Erros clássicos
Somar errado o octal. 4, 2, 1, por classe, na ordem dono, grupo,
outros. E o quarto dígito, quando aparece, é dos bits especiais: 4755 não é
permissão maluca, é 755 com SUID.
Achar que o w do arquivo é o que permite apagá-lo. Apagar altera a entrada
no diretório; depende do w do diretório. É exatamente por isso que o
sticky bit existe em /tmp.
Confundir enable com start. Habilitado e não iniciado não está no ar;
iniciado e não habilitado morre no próximo boot.
Tratar /usr como área de usuário e /root como raiz. /usr é Unix System
Resources; os arquivos pessoais estão em /home; /root é a casa do
superusuário, não /.
Chamar sinal de pipe. Sinal interrompe e não transporta dados; pipe transporta um fluxo de bytes e não interrompe.
Esquecer que “parado” é suspenso. T foi parado por sinal; quem espera
recurso está dormindo em S ou D; e zumbi não espera nada, já terminou.
Supor que o LVM protege os dados. Ele redimensiona, move e tira snapshot — não dá redundância. Perder um volume físico compromete os volumes lógicos que passavam por ele, e a recuperação depende dos metadados e do becape.
LidoPraticado