Port knocking, aprenda a melhorar as política de segurança de seu firewall Linux e Mikrotik

Port knocking é um método de abrir portas externamente em um firewall, realizando tentativas de conexões em uma sequemcia de portas fechadas pré-especificadas, e depois que esta sequência estiver correta as regras de firewall são modificadas temporariamente para permitir que o host que “bateu” nas portas tenha acesso.

Vou ensinar realizar Port knocking no Linux com nftables e iptables e Mikrotik 🙂

Primeiramente precisamos escolher 4 portas que iremos bater para ganhar acesso.
No meu exemplo irei usar as portas: 52341, 28001, 60541, 30951

Neste exemplo vou estar liberando as portas 22 e 23 após “batermos” nas portas 52341, 28001, 60541, 30951, e por 1min após bater nas portas teremos acesso as portas 22 e 23.

Se você é amante de linux, e seu desktop é um lindo linux instale o “batedor” knockd, não vamos usa-lo ainda, mas já podemos instala-lo!

$ sudo apt install knockd
$ knock -h
  -u, --udp       make all ports hits use UDP (default is TCP)
  -d, --delay <t>      wait <t> milliseconds between port hits
  -v, --verbose   be verbose
  -V, --version   display version
  -h, --help      this help

Ele funciona assim:

$ knock -d 500 -v 192.168.1.1 52341 28001 60541 30951
hitting tcp 192.168.1.1:52341
hitting tcp 192.168.1.1:28001
hitting tcp 192.168.1.1:60541
hitting tcp 192.168.1.1:30951

Linux Nftables

Primeiramente tenha o nftables instalado. Para distribuição baseadas em Debian use:

# apt install nftables
# systemctl enable nftables.service

O arquivo de configuração padrão do nftables fica em /etc/nftables.conf, então vamos edita-lo:

# vim /etc/nftables.conf

Lembre-se de criar o seu padrão de sequencia e portas, e adicione ao final do arquivo:

define protege_portas = {22,23}

table inet portknock {
   set clientes_ipv4 {
      type ipv4_addr
      flags timeout
   }

   set clientes_ipv6 {
      type ipv6_addr
      flags timeout
   }

   set toctoc_aberta_ipv4 {
      type ipv4_addr . inet_service
      flags timeout
   }

   set toctoc_aberta_ipv6 {
      type ipv6_addr . inet_service
      flags timeout
   }

   chain input {
      type filter hook input priority -10; policy accept;

      iifname "lo" return

      tcp dport 52341 add @toctoc_aberta_ipv4 {ip  saddr . 28001 timeout 60s}
      tcp dport 52341 add @toctoc_aberta_ipv6 {ip6 saddr . 28001 timeout 60s}
      tcp dport 28001 ip  saddr . tcp dport @toctoc_aberta_ipv4 add @toctoc_aberta_ipv4 {ip  saddr . 60541 timeout 60s}
      tcp dport 28001 ip6 saddr . tcp dport @toctoc_aberta_ipv6 add @toctoc_aberta_ipv6 {ip6 saddr . 60541 timeout 60s}
      tcp dport 60541 ip  saddr . tcp dport @toctoc_aberta_ipv4 add @toctoc_aberta_ipv4 {ip  saddr . 30951 timeout 60s}
      tcp dport 60541 ip6 saddr . tcp dport @toctoc_aberta_ipv6 add @toctoc_aberta_ipv6 {ip6 saddr . 30951 timeout 60s}
      tcp dport 30951 ip  saddr . tcp dport @toctoc_aberta_ipv4 add @clientes_ipv4 {ip  saddr timeout 10s} log prefix "Portknock bem-sucedido: "
      tcp dport 30951 ip6 saddr . tcp dport @toctoc_aberta_ipv6 add @clientes_ipv6 {ip6 saddr timeout 10s} log prefix "Portknock bem-sucedido: "

      tcp dport { $protege_portas } ip  saddr @clientes_ipv4 counter accept
      tcp dport { $protege_portas } ip6 saddr @clientes_ipv6 counter accept
      tcp dport { $protege_portas } ct state established,related counter accept
      tcp dport { $protege_portas } counter reject with tcp reset
   }
}

Restarte o nftables

# systemctl enable nftables.service

Se você não usa linux em seu deskop 🙁 para usar o knock, basta você jogar no seu navegador ip:porta, ex 192.168.1.1:52341 192.168.1.1:28001 192.168.1.1:60541 192.168.1.1:30951, lembre-se que você tem 1 minuto para bater nas portas e realizar sua conexão. Já já ensino como ter um servido web e liberar a porta em um click!

$ knock -d 500 -v 192.168.1.1 52341 28001 60541 30951

Para acompanhar os logs:

#  tail -f /var/log/messages

Realize o SSH (ou acesse o a porta que tenha protegido para testar)

Linux Iptables

Vou deixar um modelo com iptables, mas recomendo você ir migrando para nftables que em um futuro sera seu sucessor. Não esqueça de alterar as portas para sua realidade, em seu arquivo de firewall tenha:

#!/bin/bash
iptables -F
iptables -X
iptables -Z

iptables -N INTO-TOCTOC2
iptables -A INTO-TOCTOC2 -m recent --name TOCTOC1 --remove
iptables -A INTO-TOCTOC2 -m recent --name TOCTOC2 --set

iptables -N INTO-TOCTOC3
iptables -A INTO-TOCTOC3 -m recent --name TOCTOC2 --remove
iptables -A INTO-TOCTOC3 -m recent --name TOCTOC3 --set

iptables -N INTO-TOCTOC4
iptables -A INTO-TOCTOC4 -m recent --name TOCTOC3 --remove
iptables -A INTO-TOCTOC4 -m recent --name TOCTOC4 --set
iptables -A INTO-TOCTOC4 -j LOG --log-prefix "Portknock bem-sucedido: "

iptables -A INPUT -m recent --update --name TOCTOC1

iptables -A INPUT -p tcp --dport 52341 -m recent --set --name TOCTOC1
iptables -A INPUT -p tcp --dport 28001 -m recent --rcheck --seconds 30 --name TOCTOC1 -j INTO-TOCTOC2
iptables -A INPUT -p tcp --dport 60541 -m recent --rcheck --seconds 30 --name TOCTOC2 -j INTO-TOCTOC3
iptables -A INPUT -p tcp --dport 30951 -m recent --rcheck --seconds 60 --name TOCTOC3 -j INTO-TOCTOC4

# Para uma unica porta
#iptables -A INPUT -p tcp --dport 22 -m state --state ESTABLISHED,RELATED -j ACCEPT
#iptables -A INPUT -p tcp --dport 22 -m recent --rcheck --seconds 60 --name TOCTOC4 -j ACCEPT
#iptables -A INPUT -p tcp --dport 22 -j DROP

# Multiplas portas
iptables -A INPUT -p tcp -m multiport --dport 22,23 -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp -m multiport --dport 22,23 -m recent --rcheck --seconds 60 --name TOCTOC4 -j ACCEPT
iptables -A INPUT -p tcp -m multiport --dport 22,23 -j DROP

Pode realizar os mesmo procedimento anteriores

Mikrotik

Aqui vai uma observação muito importante para quem usa routerOS, FIREWALL TEM LUGAR PARA SER FEITO, então não sai aplicando Port Knocking em todo o lugar. Por exemplo, muitos provedores tem o costume de deixar na sua borda routerOS o serviço PPTP ativo para fazer uma conexão quando esta fora da sua rede, este é um bom exemplo de NÃO se seguir, routerOS tem q ter muito cuidado quando se cria firewall, recomendo que para esse tipo de serviço como PPTP Server, seja rodado em um router paralelo (pode ser uma hAP lite, uma VM com o routerOS mas nunca em uma borda) até por que é muito fácil de quebrar o PPTP, então para não deixar a porta 1723/PPTP aberta iremos realizar o Port Knocking, aproveitei e inclui a porta 22, altere de acordo com suas necessidades.

/ip firewall filter
add action=add-src-to-address-list address-list=toc_toc_1  \
    address-list-timeout=30s chain=input comment="Port Knocking"  \
    connection-state=new dst-port=52341 protocol=tcp
add action=add-src-to-address-list address-list=toc_toc_2  \
    address-list-timeout=30s chain=input connection-state=new dst-port=28001  \
    protocol=tcp src-address-list=toc_toc_1
add action=add-src-to-address-list address-list=toc_toc_3  \
    address-list-timeout=30s chain=input connection-state=new dst-port=60541  \
    protocol=tcp src-address-list=toc_toc_2
add action=add-src-to-address-list address-list=toc_toc_4 address-list-timeout=2m  \
    chain=input connection-state=new dst-port=30951 log=yes log-prefix="Portknock bem-sucedido"  \
    protocol=tcp src-address-list=toc_toc_3
add action=drop chain=input connection-state=new dst-port=1723,22  \
    protocol=tcp src-address-list=!toc_toc_4

Se você não usa linux em seu deskop 🙁 para usar o knock, basta você jogar no seu navegador ip:porta, ex 192.168.1.1:52341 192.168.1.1:28001 192.168.1.1:60541 192.168.1.1:30951, lembre-se que você tem 1 minuto para bater nas portas e realizar sua conexão. Já já ensino como ter um servido web e liberar a porta em um click!

$ knock -d 500 -v 192.168.1.1 52341 28001 60541 30951

para acompanhar, abra os Log sempre que um host acertar as sequencias de porta um log com Portknock bem-sucedido será exibido. Verifique também em IP-> Firewall -> Address List.

Realize o sua conexão PPTP ou SSH (ou acesse o a porta que tenha protegido para testar)

Que tal uma central “toc toc” para nosso Port knocking 😛

Leituras recomendadas:
Como ter diversos sub/domínios no mesmo servidor?
Passo-a-passo como criar um servidor WEB
Servidor DNS seguro com Bind9
Crie um subdomínio em exemplo toctoc em seu servidor DNS apontando para algum servidor web que você tenha rodando.
Ajustes o subdomíno em seu servidor web, neste ex com apache estou estarei incluído uma senha para acesso.

# mkdir /var/www/toctoc/
# htpasswd -c /var/www/toctoc/.htpasswd admin

E defina a senha para seu acesso.

# vim /etc/apache2/sites-available/toctoc.conf
<virtualhost *:80>
   ServerName toctoc.remontti.com.br
   ServerAdmin noc@remontti.com.br
   DocumentRoot /var/www/toctoc
   <Directory /var/www/toctoc/>
      Options FollowSymLinks
      AllowOverride All
      Require all denied
      <RequireAll>
          Require valid-user
          AuthBasicProvider file
          AuthType Basic
          AuthName "Login"
          AuthUserFile /var/www/toctoc/.htpasswd
      </RequireAll>
   </Directory> 
   ErrorLog ${APACHE_LOG_DIR}/error_toctoc.log
   CustomLog ${APACHE_LOG_DIR}/access_toctoc.log combined
</VirtualHost>

Criei uma paginazinha com php + javascript para executar nosso trabalho para não precisar decorar portas, sinta-se a vontade para melhorar o código: https://github.com/remontti/PortKnockingPHP

# cd /var/www/toctoc/
# wget https://raw.githubusercontent.com/remontti/PortKnockingPHP/main/index.php

Edite o arquivo index.php e altere a lista de seus servidores…

 # Nome - IP - Porta 1 - Porta 2 - Porta 3 - Porta 4 #
$array = [
    ["RouterOS PPTP","192.168.1.1","1000","2000","3000","4000"],
    ["Servicor 2","192.168.2.1","111","222","333","4444"],
    ["Servicor 3","192.168.3.1","1000","2000","3000","4000"],
    ["Servicor 4","192.168.4.1","1000","2000","3000","4000"],
];

Agora acesse seu “toctoc.remontti.com.br” e seja feliz, e não se preocupe em estar decorando portas, basta você clicar em Toc Toc.

Aplicativos para Celular/PC Windows

Dica dos leitores
Para iPhone: https://apps.apple.com/us/app/knockond/id333206277
Para Android: https://play.google.com/store/apps/details?id=com.xargsgrep.portknocker&hl=pt_BR&gl=US
Para PC Win.: http://gregsowell.com/?p=2020

Espero que tenha gostado! 🙂

Se quiser fazer uma doação para o café ficarei muito feliz pelo seu reconhecimento!

Participe do canal no telegram para ficar atualizado sempre que publicar um novo tutorial.

Se não puder doar pode deixar seu agradecimento nos comentário também ficarei feliz em saber que ajudei. Se tiver qualquer pergunta deixe-a também. Se preferir entrar em Contato clique aqui.

Rudimar Remontti

Trabalho atualmente como Gerente de Redes em um Provedor de Internet no Rio Grande do Sul.

Você pode gostar...

5 Resultados

  1. Jorge Ciriaco disse:

    Fala Remontti, tava pensando em uma forma de tentar mitigar alguns ataques nos mikrotiks aqui da rede. Mesmo eu tendo exceção dos endereços que podem acessar, por exemplo, via Winbox aqui na rede, ainda assim fica o log todo azul em alguns casos. Pensei em adicionar o src-address em uma address list com drop se por exemplo quem tiver tentando autenticar falhar x quantidade de vezes. Já viu algum caso assim?

  2. Tesch disse:

    Rudimar, para complementar o tutorial segue aplicativos para iPhone, Android e Windows.

    Para iPhone: https://apps.apple.com/us/app/knockond/id333206277

    Para Android: https://play.google.com/store/apps/details?id=com.xargsgrep.portknocker&hl=pt_BR&gl=US

    Para PC: http://gregsowell.com/?p=2020

    Parabéns pelo trabalho, sou de Porto Alegre, RS, grande abraço.

  3. Flávio disse:

    Essa já é minha segunda aula. Perfeito e didaticamente bem esplicado. Parabéns.

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *