Port Knocking é uma técnica utilizada para esconder portas importantes, normalmente a porta 22 (SSH), utilizando uma sequência pré-definida de pacotes em portas específicas para permitir o acesso. Um cenário de uso comum é a proteção do serviço SSH contra varreduras na rede (scan de portas), restringindo que um invasor detecte o serviço SSH ativo em determinado servidor.
Este guia abrange uma visão geral sobre Port Knocking, a implementação “automática” utilizando o daemon knockd e também a implementação utilizando apenas iptables. Abordaremos também aspectos de segurança relacionados ao uso de Port Knocking.
Instruções Rápidas – knockd
### No servidor
apt-get install knockd
### Habilitar Interface
vim /etc/default/knockd
### Bloquear porta com iptables
iptables -A INPUT -p tcp --dport 22 -j DROP
### Iniciar serviço
service knockd start
### No cliente
apt-get install knockd
### Testar conexão SSH
ssh USER@192.168.1.100
### Disparar port knocking
knock 192.168.1.100 7000:tcp 8000:tcp 9000:tcp
### Testar novamente a conexão SSH
ssh USER@192.168.1.100
O que é Port Knocking?
Port Knocking (batidas na porta) é um nome bem adequado para esta técnica. Literalmente, batidas (pacotes) em portas específicas permitem que o endereço de origem das batidas acessem algum serviço específico. Normalmente utilizamos esta técnica para proteger SSH, mas podemos utilizar a técnica com qualquer serviço, como telnet, ftp, ou mesmo HTTP/HTTPS. Podemos entender o Port Knocking como uma senha que abre a porta do serviço. No resto deste guia, vamos considerar apenas a porta SSH.
Explicando passo a passo o conceito, inicialmente uma tentativa de conexão SSH é bloqueada no firewall do servidor. Um usuário autorizado e ciente da implementação do Port Knocking envia uma sequência pré-definida de pacotes em portas específicas. O servidor recebe esta sequência de pacotes, e então permite o acesso ao serviço para a porta de origem dos pacotes enviados. A próxima tentativa de acesso ao serviço SSH não será bloqueada.
O uso do Port Knocking traz benefícios ao esconder o serviço de scans de portas, reduzindo o que chamamos de superfície de ataque. Creio que seja praticamente unanimidade entre administradores de rede que uma das mensagens mais comuns em logs de servidores sejam tentativas de conexão SSH.
Claro que idealmente o serviço seria permitido apenas a endereços específicos, não sendo necessário utilizar outras técnicas, mas existem situações em que o endereço de origem não pode ser determinado previamente, como por exemplos em acessos a partir de conexões residenciais onde o endereço muda eventualmente, e, por algum motivo, não seja possível utilizar VPN com IP definido. Nestas situações, onde o IP de origem pode variar, o uso de Port Knocking adiciona sim uma camada de proteção extra.
Claro que o uso de Port Knocking não substitui outras medidas de proteção, como a configuração adequada do serviço SSH, restringindo o acesso somente com o uso de chaves públicas, não permitindo acesso com usuário root, timeouts de sessão configurados, etc.
Cenário utilizado
Para mostrar as configurações e funcionamento vamos utilizar uma topologia bem simples com apenas duas máquinas, sendo uma o computador que realizará o acesso SSH (IP 192.168.1.1), e a outra um servidor (IP 192.168.1.100). Ambos estão na mesma rede, e, embora seja um cenário limitado, o conceito e configurações se aplicam a qualquer cenário, mesmo a Internet. Utilizei o PNETLab, imagens Ubuntu 20.04 Server, e um switch.

Knockd — Instalação e configuração
Implementar Port Knocking utilizando a ferramenta knockd é extremamente simples, bastando instalar o daemon no servidor e configurar dois arquivos. No cliente basta instalar a ferramenta e executar, especificando as portas configuradas no servidor.
### Debian/Ubuntu:
apt-get update
apt-get install knockd
### Pode ser necessário instalar iptables
apt-get install iptables
Normalmente temos que habilitar a interface em que o knockd ouvirá, editando o arquivo /etc/default/knockd . Neste arquivo também há a opção para que o daemon seja executado automaticamente em reboots como um serviço do sistema. Confirme qual interface o servidor está utilizando e altere o arquivo adequadamente.
vim /etc/default/knockd
### Config padrão (Notem que serviço vem desabilitado e preparado para eth1, mas comentada)
START_KNOCKD=0
#KNOCKD_OPTS="-i eth1"
### Config alterada conforme cenário (Serviço habilitado e interface alterada para eth0)
START_KNOCKD=1
KNOCKD_OPTS="-i eth0"
Configuração do knockd
O arquivo de configuração do knockd pode variar entre /etc/knockd.conf ou knockd.yaml , conforme versão ou distribuição utilizada. Aqui vamos tratar apenas da versão knockd.conf. O arquivo é estruturado na forma de eventos, ou knocks, com o nome do evento/knock entre colchetes seguido das opções específicas de cada evento. Por padrão temos os eventos [openSSH], [closeSSH], [openHTTPS] e o evento especial [options], onde definimos opções globais.
Dentro de cada evento/knock temos várias opções, sendo as principais:
- sequence: portas e protocolo que desejamos (ex.: 7000,8000,9000 ou 7000:tcp,8000:udp,9000:tcp).
- seq_timeout: intervalo de tempo para a execução da sequência.
- tcpflags: flags TCP (syn, ack, etc.).
- command: comando a executar, normalmente uma chamada a iptables (IPv4).
- command_6: comando a executar, normalmente uma chamada a ip6tables (IPv6).
- start_command: comando ao acertar sequência (abre porta – IPv4).
- start_command_6: comando ao acertar sequência (abre porta – IPv6).
- cmd_timeout: intervalo de tempo para a sessão.
- stop_command: comando ao encerrar a sessão (bloqueia porta – IPv4).
- stop_command_6: comando ao encerrar a sessão (bloqueia porta – IPv6).
As opções do evento [options] são:
- UseSyslog: que utiliza syslog para gravar as mensagens.
- LogFile: especifica em qual arquivo as mensagens de log devem ser gravadas.
- PidFile: especifica qual pidfile deve ser utilizado, quando executado em modo daemon.
- Interface: lista de interfaces que o daemon deve ouvir.
O arquivo que vem por padrão é o seguinte:
[options]
UseSyslog
[openSSH]
sequence = 7000,8000,9000
seq_timeout = 5
command = /sbin/iptables -A INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
tcpflags = syn
[closeSSH]
sequence = 9000,8000,7000
seq_timeout = 5
command = /sbin/iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
tcpflags = syn
[openHTTPS]
sequence = 12345,54321,24680,13579
seq_timeout = 5
command = /usr/local/sbin/knock_add -i -c INPUT -p tcp -d 443 -f %IP%
tcpflags = syn
Altere apenas o evento/knock [openSSH], alterando o -A para -I conforme abaixo (logo explicarei) e inicie o serviço:
[openSSH]
sequence = 7000,8000,9000
seq_timeout = 5
command = /sbin/iptables -I INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
tcpflags = syn
### Iniciar o serviço
service knockd start
Integração com firewall
Como pode-se ver pelos blocos de eventos na configuração, knockd integra-se ao firewall do servidor tranquilamente. Temos algumas observações:
knockd espera que as portas que queremos proteger estejam bloqueadas pelo firewall. Então, é necessário que estas portas estejam bloqueadas automaticamente, preferencialmente desde a inicialização do sistema. Para nosso exemplo vamos considerar um firewall muito simples, sem nos preocuparmos agora com a inicialização. Para isso insira uma regra bloqueando SSH.
# Para IPv4
iptables -A INPUT -p tcp --dport 22 -j DROP
# Para IPv6
ip6tables -A INPUT -p tcp --dport 22 -j DROP
# Conferir com:
iptables -nvL INPUT
ip6tables -nvL INPUT
# Saída esperada
Chain INPUT (policy ACCEPT 1 packets, 160 bytes)
pkts bytes target prot opt in out source destination
0 0 DROP tcp eth0 * ::/0 ::/0 tcp dpt:22
Notem que utilizamos -A, inserindo a regra de bloqueio ao fim das regras existentes. Este detalhe é importante, pois temos que inserir as regras de liberação pós knocking antes da regra de bloqueio.
Uma vez que o Port Knocking teve sucesso, sequência enviada corretamente, as linhas command, ou command_6, ou start_command ou start_command_6 inserem a regra liberando o endereço de origem do knocking
A partir deste momento a conexão SSH é possível.
Cliente knock e testes
Para testar o que fizemos até agora, vamos instalar o knock na máquina ADMIN, que será utilizada para acessar nosso servidor por SSH.
apt-get update
apt-get install knockd
Vamos testar uma conexão SSH:
ssh valdinei@192.168.1.100
### Longa espera...
ssh: connect to host 192.168.1.100 port 22: Connection timed out
Demorou, mas falhou. Exatamente o que queremos. A demora é devido ao timeout até o cliente SSH considerar a falha.
Agora, vamos tentar de novo, mas vamos dar as “batidas na porta” antes.
### Cliente knock, notem o -v (verbose) que exibe o protocolo e porta.
knock -v 192.168.1.100 7000 8000 9000
hitting tcp 192.168.1.100:7000
hitting tcp 192.168.1.100:8000
hitting tcp 192.168.1.100:9000
### Nova tentativa de acesso.
ssh valdinei@192.168.1.100
The authenticity of host '192.168.1.100 (192.168.1.100)' can't be established.
ECDSA key fingerprint is SHA256:ITCND1t7tT5i814uAc8yrpBS10tqNea+vN51FzCA+uA.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.1.100' (ECDSA) to the list of known hosts.
valdinei@192.168.1.100's password:
Welcome to Ubuntu 20.04 LTS (GNU/Linux 5.4.0-29-generic x86_64)
### Sucesso !!!
Muito interessante! Agora vamos ver o log do servidor e conferir os estágios do knockd:
### Inicio do serviço e interface em que "ouve"
Mar 17 10:18:25 SERVER systemd[1]: Started Port-Knock Daemon.
Mar 17 10:18:25 SERVER knockd[2015]: starting up, listening on eth0
### Sequência de knocks/eventos recebida
Mar 17 10:18:56 SERVER knockd[2015]: 192.168.1.1: openSSH: Stage 1
Mar 17 10:18:56 SERVER knockd[2015]: 192.168.1.1: openSSH: Stage 2
Mar 17 10:18:56 SERVER knockd[2015]: 192.168.1.1: openSSH: Stage 3
### Porta aberta, inclusive indicando comando executado para abrir
Mar 17 10:18:56 SERVER knockd[2015]: 192.168.1.1: openSSH: OPEN SESAME
Mar 17 10:18:56 SERVER knockd[2026]: openSSH: running command: /sbin/iptables -I INPUT -s 192.168.1.1 -p tcp --dport 22 -j ACCEPT
### Acesso SSH com sucesso
Mar 17 10:19:09 SERVER sshd[2034]: Accepted password for valdinei from 192.168.1.1 port 35644 ssh2
Mar 17 10:19:09 SERVER sshd[2034]: pam_unix(sshd:session): session opened for user valdinei by (uid=0)
Mar 17 10:19:09 SERVER systemd[1]: Started Session 9 of user valdinei.
Utilizar a ferramenta knock em Linux é extremamente simples, tanto a instalação quanto o uso. Mas seu uso não é obrigatório, podemos utilizar o knocking de diversas outras formas:
### utilizando netcat
nc -w1 -z -v -n 192.168.1.100 7000
nc -w1 -z -v -n 192.168.1.100 8000
nc -w1 -z -v -n 192.168.1.100 9000
As opções utilizadas são:
- -w1 Como não receberemos resposta, especificamos um timeout de 1 segundo.
- -z indicamos que não há dados a enviar ou receber, é tipo um scan.
- -v verbose
- -n não tentar resolver FQDN do IP ou serviço da porta
- -u utilizar UDP ao invés de TCP
### Utilizando telnet (apenas portas TCP)
telnet 192.168.1.100 7000
telnet 192.168.1.100 8000
telnet 192.168.1.100 9000
Funciona apenas para portas TCP, mas podemos ter problema de timeout entre os comandos, pois configuramos 5 segundos entre as “batidas”.
### Utilizando nmap
nmap -Pn --host-timeout 1s 192.168.1.100 --max-retries 0 -p 7000
nmap -Pn --host-timeout 1s -sU 192.168.1.100 --max-retries 0 -p 8000
nmap -Pn --host-timeout 1s 192.168.1.100 --max-retries 0 -p 9000
As principais opções utilizadas são:
- -Pn –> simplesmente envia o pacote, sem verificar se o host esta UP
- –host-timeout 1s –> timeout de 1 segundo
- –max-retries 0 –> para que apenas um pacote seja enviado
- -sU –> para UDP
Quem utiliza Windows pode usar WSL para rodar alguma distribuição e instalar knockd ou algum dos utilitários acima. Ou também, pode instalar algum aplicativo para isso, como Windows Port Knock , Port Knocking Tool ou algum outro. Eu particularmente não encontrei nenhuma aplicação decente, porém não sinto falta, pois utilizo Linux para administração de redes/Linux.
Usuários de Android tem o excelente aplicativo Knock on Ports . A interface de configuração é muito simples, permitindo várias tipos de knocks, como TCP, UDP, tamanho do payload UDP, ICMP e tamanho do payload ICMP. Pode parecer inútil um aplicativo para celular que faz knocking, mas, as chances são grandes que você queira fazer o acesso SSH a partir de sua casa, e as chances são grandes que sua rede residencial, incluindo o WIFI, esteja atrás de um NAT.
Quando você realizar o knocking a partir do celular, o endereço de origem no servidor será o IP público do seu NAT, e o acesso SSH terá esse mesmo IP como origem. Portanto, um knocking realizado pelo celular abrirá a porta SSH para o seu notebook/PC.
Usuários de Iphone (Apple) podem utilizar o app PortKnock, valendo as mesmas observações que para o app Android.
Para continuar, pare o serviço knockd e limpe as regras no iptables
### Parar o serviço
service knockd stop
### Limpar as regras no iptables
iptables -X
Port Knocking apenas com iptables
Agora vamos implementar o Port Knocking utilizando apenas iptables. Aqui é onde separamos os homens dos meninos (ou masoquistas de pessoas normais) e entendemos exatamente o que esta acontecendo. Vamos utilizar basicamente o modulo recent do iptables, que nos permite criar listas de endereços dinamicamente e utilizar estas listas como critério de match. O módulo recent possui diversas funções, e as que usaremos e uma explicação resumida segue abaixo:
- –name –> especifíca a lista que vamos usar
- –set –> adiciona o endereço de origem à lista. Caso já exista, atualiza a entrada na lista
- –rcheck –> verifica se o endereço de origem esta na lista
- –update –> verifica se o endereço de origem esta na lista, e atualiza a entrada
- –remove –> verifica se o endereço de origem existe na lista, e, caso exista, remove
- –seconds –> utilizado junto com –rcheck ou –update, limita o match aos segundos especificados.
Vamos utilizar as mesmas portas utilizadas no knockd e gerar mensagens no log equivalentes.
### Criando chain para tratar de conexões SSH
iptables -N SSH
### Direcionando qualquer comunicação na porta 22 para a chain SSH
iptables -I INPUT -p tcp --dport 22 -j SSH
### Permitindo conexões estabelecidas, que foram previamente permitidas pelo Port Knocking
iptables -I SSH -m state --state ESTABLISHED -j ACCEPT
### Verificando se uma nova conexão SSH é permitida, checando se o IP de origem entrou na lista SSH_ALLOW nos últimos 30 segundos
iptables -A SSH -m state --state NEW -m recent --rcheck --seconds 30 --name SSH_ALLOW -j ACCEPT
### Logando tentativa de acesso não permitida e dropando o pacote
iptables -A SSH -j LOG --log-prefix "Tentativa de Acesso SSH "
iptables -A SSH -j DROP
### Match no primeiro pacote com log e drop na sequência
iptables -A INPUT -p tcp --dport 7000 -m state --state NEW -m recent --set --name STAGE_0 -j LOG --log-prefix "STAGE 0 "
iptables -A INPUT -p tcp --dport 7000 -j DROP
### Chain para tratar segundo pacote do knocking
iptables -N STAGE_1
### Match no segundo pacote, redirecionando para a chain STAGE_1
iptables -A INPUT -p tcp --dport 8000 -m state --state NEW -m recent --rcheck --seconds 15 --name STAGE_0 -j STAGE_1
### Na chain STAGE_1, remove o endereço de origem da lista STAGE_0, adiciona na lista STAGE_1 e então dropa o pacote
iptables -A STAGE_1 -m recent --remove --name STAGE_0
iptables -A STAGE_1 -m recent --set --name STAGE_1
iptables -A STAGE_1 -j LOG --log-prefix "STAGE 1 "
iptables -A STAGE_1 -j DROP
### Chain para tratar terceiro pacote
iptables -N STAGE_2
### Match no terceiro pacote, redirecionando para a chain STAGE_2
iptables -A INPUT -p tcp --dport 9000 -m state --state NEW -m recent --rcheck --seconds 15 --name STAGE_1 -j STAGE_2
### Na chain STAGE_2, remove o endereço de origem da lista STAGE_1, adiciona na lista SSH_ALLOW e então dropa o pacote
iptables -A STAGE_2 -m recent --remove --name STAGE_1
iptables -A STAGE_2 -m recent --set --name SSH_ALLOW
iptables -A STAGE_2 -j LOG --log-prefix "READY TO SSH ACCESS "
iptables -A STAGE_2 -j DROP
Criei uma chain para tratar apenas conexões SSH, redirecionando todo tráfego para ela. Caso haja uma conexão estabelecida, é permitido com ESTABLISHED. Caso seja uma nova conexão, iptables verifica se o source foi inserido/atualizado na lista SSH_ALLOW nos últimos 30 segundos. Se estiver, aceita a conexão, caso contrário loga a tentativa e descarta o pacote. Note que o endereço de origem apenas estará na lista SSH_ALLOW caso passe pelo Port Knock.
A primeira etapa do Port Knocking acontece ao receber um pacote na porta 7000/TCP. Nesse momento o iptables insere o endereço de origem na lista STAGE_0, loga e descarta o pacote.
A segunda etapa acontece ao receber um pacote na porta 8000/TCP. Nesse momento o iptables verifica se o endereço de origem surgiu na lista STAGE_0 nos últimos 15 segundos. Caso esteja, redireciona o pacote para a chain STAGE_1. Na chain STAGE_1 o endereço de origem é removido da lista STAGE_0 e inserido na lista STAGE_1, o pacote é logado e então descartado.
A terceira etapa acontece ao receber um pacote na porta 9000/TCP. Nesse momento o iptables verifica se o endereço de origem surgiu na lista STAGE_1 nos últimos 15 segundos. Caso esteja, redireciona o pacote para a chain STAGE_2. Na chain STAGE_2 o endereço de origem é removido da lista STAGE_1 e finalmente inserido na lista SSH_ALLOW, o pacote é logado e então descartado. A partir deste momento o acesso SSH estará permitido pelos próximos 30 segundos.
Repita os testes de acesso a partir da máquina ADMIN. Os resultados deverão ser os mesmos, apenas as mensagens no log do SERVER serão diferentes.
Mar 17 19:54:06 SERVER kernel: Tentativa de Acesso SSH IN=eth0 OUT= MAC=50:48:6c:00:20:00:50:36:e6:00:1f:00:08:00 SRC=192.168.1.1 DST=192.168.1.100 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=49796 DF PROTO=TCP SPT=35666 DPT=22 WINDOW=64240 RES=0x00 SYN URGP=0
Mar 17 19:58:42 SERVER kernel: STAGE 0 IN=eth0 OUT= MAC=50:48:6c:00:20:00:50:36:e6:00:1f:00:08:00 SRC=192.168.1.1 DST=192.168.1.100 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=26881 DF PROTO=TCP SPT=42080 DPT=7000 WINDOW=64240 RES=0x00 SYN URGP=0
Mar 17 19:58:42 SERVER kernel: STAGE 1 IN=eth0 OUT= MAC=50:48:6c:00:20:00:50:36:e6:00:1f:00:08:00 SRC=192.168.1.1 DST=192.168.1.100 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=16771 DF PROTO=TCP SPT=34220 DPT=8000 WINDOW=64240 RES=0x00 SYN URGP=0
Mar 17 19:58:42 SERVER kernel: READY TO SSH ACCESS IN=eth0 OUT= MAC=50:48:6c:00:20:00:50:36:e6:00:1f:00:08:00 SRC=192.168.1.1 DST=192.168.1.100 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=45 DF PROTO=TCP SPT=58532 DPT=9000 WINDOW=64240 RES=0x00 SYN URGP=0
Mar 17 19:58:49 SERVER sshd[2555]: Accepted password for valdinei from 192.168.1.1 port 35674 ssh2
Mar 17 19:58:49 SERVER sshd[2555]: pam_unix(sshd:session): session opened for user valdinei by (uid=0)
Usar o iptables traz uma complexidade maior, fato, mas também oferece muito mais flexibilidade. Praticamente qualquer campo que podemos dar match no iptables serve, dependendo de termos condições de fazer com que o cliente knock envie o pacote do jeito esperado.
Por exemplo, vamos substituir o match na porta 8000 por um icmp com tamanho de pacote L3 de 467 bytes.
### Linha a substituir
iptables -A INPUT -p tcp --dport 8000 -m state --state NEW -m recent --rcheck --seconds 15 --name STAGE_0 -j STAGE_1
### Localize o número da linha com:
iptables -nvL INPUT --line-numbers
Chain INPUT (policy ACCEPT 876 packets, 209K bytes)
num pkts bytes target prot opt in out source destination
1 718 53226 SSH tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22
2 2 120 LOG tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:7000 state NEW recent: SET name: STAGE_0 side: source mask: 255.255.255.255 LOG flags 0 level 4 prefix "STAGE 0 "
3 2 120 DROP tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:7000
4 2 120 STAGE_1 tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:8000 state NEW recent: CHECK seconds: 15 name: STAGE_0 side: source mask: 255.255.255.255
5 2 120 STAGE_2 tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:9000 state NEW recent: CHECK seconds: 15 name: STAGE_1 side: source mask: 255.255.255.255
### É a linha 4
### Apagar entrada
iptables -D INPUT 4
Acrescentar regra para icmp
iptables -I INPUT 4 -p icmp -m length --length 467 -m recent --rcheck --seconds 15 --name STAGE_0 -j STAGE_1
Agora nosso knocking ficaria
knock 192.168.1.100 7000
ping -s 439 -c 1 192.168.1.100
knock 192.168.1.100 9000
Veja que procuramos um tamanho de 467, mas enviamos ping especificando um payload de 439 bytes. Por que? Some 8 bytes do cabeçalho ICMP a 439 e teremos 447 bytes. Some 20 bytes do cabeçalho IP e teremos 467 bytes. –length do iptables dá match no tamanho total do pacote IP (camada 3)
Podemos utilizar uma infinidade de critérios com iptables, como portas de origem envolvidas, além das de destino (700,8000 e 9000), flags TCP específicas,tamanho do pacote, algum padrão específico no payload.
Knockd vs iptables puro
| knockd | iptables | |
|---|---|---|
| Facilidade | Alta | Média |
| Flexibilidade | Baixa | Alta |
| Manutenção | Baixa | Média |
| Dependência | Alta | Baixa |
| Uso de recursos | Média | Média |
| IPv6 | Sim | Sim |
Segurança e boas práticas
A técnica de Port Knocking é uma camada extra de segurança, protegendo o serviço alvo e reduzindo a superfície de ataque. Mas, assim como qualquer assunto, haverá pessoas com argumentos contra.
O principal argumento contra o Port Knocking é o que costumam chamar de “Segurança por Obscuridade”. E esse argumento é válido quando o administrador de redes/Linux confia exclusivamente no Port Knocking, mantendo a instalação do SSH permitindo login do usuário root com senha root123, por exemplo.
Existem várias técnicas que permitem a um invasor inferir com certa precisão quais portas envolvidas num Port Knocking e a sequência, e, uma vez com essa informação, o acesso root/root123 é garantido. Para que o Port Knocking seja sim uma camada extra de proteção, o serviço SSH deve estar corretamente configurado, desabilitando o login de root e usando exclusivamente chaves SSH protegidas por passphrase. Quando não for possível por algum motivo o uso de chaves SSH, senhas fortes devem ser utilizadas.
Outro ponto normalmente abordado por quem se posiciona contra o Port knocking é que com a configuração correta não há necessidade desta camada extra. E, realmente, se é possível restringir o acesso a endereços de origem específicos, e o uso de chaves SSH é obrigatório, talvez seja exagero esta camada. Ainda assim, o seguro morreu de velho, e teremos o trabalho de implementar apenas uma vez.
Ainda, há os que defendam o uso de técnicas diversas, como Single Packet Authentication (SPA), DenyHosts, Shimmer, entre outros, no lugar de Port Knocking. Pretendo avaliar outras ferramentas futuramente, mas certamente camadas a mais de segurança são sempre bem vindas.
Conclusão
Neste post vimos como implementar Port Knocking utilizando uma ferramenta específica (knockd) e também como implementar utilizando iptables, o que exige um grande conhecimento do administrador de redes/Linux, mas também permite uma flexibilidade muito maior.
A técnica Port Knocking definitivamente deve ser considerada uma camada extra de proteção, tanto para o serviço em si quanto pela redução da superfície de ataque, principalmente em casos onde não é possível especificar endereços de origem em regras de firewall. A escolha por ferramentas, como knockd, ou implementação manual depende muito do gosto e aptidão do administrador de redes/Linux, ou de necessidades específicas.
E você, utiliza Port Knocking? Tem alguma história para compartilhar?
Referências
- man: man knockd, man knockd.conf, man iptables, man iptables-extensions
- Repositório knockd
- Sidnei Weber
- Medium
- Peter N. M. Hansteen
- Viva o Linux
- ArchLinux
- DevMedia
- Greg Sowell
- Epinox
- MK Forum
- Google Play
- Apple Store
- MITRE
- StackOverflow