Mar 07

socat tip: create virtual serial port and link it to TCP

Reading time: < 1 minute

Create a virtual serial port and publish it on TCP port:

socat pty,link=/dev/virtualcom0,rawer tcp-listen:2101

In another computer, for instance, another virtual port can be created and connected to the previous one:

socat pty,link=/dev/virtualcom0,rawer tcp:SERVER_IP:2101

If in any of those both sides we want to open a real serial port, for instance, in the server case we can run:

socat /dev/ttyS0,rawer tcp-listen:2101

More information on socat manpage.

Jun 30

Enabling linux kernel to open LOTS of concurrent connections

Reading time: < 1 minute

Just a small recipe about how to enable linux kernel to open tons of concurrent connections. Really simple and useful post entry.

echo “10152 65535″ > /proc/sys/net/ipv4/ip_local_port_range
sysctl -w fs.file-max=128000
sysctl -w net.ipv4.tcp_keepalive_time=300
sysctl -w net.core.somaxconn=250000
sysctl -w net.ipv4.tcp_max_syn_backlog=2500
sysctl -w net.core.netdev_max_backlog=2500
ulimit -n 10240
Jun 20

httptunnel: TCP sobre HTTP

Reading time: 2 – 2 minutes

HTTPtunnel logo

Amb httptunnel es poden establir connexions TCP sobre un enllaç HTTP, és a dir, disposem de dues eines el htc i el hts, escencialment el que fa és:

  • hts: publica un port simulant un servidor HTTP al conectar-hi amb htc ens enviarà cap al HOST:PORT configurats
  • htc: es conecta a hts usant HTTP i simulant un client HTTP normal (ffx, crhome, ie, etc) però en realitat transporta paquets TCP en el payload de les queries, l’usuari pot conectar-se a un port local que es publica i que permet accedir al HOST:PORT al que ha conectat hts de forma transparent

Per fer una prova de concepte jo el que he fet és conectar el hts amb un servidor VNC, al costat del htc he connectat un client VNC i he accedit al VNC de forma totalment transparent, a més amb un sniffer he comprovat que els paquets que passeben per la xarxa eren paquets HTTP estàndards, i així era. Tan senzill com això:

server:
./hts -w -F 127.0.0.1:5900 1080

client:
./htc -F 2300 server:1080
vinagre localhost:2300

A més també suporta la possibilitat de fer-ho a través d’un proxy, això si aquest només esta suportat si és sense autenticació o amb autenticació bàsica. Així doncs, a partir d’això em venen al cap algunes millores interessants:

  • suportar autenticació Digest i NTLM.
  • permetre accés al tunel via stdin/stdout (així ho podriem usar amb SSH com a ProxyCommand).
  • poder connectar-se a un segon proxy en l’extrem remot, és a dir, hts no té l’enllaç pre-establert.
  • suportar SSL, així ens estalbiariem haver d’usar stunnel per simular HTTPs.
Mar 19

UDPTunnel – enviar els paquets UDP per sobre d’enllaços TCP

Reading time: < 1 minute

Una altre d’aquelles eines que malgrat ser petitones i rares poden servir per fer mil i una coses. Per exemple, connectar a un servidor DNS a través d’un port TCP en una xarxa on el tràfic UDP estigui tancat.

UDPTunnel és una eina molt simple d’usar i la seva sintaxis és molt autoexplicativa:

 udptunnel -s TCP-port [-r] [-v] UDP-addr/UDP-port[/ttl]
 udptunnel -c TCP-addr[/TCP-port] [-r] [-v] UDP-addr/UDP-port[/ttl]

és interessant fixar-se que el mateix executable pot ser usat com a servidor o com a client, així doncs ideal per construir els dos costats de l’enllaç de forma simple.
A més si ho combinem amb httptunnel podem passar per sobre de proxies de forma senzilla.

Mar 08

reDuh: TCP sobre HTTP

Reading time: 1 – 2 minutes

La idea es força simple es tracta de transportar un fluxe TCP sobre d’una connexió HTTP convencional, fiexeu-vos que en aquest cas no estem parlant de proxies ni similars. Sinó de paquets TCP+HTTP que en la part de dades del HTTP tornen a implementar TCP, si fessim un petit esquema seria algo així:

+----+----+------+------+-----+------+
|... | IP | TCP | HTTP | TCP | DATA |
+----+----+------+------+-----+------+

Si realment teniu aquest interés montar reDuh és realment senzill, de fet, suporta servidors amb JSP, PHP i ASP. En escència l’únic que fa és usar aquests protocols per re-obrir una connexió TCP. Així doncs, al servidor on montem aquesta eina hem de tenir certs privilegis per poder obrir sockets des d’un script.
L’eina no és massa recomanable si pensem tenir fluxes de dades molt intensos, per exemple, senssions VNC. Però funciona prou bé si el que volem és transportar una sessió SSH o similar.

Nov 20

podcast 1×13: desafio networking [la solución]

This entry is part 3 of 3 in the series desafio networking
Reading time: < 1 minute

A pesar de que la solución se alcanzó y aplico durante los meses de agosto y septiembre, hasta hoy no he podido grabar la solución en este podcast. Espero que haya sabido explicarla bien y que quede claro como se ha hecho para solucionar el problema, sinó preguntad.

Oct 03

TCP bouncer amb failover

Reading time: 2 – 4 minutes

Al projecte GATv2 fa un parell de dies que hi he publicat un subprojecte que anomeno tcp-fwd. Es tracta d’un petit i simple aplicatiu programat amb Python i Twisted. La funcionalitat és molt senzilla es tracta d’un bouncer TCP que en cas de no poder connectar amb el primer destí on re-enviar el tràfic TCP ho prova amb el segon, sinó el tercer i així fins a tants servidors com s’hagin definit. Si no es pot acabar establint la connexió es desconnecta l’enllaç TCP cap al bouncer. O sigui, el comportament és transparent pel client original. Pels que no estigueu familiaritzats amb la funcionalitat d’un bouncer la intentaré explicar. Es tracta d’un socket TCP que escolta en un port i actua com un reverse proxy. O sigui, quan rep una connexió acte seguis s’obre una altre connexió cap al servidor i si aquesta es pot establir llavors connecta la primera connexió amb la segona.

L’inconvenient més gran que veig en aquesta idea és que la connexió que arriba al servidor final no té com a origien la IP del client, sinó la IP del servidor que fa de bouncer això fa que el fitxer de logs del servidor final no tingui la informació IP del client que realment s’ha connectat. Malgrat axiò hi ha escenaris en que aquesta eina és molt útil, ja que no sempre el més important són aquests logs sinó que el client acaba obtenint el servei que volia de forma trasparent i el sistema de failover que uso sempre segueix la mateixa seqüència de prova i error per cada socket que s’obre, així doncs, el sistema de failover és instantani i no perd ni una sola crida.

Una de les aplicacions per les que l’estic usant és per fer l’entrega de correu a un postfix. Es tracta d’un servidor de correu que només fa filtratge de correu i els correus que passen els filtres s’entreguen al servidor de correu real de l’empresa, doncs bé, per saber quin és el servidor de l’empresa uso el fitxer de configuració /etc/postfix/transport on s’indica segons el domini el servidor on entregar el correu. Però no he sabut veure com dir-li més d’un servidor de correu on fer l’entrega. Així doncs, el que faig és posar com a IP i port de transport una IP localhost i un port al atzar, llavors el postfix entrega el correu al bouncer situat en aquesta IP localhost i és el bouncer que intenta connectar aquest socket amb algún dels servidors de correu interns. Per tant, el tema és completament transparent pel postfix i els servidors que reben el correu tenen la mateixa IP origen que si ho haguessin rebut directament del postfix.

Suposo que la idea ha quedat ben definida, sinó ja sabeu que podeu fer-me les preguntes que calguin. El codi del projecte el teniu a: tcp-fwd.

Jul 29

podcast 1×11: desafio networking [el problema]

This entry is part 2 of 3 in the series desafio networking
Reading time: < 1 minute

Hablando sobre el problema del articulo sobre el desafio de networking. También aprovecho para enlazar una buena referencia sobre como comprender los problemas de secuencias TCP:

Espero haberme explicado bien y haber podido describir el problema algo mejor que en el articulo anterior, ya que no es sencillo describir un problema tan inusual.

Jul 24

Desafio Networking [el problema]

This entry is part 1 of 3 in the series desafio networking
Reading time: 6 – 10 minutes

Escenario

Se dispone de un dispositivo de hardware con un linux embedded al que no se puede acceder ya que el fabricante no lo facilita, se ha intentado acceder pero no hemos sido capaces de acceder ni con nuestros medios ni con los de una importante empresa de electrónica. Creemos que el kernel es un 2.4.X por lo que observamos. El dispositivo tiene una pantalla y su finlidad es mediante un protocolo propietario y un protocolo de transporte de ficheros (FTP) descargar una playlist para reproducir en la pantalla.

A través de red se conecta al servidor del fabricante de donde recoje una playlist y unos contenidos multimedia. Escencialmente usa los puertos:

  • TCP/8889 (protocolo de control del fabricante) va en ‘plain text’ ya le hemos hecho la ingenieria inversa.
  • FTP en modo pasivo

Con el servidor del fabricante descarga el 99% de la veces correctamente y sin problemas. En el fichero adjunto ‘korea-ok.cap’ si lo examinais podreis ver que todo se desarrolla perfectamente. La IP privada que podeis ver es del dispositivo en la LAN y a través de una LMDS se conecta a Korea a la IP: 210.114.220.180, si os fijais el fabricante usa como servidor FTP un ‘Serv-U’ para Windows.

Problema

Se ha implementado el protocolo propietario del fabricante con Python y funciona perfectamente, el problema es al hacer la descarga por FTP. El dispositivo se conecta a nuestro servidor FTP y de forma completamente aleatoria cierra la transmisión sin motivo aparente y se reinicia el dispositivo. Esto siempre pasa mientras se esta haciendo una conexión FTP-control (21/tcp) o FTP-data (puerto aleatorio del ftp pasivo/tcp).

En el fichero ‘cwd-fail.cap’ se puede ver uno de los típicos fallos que tiene el dispositivo al intentar descargar a un servidor FTP local (en este caso un proftpd en una Gentoo). Concrectamente al mandar el comando FTP ‘CWD’ el dispositivo decide cerrar la conexión y no seguir con la descarga. Después de varios intentos se reinicia. Para no perderos con los paquetes he dejado en la captura sólo el socket que tiene el problema.

Para no despistar recordar que esto no tiene porqué pasar en el canal de FTP-control puede pasar también en un FTP-data, puede pasar al 1% de descarga del fichero, al 30%, 50%, 98%… es completamente aleatorio.

Para tener más ejemplos de errores se adjunta el fichero ‘local-fail.cap’ donde se puede ver como se da un error igual al anterior pero ahora en el canal de datos de FTP. Concretamente podeis ver como se cierra el socket en el paquete 916 sin motivo apararente. Comentar que los errores de checksum de TCP no son relevantes ya que son debidos a que la tarjeta de red no estaba como sigue:

# ethtool -k eth0
Offload parameters for eth0:
rx-checksumming: off
tx-checksumming: off
scatter-gather: off
tcp segmentation offload: off
udp fragmentation offload: off
generic segmentation offload: off

En otras pruebas se han hecho con los parametros comentados y el error es el mismo. A pesar de que ya no aparecen las alertas por ‘checksum error’. Si se cree vital tener una captura sin los errores de checksum no hay problema en hacerla. Pero después de meses de pruebas esta claro que esto no es relevante.

Para demostrar que el comportamiento es aleatorio a continuación se adjunta un fichero ‘local-ok.cap’ con la captura de una sesión en el serividor FTP local que ha funcionado perfectamente. Se puede observar en el paquete: 18975 que se descarga bien el contenido de un fichero, concretamente un fichero .mpg, con este fichero finaliza todo el traspaso de datos correctamente.

Hardware y soft probado

Se han hecho infinidad de pruebas y de combinaciones:

5 servidores distintos:

  • 1 debian con kernel 2.6.24.5-grsec-xxxx-grs-ipv4-64 en el proveedor ovh.es (100Mpbs simétricos sin restricciones), servidor FTP proftpd puerto 2090/tcp
  • 1 debian con kernel 2.6.18-5-686 proveedor jazztel sin fw, ni restricción de ningún tipo 100Mbps simétricos contra internet y servidores FTP en el puerto 21 pure-ftpd y en el puerto 2090 proftpd.
  • 1 ubuntu con kernel 2.6.24-16-server proveedor jazztel con fortinet como fw en modo transparente, proftpd en puerto 2090.
  • 1 gentoo con kernel 2.6.25-gentoo-r5 en red local con proftpd en puerto 2090.
  • 1 windows xp virtualizado con vmware workstation 6 sobre gentoo con un servidor FTP Serv-U, la tarjeta de red virtual en modo bridget con la del sistema operativo host.

el comportamiento es el mismo con todas la combinaciones

Intuición de solución

Jugando con los parámetros del kernel de TCP (/proc/sys/net/ipv4) se consiguen hacer cambios de comportamiento en el error. Por ejemplo, se han hecho pruebas con:

tcp_adv_win_sacle = 0,1,2
tcp_allowed_congestion_control = cubic, bic, reno, etc.
tcp_base_mss = 512, 1024, 1500
tcp_dsack = 0,1
tcp_ecn = 0,1
tcp_fack = 0,1
tcp_sack = 0,1
tcp_syncookies = 0,1
tcp_timestamps = 0,1
tcp_workaround_signed_windows = 0,1
tcp_window_scaling = 0,1

infinidad de valores y combinaciones probadas en:

tcp_mem
tcp_moderate_rcvbuf
tcp_mtu_probing
tcp_rmem
tcp_tso_win_divisor
tcp_wmem

También se han hecho pruebas limitando el ancho de banda, y con algunos otros parámetros de kernel que ahora no recuerdo. Se ha probado de opimitzar los servers para rendir al máximo, al mínimo, por defecto… etc.

Lo que se consigue con todo esto es conseguir que algunas veces se haga la descarga, pero no se consigue afianzar patrones de forma feaciente, es decir, a menudo se sigue cerrando la conexión TCP.

FAQ de obviedades

  1. Es obvio que el firmware del dispositivo esta mal hecho, pero esto no se puede tocar.
  2. El dispositivo se puede configurar via una compact flash, donde se guarda un fichero de configuración, un fichero binario compilado para ARM y el contenido multimedia que se va descargando.
  3. Se ha intentado hablar mil veces con el fabricante pero es como hablar con una pared, a parte los técnicos no hablan inglés, sólo coreano. Increible, no?
  4. El problema lo tiene el stack TCP del dispositivo o algún otro elemento similar. Este es el que cierra la conexión!!! no se puede mantener la conexión abierta des del servidor cuando el dispositivo la ha cerrado, lo único que se puede hacer es evitar que el cliente la cierre. El problema es como.
  5. Si! el server del fabricante descarga bien via FTP en el 99% de los casos. Este es el gran probleam, parece tonta la pregunta pero me la han hecho como 20 veces, así que merecia estar aquí.

Ficheros

Los ficheros de los que se habla en este correo de pueden descargar de:

  • http://oriolrius.cat/downloads/korea-ok.cap
  • http://oriolrius.cat/downloads/cwd-fail.cap
  • http://oriolrius.cat/downloads/local-fail.cap
  • http://oriolrius.cat/downloads/local-ok.cap

Desafio

El entorno de laboratorio lo tengo montado en la oficina, esta abierta 24×7 para quedar conmigo para hacer pruebas in-situ. Obviamente responderé todo lo que sea online y orientaré con lo que pueda y más.

Este problema lo arrastro desde hace unos 4 meses y llevo casi 4 dias sin vida, sólo obsesionado buscando la solución pero no hay manera de ver la luz.

No dispongo de muchos recursos, debido a que ya he perdido muchísmo dinero buscando la solución durante todo este tiempo, pero bajo resultados se recompensará tanto como sea posible a la mente privilegiada que consiga dar con la solución.

Ya tengo solución

Después de darle vueltas al tema de momento no contaré las varias soluciones que a dia de hoy ya he enontrado al problemón. Así pue aprovecharé el problema para lanzar el podcast 1×11 describiendo con todo detalle el problema y dando algunas pistas de como llegar a la solución. Quizá a nadie le pique tanto la curiosidad como para seguir la solución con este detalle pero de esta forma mantengo un poco la intriga y si alguien realmente necesita saber la solución sin seguir el culebrón sólo tiene que mandarme un correo privado y se lo contaré. Para hacer boca deciros que la intuición de solución que tenia no era mala.