Manual

do

Maker

.

com

Sockets TCP com shell script

Sockets TCP com shell script

Escolhi escrever sobre sockets TCP com shell script por razões significativas. Recentemente, precisei escrever "1" linha de comando para verificar se um servidor remoto já estava disponível. Tem algumas opções como NetCat, hping3 e nmap. Como eu não queria consumir tempo em algo tão simples, optei pelo nmap, mas adivinha? Ele não vem instalado por padrão em servidores com sistemas mínimos, o que acabou se tornando uma necessidade. Eu não costumo ficar matutando no mesmo problema após encontrar uma solução, mas fica lá no meu subconciente perpetuamente, como Atlas carregando o mundo nas costas. Daí, certo dia comecei a cogitar as opções de sockets diretamente por shell e acabei escrevendo alguns scripts bastante modestos mas extremamente eficazes.

e desejar utilizar um IPC (InterProcess Communication), sugiro esse artigo onde demonstro a utilização de UNIX Sockets Domain.

Sockets TCP com shell script - Conceito básico

Primeira coisa a entender; o recurso é nativo do bash e o socket não é visível para o comando ls. UDP também está disponível, mas é mais fácil mostrar exemplos com TCP, além de outras razões relacionadas ao funcionamento do protocolo, cujo detalhes não serão abordados aqui.

Como usar socket em shell script

É bem simples, basta jogar qualquer valor para /dev///. Para exemplificar, abri um socket em Python para escuta, de forma tradicional:

#!/usr/bin/python 
import socket 
host = '127.0.0.1' 
port = 7000 
addr = (host, port) 
serv_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serv_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
serv_socket.bind(addr) 
serv_socket.listen(10) 
print 'aguardando conexao' 
con, cliente = serv_socket.accept() 
print 'conectado' 
print "aguardando mensagem" 
recebe = con.recv(1024) 
print "mensagem recebida: "+ recebe 
serv_socket.close()

Agora para escrever, simplesmente digite:

echo "hell low word" >/dev/tcp/127.0.0.1/7000

O resultado dessa comunicação é a imagem de destaque desse artigo.

Com isso, podemos seguir para exemplos de utilização mais interessantes, mas já deu pra sentir o poder do shell, hum?

Checar datetime por shell script

Para ajuste de horário em servidores, utiliza-se o NTP. Não recomendo a utilização desse recurso para fazer ajuste de hora em servidores, mas serve muito bem para desktops/notebooks. Para tal, basta pegar a informação em um servidor remoto, por exemplo:

cat </dev/tcp/time.nist.gov/13

O que resulta em algo como:

getTime_sh.webp

Aguardar até que uma porta esteja disponivel em um servidor remoto

Foi o caso em que inicie  a construção de alguns scripts para interagir com sockets por shell script. Antes de subir um serviço, era necessário saber se o banco de dados já havia sido iniciado. O servidor de banco de dados é iniciado junto ao servidor de aplicação, por isso a necessidade da validação. Poderia ser feito com nmap, como fiz inicialmente, mas a melhor maneira é essa (exemplificando com um servidor web):

#!/bin/bash
HOST="127.0.0.1"
PORT=80
OK=1
while [ $OK ];do
   (echo >/dev/tcp/$HOST/$PORT) 2>/dev/null  && {
       echo "ok"
       exit 0 
       }
   echo "$HOST:$PORT - ainda nao"
   sleep 1
done
echo "Webserver up"

E dá pra limpar mais, porque a variável $OK não foi utilizada, bastava usar true invés dela.

Alternativa ao wget

O wget é um programa riquíssimo em recursos, mas não vem instalado por padrão em uma instalação mínima. Para não ferir os protocolos de segurança da empresa e não precisar passar por uma aterrorizante sessão de burocracia, para baixar uma página simples podemos utilizar:

!/bin/bash
exec 3<>/dev/tcp/uol.com.br/80
echo -e "GET / HTTP/1.1\r\nhost: uol.com.br\r\nConnection: close\r\n\r\n" >&3
cat <&3

O resultado será um código 300 porque o site faz o redirecionamento pra HTTPS, portanto, só vai bem se não tiver redirecionamento nem SSL na transação.

Alternativa ao nmap

Mais uma vez, o nmap não é uma ferramenta qualquer. Lembra do chaveiro no filme Matrix? Enquanto ele corria com o Neo abrindo portas, a menina ficava executando o scanner do lado de fora. Quando mostrou a tel, lá estava o nmap (utilizando um exploit que já era velho na época, mas valeu mesmo assim). Mas suponhamos que fosse o caso de saber que portas estão abertas em um determinado host. Uma forma de provar o conceito seria:

#!/bin/bash
HOST="192.168.30.89"
RANGE="20 1000"
for i in `seq $RANGE`;do
    (echo >/dev/tcp/$HOST/$i) >/dev/null 2>&1 && echo "$i :open"
 done

Como saber os hosts ativos em uma rede LAN?

Mais uma vez, o nmap daria conta do recado facilmente. Mas, a maneira mais leve e simples de fazer sem precisar instalar nada deve ser essa (supondo uma rede classe C e limitando os IPs para que o scan comece fora da reserva dedicada):

#!/bin/bash
LAN="192.168.30."
RANGE="50 254"
for HOST_T in `seq $RANGE`;do
    ping -c1 -W1 $LAN$HOST_T 2>&1>/dev/null && echo "$LAN$HOST_T up"&
done

Bem, essas foram as melhores aplicações que encontrei até o momento, mas claro que sempre tem mais (ou muito mais) que pode ser feito. Espero que possa se divertir com essas dicas que servem para qualquer Linux, desde que você esteja usando o bash como shell (não sei se outros implementam o mesmo recurso).

Agora você já pode navegar tranquilamente, chamando-o pelo menu ou por um terminal.

Inscreva-se no nosso canal Manual do Maker no YouTube.

Também estamos no Instagram.

Nome do Autor

Djames Suhanko

Autor do blog "Do bit Ao Byte / Manual do Maker".

Viciado em embarcados desde 2006.
LinuxUser 158.760, desde 1997.