Port knocking com iptables
Para quem é novo nessa história de Firewall, um Firewall é responsável por criar uma barreira na comunicação de entrada ou saída de rede em um computador. Tornando a explicação um pouco mais simples: é aquilo que impede que outras pessoas entrem através da internet em sua máquina para bagunçar suas coisas.
Este artigo é voltado para máquinas com Linux e Iptables, você deve encontrar pela internet outros métodos para criar port knocking ou até configurar um Firewall com outras ferramentas, este artigo cobre este sistema operacional e essa ferramenta por serem muito comuns, e em praticamente todas as distribuições Linux você pode encontrar o Iptables muitas vezes já instalado (caso do Ubuntu). Neste artigo não cobrirei a instalação do Iptables em outras distribuições pois em alguns casos basta um apk add iptables para instalar a aplicação e executar os passos apresentados aqui (no Alpine Linux).
Se você não sabe o que é uma porta (estou falando de portas de redes de computadores), você deve começar por aqui e aí voltar para este artigo. Vale também dar uma olhada na lista de portas, isso ajuda a identificar quais portas são utilizadas pelos serviços que você usa.
Entendendo a técnica Port Knocking
Normalmente um Firewall define as portas abertas ou fechadas mas com Iptables você pode fazer muito mais, desde criar redirecionamentos até controlar a quantidade de conexões por segundo.
Como os números das portas seguem convenções (exemplo 22 para SSH) é comum trocar o número da porta do serviço para outra que não tenha nada a ver com o serviço em questão, porém com uma simples varredura de portas (port scan) você pode encontrar a porta novamente e de nada adiantou seu trabalho. A segunda alternativa costuma ser criar uma regra no Firewall para liberar a porta apenas para um IP mas isso também não ajuda muito quando você está utilizando uma conexão ADSL/3G que força você a trocar constantemente de IP.
Para resolver este problema você pode utilizar o Port Knocking, que consiste em criar uma outra porta (ou mais portas), na qual você precisa conectar na sequência antes de tentar uma conexão na porta que seu serviço está escutando.
Configurando o básico no Iptables
Se você já possui um conjunto de regras para seu Firewall com Iptables passe para a seção seguinte. Se você não possui vai a dica: crie um arquivo firewall.sh e dê permissão de execução chmod a+x firewall.sh, neste arquivo você deve escrever todas as regras abaixo, e quando precisar recarregar o Firewall basta executar este arquivo que todas as regras serão aplicadas. Não esqueça que você precisa ter privilégios de root.

Antes de sair por aí reconfigurando suas máquinas, lembre-se que o bloqueio das portas pode lhe deixar de fora da máquina (sem acesso SSH), portanto tenha sempre um plano B durante seus testes.
Código 1: Arquivo de Firewall básico
# Limpando todas as regras existentes, isso também irá liberar todas as portas # Caso faça alguma bobagem e queira remover todas as regras, execute as próximas linhas iptables -F iptables -X iptables -Z iptables -t nat -F iptables -t nat -X iptables -t mangle -F iptables -t mangle -X iptables -P INPUT ACCEPT iptables -P FORWARD ACCEPT iptables -P OUTPUT ACCEPT # Fim da limpeza # Por padrão, um firewall deve bloquear tudo, então utilizamos iptables -P INPUT DROP iptables -P FORWARD DROP # Descomente abaixo se deseja bloquear as conexões de saída também #iptables -P OUTPUT DROP # Estas regras liberam a conexão local (localhost/127.0.0.1), importante para muitos serviços iptables -A INPUT -i lo -s 0/0 -d 0/0 -j ACCEPT iptables -A OUTPUT -o lo -s 0/0 -d 0/0 -j ACCEPT # Se você quiser liberar todas as conexões para um IP específico descomente a linha abaixo # Note que TODAS as portas serão liberadas para o IP que você colocar abaixo #iptables -A INPUT -s 000.000.000.000 -j ACCEPT # Caso tenha alguns serviços que quer liberar para qualquer IP # Libere as portas 53 UDP/TCP (DNS), 80 TCP (HTTP) e 443 TCP (HTTPS) iptables -A INPUT -p tcp -m multiport --destination-ports 53,80,443 -j ACCEPT iptables -A INPUT -p udp -m multiport --destination-ports 53 -j ACCEPT # Vale também criar uma regra para que não "derrube" conexões já estabelecidas iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
Regras do Port Knocking
Se você executou o firewall.sh com o conteúdo do Código 1 já deve ter notado que nenhuma nova conexão de SSH na porta 22 é possível, ocorre timeout, e até os pings são ignorados. Com a regra de manter as conexões já estabelecidas você deve continuar com seu acesso SSH.
Para nosso exemplo liberaremos a porta 22 por alguns segundos após você conectar por TCP uma sequência de portas como 1000, 3000 e 2000 (é importante não utilizar portas sequenciais pois um port scan normalmente segue uma ordem que poderia realizar as conexões necessárias para liberar a porta 22 sem você querer).
Adicione ao final do seu arquivo de configurações de Firewall o seguinte código.
Código 2: Regras do Port Knocking
# Obs.: Uma Chain é uma lista de regras de filtragem dentro do iptables # São 3 passos de conexão, portanto criamos 2 chains iptables -N AGUARDANDO-PASSO2 iptables -N AGUARDANDO-PASSO3 # De acordo com a chain acessada, define uma flag para demonstrar o passo atingido iptables -A AGUARDANDO-PASSO2 -m recent --name PASSO2 --set iptables -A AGUARDANDO-PASSO3 -m recent --name PASSO3 --set # Para cada porta na ordem 1000 3000 2000 encaminha o pacote para a chain respectiva iptables -A INPUT -p tcp --syn --dport 1000 -m recent --set --name PASSO1 iptables -A INPUT -p tcp --syn --dport 3000 -m recent --rcheck --seconds 3 --name PASSO1 \ -j AGUARDANDO-PASSO2 iptables -A INPUT -p tcp --syn --dport 2000 -m recent --rcheck --seconds 3 --name PASSO2 \ -j AGUARDANDO-PASSO3 # Esta é a regra final, que habilita para todoos os ips (-s 0/0) a conexão na porta # 22 por 3 segundos iptables -A INPUT -p tcp -s 0/0 --dport 22 -m recent --rcheck --seconds 3 --name PASSO3 \ -j ACCEPT
Note que a validade de cada flag é de 3 segundos, portanto você não pode demorar muito para tentar a conexão em cada porta.
Realizando as chamadas TCP para liberar a porta
A liberação da porta pode ser feita através do comando telnet mas você precisa ser muito ágil para tentar realizar todas as conexões com 3 segundos entre cada chamada. Para resolver isso você pode utilizar o comando nc no Linux. Outra dica é criar um script com a sequência de liberação.
Sequência de liberação
nc -w 1 <hostdestino> 1000 # Conecta no host destino e aguarda 1 segundo para desconectar nc -w 1 <hostdestino> 3000 nc -w 1 <hostdestino> 2000 ssh <usuario>@<hostdestino>
Problemas
O Port Knocking não é o melhor mecanismo para liberação de portas em um Firewall mas é uma solução simples e fácil de aplicar em qualquer servidor.
A técnica é vulnerável a ataques replay (repetição de pacotes) e também deixa a porta exposta a port scanners durante os 3 segundos, assim sendo menos segura que outras técnicas como Single Packet Authorization mas não tão inviável se esta liberação/acesso for feita raramente pelo administrador de sistemas.

Se não conseguir identificar a imagem clique sobre ela para recarregar