Lab 8.6 - Parar um Serviço
Objetivos
Ao final deste lab, você será capaz de:
- Identificar um processo que utiliza uma porta específica
- Encontrar o serviço systemd associado a um processo
- Entender por que
killsozinho não é suficiente para parar um serviço - Usar
systemctl stopedisablepara parar definitivamente um serviço - Automatizar a identificação de um serviço via script bash
- Utilizar métodos avançados para diagnosticar serviços
Pré-requisitos
- Ter um site Wiki.js em execução
- Ter nginx instalado
- Ubuntu 24.04 instalado
- Acesso sudo/root
- Terminal aberto
Instalação do Nginx (se necessário)
sudo apt update
sudo apt install nginx -y
sudo systemctl start nginx
sudo systemctl enable nginx
sudo systemctl status nginx
Contexto
O Sr. Éric, administrador de sistemas, tenta instalar e iniciar uma aplicação chamada Wiki.js em um servidor Ubuntu. A aplicação deveria escutar na porta 3000, mas não está funcionando. Após várias tentativas frustradas, Éric inicia uma série de investigações para identificar e resolver o problema.
Etapa 1 – Verificação da Porta Utilizada
Éric começa verificando se a porta 3000 já está sendo usada por outro serviço. Ele utiliza o seguinte comando:
lsof -i :3000
Resultado obtido:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
node 9744 wikijs 22u IPv4 59242 0t0 TCP *:3000 (LISTEN)
Um processo node está escutando na porta 3000. Ele anota o PID: 9744.
Análise
- COMMAND:
node- O processo é uma aplicação Node.js - PID:
9744- Identificador do processo - USER:
wikijs- O usuário que executa o processo - PORT:
3000- A porta em escuta
Etapa 2 – Tentativa de Liberação da Porta com kill
Éric tenta parar o processo manualmente:
# Tentativa de parada limpa (SIGTERM)
kill -15 9744
# Se não funcionar, parada forçada (SIGKILL)
kill -9 9744
Verificação
Após executar esses comandos, Éric verifica novamente:
lsof -i :3000
Resultado:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
node 9842 wikijs 22u IPv4 59243 0t0 TCP *:3000 (LISTEN)
Conclusão: O processo é reiniciado automaticamente. Um novo PID (9842) aparece. Outra entidade (provavelmente um serviço systemd) o relança.
Por que o processo reinicia?
O processo reinicia automaticamente porque é gerenciado por um serviço systemd com a opção Restart=always em sua configuração. Mesmo que você mate o processo, o systemd o relança imediatamente.
Etapa 3 – Busca pelo Serviço systemd
Éric suspeita de um serviço systemd. Ele então procura identificar seu nome exato.
Comandos Utilizados
# Listar todos os serviços
systemctl list-units --type=service
# Listar os serviços parados
systemctl list-units --type=service --state=exited
# Listar os serviços em execução
systemctl list-units --type=service --state=running
# Filtrar para encontrar os serviços Wiki
systemctl list-units --type=service --state=running | grep -i wiki
Busca nos Arquivos de Serviço
# Listar os arquivos de serviço por data de modificação
ls -l --sort=time /etc/systemd/system/
# Filtrar para encontrar os serviços Wiki
ls -l /etc/systemd/system/ | grep wiki
Buscas Cruzadas
# Procurar nas conexões de rede
sudo ss | grep -i wiki
sudo ss | grep -i 3000
# Procurar processos Node.js
ps aux | grep node
# Procurar serviços contendo "node"
systemctl | grep node
Os Comandos Vencedores
Os comandos mais eficazes para identificar o serviço são:
# Encontrar os serviços Wiki em execução
systemctl list-units --type=service --state=running | grep -i wiki
# Procurar arquivos de serviço Wiki
ls -l /etc/systemd/system/ | grep wiki
# Ver processos Node.js
ps aux | grep node
# Procurar serviços contendo "node"
systemctl | grep node
Hipótese confirmada: Um serviço chamado wikijs.service parece ser responsável pelo processo.
Etapa 4 – Verificação da Correlação Entre Processo, Porta e Serviço
Éric estabelece manualmente o vínculo entre o processo node, a porta 3000 e o serviço em questão:
Identificar o Processo na Porta
# Ver o processo que escuta na porta 3000
lsof -i :3000
# Ver todos os processos Node.js e suas portas
sudo lsof -i -P -n | grep node
# Ver todos os processos Wiki.js
sudo lsof -i -P -n | grep wiki
Identificar o Arquivo de Serviço
# Procurar o arquivo de serviço
ls -l /etc/systemd/system/ | grep wiki
Arquivo identificado: wikijs.service
Verificar o Serviço
# Ver o status do serviço
sudo systemctl status wikijs.service
# Ver os logs do serviço
sudo journalctl -u wikijs.service --no-pager --lines=50
Etapa 5 – Parada Definitiva do Serviço e Liberação da Porta
Éric para corretamente o serviço e desativa seu reinício automático:
Parar o Serviço
# Parar o serviço
sudo systemctl stop wikijs.service
Desativar o Reinício Automático
# Desativar o serviço na inicialização
sudo systemctl disable wikijs.service
Verificação Final
# Verificar se a porta está liberada
lsof -i :3000
# Verificar o status do serviço
sudo systemctl status wikijs.service
Resultado: A porta 3000 agora está liberada. O serviço não será mais reiniciado automaticamente.
Etapa Bônus – Scan Completo das Portas Abertas (Opcional)
Para garantir o estado geral do servidor, Éric utiliza a ferramenta nmap:
# Instalar nmap
sudo apt install nmap -y
# Escanear as portas abertas no localhost
sudo nmap -sT -O localhost
# Escanear uma porta específica
sudo nmap -p 3000 localhost
Perguntas para Reflexão
-
Por que a porta 3000 permanecia bloqueada mesmo usando
kill?- Explique o papel do systemd na gestão de serviços
- Por que
killsozinho não é suficiente?
-
Qual método permite identificar o nome do serviço que utiliza uma porta específica?
- Descreva o método passo a passo
- Quais comandos são mais eficazes?
-
Qual comando poderia ser usado para buscar todos os serviços contendo a palavra
wikino nome ou descrição?- Proponha várias abordagens
-
Proponha um script bash para automatizar essa investigação.
- O script deve identificar automaticamente o serviço associado a uma porta
Anexo 1: Métodos Mais Avançados
O método descrito (busca manual a partir da porta com lsof, ps, systemctl, etc.) é confiável, mas artesanal. Existem métodos mais avançados e automatizados, úteis para ambientes complexos, como servidores de produção ou clusters.
1. systemd-cgls ou systemd-cgtop
Essas ferramentas permitem visualizar a árvore de serviços e processos controlados pelo systemd.
# Ver a árvore completa
systemd-cgls
# Filtrar para Wiki.js
systemd-cgls | grep -i wiki
# Filtrar para PostgreSQL
systemd-cgls | grep -i postgres
# Filtrar para Nginx
systemd-cgls | grep -i nginx
# Ver a árvore de um serviço específico
systemd-cgls /system.slice/wikijs.service
# Listar os cgroups
ls /sys/fs/cgroup/system.slice/ | grep wiki
# Ver processos Wiki
ps -ef | grep wiki
2. systemctl status Combinado com --property
Você pode consultar todos os serviços e pedir para ver seu MainPID, depois cruzar com a porta:
# Ver todos os MainPID dos serviços
systemctl show --all --property=MainPID --no-pager
# Para um serviço específico
systemctl show wikijs.service --property=MainPID
Depois:
# Ver o PID que utiliza a porta 3000
sudo lsof -i :3000
E você compara os MainPID com o PID que utiliza a porta.
3. Usar fuser para Matar Diretamente o Processo pela Porta
# Matar o processo associado à porta 3000
sudo fuser -k 3000/tcp
Atenção: Este método não desativa o serviço, então ele pode reiniciar. É útil em um script temporário.
4. Com ss --processes
# Ver o processo que escuta na porta 3000
sudo ss -lptn 'sport = :3000'
Isso mostra diretamente:
- a porta,
- o protocolo,
- o processo,
- e às vezes o nome do serviço se estiver bem configurado.
5. Usar netstat com --program (se disponível)
# Instalar net-tools se necessário
sudo apt update
sudo apt install net-tools
# Ver o processo na porta 3000
sudo netstat -tulnp | grep 3000
Permite identificar diretamente o programa usando uma porta. Você pode cruzar com systemctl:
# Ver detalhes do processo
ps -p <PID> -o pid,cmd
6. Via Logs do systemd
Se o serviço foi iniciado pelo systemd, você pode fazer:
# Ver os logs do serviço
journalctl -u wikijs.service
# Ver os logs em tempo real
journalctl -u wikijs.service -f
# Ver as últimas linhas
journalctl -u wikijs.service --no-pager --lines=50
Isso mostra o histórico de execução, incluindo a porta em escuta.
Anexo 2: Automatizando a Identificação do Serviço
Script Bash: Identificar o Serviço systemd por Trás de uma Porta
Crie um arquivo recherche_service_port.sh:
#!/bin/bash
# Solicita ao usuário o número da porta
read -p "Entrez le numéro de port (ex: 3000) : " PORT
# Etapa 1: Obter o PID do processo que escuta nesta porta
PID=$(sudo lsof -i :$PORT -sTCP:LISTEN -t)
# Verificação se um PID foi encontrado
if [ -z "$PID" ]; then
echo "Aucun processus ne semble écouter sur le port $PORT."
exit 1
fi
echo "Processus détecté sur le port $PORT : PID = $PID"
# Etapa 2: Exibir informações sobre o processo
echo "Commande liée à ce PID :"
ps -p $PID -o pid,cmd
# Etapa 3: Procurar o serviço systemd ao qual pertence este PID
echo ""
echo "Recherche du service systemd correspondant..."
# Método 1: Procurar via systemctl
SERVICE=$(systemctl | grep $PID | awk '{print $1}')
# Método 2: Se não encontrado, procurar nos arquivos de serviço
if [ -z "$SERVICE" ]; then
echo "Recherche dans les fichiers de service..."
# Procurar o PID nos cgroups
for service_file in /etc/systemd/system/*.service; do
if [ -f "$service_file" ]; then
service_name=$(basename "$service_file")
# Verificar se o serviço está ativo e corresponde ao PID
main_pid=$(systemctl show "$service_name" --property=MainPID --value 2>/dev/null)
if [ "$main_pid" = "$PID" ]; then
SERVICE="$service_name"
break
fi
fi
done
fi
# Método 3: Procurar via cgroup
if [ -z "$SERVICE" ]; then
cgroup=$(cat /proc/$PID/cgroup 2>/dev/null | grep system.slice | cut -d: -f3)
if [ -n "$cgroup" ]; then
SERVICE=$(basename "$cgroup" .service)
fi
fi
if [ -z "$SERVICE" ]; then
echo "Aucun service systemd trouvé automatiquement pour le PID $PID."
echo "Vérification manuelle possible avec :"
echo " systemctl status <nom_du_service>"
echo "ou recherche dans /etc/systemd/system/"
echo ""
echo "Commandes utiles :"
echo " ps -p $PID -o pid,cmd"
echo " systemctl list-units --type=service | grep -i wiki"
echo " ls -l /etc/systemd/system/ | grep wiki"
else
echo "Service systemd détecté : $SERVICE"
echo ""
echo "Statut du service :"
systemctl status $SERVICE --no-pager -l
echo ""
echo "Pour arrêter le service :"
echo " sudo systemctl stop $SERVICE"
echo " sudo systemctl disable $SERVICE"
fi
Utilização
- Salve o script em um arquivo:
nano recherche_service_port.sh
- Torne-o executável:
chmod +x recherche_service_port.sh
- Execute-o:
./recherche_service_port.sh
O que Você Aprendeu
- Como vincular uma porta a um processo (
lsof) - Como chegar ao serviço via
systemctlegrep - Como automatizar um diagnóstico de rede em Bash
- Como usar cgroups para identificar serviços
Resumo dos Comandos Importantes
| Comando | Descrição |
|---|---|
lsof -i :3000 | Ver o processo que escuta na porta 3000 |
kill -15 PID | Parada limpa do processo (SIGTERM) |
kill -9 PID | Parada forçada do processo (SIGKILL) |
systemctl list-units --type=service --state=running | Listar os serviços ativos |
systemctl stop wikijs.service | Parar um serviço |
systemctl disable wikijs.service | Desativar um serviço na inicialização |
systemctl status wikijs.service | Ver o status de um serviço |
journalctl -u wikijs.service | Ver os logs de um serviço |
sudo ss -lptn 'sport = :3000' | Ver o processo em uma porta com ss |
sudo fuser -k 3000/tcp | Matar o processo em uma porta |
Verificação Final
Verifique se você conseguiu:
- Identificar o processo que utiliza a porta 3000
- Entender por que
killsozinho não é suficiente - Encontrar o serviço systemd responsável
- Parar e desativar corretamente o serviço
- Verificar que a porta está liberada
- Utilizar métodos avançados de diagnóstico
- Criar e usar o script de automação
- Responder às perguntas de reflexão
Próximos Passos
- Lab 8.1: Gerenciamento de Serviços systemd (revisão)
- Lab 8.5: Instâncias Múltiplas do Wiki.js (criação de múltiplas instâncias)
- TP 3: Avaliação systemd e Processos (prova)
Lab criado em: Dezembro 2024