One place for hosting & domains

      Pasos iniciales para utilizar la biblioteca Requests de Python


      Introducción

      En muchas aplicaciones web, es habitual conectarse a varios servicios de terceros mediante API. Al utilizar estas API, puede acceder a datos como información meteorológica, resultados deportivos, listas de películas, tuits, resultados de motores de búsqueda e imágenes. También puede usar API para añadir funcionalidades a su aplicación. Entre los ejemplos se incluyen pagos, programaciones, correos electrónicos, traducciones, mapas y transferencias de archivos. Si tuviera que crear cualquiera de estos ejemplos por su cuenta, le tomaría muchísimo tiempo, pero con API pude tardar solo unos minutos en conectarse y acceder a sus características y datos.

      En este artículo, aprenderá acerca de la biblioteca Requests de Python, que le permite enviar solicitudes HTTP en Python.

      Además, dado que al usar una API se envían solicitudes HTTP y se reciben respuestas, Requests le permite usar API en Python. Demostraremos el uso de una API de traducción de idiomas para que pueda ver un ejemplo de su funcionamiento.

      Descripción general rápida de solicitudes HTTP

      La web funciona mediante solicitudes HTTP. Cada vez que navega a una página web, su navegador realiza varias solicitudes al servidor de esta. A continuación, el servidor responde con todos los datos necesarios para representar la página y, luego, su navegador la representa de modo que pueda verla.

      El proceso genérico es el siguiente: un cliente (como un navegador o una secuencia de comandos de Python que utilice Requests) enviará algunos datos a una URL y, luego, el servidor situado en la URL leerá los datos, decidirá qué hacer con ellos y mostrará una respuesta al cliente. Por último, el cliente puede decidir qué debe hacer con los datos de la respuesta.

      El método de solicitud está incluido en los datos que el cliente envía en una solicitud. Algunos métodos de solicitud frecuentes son GET, POST y PUT. Las solicitudes GET, en general, se utilizan únicamente para leer datos sin realizar modificaciones, mientras que las solicitudes POST y PUT se suelen usar para modificar datos en el servidor. Por ejemplo, la API Stripe le permite usar solicitudes POST para crear un nuevo cargo a fin de que un usuario pueda adquirir algo desde su aplicación.

      Nota: En este artículo se abarcarán solo las solicitudes GET, dado que no modificaremos datos en un servidor.

      Al enviar una solicitud desde una secuencia de comandos de Python o una aplicación web, usted, el desarrollador, puede decidir qué se envía en cada solicitud y qué hacer con la respuesta. Exploremos esto enviando una solicitud a Scotch.io y, luego, usando una API de traducción de idiomas.

      Instalar Requests de Python

      Antes de todo, debemos instalar la biblioteca. Instalaremos, entonces, Requests usando pip. Es recomendable crear un entorno virtual primero si aún no cuenta con uno.

      Nuestra primera solicitud

      Para comenzar, usaremos Requests para enviar una solicitud al sitio Scotch.io. Cree un archivo denominado script.py y añádale el código siguiente. En este artículo, la cantidad de código con el que trabajaremos será reducida; por lo tanto, cuando se realice algún cambio podrá actualizar el código existente en lugar de añadir nuevas líneas.

      script.py

      import requests
      
      res = requests.get('https://scotch.io')
      
      print(res)
      

      Lo único que hace este código es enviar una solicitud GET a Scotch.io. Este es el mismo tipo de solicitud que envió su navegador para ver esta página, pero la única diferencia es que Requests no puede representar el HTML. Por lo tanto, en su lugar solo obtendrá el HTML sin procesar y el resto de la información de la respuesta.

      En este caso, usaremos la función .get(). Sin embargo, Requests también le permite usar otras funciones, como .post() y .put(), para enviar estas solicitudes.

      Puede ejecutarla con el archivo script.py.

      Recibirá esta respuesta: script run with output of `Response 200`

      Códigos de estado

      Lo primero que podemos hacer es verificar el código de estado. Los códigos HTTP van de “1XX” a “5XX”. Los códigos de estado frecuentes que probablemente haya visto son “200”, “404” y “500”.

      A continuación, le ofrecemos una descripción general rápida del significado de cada código de estado:

      • 1XX: información
      • 2XX: éxito
      • 3XX: redireccionamiento
      • 4XX: error del cliente (usted cometió un error)
      • 5XX: error del servidor (se cometió un error en este)

      En general, al realizar sus propias solicitudes lo que busca son códigos de estado del orden del 200.

      Requests reconoce que los códigos de estado 4XX y 5XX son errores. Por lo tanto, si se muestran estos códigos de estado, el objeto de respuesta de la solicitud se evalúa como False.

      Puede probar si se respondió correctamente una solicitud verificando si la respuesta es verdadera. Por ejemplo:

      script.py

      if res:
          print('Response OK')
      else:
          print('Response Failed')
      

      Resultado “Response 200” seguido de “Response OK”

      El mensaje “Response Failed” solo aparecerá si se muestra un código de estado 400 o 500. Pruebe cambiar la URL por cualquier texto no tenga sentido para ver la falla de la respuesta y la aparición del estado 404.

      Puede ver el código de estado directamente añadiendo lo siguiente:

      script.py

      print(res.status_code)
      

      Con esto, verá el código de estado directamente para poder verificar el número.

      Resultado de error con 404

      Encabezados

      Otro elemento que puede obtener de la respuesta son los encabezados. Puede consultarlos usando el diccionario de encabezados del objeto de respuesta.

      script.py

      print(res.headers)
      

      Resultado con encabezados impresos en salida estándar

      Los encabezados se envían junto con la solicitud y se muestran en la respuesta. Los encabezados se utilizan para que tanto el cliente como el servidor puedan interpretar los datos que se envían y se reciben en el envío o la respuesta.

      Vemos los diversos encabezados que se muestran. En muchas ocasiones, no necesitará usar la información de encabezados directamente, pero se encuentra allí si la necesita.

      El tipo de contenido suele ser el que necesita, dado que muestra el formato de los datos; por ejemplo, HTML, JSON, PDF y texto, entre otros. Sin embargo, Requests suele gestionar el tipo de contenido para que pueda acceder a los datos que se muestran.

      Texto de respuesta

      Por último, si examinamos res.text (que funciona para datos textuales, como la página HTML que visualizamos) podemos ver todo el HTML necesario para crear la página de inicio de Scotch. No se representará, pero podemos ver que parece pertenecer a Scotch. Si guardara esto en un archivo y lo abriera, vería algo similar al sitio de Scotch. En una situación real, se deben realizar varias solicitudes para que una página web cargue cosas como imágenes, secuencias de comandos y hojas de estilo. Por lo tanto, si guarda únicamente el HTML en un archivo, no se parecerá en absoluto a la página Scotch.io que ve en su navegador, dado que se realizó una sola solicitud para obtener datos HTML.

      script.py

      print(res.text)
      

      Datos HTML impresos en la línea de comandos

      Usar la API de traducción

      Ahora, pasemos a algo más interesante. Usaremos la API de traducción de Yandex para realizar una solicitud de traducción de texto a otro idioma.

      Para usar la API, primero, debe registrarse. Una vez que se haya registrado, diríjase a la API de traducción y cree una clave de API. Cuando tenga la clave de API, agréguela a su archivo como una constante. Este es el enlace en el que podrá encontrar todo lo mencionado: https://tech.yandex.com/translate/.

      script.py

      API_KEY = 'your yandex api key'
      

      Necesitamos una clave de API para que Yandex pueda autenticarnos cada vez que queramos usar su API. La clave de API es una forma de autenticación ligera, dado que se añade al final de la URL de la solicitud al enviarla.

      Para saber qué URL debemos enviar para usar la API, podemos consultar la documentación de Yandex.

      Allí, veremos toda la información necesaria para aplicar su API de traducción en la traducción de texto.

      Sintaxis de la solicitud para usar la API

      Cuando vemos una URL con “&”, “?” y “=”, podemos estar seguros de que la URL se utiliza para solicitudes GET. Estos símbolos especifican los parámetros que se incluyen con la URL.

      En general, todo lo que se encuentre entre corchetes ([]) será opcional. En este caso, el formato, las opciones y la devolución de llamada son opcionales, mientras que la clave, el texto y el idioma son obligatorios para la solicitud.

      Añadiremos código para enviar a esa URL. Puede sustituir la primera solicitud que creamos por esta:

      script.py

      url = 'https://translate.yandex.net/api/v1.5/tr.json/translate'
      res = requests.get(url)
      

      Hay dos formas de añadir parámetros. Podemos añadirlos directamente al final de la URL o hacer que Requests lo haga por nosotros. Para hacer esto último, podemos crear un diccionario para nuestros parámetros. Los tres elementos que necesitamos son la clave, el texto y el idioma. Crearemos el diccionario usando la clave de API 'Hello' para el texto y 'en-es' como idioma, que significa que queremos traducir contenido del inglés al español.

      Si necesita otros códigos de idiomas, puede consultarlos aquí. Busque la columna 639-1.

      Creamos un diccionario de parámetros usando la función dict() y proporcionando las claves y los valores que queremos en nuestro diccionario.

      script.py

      params = dict(key=API_KEY, text='Hello', lang='en-es')
      

      Ahora, pasaremos el diccionario de parámetros a la función .get().

      script.py

      res = requests.get(url, params=params)
      

      Cuando pasemos los parámetros de esta forma, Requests procederá a añadir los parámetros a la URL por nosotros.

      Ahora, añadiremos una instrucción de impresión para el texto de respuesta y veremos lo que se muestre en la respuesta.

      script.py

      print(res.text)
      

      Diccionario de salida con los valores ingresados

      Se ven tres elementos: El código de estado, que es exactamente el mismo de la respuesta, el idioma que especificamos y el texto traducido dentro de la lista. Por lo tanto, debe ver 'Hola' en el texto traducido.

      Vuelva a probar con el código de idiomas en-fr. Ahora, debería ver 'Bonjour' en la respuesta.

      script.py

      params = dict(key=API_KEY, text='Hello', lang='en-fr')
      

      Texto traducido al francés

      Veamos los encabezados de esta respuesta en particular.

      script.py

      print(res.headers)
      

      Encabezados impresos en el resultado

      Obviamente, los encabezados serán distintos porque nos comunicamos con un servidor diferente, pero en este caso el tipo de contenido es application/json en lugar de text/html. Esto significa que los datos se pueden interpretar como JSON.

      Cuando application/json es el tipo de contenido de la respuesta, podemos hacer que Requests convierta la respuesta en un diccionario y una lista para que podamos acceder a los datos con mayor facilidad.

      Para que los datos se analicen como JSON, usaremos el método .json() en el objeto de respuesta.

      Si lo imprime, verá que los datos tienen el mismo aspecto, pero el formato es ligeramente diferente.

      script.py

      json = res.json()
      print(json)
      

      Es distinto porque ya no es texto simple que usted obtiene de res.text. En este caso, es una versión impresa de un diccionario.

      Supongamos que queremos acceder al texto. Puesto que ahora se trata de un diccionario, podemos usar la clave de texto.

      script.py

      print(json['text'])
      

      Ahora solo vemos los datos de esa clave. En este caso, vemos una lista de un elemento; por lo tanto, si quisiéramos obtener ese texto en la lista directamente podríamos acceder a él mediante el índice.

      script.py

      print(json['text'][0])
      

      “Bonjour” sin corchetes

      Ahora, lo único que vemos es la palabra traducida.

      Por supuesto, si modificamos nuestros parámetros obtendremos resultados distintos. Cambiaremos el texto que se traducirá de Hello a Goodbye, volveremos a fijar el español como idioma de destino y reenviaremos la solicitud.

      script.py

      params = dict(key=API_KEY, text='Goodbye', lang='en-es')
      

      “Adiós” impreso en el resultado Pruebe traducir textos más largos en distintos idiomas para ver qué respuestas recibe de la API.

      Casos de error en la API de traducción

      Por último, veremos un caso de error. No siempre funciona todo bien. Por lo tanto, necesitamos saber cuándo ocurre un error.

      Pruebe cambiar su clave de API eliminando un carácter. Cuando lo haga, su clave de API dejará de ser válida. Luego, intente enviar una solicitud.

      Al observar el código de estado, esto es lo que verá:

      script.py

      print(res.status_code)
      

      Error 403 Por lo tanto, cuando utilice la API será conveniente que verifique si todo está en orden o no para poder manejar los casos de error de acuerdo con las necesidades de su aplicación.

      Conclusión

      A continuación, se muestra lo que aprendió:

      • Cómo funcionan las solicitudes HTTP
      • Diversos códigos de estado posibles de una respuesta
      • Cómo enviar solicitudes y recibir respuestas usando la biblioteca Requests de Python
      • Cómo usar una API de traducción de idiomas para traducir texto
      • Cómo convertir respuestas de contenido application/JSON en diccionarios

      Si desea ampliar sus posibilidades, consulte esta lista para ver los diferentes tipos de API disponibles e intente usarlos con Requests de Python.



      Source link

      Pasos recomendados para proteger un clúster de Kubernetes de DigitalOcean


      El autor seleccionó Open Sourcing Mental Illness para recibir una donación como parte del programa Write for DOnations.

      Introducción

      Kubernetes, la plataforma de orquestación de contenedores de código abierto, se está convirtiendo en la solución preferida para automatizar, escalar y administrar clústeres de alta disponibilidad. Como resultado de su creciente popularidad, la seguridad en ella se ha vuelto cada vez más relevante.

      Tomando en cuenta los elementos móviles que intervienen en Kubernetes y la variedad de escenarios de implementación, proteger Kubernetes a veces puede ser un proceso complejo. Debido a esto, el objetivo de este artículo es proporcionar una base de seguridad sólida para un clúster de Kubernetes de DigitalOcean (DOKS). Tenga en cuenta que este tutorial contempla las medidas básicas de seguridad para Kubernetes y está pensado para ser un punto de partida más que una guía exhaustiva. Para hallar pasos adicionales, consulte la documentación oficial de Kubernetes.

      A través de esta guía, completará pasos básicos para proteger su clúster de Kubernetes de DigitalOcean. Configurará la autenticación local segura con certificados TLS y SSL, concederá permisos a los usuarios locales con controles de acceso basados en roles (RBAC), concederá permisos a aplicaciones e implementaciones de Kubernetes con cuentas de servicio y establecerá límites de recursos con los controladores de admisión ResourceQuota y LimitRange.

      Requisitos previos

      Para completar este tutorial, necesitará lo siguiente:

      • Un clúster administrado por DigitalOcean de Kubernetes (DOKS) con 3 nodos estándares configurados cada uno con al menos 2 GB de RAM y 1 vCPU. Para hallar instrucciones detalladas sobre cómo crear un clúster DOKS, consulte nuestra guía de inicio rápido de Kubernetes. En este tutorial se utiliza DOKS 1.16.2-do.1.
      • Un cliente local configurado para administrar el clúster DOKS, con un archivo de configuración de clúster descargado del panel de control de DigitalOcean y guardado como ~/.kube/config. Para hallar instrucciones detalladas sobre cómo configurar la administración remota de DOKS, lea nuestra guía Cómo establecer conexión con un clúster de Kubernetes de DigitalOcean. En particular, necesitará lo siguiente:
        • La interfaz de línea de comandos kubectl instalada en su computadora local. Puede obtener más información sobre cómo instalar y configurar kubectl en su documentación oficial. En este tutorial, usaremos la versión 1.17.0-00 de kubectl.
        • La herramienta de línea de comandos oficial de DigitalOcean, doctl. Para hallar instrucciones sobre cómo instalar esto, consulte la página sobre doctl de GitHub. En este tutorial, se usará la versión 1.36.0 de doctl.

      Paso 1: Habilitar la autenticación remota de usuarios

      Una vez completados los requisitos previos, obtendrá un superusuario de Kubernetes que se autentica a través de un token de portador de DigitalOcean predefinido. Sin embargo, compartir esas credenciales no es una práctica de seguridad recomendada, ya que en esta cuenta se pueden ocasionar cambios a gran escala y posiblemente destructivos para su clúster. Para reducir esta posibilidad, puede configurar usuarios adicionales que se autentiquen desde sus respectivos clientes locales.

      En esta sección, autenticará nuevos usuarios en el clúster DOKS remoto de los clientes locales usando certificados SSL y TLS seguros. Será un proceso de tres pasos: primero, creará solicitudes de firma de certificados (CSR) para cada usuario. Luego, aprobará esos certificados directamente en el clúster a través de kubectl. Por último, creará para cada usuario un archivo kubeconfig con los certificados correspondientes. Para obtener más información sobre los métodos de autenticación adicionales compatibles con Kubernetes, consulte la documentación de autenticación de Kubernetes.

      Crear solicitudes de firma de certificados para nuevos usuarios

      Antes de comenzar, compruebe la conexión del clúster DOKS desde la máquina local configurada en los requisitos previos:

      Dependiendo de su configuración, el resultado será similar a este:

      Output

      Kubernetes master is running at https://a6616782-5b7f-4381-9c0f-91d6004217c7.k8s.ondigitalocean.com CoreDNS is running at https://a6616782-5b7f-4381-9c0f-91d6004217c7.k8s.ondigitalocean.com/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

      Esto significa que está conectado al clúster DOKS.

      A continuación, cree una carpeta local para los certificados de cliente. A los efectos de esta guía, se usará ~/certs para almacenar todos los certificados:

      En este tutorial, para acceder al clúster autorizaremos un nuevo usuario llamado sammy. Puede cambiarlo por un usuario que elija. Usando la biblioteca OpenSSL de SSL y TLS, genere una nueva clave privada para su usuario con el siguiente comando:

      • openssl genrsa -out ~/certs/sammy.key 4096

      Con el indicador -out se creará el archivo de salida ~/certs/sammy.key, y con 4096 se fija la clave en 4096 bits. Para obtener más información sobre OpenSSL, consulte nuestra guía Aspectos básicos de OpenSSL.

      A continuación, cree un archivo de configuración de la solicitud de firma de certificados. Abra el siguiente archivo con un editor de texto (para este tutorial, usaremos nano):

      • nano ~/certs/sammy.csr.cnf

      Añada el siguiente contenido al archivo sammy.csr.cnf para especificar en el tema el nombre de usuario deseado como nombre común (CN) y el grupo como organización (O):

      ~/certs/sammy.csr.cnf

      [ req ]
      default_bits = 2048
      prompt = no
      default_md = sha256
      distinguished_name = dn
      [ dn ]
      CN = sammy
      O = developers
      [ v3_ext ]
      authorityKeyIdentifier=keyid,issuer:always
      basicConstraints=CA:FALSE
      keyUsage=keyEncipherment,dataEncipherment
      extendedKeyUsage=serverAuth,clientAuth
      

      En el archivo de configuración de la solicitud de firma de certificados se incluyen toda la información necesaria, la identidad del usuario y los parámetros de uso adecuados para el usuario. El ltimo argumento extendedKeyUsage=serverAuth,clientAuth permitirá que los usuarios autentiquen sus clientes locales con el clúster DOKS usando el certificado una vez que se haya firmado.

      A continuación, cree la solicitud de firma de certificados sammy:

      • openssl req -config ~/certs/sammy.csr.cnf -new -key ~/certs/sammy.key -nodes -out ~/certs/sammy.csr

      Con -config se le permite especificar el archivo de configuración para la CSR, y -new indica que creará una nueva CSR para la clave especificada por -key.

      Puede verificar la solicitud de firma de certificados ejecutando el siguiente comando:

      • openssl req -in ~/certs/sammy.csr -noout -text

      Se pasa la CSR con -in y se utiliza -text para imprimir la solicitud del certificado en texto.

      En el resultado, se mostrará la solicitud del certificado, cuyo comienzo tendrá un aspecto similar a este:

      Output

      Certificate Request: Data: Version: 1 (0x0) Subject: CN = sammy, O = developers Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public-Key: (4096 bit) ...

      Repita el mismo procedimiento para crear CSR para cualquier usuario adicional. Una vez que tenga todas las solicitudes de firma de certificados guardadas en la carpeta del administrador ~/certs, proceda con el paso siguiente para aprobarlas.

      Administrar solicitudes de firma de certificados con la API de Kubernetes

      Puede aprobar o negar certificados TLS emitidos para la API de Kubernetes usando la herramienta de línea de comandos kubectl. Con esto, tendrá la capacidad de garantizar que el acceso solicitado sea apropiado para el usuario en cuestión. En esta sección, enviará la solicitud de certificado para sammy y la aprobará.

      Para enviar una CSR al clúster DOKS, utilice el siguiente comando:

      cat <<EOF | kubectl apply -f -
      apiVersion: certificates.k8s.io/v1beta1
      kind: CertificateSigningRequest
      metadata:
        name: sammy-authentication
      spec:
        groups:
        - system:authenticated
        request: $(cat ~/certs/sammy.csr | base64 | tr -d 'n')
        usages:
        - digital signature
        - key encipherment
        - server auth
        - client auth
      EOF
      

      Mediante un here document de Bash, este comando utiliza cat para pasar la solicitud de certificado a kubectl apply.

      Veamos con más detalle la solicitud de certificado:

      • Con name: sammy-authentication, se crea un identificador de metadatos llamado en este caso sammy-authentication.
      • Con request: $(cat ~/certs/sammy.csr | base64 | tr -d 'n') se envía la solicitud de firma de certificados sammy.csr al clúster, codificado como base64.
      • Con server auth y client auth se especifica el uso previsto del certificado. En este caso, el propósito es autenticar el usuario.

      El resultado tendrá un aspecto similar a este:

      Output

      certificatesigningrequest.certificates.k8s.io/sammy-authentication created

      Puede verificar el estado de la solicitud de firma de certificados usando el siguiente comando:

      Dependiendo de la configuración de su clúster, el resultado será similar a este:

      Output

      NAME AGE REQUESTOR CONDITION sammy-authentication 37s your_DO_email Pending

      A continuación, apruebe la CSR usando el siguiente comando:

      • kubectl certificate approve sammy-authentication

      Verá un mensaje que confirmará la operación:

      Output

      certificatesigningrequest.certificates.k8s.io/sammy-authentication approved

      Nota: Como administrador, también puede negar una CSR usando el comando kubectl certificate deny sammy-authentication. Para obtener más información sobre la administración de certificados TLS, consulte la documentación oficial de Kubernetes.

      Ahora que se aprobó la CSR, puede descargarla a la máquina local ejecutando lo siguiente:

      • kubectl get csr sammy-authentication -o jsonpath='{.status.certificate}' | base64 --decode > ~/certs/sammy.crt

      Con este comando, se decodifica el certificado de Base64 para que kubectl lo use correctamente; luego se guarda como ~/certs/sammy.crt.

      Una vez firmado el el certificado sammy, podrá crear el archivo kubeconfig del usuario.

      Crear Kubeconfig para usuarios remotos

      A continuación, creará un archivo kubeconfig específico para el usuario sammy. Esto le proporcionará más control sobre el acceso del usuario a su clúster.

      El primer paso para crear un nuevo kubeconfig es hacer una copia del archivo kubeconfig actual. A los efectos de esta guía, el nuevo archivo kubeconfig recibirá el nombre config-sammy:

      • cp ~/.kube/config ~/.kube/config-sammy

      A continuación, edite el nuevo archivo:

      • nano ~/.kube/config-sammy

      Conserve las primeras ocho líneas de este archivo, ya que contienen la información necesaria para la conexión SSL y TLS con el clúster. Luego, empezando por el parámetro de user, sustituya el texto por las siguientes líneas resaltadas de modo que el archivo tenga un aspecto similar al siguiente:

      config-sammy

      apiVersion: v1
      clusters:
      - cluster:
          certificate-authority-data: certificate_data
        name: do-nyc1-do-cluster
      contexts:
      - context:
          cluster: do-nyc1-do-cluster
          user: sammy
        name: do-nyc1-do-cluster
      current-context: do-nyc1-do-cluster
      kind: Config
      preferences: {}
      users:
      - name: sammy
        user:
          client-certificate: /home/your_local_user/certs/sammy.crt
          client-key: /home/your_local_user/certs/sammy.key
      

      Nota: Tanto para client-certificate como client-key, utilice la ruta absoluta hacia las ubicaciones de sus certificados correspondientes. De lo contrario, en kubectl se producirá un error.

      Guarde el archivo y ciérrelo.

      Puede probar la conexión del usuario nuevo usando kubectl cluster-info:

      • kubectl --kubeconfig=/home/your_local_user/.kube/config-sammy cluster-info

      Verá un error similar a este:

      Output

      To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'. Error from server (Forbidden): services is forbidden: User "sammy" cannot list resource "services" in API group "" in the namespace "kube-system"

      Este error se espera, ya que el usuario sammy no tiene autorización para enumerar ningún recurso en el clúster. En el siguiente paso, se cubrirá la concesión de autorización a los usuarios. Por ahora, en el resultado se confirma que la conexión SSL y TLS fue exitosa y la API de Kubernetes aceptó las credenciales de autenticación de sammy.

      Paso 2: Autorizar usuarios a través del control de acceso basado en roles (RBAC)

      Una vez que un usuario se autentica, en la API se determinan sus permisos usando el modelo integrado de control de acceso basado en roles (RBAC) de Kubernetes. El RBAC es un método eficaz para restringir derechos de usuarios en función del rol asignado. Desde el punto de vista de la seguridad, con RBAC se permite la personalización avanzada de permisos para limitar, en el caso de los usuarios, el acceso a datos confidenciales o la ejecución de comandos en el nivel del superusuario. Para obtener más información sobre los roles de usuario, consulte la documentación de RBAC de Kubernetes.

      En este paso, usará kubectl para asignar el rol predefinido edit al usuario sammy en el espacio de nombres default. En un entorno de producción, es posible que quiera usar roles personalizados o vinculaciones de estos roles.

      Conceder permisos

      En Kubernetes, conceder permisos implica asignar el rol deseado a un usuario. Asigne los permisos edit al usuario sammy en el espacio de nombres default usando el siguiente comando:

      • kubectl create rolebinding sammy-edit-role --clusterrole=edit --user=sammy --namespace=default

      Con esto, se mostrará un resultado similar al siguiente:

      Output

      rolebinding.rbac.authorization.k8s.io/sammy-edit-role created

      Analizaremos este comando en mayor detalle:

      • Con create rolebinding sammy-edit-role se crea un nueva vinculación de rol, en este caso llamada sammy-edit-role.
      • Con --clusterrole=edit se asigna el rol predefinido edit en un ámbito global (rol de clúster).
      • Con --user=sammy se especifica el usuario con el que se vinculará el rol.
      • Con --namespace=default se conceden al usuario los permisos del rol dentro del espacio de nombres especificado; en este caso, default.

      A continuación, verifique los permisos del usuario enumerando pods en el espacio de nombres default. Puede comprobar si la autorización de RBAC funciona como se espera si no se muestran errores.

      • kubectl --kubeconfig=/home/your_local_user/.kube/config-sammy auth can-i get pods

      Verá el siguiente resultado:

      Output

      yes

      Ahora que asignó permisos a sammy, en la siguiente sección puede practicar la revocación de esos permisos.

      Revocar permisos

      La revocación de permisos en Kubernetes se realiza eliminando la vinculación de rol del usuario.

      Para este tutorial, elimine el rol edit del usuario sammy ejecutando el siguiente comando:

      • kubectl delete rolebinding sammy-edit-role

      Verá el siguiente resultado:

      Output

      rolebinding.rbac.authorization.k8s.io "sammy-edit-role" deleted

      Verifique si los permisos del usuario se revocaron como se esperaba enumerando los pods del espacio de nombres default:

      • kubectl --kubeconfig=/home/localuser/.kube/config-sammy --namespace=default get pods

      Obtendrá el siguiente error:

      Output

      Error from server (Forbidden): pods is forbidden: User "sammy" cannot list resource "pods" in API group "" in the namespace "default"

      Esto muestra que se revocó la autorización.

      Desde el punto de vista de la seguridad, con el modelo de autorización de Kubernetes se brinda a los administradores la flexibilidad necesaria para cambiar los derechos de los usuarios a pedido, según sea necesario. Además, el control de acceso basado en roles no se limita a un usuario físico; también puede conceder y eliminar permisos a servicios de clústeres, como se explicará en la siguiente sección.

      Para obtener más información sobre la autorización de RBAC y la manera de crear roles personalizados, consulte la documentación oficial.

      Paso 3: Administrar permisos de aplicación con cuentas de servicio

      Como se mencionó en la sección anterior, los mecanismos de autorización de RBAC van más allá de los usuarios humanos. Los usuarios de clústeres no humanos, como las aplicaciones, los servicios y los procesos que se ejecutan dentro de pods, se autentican con el servidor de API usando lo que en Kubernetes se conoce como cuentas de servicio. Cuando se crea un pod dentro de un espacio de nombres, puede permitir que se utilice la cuenta de servicio default o definir una cuenta de servicio que elija. La capacidad de asignar cuentas de servicio individuales a aplicaciones y procesos brinda a los administradores la libertad de conceder o revocar permisos según sea necesario. Además, se considera una buena práctica de seguridad asignar cuentas de servicio específicas a aplicaciones críticas para la producción. Debido a que las cuentas de servicio (SA) se utilizan para la autenticación, y por lo tanto para realizar comprobaciones de autorización de RBAC, los administradores de clústeres pueden contener las amenazas de seguridad cambiando los derechos de acceso de las cuentas de servicio y aislando el proceso delictivo.

      Para ofrece una demostración de las SA, en este tutorial utilizaremos un servidor web Nginx como una aplicación de ejemplo.

      Antes de asignar una SA en particular a su aplicación, deberá crear dicha SA. Cree una nueva cuenta de servicio llamada nginx-sa en el espacio de nombres default:

      • kubectl create sa nginx-sa

      Obtendrá este resultado:

      Output

      serviceaccount/nginx-sa created

      Verifique que la cuenta de servicio se haya creado ejecutando lo siguiente:

      Esto le proporcionará una lista de sus cuentas de servicios:

      Output

      NAME SECRETS AGE default 1 22h nginx-sa 1 80s

      A continuación, asignará un rol a la cuenta de servicio nginx-sa. Para este ejemplo, conceda a nginx-sa los mismos permisos que al usuario sammy:

      • kubectl create rolebinding nginx-sa-edit
      • --clusterrole=edit
      • --serviceaccount=default:nginx-sa
      • --namespace=default

      Al ejecutar esto, obtendrá el siguiente resultado:

      Output

      rolebinding.rbac.authorization.k8s.io/nginx-sa-edit created

      En este comando se utiliza el mismo formato que para el usuario sammy, a excepción del indicador --serviceaccount=default:nginx-sa, donde asigna la cuenta de servicio nginx-sa en el espacio de nombres default.

      Compruebe que la vinculación del rol se haya realizado correctamente usando este comando:

      Esto generará el siguiente resultado:

      Output

      NAME AGE nginx-sa-edit 23s

      Una vez que haya confirmado que la vinculación del rol para la cuenta del servicio se configuró correctamente, podrá asignar la cuenta de servicio a una aplicación. Asignar una cuenta de servicio particular a una aplicación le permitirá administrar sus derechos de acceso en tiempo real y, por lo tanto, mejorar la seguridad del clúster.

      A los efectos de este tutorial, un pod de nginx servirá como la aplicación de muestra. Cree el nuevo pod y especifique la cuenta de servicio nginx-sa con el siguiente comando:

      • kubectl run nginx --image=nginx --port 80 --serviceaccount="nginx-sa"

      En la primera parte del comando se crea un nuevo pod ejecutando un servidor web nginx en el puerto :80, y en la última parte en --serviceaccount="nginx-sa" se indica que en este pod se debe usar la cuenta de usuarionginx-sa y no la SA default.

      Con esto, se mostrará un resultado similar al siguiente:

      Output

      deployment.apps/nginx created

      Verifique que en la nueva aplicación se utilice la cuenta de servicio usando kubectl describe:

      • kubectl describe deployment nginx

      Con esto se mostrará una descripción extensa de los parámetros de implementación. En la sección de Pod Template, verá un resultado similar al siguiente:

      Output

      ... Pod Template: Labels: run=nginx Service Account: nginx-sa ...

      En esta sección, creó la cuenta de servicio nginx-sa en el espacio de nombres default y la asignó al servidor web nginx. Ahora puede controlar los permisos de nginx en tiempo real cambiando sus roles según sea necesario. También puede agrupar aplicaciones asignando la misma cuenta de servicio a cada una y luego aplicar cambios en bloque a los permisos. Finalmente, puede aislar aplicaciones críticas asignándoles una cuenta de usuario única.

      En resumen, la idea de asignar roles a sus aplicaciones e implementaciones es ajustar los permisos. En los entornos de producción reales, es posible que tenga varias implementaciones que requieran diferentes permisos, que abarcan desde privilegios de solo lectura a privilegios administrativos completos. Con el uso del RBAC se le proporciona la flexibilidad necesaria para restringir el acceso al clúster según sea necesario.

      A continuación, establecerá los controladores de admisión para controlar los recursos y protegerse de los ataques de agotamiento de recursos.

      Paso 4: Configurar controladores de admisión

      Los controladores de admisión de Kubernetes son complementos opcionales que se compilan en el binario kube-apiserver para ampliar las opciones de seguridad. Los controladores de admisión interceptan solicitudes una vez que superan la fase de autenticación y autorización. Cuando interceptan una solicitud, los controladores de admisión ejecutan el código especificado justo antes de que esta se aplique.

      Si bien el resultado de una verificación de autenticación o autorización es un booleano con el que se permite o deniega la solicitud, los controladores de admisión pueden ser mucho más diversos. Los controladores de admisión pueden validar las solicitudes de la misma forma que la autenticación, pero también pueden mutar o cambiar las solicitudes y modificar los objetos antes de su admisión.

      En este paso, usará los controladores de admisión ResourceQuota y LimitRange para proteger su clúster mediante la mutación de las solicitudes que podrían contribuir a un ataque de agotamiento de recursos o denegación de servicio. Con el controlador de admisión ResourceQuota se permite a los administradores restringir los recursos informáticos y de almacenamiento, y la cantidad de cualquier objeto dentro de un espacio de nombres, mientras que el controlador de admisión LimitRange limita el número de recursos que los contenedores utilizan. Utilizar estos dos controladores de admisión juntos protegerá su clúster contra ataques que hacen que sus recursos no estén disponibles.

      Para demostrar cómo funciona ResourceQuota, implementará algunas restricciones en el espacio de nombres default. Comience creando un nuevo archivo de objeto ResourceQuota:

      • nano resource-quota-default.yaml

      Añada la siguiente definición de objeto para establecer restricciones para el consumo de recursos en el espacio de nombres default. Puede ajustar los valores según sea necesario dependiendo de los recursos físicos de sus nodos:

      resource-quota-default.yaml

      apiVersion: v1
      kind: ResourceQuota
      metadata:
        name: resource-quota-default
      spec:
        hard:
          pods: "2"
          requests.cpu: "500m"
          requests.memory: 1Gi
          limits.cpu: "1000m"
          limits.memory: 2Gi
          configmaps: "5"
          persistentvolumeclaims: "2"
          replicationcontrollers: "10"
          secrets: "3"
          services: "4"
          services.loadbalancers: "2"
      

      En esta definición se utiliza la palabra clave hard para establecer restricciones estrictas, como el número máximo de pods, configmaps, PersistentVolumeClaims, ReplicationControllers, secrets, services y loadbalancers. Con esto también se establecen restricciones en los recursos de proceso, como las siguientes:

      • requests.cpu fija el valor de CPU máximo de solicitudes en milliCPU o una milésima parte de un núcleo de CPU.
      • requests.memory fija el valor de memoria máximo de solicitudes en bytes.
      • limits.cpu fija el valor máximo de CPU de los límites en milliCPU.
      • limits.memory fija el valor máximo de memoria de los límites en bytes.

      Guarde el archivo y ciérrelo.

      Ahora, cree el objeto en el espacio de nombres ejecutando el siguiente comando:

      • kubectl create -f resource-quota-default.yaml --namespace=default

      Obtendrá el siguiente resultado:

      Output

      resourcequota/resource-quota-default created

      Tenga en cuenta que usará el indicador -f para marcar en Kubernetes la ubicación del archivo ResourceQuota y el indicador --namespace para especificar el espacio de nombres que se actualizará.

      Una vez creado el objeto, ResourceQuota estará activo. Puede verificar las cuotas del espacio de nombres default con describe quota:

      • kubectl describe quota --namespace=default

      El resultado será similar al siguiente, con los límites estrictos que estableció en el archivo resource-quota-default.yaml:

      Output

      Name: resource-quota-default Namespace: default Resource Used Hard -------- ---- ---- configmaps 0 5 limits.cpu 0 1 limits.memory 0 2Gi persistentvolumeclaims 0 2 pods 1 2 replicationcontrollers 0 10 requests.cpu 0 500m requests.memory 0 1Gi secrets 2 3 services 1 4 services.loadbalancers 0 2

      Las ResourceQuotas se expresan en unidades absolutas. Por ello, añadir nodos no aumentará automáticamente los valores definidos aquí. Si se añaden nodos, deberá editar manualmente los valores aquí para equilibrar los recursos. Las ResourceQuotas pueden modificarse tanta veces como lo necesite, pero no pueden eliminarse a menos que se quite todo el espacio de nombres.

      Si necesita modificar una ResourceQuota en particular, actualice el archivo .yaml correspondiente y aplique los cambios usando el siguiente comando:

      • kubectl apply -f resource-quota-default.yaml --namespace=default

      Para obtener más información sobre el controlador de admisión ResourceQuota, consulte la documentación oficial.

      Ahora que su ResourceQuota está establecido, procederá con la configuración del controlador de admisión LimitRange. Así como ResourceQuota impone límites para los espacios de nombres, de forma similar LimitRange aplica las limitaciones declaradas validando y mutando contenedores.

      Siguiendo un procedimiento similar al que usó antes, comience creando el archivo objeto:

      • nano limit-range-default.yaml

      Ahora, puede usar el objeto LimitRange para restringir el uso de recursos según sea necesario. Añada el siguiente contenido como ejemplo de un caso de uso típico:

      limit-ranges-default.yaml

      apiVersion: v1
      kind: LimitRange
      metadata:
        name: limit-range-default
      spec:
        limits:
        - max:
            cpu: "400m"
            memory: "1Gi"
          min:
            cpu: "100m"
            memory: "100Mi"
          default:
            cpu: "250m"
            memory: "800Mi"
          defaultRequest:
            cpu: "150m"
            memory: "256Mi"
          type: Container
      

      Con los valores de ejemplo utilizados en limit-ranges-default.yaml se restringe la memoria del contenedor a un máximo de 1Gi y se limita el uso del CPU a un máximo de 400m, lo cual es una métrica de Kubernetes equivalente a 400 milliCPU. Esto implica que el uso del contenedor se limita a casi la mitad de su núcleo.

      A continuación, implemente el objeto en el servidor de API usando el siguiente comando:

      • kubectl create -f limit-range-default.yaml --namespace=default

      Esto generará el siguiente resultado:

      Output

      limitrange/limit-range-default created

      Ahora puede verificar los nuevos límites con el siguiente comando:

      • kubectl describe limits --namespace=default

      El resultado tendrá un aspecto similar a este:

      Output

      Name: limit-range-default Namespace: default Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio ---- -------- --- --- --------------- ------------- ----------------------- Container cpu 100m 400m 150m 250m - Container memory 100Mi 1Gi 256Mi 800Mi -

      Para ver LimitRanger en acción, implemente un contenedor estándar nginx con el siguiente comando:

      • kubectl run nginx --image=nginx --port=80 --restart=Never

      Esto generará el siguiente resultado:

      Output

      pod/nginx created

      Ejecutando el siguiente comando, compruebe la forma en que el controlador de admisión mutó el contenedor:

      • kubectl get pod nginx -o yaml

      Esto generará muchas líneas de resultado. Busque en la sección de especificaciones de los contenedores para encontrar los límites de recursos especificados en el controlador de admisión LimitRange.

      Output

      ... spec: containers: - image: nginx imagePullPolicy: IfNotPresent name: nginx ports: - containerPort: 80 protocol: TCP resources: limits: cpu: 250m memory: 800Mi requests: cpu: 150m memory: 256Mi ...

      Esto sería lo mismo que declarar manualmente resources y requests en la especificación del contenedor.

      En este paso, usó los controladores de admisión ResourceQuota y LimitRange para protegerse de los ataques malintencionados contra los recursos de su clúster. Para obtener más información sobre el controlador de admisión LimitRange, consulte la documentación oficial.

      Conclusión

      A través de esta guía, configuró una plantilla básica de seguridad de Kubernetes. Con esto, se establecieron la autenticación y autorización de usuarios, los privilegios de aplicaciones y la protección de los recursos de clústeres. Combinando todas las sugerencias de este artículo, tendrá una base sólida para una implementación de un clúster de Kubernetes de producción. A partir de ahí, puede comenzar a reforzar aspectos individuales de su clúster dependiendo de su escenario.

      Si desea obtener más información sobre Kubernetes, consulte nuestra página de recursos de Kubernetes o complete nuestro curso de aprendizaje por cuenta propia de Kubernetes para desarrolladores “full-stack”.



      Source link

      Pasos recomendados para reforzar un servidor HTTP de Apache en FreeBSD 12.0


      El autor seleccionó la Free and Open Source Fund para recibir una donación como parte del programa Write for DOnations.

      Introducción

      Aunque la instalación predeterminada de un servidor HTTP Apache ya es segura, la configuración puede mejorar en gran medida con algunas modificaciones. Puede complementar los mecanismos de seguridad ya existentes, por ejemplo, estableciendo protecciones en torno a las cookies y los encabezados, de modo que las conexiones no se puedan manipular al nivel de cliente del usuario. Realizando esto puede reducir notablemente las posibilidades de exponerse a varios métodos de ataque, como los de secuencias de comandos entre sitios (también conocidos como XSS). También puede evitar otros tipos de ataques, como la falsificación de solicitudes entre sitios, los secuestros de sesiones o la denegación de servicios.

      A lo largo de este tutorial, implementará algunos pasos recomendados para reducir la cantidad de información expuesta en su servidor. Verificará los listados de directorios y desactivará la indexación para chequear el acceso a recursos. También cambiará el valor predeterminado de la directiva timeout para poder mitigar el tipo de ataque de denegación de servicio. Además, desactivará el método TRACE para que las sesiones no se puedan revocar ni secuestrar. Por último, protegerá los encabezados y las cookies.

      La mayoría de los ajustes de configuración se aplicarán al archivo de configuración principal del servidor HTTP Apache ubicado en /usr/local/etc/apache24/httpd.conf.

      Requisitos previos

      Para completar esta guía, necesitará lo siguiente:

      Una vez completados los requisitos previos tendrá un sistema de FreeBSD con una pila adicional capaz de proporcionar contenido web usando cualquier cosa escrita en PHP, como un software importante de CMS. Además, cifró conexiones seguras a través de Let´s Encrypt.

      Reducir la información del servidor

      El banner del sistema operativo es un método utilizado por computadoras, servidores y dispositivos de todo tipo para presentarse en las redes. Individuos malintencionados pueden usar esta información para obtener beneficios de explotación en los sistemas en cuestión. En esta sección, reducirá la cantidad de información publicada por este banner.

      En los conjuntos de directivas se controla la manera en la que se muestra esta información. Para esto, es importante la directiva ServerTokens; por defecto, muestra toda la información sobre el sistema operativo y los módulos compilados al cliente que establece conexión.

      Antes de aplicar cualquier cambio, usará una herramienta para escanear la red y verificar la información que se muestra actualmente. Para instalar nmap ejecute el siguiente comando:

      Para obtener la dirección IP de su servidor, puede ejecutar el siguiente comando:

      • ifconfig vtnet0 | awk '/inet / {print $2}'

      Puede verificar la respuesta del servidor web usando el siguiente comando:

      • nmap -sV -p 80 your-server-ip

      Invoca nmap para hacer un escaneo (por ello se usa el indicador -s), a fin de mostrar la versión (el indicador -V) en el puerto 80 (el indicador -p) en el IP o dominio determinado.

      Recibirá información sobre su servidor web similar a la siguiente:

      Output

      Starting Nmap 7.80 ( https://nmap.org ) at 2020-01-22 00:30 CET Nmap scan report for 206.189.123.232 Host is up (0.054s latency). PORT STATE SERVICE VERSION 80/tcp open http Apache httpd 2.4.41 ((FreeBSD) OpenSSL/1.1.1d-freebsd Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 7.59 seconds

      En el resultado se muestra que la información como la del sistema operativo, la versión del servidor HTTP Apache y OpenSSL es visible. Esto puede ser útil para que los atacantes obtengan información sobre el servidor y elijan las herramientas adecuadas para explotar, por ejemplo, una vulnerabilidad en el software que se ejecuta en el servidor.

      Disponga la directiva ServerTokens en el archivo de configuración principal, ya que no viene configurada por defecto. La falta de esta configuración hace que el servidor HTTP Apache muestre su información completa como se indica en la documentación. Para limitar la información que se muestra acerca de su servidor y configuración, dispondrá la directiva ServerTokens dentro del archivo de configuración principal.

      Dispondrá esta directiva después de la entrada de ServerName en el archivo de configuración. Ejecute el siguiente comando para encontrar la directiva:

      • grep -n 'ServerName' /usr/local/etc/apache24/httpd.conf

      Encontrará el número de línea que luego podrá buscar con vi:

      Output

      226 #ServerName www.example.com:80

      Ejecute el siguiente comando:

      • sudo vi +226 /usr/local/etc/apache24/httpd.conf

      Añada la siguiente línea resaltada:

      /usr/local/etc/apache24/httpd.conf

      . . .
      #ServerName www.example.com:80
      ServerTokens Prod
      

      Guarde y cierre el archivo con :wq e INTRO.

      Fijar la directiva ServerTokens en Prod hará que solo se muestre que este es un servidor web de Apache.

      Para que esto se implemente, reinicie el servidor HTTP Apache:

      Para probar los cambios, ejecute el siguiente comando:

      • nmap -sV -p 80 your-server-ip

      Verá un resultado similar al siguiente con la información mínima adicional acerca de su servidor web de Apache:

      Output

      Starting Nmap 7.80 ( https://nmap.org ) at 2020-01-22 00:58 CET Nmap scan report for WPressBSD (206.189.123.232) Host is up (0.056s latency). PORT STATE SERVICE VERSION 80/tcp open http Apache httpd Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 7.59 seconds

      Vio la información que se anunciaba en el servidor antes del cambio y ahora la redujo al mínimo. Con esto, proporcionará a un agente externo menos pistas acerca de su servidor. En el siguiente paso, administrará los listados de directorios para su servidor web.

      Administrar los listados de directorios

      En este paso, se asegurará de que el listado de directorios esté configurado correctamente para que las partes adecuadas del sistema estén disponibles públicamente como se espera, mientras el resto quede protegido.

      Nota: Cuando se declara un argumento, este está activo, pero el signo + puede reforzar por medios visuales la sugerencia de que efectivamente se encuentra habilitado. Cuando se dispone un signo menos - el argumento se niega; por ejemplo, Options -Indexes.

      Los argumentos con + o con - no se pueden mezclar, se consideran como elementos de mala sintaxis en el servidor HTTP Apache y se pueden rechazar al inicio.

      Añadir la instrucción Options -Indexes establecerá el contenido dentro de la ruta de datos /usr/local/www/apache24/data para no realizar la indexación (leer listado) de forma automática si no existe un archivo .html y no mostrar si una URL asigna este directorio. Esto también se aplicará al utilizar configuraciones de host virtuales como la que se emplea para el tutorial de requisitos previos para el certificado de Let´s Encrypt.

      Establecerá la directiva Options con el argumento -Indexes y con la directiva +FollowSymLinks, que permitirá el seguimiento de los enlaces simbólicos. Usará el símbolo + para cumplir con las convenciones HTTP de Apache.

      Ejecute el siguiente comando para encontrar la línea que editará en el archivo de configuración:

      • grep -n 'Options Indexes FollowSymLinks' /usr/local/etc/apache24/httpd.conf

      Visualizará un resultado similar al siguiente:

      Output

      263 : Options Indexes FollowSymLinks

      Ejecute este comando para acceder de manera directa a la línea para editar:

      • sudo vi +263 /usr/local/etc/apache24/httpd.conf

      Ahora, edite la línea conforme a la configuración:

      /usr/local/etc/apache24/httpd.conf

      . . .
      #
      Options -Indexes +FollowSymLinks
      
      #
      . . .
      

      Guarde y cierre el archivo con :wq e INTRO.

      Reinicie el servidor HTTP Apache para implementar estos cambios:

      En su dominio en el navegador, verá un mensaje de acceso prohibido, también conocido como el error 403. Esto se debe a los cambios que implementó. Con la disposición de -Indexes en la directiva Options se desactivó la capacidad de aplicar indexación de forma automática en el servidor HTTP Apache y, por lo tanto, no existe un archivo index.html dentro de la ruta de datos.

      Puede solucionar esto disponiendo un archivo index.html dentro del VirtualHost habilitado en el tutorial de requisitos previos para el certificado de Let´s Encrypt. Usará el bloque predeterminado dentro de HTTP Apache y lo dispondrá en la misma carpeta que el DocumentRoot que declaró en el host virtual.

      /usr/local/etc/apache24/extra/httpd-vhosts.conf

      <VirtualHost *:80>
          ServerAdmin your_email@your_domain.com
          DocumentRoot "/usr/local/www/apache24/data/your_domain.com"
          ServerName your_domain.com
          ServerAlias www.your_domain.com
          ErrorLog "/var/log/your_domain.com-error_log"
          CustomLog "/var/log/your_domain.com-access_log" common
      </VirtualHost>
      

      Para hacerlo utilice el siguiente comando:

      • sudo cp /usr/local/www/apache24/data/index.html /usr/local/www/apache24/data/your_domain.com/index.html

      Ahora, cuando visite su dominio verá un mensaje It works!

      En esta sección, estableció restricciones a la directiva Indexes para no escribir y mostrar de forma automática contenido diferente del que pretende. Si no existe un archivo index.html dentro de la ruta de datos, en el servidor HTTP Apache no se creará de manera automática un índice de contenidos. En el siguiente paso, irá más allá del ocultamiento de información y personalizará diferentes directivas.

      Reducir el valor de la directiva Timeout

      La directiva Timeout establece el límite de tiempo que el servidor HTTP Apache otorgará para nuevas entradas o salidas antes de que falle la solicitud de conexión. Esta falla puede producirse debido a diferentes circunstancias, como los casos en que los paquetes no llegan al servidor o el cliente no confirma como recibidos los datos.

      Por defecto, el tiempo de espera se fija en 60 segundos. En los entornos en los cuales el servicio de Internet es lento, este valor predeterminado puede ser razonable, pero un minuto es bastante tiempo; en particular, si el servidor abarca un grupo de usuarios con un servicio de Internet más rápido. Además, el tiempo durante el cual no se cierra la conexión en el servidor puede aprovecharse para ataques de denegación de servicio (DoS). Si se produce una sobrecarga de estas conexiones malintencionadas, el servidor se bloqueará, y posiblemente se saturará y no responderá.

      Para cambiar el valor encontrará las entradas de Timeout en el archivo httpd-default.conf:

      • grep -n 'Timeout' /usr/local/etc/apache24/extra/httpd-default.conf

      Verá un resultado similar al siguiente:

      Output

      8 # Timeout: The number of seconds before receives and sends time out. 10 Timeout 60 26 # KeepAliveTimeout: Number of seconds to wait for the next request from the 29 KeepAliveTimeout 5 89 RequestReadTimeout header=20-40,MinRate=500 body=20,MinRate=500

      En la línea de salida, se fija el valor de la directiva Timeout en 10. Para acceder directamente a esta línea, ejecute el siguiente comando:

      • sudo vi +10 /usr/local/etc/apache24/extra/httpd-default.conf

      La cambiará a 30 segundos, por ejemplo, como en el siguiente ejemplo:

      /usr/local/etc/apache24/extra/httpd-default.conf

      #
      # Timeout: The number of seconds before receives and sends time out.
      #
      Timeout 30
      

      Guarde y cierre el archivo con :wq e INTRO.

      En el valor de la directiva Timeout se debe equilibrar un rango de tiempo suficientemente extenso como para que estos eventos permitan que se establezca una conexión legítima y exitosa, pero suficientemente breve como para evitar los intentos de conexiones no deseadas.

      Nota: Los ataques de denegación de servicio pueden drenar los recursos del servidor de forma eficaz. Una medida complementaria y muy eficaz para contrarrestar esto consiste en usar un MPM anidado para obtener el mejor rendimiento en cuanto a la forma en que se manejan las conexiones y los procesos en el servidor HTTP Apache. En el tutorial Cómo configurar HTTP Apache con MPM Event y PHP-FPM en FreeBSD 12.0 se ofrecen pasos para habilitar esta capacidad.

      Para que este cambio tenga efecto, reinicie el servidor HTTP Apache:

      Cambió el valor predeterminado de la directiva Timeout para mitigar parcialmente los ataques de DoS.

      Deshabilitar el método TRACE

      El Protocolo de transferencia de hipertexto se desarrolló siguiendo un modelo de servidor y cliente y, como tal, en el protocolo existen métodos de solicitud para recuperar o disponer información desde el servidor o en él. El servidor debe interpretar estos conjuntos de métodos y la interacción entre ellos. En este paso, configurará los métodos básicos necesarios.

      El método TRACE, que se consideraba inofensivo, se aprovechó para realizar ataques de rastreo entre sitios. Este tipo de ataques permite a individuos malintencionados robar sesiones de los usuarios a través del método. El método se diseñó para la depuración a través del servidor devolviendo la misma solicitud originalmente enviada por el cliente. Debido a que la cookie de la sesión del navegador se envía al servidor, se enviará de regreso nuevamente. Sin embargo, un individuo malintencionado podría interceptar esto y luego redirigir la conexión de un navegador a un sitio bajo su control y no al servidor original.

      Debido a la posibilidad del mal uso que se puede dar al método TRACE, se recomienda usarlo únicamente para la depuración y no en la producción. En esta sección, desactivará este método.

      Edite el archivo httpd.conf con el siguiente comando y presione G para llegar al final del archivo:

      • sudo vi /usr/local/etc/apache24/httpd.conf

      Añada la siguiente ruta de entrada al final del archivo:

      /usr/local/etc/apache24/httpd.conf

      . . .
      TraceEnable off
      

      Se recomienda especificar únicamente los métodos que usará en su servidor web HTTP Apache. Esto ayudará a limitar los puntos de entrada potenciales para los individuos malintencionados.

      LimitExcept puede ser útil para este propósito, ya que no se permitirán otros métodos aparte de los declarados en este. Por ejemplo, puede establecer una configuración como la siguiente:

      /usr/local/etc/apache24/httpd.conf

      DocumentRoot "/usr/local/www/apache24/data"
      <Directory "/usr/local/www/apache24/data">
          Options -Indexes +FollowSymLinks -Includes
          AllowOverride none
           <LimitExcept GET POST HEAD>
             deny from all
          </LimitExcept>
          Require all granted
      </Directory>
      

      Como se declara en la directiva LimitExcept solo se permiten los métodos GET, POST y Head en la configuración.

      • El método GET es parte del protocolo HTTP y se utiliza para recuperar datos.
      • El método POST también es parte del protocolo HTTP y se utiliza para enviar datos al servidor.
      • El método HEAD es similar a GET. Sin embargo, no tiene cuerpo de respuesta.

      Usará el siguiente comando y dispondrá el bloque de LimitExcept dentro del archivo:

      • sudo vi +272 /usr/local/etc/apache24/httpd.conf

      Para establecer esta configuración, dispondrá el siguiente bloque en la entrada de la directiva DocumentRoot de donde se leerá el contenido, más específicamente dentro de la entrada Directory.

      /usr/local/etc/apache24/httpd.conf

      . . .
      <LimitExcept GET POST HEAD>
         deny from all
      </LimitExcept>
      . . .
      

      Para implementar los cambios, reinicie el servidor HTTP Apache:

      En la directiva más reciente AllowedMethods se proporciona una funcionalidad similar, aunque su estado es aún experimental.

      Vio los métodos HTTP, su uso y la protección que ofrecen contra la actividad malintencionada que se aprovecha del método TRACE, así como la forma de declarar los métodos que se usarán. A continuación, trabajará con más protecciones dedicadas a los encabezados y las cookies HTTP.

      Proteger los encabezados y las cookies

      En este paso, establecerá directivas específicas para proteger las sesiones que se abrirán en las máquinas cliente cuando visite su servidor web HTTP Apache. De esta manera, en su servidor no se cargará contenido no deseado, el cifrado no se degradará y evitará el espionaje de contenido.

      Los encabezados son componentes de los métodos de solicitudes. Existen encabezados para ajustar la autenticación, la comunicación entre el servidor y el cliente, el almacenamiento en caché y la negociación de contenido, entre otros aspectos.

      Las cookies son pequeños fragmentos de información que el servidor envía al navegador. Estos pequeños fragmentos permiten que en el servidor se reconozca el navegador del cliente de una computadora a otra. También permiten que en los servidores se reconozcan sesiones de usuarios. Por ejemplo, se puede hacer un seguimiento del carrito de compras de un usuario que inició sesión, la información de pago y el historial, entre otros datos. Las cookies se utilizan y se conservan en el navegador web del cliente, ya que HTTP es un protocolo sin estado; esto significa que cuando la conexión se cierra en el servidor no se registra la solicitud enviada por uno u otro cliente.

      Es importante proteger los encabezados y las cookies porque permiten la comunicación entre el cliente del navegador web y el servidor web.

      El módulo headers viene activado por defecto. Para verificar si está cargado, usará el siguiente comando:

      • sudo apachectl -M | grep 'headers'

      Verá el siguiente resultado:

      Output

      headers_module (shared)

      Si no ve un resultado, verifique si el módulo está activo dentro del archivo httpd.conf de Apache:

      • grep -n 'mod_headers' /usr/local/etc/apache24/httpd.conf

      Como resultado, verá una línea sin comentarios con referencia al módulo específico para encabezados:

      /usr/local/etc/apache24/httpd.conf

      . . .
      122  LoadModule headers_module libexec/apache24/mod_headers.so
      . . .
      

      Si está presente, elimine el hashtag al inicio de la línea mod_headers.so para activar la directiva.

      Usando las siguientes directivas HTTP de Apache, protegerá los encabezados y las cookies contra actividades malintencionadas para reducir el riesgo al que se exponen los clientes y los servidores.

      Ahora, configurará la protección del encabezado. Dispondrá todos estos valores de encabezado en un bloque. Puede optar por aplicar estos valores como lo desee, pero todos se recomiendan.

      Edite el archivo httpd.conf con el siguiente comando y presione G para llegar al final del archivo:

      • sudo vi /usr/local/etc/apache24/httpd.conf

      Disponga el siguiente bloque al final del archivo:

      /usr/local/etc/apache24/httpd.conf

      . . .
      <IfModule mod_headers.c>
        # Add security and privacy related headers
        Header set Content-Security-Policy "default-src 'self'; upgrade-insecure-requests;"
        Header set Strict-Transport-Security "max-age=31536000; includeSubDomains"
        Header always edit Set-Cookie (.*) "$1; HttpOnly; Secure"
        Header set X-Content-Type-Options "nosniff"
        Header set X-XSS-Protection "1; mode=block"
        Header set Referrer-Policy "strict-origin"
        Header set X-Frame-Options: "deny"
        SetEnv modHeadersAvailable true
      </IfModule>
      
      • Header set Strict-Transport-Security "max-age=31536000; includeSubDomains": la seguridad estricta de transporte de HTTP (HTSTS) es un mecanismo para que los servidores y clientes web (principalmente navegadores) establezcan comunicaciones utilizando solo HTTPS. Al implementar esto evitará la presencia de atacantes desconocidos, en cuyo caso un tercero en medio de la comunicación podría acceder a los fragmentos de información y manipularlos.

      • Header always edit Set-Cookie (. *) "$1; HttpOnly; Secure": los indicadores HttpOnly y Secure en los encabezados ayudan a prevenir las secuencias de comandos entre sitios, también conocidas como XSS. Los atacantes pueden utilizar las cookies de forma indebida para simular ser visitantes legítimos al presentarse como otras personas (robo de identidad), o para ser manipuladas.

      • Header set Referrer-Policy "strict-origin": en el encabezado Referrer-Policy se establece la información que se incluye como información de referencia en el campo de encabezado.

      • Header set Content-Security-Policy "default-src 'self'; upgrade-insecure-requests;": en el encabezado de Content-Security-Policy (CSP) se evitará por completo la carga de contenido que no esté especificada en los parámetros, lo cual es útil para evitar las secuencias de comandos en sitios cruzados (XSS). Existen muchos parámetros posibles para configurar la política de este encabezado. El objetivo final es configurarlo para cargar contenido del mismo sitio y actualizar cualquier contenido con un origen HTTP.

      • Header set X-XSS-Protection "1; mode=block": esto es compatible con navegadores antiguos en los que no se procesan encabezados Content-Security-Policy. En el encabezado ‘X-XSS-Protection’ se ofrece protección contra secuencias de comandos entre sitios. No necesita configurar este encabezado a menos que se necesite compatibilidad con versiones anteriores de navegadores, lo cual es poco común.

      • Header set X-Frame-Options: "deny": con esto se evitan ataques de clickjacking (secuestro de clics). En el encabezado ‘X-Frame-Options’ se indica a un navegador si una página se puede presentar en <frame>, <iframe>, <embed> o <object>. De esta manera, los contenidos de sitios diferentes no pueden integrarse a otros, lo cual previene los ataques de clickjacking. Aquí, niega toda la presentación de marco para que la página web no se pueda integrar en otro lugar, ni siquiera dentro del mismo sitio web. Puede adecuar esto a sus necesidades si, por ejemplo, debe autorizar la presentación de algunas páginas debido a que son anuncios o colaboraciones con sitios web específicos.

      • Header set X-Content-Type-Options "nosniff": en el encabezado ‘X-Content-Type-Options’ se controlan los tipos MIME para que no se sometan a cambios ni a seguimiento. Los tipos MIME son estándares de formatos de archivo; funcionan para texto, audio, video e imagen, entre otros. Con este encabezado se bloquean los intentos de espiar dichos archivos y modificar sus tipos por parte de individuos malintencionados.

      Ahora, reinicie Apache para implementar los cambios:

      Para evaluar los niveles de seguridad de sus configuraciones, consulte el sitio web de Security Headers. Después de seguir los pasos de este tutorial, la calificación de su dominio será A.

      Nota: Si evalúa sus encabezados visitando https://securityheaders.com/ y obtiene una calificación F, podría deberse a que index.html no se encuentra dentro del DocumentRoot de su sitio, como se indica al final del paso 2. Si cuando evalúa sus encabezados obtiene una calificación que no sea a A o sea F, revise cada línea Header set en busca de cualquier error ortográfico que pueda haber causado una calificación menor.

      En este paso, trabajó con hasta siete configuraciones para mejorar la seguridad de sus encabezados y cookies. Esto permitirá evitar las secuencias de comandos entre sitios, el clickjacking y otros tipos de ataques.

      Conclusión

      En este tutorial, se abordaron varios aspectos relacionados con la seguridad, desde la divulgación de información hasta la protección de las sesiones y el ajuste de parámetros de configuración alternativos para funciones importantes.

      Si desea obtener más información sobre el reforzamiento de Apache, a continuación se ofrecen algunas otras referencias:

      Si desea acceder a más herramientas para la protección del servidor HTTP Apache:

      • mod_evasive es una herramienta útil para ayudar a mitigar los ataques de DoS. Puede encontrar más información en el tutorial Cómo protegerse contra DoS y DDoS con mod_evasive para Apache.

      • freail2ban es un software de prevención de intrusiones que es útil para bloquear intentos de inicio de sesión repetidos por parte de usuarios no autorizados. Puede obtener más información acerca de esto en el tutorial Cómo proteger un servidor Apache con Fail2Ban.

      • ModSecurity es un Firewall de aplicación web (o WAF) y, como tal, ofrece una amplia variedad de posibilidades basada en reglas predefinidas escritas por SpyderLabs y miembros de la comunidad. Puede leer más acerca de esto en el tutorial Cómo configurar ModSecurity con Apache.



      Source link