====== 18. TCP en Linux ====== ===== ss ===== La orden ''ss'' permite ver que puertos están escuchando y que conexiones TCP hay Veamos las opciones que tiene ^Opción ^ Explicación ^ | -t | Solo mostrar información de TCP | | -u | Solo mostrar información de UDP | | -n | Mostrar los números de puerto en vez de sus nombres, por ejemplo mostrará 22 en vez de **ssh** | | **-l** | Solo mostrar información de puertos que está escuchando (servidores). La ''l'' viene de la palabra "listening" que significa escuchando. | | **-a** | Solo mostrar información de puertos que conectados a otros Hosts | | -p | Muestra el proceso que se ha conectado a ese puerto.**Es necesario lanzar la orden ss con sudo para ver los procesos de otros usuarios** | | -4 | Solo mostrar información de IPv4 | | -6 | Solo mostrar información de IPv6 | Las opciones mas importantes son "-l" y "-a". Con la opción "-l" veremos los puertos que estás escuchando, es decir los puertos en los que estamos esperando recibir conexiones de otros Hosts. Mientras que con la opción "-a" veremos todas las conexiones que hay Mas infornmación en: * [[http://www.cyberciti.biz/tips/linux-investigate-sockets-network-connections.html|ss: Display Linux TCP / UDP Network and Socket Information]] * [[http://www.binarytides.com/linux-ss-command/|Linux ss command]] logongas@beren:~$ ss -tl4n State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 0.0.0.0:17500 0.0.0.0:* LISTEN 0 128 127.0.0.1:17600 0.0.0.0:* LISTEN 0 128 127.0.0.1:17603 0.0.0.0:* Las opciones "-tl4n" indican que solo mostrar puertos TCP, solo mostrar lo que están escuchando , solo mostrar de la versión IPv4 y por último que los puertos se muestren en formato numérico. Lo mas interesante es la columna de "Local Address:Port". Que muestra para cada puerto, la IP en la que está escuchando. Recordar que un ordenador puede tener varias IPs. Vamos que se muestran al menos 2 IPs: * 127.0.0.1: En este caso el proceso servidor solo podra ser conectado por procesos de nuestra propia máquina ,ya que 127.0.0.1 solo es accesible desde nuestra propia máquima. * 0.0.0.0: Significa que el proceso servidor está escuchando en cualquier IP que tenga la máquina. La primera columna ahora siempre muestra "LISTEN" ya que al poner la opción "-l" somo muestra los puertos que están escuchando. Así que tenemos a un proceso escuchando en el puerto 17500 que puede ser conectado por cualquier Host. Como ya dijimos no es muy adecuado que tengamos eso. Por ello vamos a ver ahora que proceso lo ha abierto , para ello añadimos la opción "-p" logongas@beren:~$ sudo ss -tl4np State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 0.0.0.0:17500 0.0.0.0:* users:(("dropbox",pid=3782,fd=89)) LISTEN 0 128 127.0.0.1:17600 0.0.0.0:* users:(("dropbox",pid=3782,fd=68)) LISTEN 0 128 127.0.0.1:17603 0.0.0.0:* users:(("dropbox",pid=3782,fd=99)) Y podemos ver que es algo de dropbox, y si hacemos una búsqueda de ese puerto en internet nos sale que es "used for LAN discovery and file Sync between Dropbox Clients.". Así que no debemos preocuparnos. Ahora vamos a ver todos los puertos que tienen una conexión establecida, para ello usaremos la opción "-a" pero también un grep para filtrar aquellos cuyo "State" es "ESTAB" logongas@beren:~$ sudo ss -ta4np | grep "^ESTAB" ESTAB 0 0 192.168.1.110:36664 162.125.19.131:443 users:(("dropbox",pid=3782,fd=76)) ESTAB 0 0 192.168.1.110:34140 162.125.68.13:443 users:(("dropbox",pid=3782,fd=119)) Ahora vemos que hay una columna mas que antes, como son conexiones establecida con otro ordenador, la primera "IP:Puerto" es el origen de la conexión y la segunda "IP:Puerto" es destino de la conexión. Podemos ver que dropbox tiene establecidas dos conexiones contra las IPs 162.125.19.131 y 162.125.68.13 ambas al puerto 443. Notar que el puerto origen de las conexiones se establecía de forma "aleatoria" por el sistema operativo. Así que acabamos de ver realmente las conexiones que tenemos en nuestro ordenador recordando que de forma teórica decíamos que era de la siguiente manera: TCP (IP Origen,Puerto Origen) ----------> (IP Destino,Puerto Destino) Y vemos por ejemplo con dropbox TCP (192.168.1.110,36664) ----------> (162.125.19.131,443) ===== iftop ===== La orden ''iftop'' sirve para ver cuanto ancho de banda consume cada conexiones que tenemos establecida. Mas información: * [[http://en.wikipedia.org/wiki/Iftop|iftop]] * [[http://www.linuxjournal.com/content/sysadmins-toolbox-iftop|The Sysadmin's Toolbox: iftop]] logongas@beren:~$ sudo apt install iftop Lo primero es instalar el pequete ''iftop'' Y luego no hay mas que ejecutarla: logongas@beren:~$ sudo iftop -n 12,5Kb 25,0Kb 37,5Kb 50,0Kb 62,5Kb └───────────────┴───────────────┴───────────────┴───────────────┴─────────────── 192.168.1.110 => 192.168.1.103 0b 0b 0b <= 2,12Kb 2,12Kb 2,12Kb 192.168.1.110 => 35.201.97.85 0b 462b 462b <= 0b 1,03Kb 1,03Kb 192.168.1.110 => 31.13.83.51 540b 270b 270b <= 568b 284b 284b 255.255.255.255 => 192.168.1.1 0b 0b 0b <= 0b 402b 402b 192.168.1.110 => 239.255.255.250 0b 400b 400b <= 0b 0b 0b ──────────────────────────────────────────────────────────────────────────────── TX: cum: 566B peak: 1,68Kb rates: 540b 1,11Kb 1,11Kb RX: 5,00KB 15,0Kb 15,0Kb 9,99Kb 9,99Kb TOTAL: 5,55KB 15,6Kb 15,6Kb 11,1Kb 11,1Kb La primera columna es la IP de nuestro ordenador, la segunda es la IP del otro Host. Y las 3 últimas el lo enviado o recibido en lo últimos 2, 10 y 40 segundos. Vemos que para cada conexión hay dos líneas ya que la primera línea es lo enviado y la segunda linea es lo recibido. En la parte de abajo tenemos los totales desde que se inició la aplicación. Con el total acumulado enviado y recibido (donde pone cum), el máximo de velocidad (donde pone peak) y luego el total de los últimos 2, 10 y 40 segundos. Aunque el objetivo de iftop es saber el ancho de banda que se está usando, hay otra cosa mas interesante. Con la orden ''ss'' veiamos las conexiones que había en ese momento , peor hay muchas conexiones que duran muy poco tiempo, porque es establecerla, enviar un dato y cerrarla, así que con ''ss'' tendríamos que cazarla en el momento. Así que la ventaja de ''iftop'' es que las vemos "en directo". Con iftop se puede añadir también la opción "-n" para que las direcciones IP salga numéricamente en vez de los "nombres DNS" logongas@beren:~$ sudo iftop -n ===== nload ===== La orden ''nload'' es similar a ''iftop'' solo que muestra una gráfica en modo texto del uso del ancho de banda y siempre es del total no de cada conexión por separado. Mas información: * [[https://ubunlog.com/nload-controlar-trafico-red/|Nload, un programa para la terminal con el que controlar el tráfico de red]] logongas@beren:~$ sudo nload Device enp2s0 [192.168.1.110] (2/3): ============================================================================================ Incoming: ## . ## ##. ## # ## ### ## # ## ### ## ## |# ## ### # ## ## ### ## ### # ## ##|### ## ### |# ## ######| ## . ###| ##.| ## #| ####### ## #| #### ####. Curr: 1.37 kBit/s ##.## ####### ## ## #### ##### Avg: 1.65 MBit/s ##### ####### .##| .## #### . #|##### Min: 0.00 Bit/s #####|########.####.###| #### . ## |####### Max: 28.26 MBit/s ########################..####. ####|########| Ttl: 642.71 MByte Outgoing: Curr: 2.45 kBit/s Avg: 189.84 kBit/s |# Min: 0.00 Bit/s .. |### . .. . Max: 2.36 MBit/s ||.##.||####|. .### .... |##| .|#|...###. Ttl: 56.40 MByte Se muestran dos gráficas. La superior con los datos que entran y la inferior con los que salen. En el eje X se muestra el tiempo y en el eje Y se muestra el ancho de banda. Si hay mas de una tarjeta de red, se puede pasar de una tarjeta a otra con las teclas de cursor de izquierda y derecha. Una orden similar a "nload" es "bmon" que muestra información similar pero de una manera mas clara. Ademas que para cambiar de tarjeta de red se usan las teclas de "arriba" y "abajo" en vez de "izquierda" y "derecha" {{:clase:daw:si:3eval:bmon.png?300|}} Mas información en: * [[https://www.howtogeek.com/664589/how-to-use-bmon-to-monitor-network-bandwidth-on-linux/|How to Use bmon to Monitor Network Bandwidth on Linux]] ===== nmap ===== La orden ''nmap'' permite saber que Hosts tenemos en nuestra red y que puertos están escuchando. Mas información: * [[http://www.cyberciti.biz/networking/nmap-command-examples-tutorials/|Top 30 Nmap Command Examples For Sys/Network Admins]] apt install nmap Primero hay que instalarla logongas@beren:~$ nmap 192.168.3.0/24 Starting Nmap 7.60 ( https://nmap.org ) at 2020-05-02 22:15 CEST Nmap scan report for 192.168.3.1 Host is up (0.019s latency). Not shown: 994 closed ports PORT STATE SERVICE 21/tcp filtered ftp 22/tcp open ssh 23/tcp filtered telnet 80/tcp open http 443/tcp open https 8080/tcp open http-proxy Nmap scan report for 192.168.3.106 Host is up (0.0018s latency). Not shown: 995 closed ports PORT STATE SERVICE 22/tcp open ssh 139/tcp open netbios-ssn 445/tcp open microsoft-ds 4662/tcp open edonkey 9091/tcp open xmltec-xmlmail Nmap done: 256 IP addresses (2 hosts up) scanned in 3.89 seconds La orden nos ha dicho que en la red "192.168.3.0/24" hay dos Hosts con puerto escuchando. Las IPs son "192.168.3.1" y "192.168.3.106". Por ejemplo , los puertos que están escuchando en "192.168.3.1" son el 80 , el 443, etc. En "nmap" cuando un puerto está escuchando no dice que está "LISTEN", como decía en la orden "ss" . En "nmap" se indica como "open". Es decir que las siguientes palabras referidas a un puerto son sinómimas: * open * abierto * listen * escuchando ¿Y que pasa con la palabra "servidor"?. Se dice que el puerto está abierto o escuchando pero que el proceso hace de servidor. ===== netcat ===== La orden ''netcat'' es una orden para conectarse a puertos y escuchar en ellos. Es una forma sencilla desde Bash de crear servidores. Nosotros la vamos a usar para ver como hemos abierto un puerto Mas información * [[https://blog.desdelinux.net/usando-netcat-algunos-comandos-practicos/|Usando Netcat: algunos comandos prácticos]] * [[https://www.ochobitshacenunbyte.com/2019/01/19/netcat-herramienta-avanzada-de-red-en-gnu-linux/|Netcat: Herramienta avanzada de red en GNU Linux]] Lo primero es instalarla logongas@beren:~$ sudo apt install netcat logongas@beren:~$ netcat -l 192.168.1.100 55555 Decimos que netcat se ponga a escuchar en el puerto 55555 de la IP 192.168.1.100. Una vez lanzado, los bytes que lleguen se mostrarán como texto por la pantalla logongas@beren:~$ echo "Hola mundo" | netcat 192.168.1.100 55555 Decimos que netcat envíe al host 192.168.1.100 y al puerto 55555 el texto "hola mundo". Con "netcat" haremos luego ejercicios de ejemplos de procesos de redes que envían y reciben datos. ===== Flent ===== [[https://flent.org/|Flent]] es una herramienta que nos permite obtener con mucho detalla el rendimiento de una red TCP/IP. {{:clase:daw:si:3eval:flent1.png?direct|}} {{:clase:daw:si:3eval:flent2.png?direct|}} {{:clase:daw:si:3eval:flent3.png?direct|}} {{:clase:daw:si:3eval:flent4.png?direct|}} Los pasos de la instalación son: apt install netperf apt install flent Mas información: * [[https://www.linuxadictos.com/flent-completo-kit-tests-probar-conexiones-red.html|Flent: un completo kit de tests para probar las conexiones de red]] ===== Ejercicios ===== ==== Ejercicio 1 ==== - Actualiza Ubuntu, para ello lanza las órdenes: logongas@beren:~$ sudo apt update logongas@beren:~$ sudo apt upgrade ==== Ejercicio 2 ==== - Muestra que números de puerto están abiertos para TCP con IPv6 - Muestra que números de puerto están abiertos para UDP con IPv4 - Muestra los procesos que están conectados a los puertos abiertos para TCP ==== Ejercicio 3 ==== - Muestra únicamente las conexiones que hay establecidas por TCP - Desde tu ordenador real, conectate a Linux por SSH - Muestra únicamente las conexiones que hay establecidas por TCP y comprueba que ahora está la conexión por SSH - Según el resultado de la orden anterior, indica el números de puerto origen , el números de puerto destino de la conexión y el proceso que está conectado al puerto de SSH ==== Ejercicio 4 ==== - Usanfo "iftop", muestra las conexiones que se están produciendo en tu ordenador - Explica a que Host se están conectado e intenta averiguar porqué se están conectando ahí. - Usando la orden "wget" que permite descargar una página web. Descarga varias paginas web de sitios distintos - Comprueba como a la vez , van a apareciendo en iftop cada vez que te conectas a las páginas === Ejercicio 5 === - Instala los monitores de red "nload" y "bmon". Y di cual prefieres usar. - Haz una captura de pantalla en las que se vea alguna gráfica del uso de la red - Usando la orden "wget" , descarga alguna pagina web que tenga muchas imágenes. - Usando "bmon" comprueba como ha cambiando la gráfica al usar wget - Usar varias veces seguidas wget y comprueba como cada vez que la usas, se ve en la gráfica de "bmon" el uso de la red ==== Ejercicio 6 ==== - Averigua que Hosts hay en la red de tu casa y los puertos que tiene abierto cada Host. - Intenta conectarte a alguno de los puertos que haya abiertos. - Para saber que un puerto está abierto, ¿Cual es la diferencia entre usar "ss" y "nmap"? ==== Ejercicio 7 ==== - usando netcat haz que se ponga a escuchar en el puerto "12345" - Comprueba ahora que el puerto está abierto. - Envía datos por http desde el navegador de tu ordenador real al puerto "12345" de tu máquina Linux. Para indicar el puerto en la URL, debes añadir a la URL ":" y el número de puerto. - ¿Que datos he enviado el navegador y que han llegado hasta el servidor que está escuchando en el puerto "12345"? Los datos que han llegado son el protocolo HTTP que verás el año que viene. ==== Ejercicio 8 ==== En este ejercicio vamos a crea un servidor Web desde Java. - Desde tu ordenador real , compila el siguiente código Java para el JDK 11 y crear un fichero "jar" llamado "server.jar". package com.fpmislata.daw; import java.io.IOException; import java.io.OutputStream; import java.net.InetSocketAddress; import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpServer; public class Server { public static int tcpPortNumber=8080; public static void main(String[] args) throws Exception { HttpServer httpServer = HttpServer.create(new InetSocketAddress(tcpPortNumber), 0); httpServer.createContext("/", new RootHttpHandler()); httpServer.start(); System.out.println("El servidor ha arrancado corectamente en el puerto:"+tcpPortNumber); } static class RootHttpHandler implements HttpHandler { @Override public void handle(HttpExchange httpExchange) throws IOException { //Crear un HTML con la direccion y el puerto tanto origen como destino StringBuilder html = new StringBuilder(); html.append(""); html.append("

Direccion Local ==> "+httpExchange.getLocalAddress().getHostString()+ "  :  " + httpExchange.getLocalAddress().getPort()+"

"); html.append("

Direccion Remota ==> "+httpExchange.getRemoteAddress().getHostString()+ "  :  " + httpExchange.getRemoteAddress().getPort()+"

"); html.append(""); //Enviar el HTML por TCP httpExchange.getResponseHeaders().add("Content-Type", "text/html"); httpExchange.sendResponseHeaders(200, html.length()); OutputStream outputStream = httpExchange.getResponseBody(); outputStream.write(html.toString().getBytes()); outputStream.close(); } } }
- Ahora en tu máquina linux, instala el JDK 11. logongas@beren:~$ sudo apt install openjdk-11-jre-headless - Copiar el fichero "server.jar" desde windows a Linux , usando el prgrama "WindSCP". - Dale permisos de ejecución y lectura a "server.jar" - Ejecuta en Linux el servidor java con: java -jar server.jar - Comprueba que el puerto está abierto. - Conéctate desde tu ordenador real con el navegador al servidor Web de Linux. - Comprueba el puerto origen de la conexión - Conéctate desde tu ordenador real con otro navegador navegador al servidor Web de Linux. - Comprueba el puerto origen de la conexión es distinto que el de antes - Modifica el programa para que en vez de usar el puerto 8080 , use el puerto 80. - Vuelve a ejecutar el servidor Java, no te dejará. - Vuelve a ejecutar el servidor Java pero ahora con "sudo" y ya no te dejará. Eso es porque Linux solo deja abrir puertos por debajo del 1024 al usuario root.