(hosts.allow e hosts.deny)
TCP Wrapper é um sistema de controle de acesso a serviços de rede, usado para filtrar as tentativas de conexões. Em alguns momentos, ele é bem parecido com o famoso "IPTABLES", mas logo se nota que é bem mais flexível e refinado, porém limitado aos acessos em direção do serviço (somete INPUT) que é oferecido e envolvendo somente o protocolo TCP.
O TCP Wrapper é um pacote que é instalado por padrão na maioria dos GNU/Linux e junto com ele é instalada uma biblioteca chamada "libwrap.a". Essa biblioteca provê todas as funcionalidades, inclusive a de linkar serviços de rede com o TCP Wrapper. Caso se queira determinar se um serviço de rede está linkado com a "libwrap.a", digite os seguintes comandos como "root".
# strings -f service_binary_path | grep hosts_access ou strings -f service_binary_path | grep libwrapPor exemplo, para verificar se o serviço SSH está incluso no TCP Wrapper digite:
# strings /usr/sbin/sshd | grep hosts_access ou strings /usr/sbin/sshd | grep libwrapNão se pode deixar de falar do "tcpd". O "tcpd" é um facility para o controle de acesso aos internet services (serviços da Internet). O tcpd é um programa que pode e que é geralmente configurado para monitorar as requisições à serviços como o telnet, finger, ftp, exec, rsh, rlogin, tftp, talk, comsat, ou seja, serviços "inetd/xinetd" e também à "daemons" (serviços que têm mapeamento de um-para-um - standalone - em arquivos executáveis como o sshd, httpd, slapd etc). Devido as suas características, o "tcpd" pode ser usado para gerenciar e até restringir as conexões através dos arquivos "hosts.allow" e "hosts.deny".
Resumindo, existem dois modos de operação para monitorar as conexões com o "tcpd": um é através do inetd/xinetd (ftp, telnet etc) e o outro é através de um daemon standalone (sshd, htttpd etc). Nesse último caso, esses daemons usam/possuem uma biblioteca compartilha chamada "libwrap", conforme já foi mostrado anteriormente (on the fly).
Os arquivos de configuração do TCP Wrappers são dois: "/etc/hosts.allow" e "/etc/hosts.deny". Quando um cliente tenta acessar um serviço de rede, são feitas as seguintes etapas:
- O serviço em questão verifica o arquivo "/etc/hosts.allow" e aplica a primeira regra que encontrada que coincida para tal serviço TCP wrapped. Se a regra coincidir, é permitda a conexão. Se não, é realizado a etapa a seguir;
- O serviço em questão verifica o "/etc/hosts.deny" e aplica a primeira regra especificada para tal serviço TCP wrapped. Se a regra for achada, é negada a conexão. Se não, o acesso ao serviço é concedido;
Existem alguns outros pontos importantes que devemos considerar quando usamos o TCP Wrappers:
- Devido as regras do "hosts.allow" serem aplicadas primeiro, elas têm precedência sobre as regras especificadas em hosts.deny. Assim, se um acesso a um serviço é permitido em "hosts.allow", uma regra negando tal acesso em "hosts.deny" será ignorada;
- As regras dentro dos dois arquivos (hosts.allow e hosts.deny) são lidas de cima para baixo e a primeira que coincidir com a tentativa de conexão, será a única regra aplicada. Assim, a ordem das regras é extremamente importante;
- Se nenhum regra para um serviço for achada nos arquivos ou se nenhum arquivo existir, o acesso ao serviço será garantido;
- VER: Se existir um regra liberando um acesso em "/etc/hosts.allow" e o "/etc/hosts.deny" estiver vazio ou não existir, todos terão acesso. Assim, para liberar somente um determinado acesso, além de especificá-lo em "/etc/hosts.allow", é necessário bloquer todos os outros em "/etc/hosts.deny" (ALL: all);
- Os serviços TCP Wrapped não fazem cache das regras inseridas nos arquivos, ou seja, ao mudar o hosts.allow e/ou hosts.deny o efeito será imediato sem a necessidade de reiniciar qualquer serviço;
O formato das regras de acesso em ambos os arquivo "/etc/hosts.allow" e "/etc/hosts.deny" são idênticas. Linhas em branco ou iniciadas com um "#" serão ignoradas e cada regra deve ter suas própria linha. A seguir é mostrada o formato das regras:
<daemon list>: <client list> [: <option>: <option>: ...]- daemon list: ALL, daemon_name ou ALL EXCEPT daemon_name;
- client list: ALL, LOCAL, KNOWN, UNKNOWN, PARANOID, EXCEPT, IP, Net/Mask, HostName, DomainName e/ou UserName;
- option: twist, spawn, allow, deny, command (ver: man hosts_access);
Não se preocupe com todos esses termos acima, pois eles serão explanados mais a frente. Para entender melhor, nada como colocar vários exemplos práticos e a suas respectivas explicações. Assim, seguem várias regras que podem ser colocados dentro dos arquivos "/etc/hosts.allow" e "/etc/hosts.deny":
Domínio
ALL: *.telemikro.local (o computador que tem essa regra impede o acesso de computadores cujo domínio de origem seja “telemikro.local”)
ALL: .telemikro.local (idem)
ALL: tlksrv01.telemikro.local (impede o acesso do computador “tlksrv01” do domínio “telemikro.local” no computador que tinha essa regra. Para bloquear usando o nome de origem é realizada uma pergunta reversa no DNS, ou seja, traduz o IP para nome)
Obs: o parâmetro "ALL" significa todos os serviços que o TCP Wrapper trabalha. (idem)
Rede/Máscara
ALL: 192.168.200.0/255.255.255.0 (impediu o acesso dos computadores da rede “192.168.200.0/255.255.255.0” no computador que tinha essa regra)
ALL: 192.168.200.0/24 (idem)
ALL: 192.168.200.0 (não impediu o acesso dos computadores da rede “192.168.200.0/255.255.255.0” no computador que tinha essa regra)
Obs: Nos testes que fiz, não funcionou muito bem as regras com máscara quebrada.
Parte do endereço IP terminando com um ponto final
ALL: 192.168.200. (impediu o acesso dos computadores que o IP iniciem com “192.168.200.” no computador que tinha essa regra)
ALL: 192.168. (impediu o acesso dos computadores que o IP iniciem com “192.168.” no computador que tinha essa regra)
ALL: 192. (impediu o acesso dos computadores que o IP iniciem com “192.” no computador que tinha essa regra)
IP
ALL: 192.168.200.1 (impediu o acesso do computador com o IP “192.168.200.1” no computador que tinha essa regra)
Serviço
sshd: 192.168.200.1 (impediu o acesso do computador com o IP “192.168.200.1” no computador que tinha essa regra, mas somente ao processo chamado “sshd”. Para ver os nomes dos processos digitar “ps ax”)
sshd: tlksrv00 (impediu o acesso do computador com o Hostname “tlksrv00” no computador que tinha essa regra, mas somente ao processo chamado “sshd”. Para ver os nomes dos processos digitar “ps ax”. Para bloquear usando o nome de origem é realizada uma pergunta reversa no DNS)
sshd: tlksrv00.telemikro.local (idem, mas especificando o domínio)
sshd: ALL (impediu o acesso dos computadores no computador que tinha essa regra, mas somente ao processo chamado “sshd”. Para ver os nomes dos processos digitar “ps ax”)
in.telnetd: ALL (idem, mas somente ao processo/args chamado “in.telnetd”. Para ver os nomes dos processos digitar “vi /etc/inetd.conf”. Esse caso é diferente, pois é um superserver.)
in.telnetd: ALL : deny (idem, mas por causa do “deny” haverá bloqueio mesmo que essa linha esteja em “hosts.allow”)
in.telnetd: ALL : allow (idem, ao contrário)
Serviço + E-mail
in.telnetd: ALL : spawn /usr/bin/mail [email protected] <mailto:[email protected]> < /root/.profile (permite ou proíbe o acesso ao servidor telnet. Ao permitir ou proibir executa o comando que vem depois do “spawn”. Nesse caso envia um e-mail para [email protected]<mailto:[email protected]> com o conteúdo do arquivo “/root/.profile”)
in.telnetd: ALL : spawn /usr/bin/mail [email protected] <mailto:[email protected]> -a “$(/Bin/date) ; $(/sbin/ifconfig)” (permite ou proíbe o acesso ao servidor telnet. Ao permitir ou proibir envia a saída padrão dos comando “date” e “ifconfig” no corpo do e-mail)
Envio de mensagens ao cliente
in.telnetd: ALL : twist /bin/echo “Caia Fora, Hacker do mal!” (substitui o serviço requisitado por um comando específico, ou seja, se essa regra estiver em host.allow ou host.deny o cliente não conseguirá a conexão e receberá a mensagem colocada entre as aspas)
sshd: ALL : twist /bin/echo “Caia Fora, Hacker do mal!” (idem)
USUÁRIO DE ORIGEM
ALL: [email protected] (impedi ou permite o acesso do usuário de origem [email protected] (usuário “root” computador “tlksrv01.telemikro.local”) no computador que tinha essa regra. Exemplo de comando que utilizei em um cliente SSH e que foi impedido: # ssh 172.16.0.137. Já este comando não foi impedido: $ ssh 172.16.0.137. Perceba que esse usuário é o usuário de origem e não o de destino. Em outras palavras, é o usuário que está logado no momento que o comando "ssh" foi executado (quando se tem no prompt o caracter "#" o usuário e o root e quando se tem o "$" é um usuário comum). Já os comandos "ssh [email protected] e ssh 172.16.0.137 -l username definem no username o usuário de destino. Já o usuário de origem é definido com o usuário que está logado no momento, sendo que o cerquilha (#) define o usuário "root" e o cifrão ($) define um usuário comum. Para saber qual é o usuário de origem digite o comando “whoami” no computador que é o cliente de algum serviço (ex: um cliente SSH)
ALL: [email protected] (impedi ou permite o acesso de todos os usuários do computador “tlksrv01.telemikro.local” no computador que tinha essa regra. Não esquecer que é o usuário de origem - "whoami")
WildCard (<client list>)
<daemon list>: <client list> [: <option>: <option>: ...]
- ALL: o wilcard universal que sempre faz comparações. Exemplos acima;
- LOCAL: é equivalente ao 127.0.0.1 ou a qualquer hostname que tenha esse IP, como, por exemplo, o localhost. Ver o “/etc/hosts”. Ex servidor: ALL: LOCAL à permite ou nega todos os serviços desde que ele sejam acessado por 127.0.0.1 ou localhost. Ex cliente: ssh 127.0.0.1 ou ssh localhost;
- UNKNOWN: relaciona-se com usuário e/ou host que são desconhecidos. Essa opção está relacionada as requisições que chegam no servidor, obrigando-o a perguntar ao DNS se aquele endereço do cliente existe. Se existir o servidor aceita a conexão. Se o cliente tentar acessar o servidor usando o IP, o servidor perguntará qual o hostname do IP do cliente (pergunta reversa - PTR). Se o cliente tentar acessar o servidor usando o HostName, o servidor também perguntará qual o hostname do IP do cliente (pergunta reversa – PTR – nesse caso também será feito o PTR, pois quando o cliente acessa o servidor usando o HostName, primeiro o cliente pergunta ao DNS qual o IP do servidor, depois envia o tráfego ao servidor e o servidor perguntará qual o HostName do cliente). Muito cuidado ao usar essa opção, pois se os DNS estiverem inacessíveis ou com problemas, o servidor com a configuração “UNKNOWN” também estará. Em relação ao impedimento de usuário, pelo menos aos usuários de origem, essa opção não teve efeito. Essa opção geralmente é usada no /etc/hosts.deny, pois se usar e /etc/hosts.allow e o /etc/hosts.deny estiver vazio, a opção UNKNOWN não fará efeito. Ex servidor: ALL: UNKNOWN
- KNOWN: relaciona-se com usuário e/ou host que são conhecidos. Essa opção está relacionada as requisições que chegam no servidor, obrigando-o a perguntar ao DNS se aquele endereço do cliente existe. Se existir o servidor não aceita a conexão (NXDomain). Se o cliente tentar acessar o servidor usando o IP, o servidor perguntará qual o hostname do IP do cliente (pergunta reversa - PTR). Se o cliente tentar acessar o servidor usando o HostName, o servidor também perguntará qual o hostname do IP do cliente (pergunta reversa – PTR – nesse caso também será feito o PTR, pois quando o cliente acessa o servidor usando o HostName, primeiro o cliente pergunta ao DNS qual o IP do servidor, depois envia o tráfego ao servidor e o servidor perguntará qual o HostName do cliente). Muito cuidado ao usar essa opção, pois se os DNS estiverem inacessíveis ou com problemas, o servidor com a configuração “KNOWN” ficará totalmente acessível. Em relação ao impedimento de usuário, pelo menos aos usuários de origem, essa opção não teve efeito. Essa opção geralmente é usada no /etc/hosts.deny, pois se usar e /etc/hosts.allow e o /etc/hosts.deny estiver vazio, a opção KNOWN não fará efeito. Ex servidor: ALL: KNOWN
- PARANOID: nos testes que fiz sempre permitiu o acesso. Contudo, sempre perguntava ao DNS a existência de tal IP (PTR – pergunta reversa)
EXCEPT
ALL: 172.16.0.0/24 EXCEPT 172.16.0.135 (impede ou permite o acesso dos computadores da rede “172.16.0.0/24” no computador que tinha essa regra EXCETO do computador que tinha o IP 172.16.0.135)
ALL EXCEPT sshd: 172.16.0.0/24 (impede ou permite TODOS os acessos da rede “172.16.0.0/24” EXCETO dos computadores da rede “172.16.0.0/24” ao serviço do SSH. As outras redes conseguirão acessar todos os serviços inclusivo o SSHD)
LOGGING
sshd: tlksrv00 : severity emerg (impede o permite o acesso do computador com o Hostname “tlksrv00” no computador que tinha essa regra, mas somente ao processo chamado “sshd”. Além disso, mudou o nível de registro dos logs (severity emerg). O emerg aumenta o nível de detalhamento dos logs que ficam em “/var/log/auth.log”)
EXPANSIONS
sshd: ALL : spawn /bin/echo $(date) acesso negado para %h>>/var/log/sshd2.log (permite ou proíbe um acesso ssh nesse servidor. Ao realizar essa ação cria um arquivo log com a data e o hostaname do cliente (%h))
sshd: ALL : twist /bin/echo “421 %h saia daqui seu hacker!” (permite ou proíbe um acesso ssh nesse servidor. Ao realizar essa ação cria um arquivo log com a data e o hostaname do cliente (%h))
- %a: The client's IP address;
- %A: The server's IP address;
- %c: Supplies a variety of client information, such as the username and hostname, or the username and IP address;
- %d: The daemon process name;
- %h: The client's hostname (or IP address, if the hostname is unavailable);
- %H: The server's hostname (or IP address, if the hostname is unavailable);
- %n: The client's hostname. If unavailable, unknown is printed. If the client's hostname and host address do not match, paranoid is printed;
- %N: The server's hostname. If unavailable, unknown is printed. If the server's hostname and host address do not match, paranoid is printed;
- %p: The daemon process ID;
- %s: Various types of server information, such as the daemon process and the host or IP address of the server;
- %u: The client's username. If unavailable, unknown is printed;
Mais fechado ou aberto
ALL: ALL (permite ou nega todos os serviços para todos os hosts)
ALL: LOCAL @algum_dominio (permite ou nega todos os serviços do hosts dentro do domínio local e dos membros do domínio “@algum_dominio”)
Comando que verifica a syntax
# tcpdchk (comando que verifica a syntax dos arquivos "/etc/hosts.allow" e "/etc/hosts.deny" e/ou compara as entradas desses arquivos com as dos arquivos de configuração do "inetd" ou "xinetd")
# tcpdchk -v (verbose)
Comando que informa como o TCPWrapper manuseará um serviço
O "tcpdmatch" é um comando que informa como o TCPWrapper manuserá um serviço de acordo com as entradas que estão dentro de "/etc/hosts.allow" e "/etc/hosts.deny". Exemplos:
# tcpdmatch <daemon> <client> (syntax)# tcpdmatch sshd localhost
# tcpdmatch sshd 172.16.200.119
# tcpdmatch ftpd 211.44.0.12
Referências Bibliográgicas
http://www.redhat.com/docs/manuals/linux/RHL-9-Manual/ref-guide/ch-tcpwrappers.html