Servidor WEB Nativo de OpenBSD-6.7

 OpenBSD-6.7

Indicaremos las principales características del demonio httpd de OpenBSD. [Author](Reyk Floeter (reyk@openbsd.org) March 2015)

Abstracto

OpenBSD incluye un nuevo servidor web que se inició solo dos semanas antes de que finalizara la versión 5.6 [11]. El trabajo está en progreso activo y se han realizado mejoras significativas desde su aparición inicial. Pero, ¿por qué necesitamos otro servidor web?

Este documento trata sobre la historia, el diseño y la implementación del nuevo httpd (8). Hace unos 17 años, OpenBSD importó por primera vez el servidor web Apache [8] en su sistema base. Se limpió y mejoró y se parchó para eliminar privilegios y chroot por defecto. Pero años de lucha con la creciente base de código, aguas arriba y el desastre inaceptable de Apache 2 dejaron a OpenBSD con una bifurcación involuntaria del viejo Apache 1.3.29 durante muchos años.

Cuando apareció nginx [10], prometía una alternativa mucho mejor de un servidor web popular y moderno con una licencia BSD adecuada y un diseño superior. Fue parcheado para soltar privilegios y chroot por defecto y eventualmente reemplazó a Apache como el servidor web predeterminado de OpenBSD. Pero la historia se repitió: una creciente base de código, la lucha contra la corriente ascendente y la dirección de su entidad comercial recién formada creó un descontento entre muchos desarrolladores. Hasta que un día en el Hackathon g2k14 de OpenBSD en Eslovenia, experimenté con relayd [5] y lo convertí en un simple servidor web. Una cadena de eventos respaldados por Bob Beck y Theo de Raadt lo convirtió en un proyecto serio que eventualmente reemplazó a nginx como el nuevo valor predeterminado. Muchos usuarios lo adoptaron rápidamente: nació “OpenBSD httpd”, un servidor web simple y seguro para archivos estáticos, FastCGI y TLS con tecnología LibreSSL. Y, por supuesto, *httpd es escala web*.

Historia - Introducción

Este documento proporciona una breve descripción del nuevo servidor web httpd (8) de OpenBSD, que incluye antecedentes técnicos, historia y mi motivación personal para crearlo. Se pretende proporcionar información complementaria para mi charla en AsiaBSDCon 2015.

 OpenBSD-6.7

Al principio, Theo de Raadt creó OpenBSD y en los primeros días del proyecto, se importó el servidor web Apache. Y Apache no estaba en buena forma, y casi vacío; y tenía muchas partes oscuras en las profundidades del código fuente. Y hubo algunos esfuerzos para limpiarlo, para traer algo de luz; Henning Brauer lo hizo, y fue bueno. Y el código fuente se dividió y gran parte del código no utilizado se eliminó del sistema base. Y este nuevo servidor web se hizo conocido como Apache de OpenBSD, que era diferente pero basado en Apache 1.3. Así es como apareció el primer servidor web en OpenBSD.

Más de 16 años después, el antiguo servidor web de OpenBSD, basado en Apache 1.3.29, fue reemplazado por un servidor totalmente nuevo escrito por Reyk Floeter. Pero primero Apache tuvo que ser eliminado; Una búsqueda que tomó un largo camino. Apareció por primera vez en OpenBSD 2.3 de marzo de 1998 y ha sido parcheado y mantenido durante mucho tiempo. El servidor se modificó con cambios personalizados, soporte de IPv6 y todas las mejoras de seguridad como chroot y alguna limpieza seria de código. Realmente siguió la tradición de ser “un servidor web irregular”. Pero en algún momento terminó siendo un diseño ineficiente y algo antiguo que ya no coincidía con los estándares de los demonios de red modernos en OpenBSD.

Cuando Nginx se hizo más popular, parecía ser el reemplazo perfecto: un servidor rápido, moderno, de un solo subproceso y sin bloqueo con un diseño de E / S asíncrono, que hizo FastCGI en lugar de bifurcar procesos CGI clásicos o cargar todo tipo de módulos peligrosos en el servidor mismo. Y, después de todo, venía con una licencia tipo BSD de 2 cláusulas. No proporcionó todas las mejoras de seguridad, pero se parchó para ejecutar chroot como el viejo Apache de OpenBSD. nginx se importó a OpenBSD a fines de 2011 y apareció por primera vez en la versión 5.1 en mayo de 2012.

Durante algún tiempo, ambos servidores web existieron en OpenBSD al mismo tiempo y tardó hasta marzo de 2014 antes de que Apache finalmente fuera eliminado. Nginx se convirtió en el nuevo servidor web predeterminado en OpenBSD. El retraso se debió principalmente a la limitación de Nginx de que no admitía CGI clásico. Los sysadmins usaban comúnmente scripts CGI simples en sus servidores OpenBSD, e incluso el sistema base se entrega con bgplg (8), un espejo basado en CGI para bgpd (8). Apache no se pudo eliminar antes de que hubiera una manera de ejecutar estos scripts con FastCGI en Nginx. Florian Obser implementó un contenedor FastCGI en el sistema base, slowcgi (8), e importó en mayo de 2013 para resolver el problema.

La monocracia de Nginx no duró mucho. Una serie de eventos llevaron a su eliminación en agosto de 2014. Ha sido reemplazado por un nuevo servidor web: el nuevo httpd de OpenBSD de Reyk Floeter; La historia y la implementación se describen en los siguientes capítulos.

El historia más reciente de Apache, nginx y httpd en la base de OpenBSD se puede resumir mediante una simple búsqueda en Google.

Seguridad Shokunin

El proyecto OpenBSD tiene hackatones en diferentes ubicaciones internacionales durante todo el año. El más grande ocurre una vez al año, desde 1999, y es atendido por la mayoría de los desarrolladores activos. El general Hackathon g2k14 de 2014 tuvo lugar en julio en Ljubljana, Eslovenia, y contó con la asistencia de 49 desarrolladores. Estas reuniones de desarrolladores se utilizan para un trabajo muy activo en el árbol de fuentes de OpenBSD: para comenzar nuevos parches y proyectos, para terminar los más antiguos y para realizar optimizaciones cuidadosas. La seguridad y la calidad del código de OpenBSD se mejoran constantemente, un esfuerzo continuo para obtener la perfección que recuerda mucho al Shokunin japonés.

 Shokunin

OpenBSD acaba de presentar la nueva función reallocarray(3) con protección contra desbordamiento en su biblioteca C y muchos desarrolladores han comenzado a reemplazar las llamadas sospechosas de calloc(3) y malloc(3) en el árbol fuente. También estaba el infame error *Heartbleed* que condujo al subproyecto LibreSSL de OpenBSD, bifurcado de OpenSSL. Una de las principales técnicas de mitigación de vulnerabilidades de explotación de OpenSSL que hizo que todos los sistemas, incluido OpenBSD, fueran vulnerables al error *Heartbleed* fue su asignador de memoria oculta que omitía silenciosamente las protecciones malloc de OpenBSD preasignando y reutilizando grandes fragmentos de memoria.

Reyk miró a Nginx y escribió un parche grande para reemplazar todas las llamadas riesgosas de malloc y calloc con multiplicaciones de matriz con reallocarray(3), o su predecesor mallocarray. Resultó que Nginx usa muchas llamadas con el idioma malloc (número * tamaño) y no intenta detectar desbordamientos de enteros; esto es seguro siempre que los valores sean pequeños y se garantice que no causará desbordamientos de enteros. Pero los supuestos basados en condiciones previas o información no obvia, algunos de estos valores tienen límites de tamaño basados en variables informadas por el núcleo, son muy peligrosos y siempre pueden conducir a errores. Reallocarray(3) de OpenBSD ha sido diseñado para verificar el desbordamiento y devolver NULL como falla en tal caso (Copyright c 2008 Otto Moerbeek):

#define MUL_NO_OVERFLOW (1UL << (sizeof(size_t) * 4))
if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && nmemb > 0 && SIZE_MAX / nmemb < size){
  errno = ENOMEM;
  return NULL;
    } 
return realloc(optr, size * nmemb);

El parche mencionado se hizo muy grande y finalmente se descartó. Hubiera sido muy difícil mantenerlo como un parche personalizado para Nginx en el árbol fuente de OpenBSD, y no había indicios de que upstream lo hubiera importado en el corto plazo o incluso en absoluto. Pero ese no fue el único problema estéticamente desafiante en Nginx, resultó que Nginx usa una serie de asignadores de memoria personalizados que preasignan y reutilizan casi todos los objetos de memoria dinámica que necesita. Esto recordaba demasiado el problema “Heartbleed” y los asignadores de memoria personalizados de OpenSSL que se han eliminado de LibreSSL. El software para OpenBSD debe usar las rutinas malloc(3) del sistema, y no debe sacrificar la seguridad por el rendimiento al pasar por alto todas las aleatorizaciones y las comprobaciones de seguridad de “Otto Malloc” en libc.

 Shokunin

Además, la base de código Nginx se hizo más grande desde su importación inicial a OpenBSD en 2011. Por una buena razón, OpenBSD había decidido seguir las versiones estables de nginx desde arriba y aplicar sus parches locales, como chroot, que no lo hicieron una copia de seguridad. Este trabajo tuvo sus desafíos y la aplicación repetida de los parches dificultó el mantenimiento. La base de código Nginx tiene muchos archivos y características cada vez mayores, que pueden o no importar para OpenBSD. La revisión de la base del código reveló que usa demasiado código: reimplementaciones personalizadas de las funciones estándar de la biblioteca C, muchas capas, módulos e incluso una copia local de la biblioteca PCRE Errata 1 para expresiones regulares extendidas.

En junio de 2013, mucho antes del Hackathon g2k14, Reyk había deshabilitado el módulo SPDY que está incluido en Nginx y habilitado por defecto para la Errata 2. Ese fue un movimiento muy controvertido que incluso generó disidencia entre los desarrolladores senior en OpenBSD. “¿Hay alguna razón para creer que este código específico es peor que cualquier otro?”. No hubo evidencia, solo la empresa cree que el peor enemigo de la seguridad es la complejidad y que demasiado código siempre es un riesgo potencial. Además, SPDY se apagó porque nadie en el proyecto OpenBSD había pasado tiempo revisando y entendiendo el protocolo en este momento. Aproximadamente un año después, este movimiento ha salvado a OpenBSD de dos vulnerabilidades de seguridad principales en Nginx: “desbordamiento del búfer de almacenamiento dinámico SPDY” [1] y “corrupción de memoria SPDY” [2].

El nuevo httpd de OpenBSD

 Httpd

Hay una decisión puramente técnica que condujo a la creación de httpd, pero también hay una anécdota sobre la motivación que inició el proyecto.

Después de sentirse frustrado por la imposibilidad de hacer cambios más grandes en Nginx, y la dirección general de upstream y su compañía asociada, Reyk trató de encontrar una alternativa. Es el autor principal y el mantenedor de relayd(8), el balanceador de carga de OpenBSD, y sabía que básicamente implementa un motor HTTP altamente escalable. Entonces, mientras todavía estaba en el Hackathon g2k14, comenzó un día por la tarde experimentando con relayd para convertirlo en un servidor web chroot simple que sirve archivos estáticos. Unas horas más tarde, el servidor basado en relayd, convenientemente llamado httpd, pudo servir una copia local del sitio web de OpenBSD.

El mismo día, Reyk demostró el experimento del servidor a Theo de Raadt y Bob Beck, quienes se sentaron y trabajaron en el mismo “Hackroom” del evento. Para la sorpresa inicial del autor, rápidamente se convencieron del intento y alentaron a Reyk a importar httpd en el árbol fuente de OpenBSD. Desvinculado de las compilaciones, pero como parte visible en el repositorio CVS. Ya era un momento bastante tarde del día, y los desarrolladores habían comenzado a beber algunas cantidades razonables de cerveza, cuando httpd se comprometió con OpenBSD. Un día después, el desarrollador escribió en Twitter: “Hoy me desperté con pena y me di cuenta de que anoche hice un commit de un servidor web” [6].

Solo tomó dos semanas más, antes de que httpd se vinculó a las compilaciones, la versión OpenBSD 5.6 se etiquetó y finalmente se envió con la versión inicial de la nueva httpd. Muchos desarrolladores habían contribuido con código, especialmente Florian Obser por su implementación de FastCGI y Joel Sing para SSL/TLS. La versión 5.6 de httpd se proporcionó “tal cual”, pero es totalmente funcional como un servidor web básico que es seguro, sirve archivos estáticos y es compatible con FastCGI y TLS.

Diseño e Implementación

El diseño de httpd (8) está significativamente influenciado por su antecesor relayd(8): heredó grandes partes del código. Es un demonio separado de privilegios, que usa proc.c y el marco *imsg* que usa E/S asíncrona con OpenBSD's libevent. El servidor web está escrito con cuidado y no está recortado para reducir su tamaño; pero consta de aproximadamente 10,000 líneas de código (relayd tiene aproximadamente 24,000 líneas de código). El desarrollo principal de la implementación ocurre en OpenBSD y en el repositorio CVS del proyecto. Ocasionalmente, un espejo del código fuente se envía al repositorio httpd en GitHub [7].

Sencillez

httpd (8) está diseñado para ser un servidor web simple que realiza algunas tareas básicas pero potentes. Por diseño, está destinado a admitir solo una selección de características “básicas” que se requieren para aplicaciones web modernas y comunes. No admitirá características especiales y un objetivo principal de diseño es mantenerlo razonablemente pequeño. Algo es muy exclusivo de httpd: utiliza una etiqueta de *Featuritis* en su rastreador de problemas para rastrear las características rechazadas [4] y para recordarles a todos las razones más adelante. Muchas solicitudes de funciones ya han sido rechazadas porque excederían el alcance actual o violarían su simplicidad.

La simplicidad también significa que debería ser fácil de usar y proporcionar un archivo de configuración legible por humanos con valores predeterminados razonables. httpd.conf es fácil de usar y una configuración básica del servidor web solo necesita 3 líneas de configuración:

server "www.example.com" {
	  listen on * port 80
}

Caracteristicas

*Características* se convirtió en una palabra muy negativa, ya que indica la necesidad de tener muchas de ellas. Casi se espera que las nuevas versiones de software introduzcan un nuevo conjunto de características. Los desarrolladores agregan funciones, solo para agregar nuevas funciones y los usuarios exigen nuevas funciones, solo tienen nuevas funciones. En realidad, se volvió muy atípico evitar las características y evitar la *Featuritis*.

Para httpd, es más importante qué funcionalidad *central* necesita y qué características no debería tener. Es una lucha constante con los usuarios que desean más funciones porque solo unos pocos llegan a la lista. Y, quién sabe, algunas de las características existentes podrían eliminarse cuando resulten innecesarias.

Los siguientes conceptos y funciones “principales” son compatibles actualmente y caracterizan la implementación:

  • Static Files: El objetivo principal es servir archivos y directorios estáticos a través de la indexación automática opcional. Si la indexación automática está habilitada, los directorios se devuelven como listas HTML.
  • FastCGI: El protocolo proporciona la interfaz única y rápida para servir contenido dinámico como una alternativa a CGI o cualquier otra secuencia de comandos integrada o mecanismo similar a CGI. Admite FastCGI asíncrono y directo a través de un socket UNIX o TCP/IP.
  • Secure: la seguridad no opcional ejecutando chroot 'y con separación de privilegios de forma predeterminada.
  • TLS: Admite conexiones seguras a través de TLS con tecnología de LibreSSL y la API libtls. La pila TLS utiliza estándares de seguridad de última generación y desactiva las características SSL/TLS inseguras u obsoletas.
  • Virtual Servers: Configuración flexible con soporte para servidores virtuales basados en nombre e IP en IPv4 e IPv6.
  • Reconfiguration: La configuración en ejecución se puede cambiar y volver a cargar sin interrupción o la necesidad de reiniciar el servidor.
  • Logging: Admite el registro por servidor a través de acceso local y archivos de error. Alternativamente, el registro a través de syslog es compatible de forma predeterminada.
  • Blocking: Se requieren bloqueos, caídas y redirecciones para evitar el acceso no autorizado a subdirectorios y para redirigir a URL alternativas.

Seguridad

OpenBSD ejecuta sus servidores web en un chroot durante muchos años; Apache y nginx han sido parcheados para ejecutar chroot de forma predeterminada. Upstream nunca ha aceptado estos parches, pero proporcionan un beneficio significativo.

El mundo se sorprendió cuando se descubrió la vulnerabilidad *shellshock*[13] en 2014. Si bien la vulnerabilidad en sí misma estaba relacionada con un error en el shell de la línea de comando bash de GNU, el impacto podría haberse mitigado al limitar el acceso al sistema de archivos de los afectados aplicaciones web y servidores. Y el servidor web no debería poder leer archivos de base de datos sin procesar, archivos de contraseña o credenciales del sistema de archivos, especialmente no como root. Shellshock expuso todo tipo de problemas que plantearon preguntas como: “¿Por qué una aplicación web de una empresa multimillonaria ejecuta comandos bash privilegiados con acceso completo al sistema de archivos?”.

httpd(8) ha sido diseñado para ejecutar chroot de forma predeterminada. No se puede apagar, el servidor web utiliza la separación de privilegios para bifurcar diferentes procesos, incluidos los procesos “padre”, “registrador” y “servidor”. El padre es el único proceso privilegiado que se ejecuta como root, el registrador serializa los mensajes de registro y los escribe en los archivos de registro y los procesos del servidor aceptan y manejan las solicitudes HTTP y FastCGI. Todos los procesos, excepto el padre, se encarcelan en un chroot, generalmente en */var/www*. La mensajería entre los procesos se realiza con imsg.

El servidor se implementa con una revisión por pares intensiva, siguiendo las prácticas de codificación de OpenBSD, y utiliza el style(9) alias KNF. Implementa la contabilidad del descriptor de archivos para evitar la devoración de recursos con altas cargas y DoS.

TLS con LibreSSL

El proyecto OpenBSD bifurcó el LibreSSL SSL/TLS y la pila de cifrado de OpenSSL en respuesta a la vulnerabilidad *Heartbleed* en su antepasado. El proyecto se inició con el objetivo de modernizar la base de código, mejorar la seguridad y aplicar mejores prácticas en procesos de desarrollo.

Al igual que con cualquier otro proyecto portátil que se originó en OpenBSD, el desarrollo primario ocurre en el árbol fuente de OpenBSD y la versión portátil para varios otros sistemas operativos como Linux, FreeBSD, Solaris y Windows se empaquetan regularmente en base a esta versión.

httpd(8) utiliza la nueva API libtls de LibreSSL que se proporciona como alternativa a la API libssl tradicional de OpenSSL. Está diseñado para proporcionar una API simple y bien diseñada que hace que sea más fácil y seguro escribir clientes y servidores TLS. Se implementa sobre libssl y libcrypto sin exponer los detalles de la API subyacente de OpenSSL; la biblioteca de backend podría incluso ser reemplazada en el futuro.

El servidor web httpd(8) se utilizó como una implementación de referencia para la API del servidor, que fue diseñada y escrita por Joel Sing con aportes de Ted Unangst y Reyk Floeter. El lado del cliente de la API se diseñó reemplazando el código libssl en la herramienta ftp(1) de OpenBSD. Como httpd(8) se basó originalmente en el relayd de OpenBSD(8), parte de su código SSL/TLS se utilizó como referencia para la implementación en libtls.

FastCGI

FastCGI es crucial para servir contenido dinámico, es la interfaz rápida de httpd para ejecutar aplicaciones web, aplicaciones y hacerlas *escala web*. Inicialmente se diseñó para superar las limitaciones de escalabilidad y uso compartido de recursos del protocolo CGI. Si bien los scripts CGI deben bifurcarse para cada solicitud, los scripts FastCGI pueden mantenerse en ejecución y manejar muchas solicitudes HTTP. CGI no es directamente compatible con httpd.

La implementación de FastCGI fue escrita por Florian Obser y se basa en su servidor *slowcgi*. slowcgi es un servidor simple que traduce las solicitudes FastCGI al protocolo CGI; ejecuta chroot’s y ejecuta el script CGI solicitado, y traduce su salida nuevamente al protocolo FastCGI. La implementación de FastCGI en httpd toma las solicitudes HTTP, las encapsula en solicitudes FastCGI y las envía a un servidor FastCGI como slowcgi. El protocolo en sí es una especificación abierta que está basada en frames y permite intercambiar parámetros encapsulados y carga útil o payload stdin/stdout entre el servidor web y el servidor fastcgi.

Implementé slowcgi porque no dejaste de quejarte en icb que nginx no
puede ejecutar bgplg.  

Y fastcgi en httpd: (Bob) Beck me ha preguntado si puedo ayudarlo.

Configuración

El archivo de configuración *httpd.conf* está utilizando el estilo moderno de OpenBSD de un lenguaje de configuración sensato, que intenta ser flexible y legible. No utiliza un marcado con semicola o etiquetas, solo palabras clave en inglés y bloques identificados con llaves (“{}”). Esto se conoce comúnmente como la configuración basada en *parse.y* dentro de OpenBSD, porque se origina en la gramática y el analizador que se escribió para pf.

Dentro del archivo de configuración hay cuatro secciones principales: Macros (variables definidas por el usuario que se pueden definir y usar más adelante, simplificando el archivo de configuración), Global Configuration (configuración global para httpd (8)), Servers (servidores web HTTP que escuchan), y Type (tipos de medios y extensiones).

Dentro de las secciones, se puede especificar una dirección de host por dirección IPv4, dirección IPv6, nombre de interfaz, grupo de interfaz o nombre de host DNS. Si la dirección es un nombre de interfaz, httpd (8) buscará la primera dirección IPv4 y cualquier otra dirección IPv4 e IPv6 de la interfaz de red especificada. Si el `*` se proporciona como una dirección, se usará como un alias para 0.0.0.0 para escuchar en todas las direcciones IPv4. Del mismo modo, `::` se puede usar para escuchar en todas las direcciones IPv6. Un puerto se puede especificar por número o nombre; con nombres de acuerdo con el archivo */etc/services*.

La línea actual se puede extender sobre varias líneas usando una barra invertida `\`. Los comentarios se pueden colocar en cualquier parte del archivo con una marca de hash `#` y extenderse hasta el final de la línea actual. Se debe tener cuidado al comentar texto de varias líneas: el comentario es efectivo hasta el final de todo el bloque.

Los nombres de argumentos que no comienzan con una letra, dígito o guión bajo deben ser citados. Se pueden incluir archivos de configuración adicionales con la palabra clave include, por ejemplo:

include "/etc/httpd.conf.local"

MACROS

Como en todos los archivos de configuración basados en *parse.y* de OpenBSD, se pueden definir macros que luego se expandirán en contexto. Los nombres de macro deben comenzar con una letra, dígito o guión bajo, y pueden contener cualquiera de esos caracteres. Los nombres de macro no pueden ser palabras reservadas (por ejemplo, directory, log, or root). Las macros no se expanden entre comillas. Por ejemplo:

ext_ip="10.0.0.1"

server "default" {
	  listen on $ext_ip port 80
}

GLOBAL CONFIGURATION

La configuración global se puede configurar para establecer valores predeterminados o para modificar el tiempo de ejecución. La mayoría de las configuraciones globales no se pueden cambiar en la recarga de la configuración.

  • Chroot Directory: Establezca el directorio chroot(2). Si no se especifica, el valor predeterminado es */var/www*, el directorio de inicio del usuario www.
  • Logdir Directory: Especifica la ruta completa del directorio en el que se escribirán los archivos de registro. Si no se especifica, el valor predeterminado es */logs* dentro del directorio chroot(2).
  • Prefork number: Ejecuta el número especificado de procesos del servidor. Esto aumenta el rendimiento y evita demoras al conectarse a un servidor. httpd(8) ejecuta 3 procesos de servidor por defecto.

SERVERS

Los servidores se especifican como bloques de configuración, marcados por la palabra clave server, un nombre y la configuración real del servidor encapsulada en llaves (“{}”).

  • alias name: Especifica un nombre de alias adicional para este servidor.
  • [no] authenticated [realm] with htpasswd: Autentique a un usuario remoto para el realm (dominio) comprobando las credenciales con el archivo de autenticación de usuario htpasswd. El nombre del archivo es relativo al chroot y el usuario de *www* debe poder leerlo. Use la directiva no autenticar para deshabilitar la autenticación en una ubicación.
  • block drop: Desconecte la conexión sin enviar una página de error.
  • block [return code [uri]]: Cierre la conexión y envíe una página de error. Si no se especifica el código de retorno opcional, httpd(8) niega el acceso con una respuesta *403 Prohibido*. El argumento uri opcional se puede usar con códigos de retorno en el rango 3xx para enviar un encabezado “Ubicación:” para la redirección a un URI especificado.

La url puede contener macros predefinidas que se expandirán en tiempo de ejecución:

  1. $DOCUMENT URI: La ruta de solicitud.
  2. $QUERY STRING: Cadena de consulta opcional.
  3. $REMOTE ADDR: Dirección IP remota.
  4. $REMOTE PORT: Puerto de origen TCP, remoto.
  5. $REMOTE USER: Usuario HTTP autentificado.
  6. $REQUEST URI: Ruta de solicitud y cadena de consulta opcional.
  7. $SERVER ADDR: Dirección IP del Servidor.
  8. $SERVER PORT: Puerto TCP del Servidor.
  9. $SERVER_NAME: Nombre del Servidor.
  • connection options: Establezca las opciones y límites especificados para las conexiones HTTP. Las opciones válidas son:
    1. max request body [number]: Establezca el tamaño máximo del cuerpo en bytes que el cliente puede enviar al servidor. El valor predeterminado es 1048576 bytes (1M).
    2. max requests [number]: Establezca el número máximo de solicitudes por conexión HTTP persistente. Las conexiones persistentes se negocian utilizando el encabezado Keep-Alive en HTTP/1.0 y se habilitan por defecto en HTTP/1.1. El número máximo predeterminado de solicitudes por conexión es 100.
    3. timeout [seconds]: Especifique el tiempo de espera de inactividad en segundos para las sesiones aceptadas. El tiempo de espera predeterminado es de 600 segundos (10 minutos). El máximo es 2147483647 segundos (68 años).
  • directory option: Establezca las opciones especificadas al servir o acceder a directorios. Las opciones válidas son:
    1. [no] auto index: Si no se encuentra ningún archivo de índices (index.html, index.php), genera automáticamente una lista de directorio. Esto está deshabilitado por defecto.
    2. index [string]: Establezca el archivo de índice del directorio. Si no se especifica, el valor predeterminado es index.html.
    3. no index: Deshabilita el índice del directorio. httpd(8) no mostrará ni generará un índice de directorio.
  • [no] fastcgi [socket socket]: Habilite FastCGI en lugar de servir

archivos. El socket es un nombre de ruta local dentro del directorio raíz chroot(2) de httpd(8) y por defecto es /run/slowcgi.sock.

  • listen on [address] [tls] port [number]: Establezca la dirección de escucha y el puerto. Esta declaración se puede especificar varias veces.
  • location [path] {….}: Especifique las reglas de configuración del servidor para una ubicación específica. El argumento de la ruta se comparará con la ruta de la solicitud con reglas globales de shell. Una sección de ubicación puede incluir la mayoría de las reglas de configuración del servidor, excepto conexión, escucha, ubicación y tcp.
  • [no] log [options]: Establecer las opciones de registro especificadas. El registro está habilitado de manera predeterminada mediante el acceso estándar y los archivos de registro de errores, pero se puede cambiar por servidor o ubicación. Use la directiva no log para deshabilitar el registro de cualquier solicitud. Las opciones válidas son:
    1. access [name]: Establezca el nombre del archivo de registro de acceso relativo al directorio de registro. Si no se especifica, el valor predeterminado es access.log.
    2. error [name]: Establezca el nombre del archivo de registro de errores relativo al directorio de registro. Si no se especifica, el valor predeterminado es error.log.
    3. style [style]: Establecer el estilo de registro. El estilo puede ser común, combinado o de conexión. Los estilos comunes y combinados escriben una entrada de registro después de cada solicitud similar a los formatos estándar de registro de acceso Apache y Nginx. La conexión de estilo escribe una entrada de registro resumida después de cada conexión, que puede tener múltiples solicitudes, similar al formato utilizado por relayd(8). Si no se especifica, el valor predeterminado es común.
    4. [no] syslog: Active o desactive el registro en syslog (3) en lugar de los archivos de registro.
  • pass: Deshabilita cualquier block anterior de location.
  • root option: Configure la raíz del documento y las opciones para la ruta de solicitud. Las opciones válidas son:
    1. directory: Establece el DocumentRoot del Servidor. El directorio es un nombre de ruta dentro del directorio raíz chroot(2) de httpd (*/var/www*). Si no se especifica, el valor predeterminado es */htdocs*.
    2. strip [number]: Elimine los componentes de la ruta numérica desde el comienzo de la ruta de solicitud antes de buscar la ruta despojada en la raíz del documento.
  • tcp option: Habilita o deshabilita las opciones TCP/IP especificadas; Consulte tcp(4) e ip(4) para obtener más información sobre las opciones. Las opciones válidas son:
    1. backlog [number]: Número de acumulación, establezca la longitud máxima a la que puede crecer la cola de conexiones pendientes. La opción de reserva es 10 por defecto y está limitada por la variable `kern.somaxconn` en sysctl(8).
    2. ip minttl [number]: Esta opción para la conexión IP subyacente se puede usar para descartar paquetes con un TTL inferior al valor especificado. Esto se puede utilizar para implementar el Mecanismo de seguridad TTL generalizado (GTSM) de acuerdo con RFC-5082.
    3. ip ttl [number]: Cambie el valor predeterminado del tiempo de vida en los encabezados IP.
    4. [no] nodelay: Habilite la opción TCP NODELAY para esta conexión. Esto se recomienda para evitar demoras en el flujo de datos.
    5. [no] sack: Use reconocimientos selectivos para esta conexión.
    6. socket buffer [number]: Establezca el tamaño del búfer de nivel de socket para entrada y salida para esta conexión. Esto afectará el tamaño del paquete TCP.
  • tls options: Establezca la configuración de TLS para el servidor. Estas opciones solo se usan si TLS se ha habilitado a través de la directiva de escucha (listen). Las opciones válidas son:
    1. certificate [file]: Especifique el certificado a utilizar para este servidor. El archivo debe contener un certificado codificado PEM.
    2. ciphers [string]: Especifique la cadena de cifrado TLS. Si no se especifica, se utilizará el valor predeterminado *HIGH:!aNULL* (cifrado criptografico fuerte sin DH anónimo). Consulte la sección CIPHERS de openssl(1) para obtener información sobre los conjuntos de cifrado SSL/TLS y las listas de preferencias.
    3. dhe [params]: Especifique los parámetros DHE que se utilizarán para los conjuntos de cifrado DHE. Los valores de parámetros válidos son none, legacy y auto. Para el legacy, se usa una longitud de clave fija de 1024 bits, mientras que para el auto la longitud de la clave se determina automáticamente. El valor predeterminado es *none*, que deshabilita los conjuntos de cifrado DHE.
    4. ecdhe [curve]: Especifique la curva ECDHE que se utilizará para los conjuntos de cifrado ECDHE. Los valores válidos de los parámetros son none, auto y el nombre corto de cualquier curva conocida. El valor predeterminado es auto.
    5. key [file]: Especifique la clave privada que se usará para este servidor. El archivo debe contener una clave privada codificada por PEM y residir fuera del directorio raíz chroot(2) de httpd.
    6. protocols [strings]: Especifique los protocolos TLS a habilitar para este servidor. Si no se especifica, se utilizará el valor predeterminado todos (todos los protocolos disponibles). Consulte la función tls/config/parse/protocols(3) para ver otros valores de cadena de protocolo válidos.

TYPES

Configure los tipos de medios compatibles. httpd(8) establecerá el Tipo de contenido del encabezado de respuesta en función de la extensión de archivo que figura en la sección de tipos. Si no se especifica, httpd(8) utilizará tipos de medios integrados para text/css, text/html, text/plain, image/gif, image/png, image/jpeg y application/javascript.

La sección de tipos debe incluir una o más líneas de la siguiente sintaxis:

  • type/subtype name [name …]: Establezca el tipo de medio y el subtipo en el nombre de la extensión especificada. Se pueden especificar uno o más nombres por línea. Cada línea puede terminar con un punto y coma opcional.
  • include [file]: Incluya definiciones de tipos de un archivo externo, por ejemplo */usr/share/misc/mime.types*.

Ejemplos

Todas las opciones de configuración anteriores se pueden usar para crear archivos de configuración increíblemente obvios. httpd(8) no instala un archivo de configuración predeterminado largo, el archivo mínimo solo necesita 3 líneas (como se ilustra anteriormente) y todos los valores predeterminados están integrados. El siguiente ejemplo avanzado incluye algunas directivas adicionales:

server "www.example.com" {
	  listen on * port 80
  listen on * tls port 443
  
  # Logging is enabled by default no log
  location "/download/*" {
	  directory auto index
	  log style combined
	  } 
  
  location "/pub/*" {
 	  block return 301 \
	  "http://ftp.example.com/\
	  $REQUEST_URI"
	  }
  
  location "*.php" {
	  fastcgi socket "/run/php-fpm.sock"
	  }
  
  location "/cgi-bin/*" {
	  fastcgi
	  root "/"
	  }
  
  root "/htdocs/www.example.com"
}

Conclusión

httpd se implementó muy rápidamente, solo tomó dos semanas para OpenBSD 5.6 y un ciclo de lanzamiento adicional de aproximadamente 4 meses para la próxima versión 5.7, y se convirtió en un servidor web serio y digno de reemplazo para Nginx/Apache de OpenBSD.

Muchos usuarios ya han comenzado a usarlo, y la comunidad lo ha aceptado muy bien. Tomará muchos años más, tal vez para siempre, hacerlo perfecto, pero parte de este esfuerzo incluirá la eliminación y renovación del código.

Autor Original del Articulo

Reyk Floeter es el fundador de Esdenera Networks GmbH [3], una compañía que desarrolla productos de red y seguridad basados en OpenBSD para redes basadas en la nube y definidas por software. Durante más de diez años, adquirió experiencia en la creación y el soporte comercial de productos de clase empresarial basados en OpenBSD, como el más reciente Esdenera Firewall.

Reyk se encuentra en Hannover, Alemania, pero trabaja con clientes internacionales como Internet Initiative Japan Inc. (IIJ) en Tokio[9]. Es autor del popular balanceador de carga relayd y hacker en el proyecto OpenBSD [12], donde contribuyó con varias características, correcciones, controladores de red y demonios desde 2004, como ath, trunk (también conocido como lagg), vic, hostapd de OpenBSD. relayd, snmpd, iked y httpd.

References

[1] Maxim Dounin, SPDY heap buffer overflow, nginx security advisory (CVE-2014-0133), http://mailman.nginx.org/pipermail/nginx-announce/2014/000135.html?_ga=1.137394864.1013509854.1363164706.

[2] SPDY memory corruption, nginx security advisory (CVE-2014-0088), http://mailman.nginx.org/pipermail/nginx-announce/2014/000132.html?_ga=1.169007649.1013509854.1363164706.

[3] Esdenera, Esdenera Networks GmbH, http://www.esdenera.com/.

[4] Reyk Floeter, httpd Issue Tracker, https://github.com/reyk/httpd/issues?q=label%3Afeaturitis+.

[5] relayd, http://bsd.plumbing/.

[6] reykfloeter@ I committed a web server last night, https://twitter.com/reykfloeter/status/488262609981145088.

[7] reyk/httpd at GitHub, https://github.com/reyk/httpd.

[8] The Apache Software Foundation, The Apache HTTP Server Project, http://httpd.apache.org/.

[9] IIJ, Internet Initiative Japan Inc., http://www.iij.ad.jp/.

[10] Nginx Inc., NGINX, http://nginx.com/.

[11] OpenBSD, OpenBSD 5.6, http://www.openbsd.org/56.html.

[12] The OpenBSD Project, http://www.openbsd.org/.

[13] Florian Weimer, shellshock, CVE-2014-6271:remote code execution through bash, http://seclists.org/oss-sec/2014/q3/649.

informatica/unix_openbsd/obsd-67-http1.txt · Última modificación: 2022/07/18 12:58 por 127.0.0.1
Recent changes RSS feed Creative Commons License Donate Minima Template by Wikidesign Driven by DokuWiki