66.62 Redes de Computadoras Workshop de HTTP leaked version1 Matsunaga, Nicolás 1.er cuatrimestre 2012 1 esto significa que está más que incompleto ÍNDICE Índice 1. Objetivo del apunte 2 2. Introducción 2 3. Consultas con telnet 3.1. Prueba 1 - Consulta Básica . . . . . 3.2. Prueba 2 - Redirección . . . . . . . . 3.3. Prueba 3 - HTTP/1.1 . . . . . . . . 3.4. Prueba 4 - Virtualhosts . . . . . . . . 3.5. Prueba 5 - Autenticación . . . . . . . 3.6. Prueba 6 - HEAD . . . . . . . . . . . 3.7. Prueba 7 - Método inexistente PGET 3.8. Prueba 8 - Proxy a un no-proxy . . . 3.9. Prueba 9 - método CONNECT . . . 2 2 3 4 5 6 7 7 8 9 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1 Objetivo del apunte 1. Objetivo del apunte El objetivo de este apunte será introducir al alumno en el mundo real en el uso del protocolo HTTP, que es uno de los componentes de Internet más importantes. 2. Introducción Para las prácticas de este taller utilizaremos la siguientes herramientas: telnet: es un utilitario de entorno Linux/Unix/Windows que para establecer conexiones TCP en modo texto. 3. Consultas con telnet En esta sección veremos las consultas más tı́picas que pueden hacerse con el utilitario telnet. Por el momento nos restringiremos a realizar operaciones de tipo GET. Convención de colores en magenta indicaremos el Full-Request en verde resaltaremos algunos headers relacionados con una respuesta exitosa en rojo resaltaremos algunos headers relacionados con una respuesta no exitosa en azul resaltaremos el entity-body 3.1. Prueba 1 - Consulta Básica GET / HTTP/1.0 # telnet 192.168.92.136 80 Trying 192.168.92.136... Connected to 192.168.92.136 (192.168.92.136). Escape character is ’^]’. GET / HTTP/1.0 HTTP/1.1 200 OK Date: Sun, 10 Jun 2012 10:36:37 GMT Server: Apache/2.2.3 (CentOS) Last-Modified: Sun, 10 Jun 2012 10:36:27 GMT ETag: "86974-a-4c21bce3f40c0" Accept-Ranges: bytes Content-Length: 10 Connection: close Content-Type: text/html; charset=UTF-8 Anda bien Connection closed by foreign host. 2 3.2 Prueba 2 - Redirección Aquı́ observamos que la petición fue exitosa y vemos como el server nos cierra la conexión. Además implementa correctamente HTTP 1.0 que especifica que la respuesta debe contener al header Content-Length. En servidores que no implementan correctamente, la longitud podrı́a llegar a deducirse por el cierre de la conexión2 . Cuando especificamos un sólamente un directorio como URI, el servidor HTTP busca el archivo por default en dicho directorio. En este caso fue el index.html, pero esto depende de la configuración del servidor web. 3.2. Prueba 2 - Redirección GET /otros HTTP/1.0 # telnet 192.168.92.136 80 Trying 192.168.92.136... Connected to 192.168.92.136 (192.168.92.136). Escape character is ’^]’. GET /otros HTTP/1.0 HTTP/1.1 301 Moved Permanently Date: Sun, 10 Jun 2012 10:39:27 GMT Server: Apache/2.2.3 (CentOS) Location: http://default.example.com/otros/ Content-Length: 325 Connection: close Content-Type: text/html; charset=iso-8859-1 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> <title>301 Moved Permanently</title> </head><body> <h1>Moved Permanently</h1> <p>The document has moved <a href="http://default.example.com/otros/">here</a>.</p> <hr> <address>Apache/2.2.3 (CentOS) Server at default.example.com Port 80</address> </body></html> Connection closed by foreign host. Aquı́ observamos que la respuesta es una redirección permanente. En este caso se debe a que el URI relativo /otros se refiere a un directorio y entonces el servidor HTTP interpreta que quisimos poner /otros/. Éso nos lo comunica a través del header Location. GET /otros/ HTTP/1.0 # telnet 192.168.92.136 80 Trying 192.168.92.136... Connected to 192.168.92.136 (192.168.92.136). Escape character is ’^]’. GET /otros/ HTTP/1.0 HTTP/1.1 200 OK Date: Sun, 10 Jun 2012 10:40:11 GMT Server: Apache/2.2.3 (CentOS) Last-Modified: Sun, 10 Jun 2012 10:39:14 GMT ETag: "86995-f-4c21bd8337880" Accept-Ranges: bytes 2 aunque podrı́a ser el caso de que la conexión se cortó y nunca se sabrı́a si todo el contenido fue transferido 3 3.3 Prueba 3 - HTTP/1.1 Content-Length: 15 Connection: close Content-Type: text/html; charset=UTF-8 otro contenido Connection closed by foreign host. Ahora funciona correctamente. El rehacer la consulta con el URI especificado por el header Location nosotros hicimos a mano, pero el browser lo hace automáticamente. 3.3. Prueba 3 - HTTP/1.1 GET / HTTP/1.1 # telnet 192.168.92.136 80 Trying 192.168.92.136... Connected to 192.168.92.136 (192.168.92.136). Escape character is ’^]’. GET / HTTP/1.1 HTTP/1.1 400 Bad Request Date: Sun, 10 Jun 2012 10:40:53 GMT Server: Apache/2.2.3 (CentOS) Content-Length: 310 Connection: close Content-Type: text/html; charset=iso-8859-1 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> <title>400 Bad Request</title> </head><body> <h1>Bad Request</h1> <p>Your browser sent a request that this server could not understand.<br /> </p> <hr> <address>Apache/2.2.3 (CentOS) Server at default.example.com Port 80</address> </body></html> Connection closed by foreign host. Aquı́ intentamos hacer una petición similar a la de la subsección §3.1 pero sólo cambiando la versión de HTTP/1.0 a HTTP/1.1. Y vemos que no funciona porque se en HTTP 1.1 es obligatorio el uso del header Host. Lo que nos da es un código de estado “4XY”3 , en particular el 400 que significa que la petición no está bien hecha. GET / HTTP/1.1 Host: 192.168.92.136 # telnet 192.168.92.136 80 Trying 192.168.92.136... Connected to 192.168.92.136 (192.168.92.136). Escape character is ’^]’. GET / HTTP/1.1 Host: 192.168.92.136 HTTP/1.1 200 OK Date: Sun, 10 Jun 2012 10:42:29 GMT 3 Recordemos que los códigos “4XY” corresponden a errores causados por el usuario. 4 3.4 Prueba 4 - Virtualhosts Server: Apache/2.2.3 (CentOS) Last-Modified: Sun, 10 Jun 2012 10:36:27 GMT ETag: "86974-a-4c21bce3f40c0" Accept-Ranges: bytes Content-Length: 10 Connection: close Content-Type: text/html; charset=UTF-8 Anda bien Connection closed by foreign host. Cuando le agregamos el header Host la petición es exitosa. 3.4. Prueba 4 - Virtualhosts Una funcionalidad que brinda HTTP 1.1 es el VirtualHosting. Esto permite que haya varios sitios hosteados en una misma IP. La “discriminación” para permitir elegir el sitio se hace a través del header Host. A continuación veremos dos RequestLines idénticas (GET / HTTP/1.1) que dan resultados distintos ya que apuntan a distintos virtualhosts (ocio.example.com y trabajo.example.com). GET / HTTP/1.1 Host: ocio.example.com # telnet 192.168.92.136 80 Trying 192.168.92.136... Connected to 192.168.92.136 (192.168.92.136). Escape character is ’^]’. GET / HTTP/1.1 Host: ocio.example.com HTTP/1.1 200 OK Date: Sun, 10 Jun 2012 10:43:53 GMT Server: Apache/2.2.3 (CentOS) Last-Modified: Mon, 23 May 2011 19:42:31 GMT ETag: "8696d-12-4a3f6ac1237c0" Accept-Ranges: bytes Content-Length: 18 Connection: close Content-Type: text/html; charset=UTF-8 aca hacemos fiaca Connection closed by foreign host. GET / HTTP/1.1 Host: trabajo.example.com # telnet 192.168.92.136 80 Trying 192.168.92.136... Connected to 192.168.92.136 (192.168.92.136). Escape character is ’^]’. GET / HTTP/1.1 Host: trabajo.example.com HTTP/1.1 200 OK Date: Sun, 10 Jun 2012 10:45:28 GMT Server: Apache/2.2.3 (CentOS) Last-Modified: Mon, 23 May 2011 19:42:49 GMT ETag: "8696e-18-4a3f6ad24e040" Accept-Ranges: bytes Content-Length: 24 5 3.5 Prueba 5 - Autenticación Connection: close Content-Type: text/html; charset=UTF-8 uy.. hay que laburar :( Connection closed by foreign host. 3.5. Prueba 5 - Autenticación GET /secreto/ HTTP/1.0 # telnet 192.168.92.136 80 Trying 192.168.92.136... Connected to 192.168.92.136 (192.168.92.136). Escape character is ’^]’. GET /secreto/ HTTP/1.0 HTTP/1.1 401 Authorization Required Date: Sun, 10 Jun 2012 10:53:13 GMT Server: Apache/2.2.3 (CentOS) WWW-Authenticate: Basic realm="Webpage Top Secret" Content-Length: 485 Connection: close Content-Type: text/html; charset=iso-8859-1 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> <title>401 Authorization Required</title> </head><body> <h1>Authorization Required</h1> <p>This server could not verify that you are authorized to access the document requested. Either you supplied the wrong credentials (e.g., bad password), or your browser doesn’t understand how to supply the credentials required.</p> <hr> <address>Apache/2.2.3 (CentOS) Server at default.example.com Port 80</address> </body></html> Connection closed by foreign host. GET /secreto/ HTTP/1.0 Authorization: Basic YWx1bW5vOmVzdHVkaWFy # telnet 192.168.92.136 80 Trying 192.168.92.136... Connected to 192.168.92.136 (192.168.92.136). Escape character is ’^]’. GET /secreto/ HTTP/1.0 Authorization: Basic YWx1bW5vOmVzdHVkaWFy HTTP/1.1 200 OK Date: Sun, 10 Jun 2012 11:00:33 GMT Server: Apache/2.2.3 (CentOS) Last-Modified: Sun, 10 Jun 2012 10:48:26 GMT ETag: "86997-30-4c21bf91a5280" Accept-Ranges: bytes Content-Length: 48 Connection: close Content-Type: text/html; charset=UTF-8 si ves esto sabes el secreto para aprobar redes Connection closed by foreign host. 6 3.6 Prueba 6 - HEAD Para saber cual es el secreto para aprobar la materia, busquen en Google “base64 decoder” y copien y peguen YWx1bW5vOmVzdHVkaWFy. Recuerden que en el URI la autenticación se ponı́a user:password o en este caso para darle más sentido user:secret :). 3.6. Prueba 6 - HEAD Con el método HEAD sólo traigo los header que hubiese obtenido de hacer una operación GET. HEAD /otros/karl640.jpg HTTP/1.0 # telnet 192.168.92.136 80 Trying 192.168.92.136... Connected to 192.168.92.136 (192.168.92.136). Escape character is ’^]’. HEAD /otros/karl640.jpg HTTP/1.0 HTTP/1.1 200 OK Date: Sun, 10 Jun 2012 11:10:32 GMT Server: Apache/2.2.3 (CentOS) Last-Modified: Sun, 10 Jun 2012 11:10:33 GMT ETag: W/"86996-5404-4c22226a70800" Accept-Ranges: bytes Content-Length: 21508 Connection: close Content-Type: image/jpeg X-Pad: avoid browser bug Connection closed by foreign host. Aquı́ podemos ver que el recurso al que apuntamos es una imagen jpeg cuyo tamaño es 21508 Bytes. 3.7. Prueba 7 - Método inexistente PGET Ahora vamos a pedirle una consulta de Proxy a un servidor HTTP. PGET http://www.google.com/ HTTP/1.0 # telnet 192.168.92.136 80 Trying 192.168.92.136... Connected to 192.168.92.136 (192.168.92.136). Escape character is ’^]’. PGET http://www.google.com/ HTTP/1.0 HTTP/1.1 501 Method Not Implemented Date: Sun, 10 Jun 2012 17:15:14 GMT Server: Apache/2.2.3 (CentOS) Allow: GET,HEAD,POST,OPTIONS,TRACE Content-Length: 295 Connection: close Content-Type: text/html; charset=iso-8859-1 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> <title>501 Method Not Implemented</title> </head><body> <h1>Method Not Implemented</h1> <p>PGET to /index.html not supported.<br /> 7 3.8 Prueba 8 - Proxy a un no-proxy </p> <hr> <address>Apache/2.2.3 (CentOS) Server at www.google.com Port 80</address> </body></html> Connection closed by foreign host. Lo que observamos es que el servidor da un código 501, método no implementado. Acá vemos que no dió bad request ya que HTTP es extensible. También podemos ver el header Allow donde dice que métodos soporta el server al cual nos conectamos. 3.8. Prueba 8 - Proxy a un no-proxy GET http://www.google.com/ HTTP/1.0 # telnet 192.168.92.136 80 Trying 192.168.92.136... Connected to 192.168.92.136 (192.168.92.136). Escape character is ’^]’. GET http://www.google.com/ HTTP/1.0 HTTP/1.1 200 OK Date: Sun, 10 Jun 2012 17:28:41 GMT Server: Apache/2.2.3 (CentOS) Last-Modified: Sun, 10 Jun 2012 10:36:27 GMT ETag: "86974-a-4c21bce3f40c0" Accept-Ranges: bytes Content-Length: 10 Connection: close Content-Type: text/html; charset=UTF-8 Anda bien Connection closed by foreign host. Notar que el servidor nos responde con su recurso “/”. Es decir que saca el network path de la URL. Además verificamos que la máquina ni siquiera tiene una ruta para dicho fqdn. Notar que sı́ resolvió el nombre porque sino no hubiese podido determinar qué no tiene una ruta hacia ese destino. # ping www.google.com connect: Network is unreachable Para terminar de convencernos que le saca el network path hacemos un request de http://www.google.com/otros/ pero nos delvolverá el recurso /otros/. GET http://www.google.com/otros/ HTTP/1.0 # telnet 192.168.92.136 80 Trying 192.168.92.136... Connected to 192.168.92.136 (192.168.92.136). Escape character is ’^]’. GET http://www.google.com/otros/ HTTP/1.0 HTTP/1.1 200 OK Date: Sun, 10 Jun 2012 17:31:42 GMT Server: Apache/2.2.3 (CentOS) Last-Modified: Sun, 10 Jun 2012 10:39:14 GMT 8 3.9 Prueba 9 - método CONNECT ETag: "86995-f-4c21bd8337880" Accept-Ranges: bytes Content-Length: 15 Connection: close Content-Type: text/html; charset=UTF-8 otro contenido Connection closed by foreign host. 3.9. Prueba 9 - método CONNECT CONNECT www.facebook.com:443/ HTTP/1.0 # telnet 127.0.0.1 3128 Trying 127.0.0.1... Connected to coriolis.uyr.com.ar (127.0.0.1). Escape character is ’^]’. CONNECT www.facebook.com:443/ HTTP/1.0 HTTP/1.0 200 Connection established ...(acá es donde empieza la parte de tráfico segurizado) Aquı́ observamos el funcionamiento de HTTP en modo túnel a través de un proxy. De esta manera puede existir una comunicación encriptada end-to-end. Es decir, que NO hay encriptación y desencriptación en cada sistema intermedio. La encriptación es punto a punto, por eso es un túnel. 9