viernes, noviembre 27, 2015

osquery(II): Configurar osqueryd

En el primera entrada sobre osquery estuve probando las posibilidades de osquery para obtener información del sistema desde la línea de comandos con osqueryi. Pero la fortaleza de una herramienta de este tipo es poder definir aquellas consultas que queramos y que el programa las vaya ejecutando cada cierto tiempo, almacenando el resultado de las mismas o los cambios que se han producido en las partes del sistema que estamos monitorizando.

El programa que se encarga de ejecutar las consultas programadas en osqueryd. Éste lee su fichero de configuración en el cual se definen las diferentes opciones, las consultas que ejecutará para obtener la información del sistema, los ficheros y directorios que monitorizará para detectar cambios y las opciones de salida. Por defecto, esta información la almacenará en una base de datos RocksDB y en un fichero de texto donde cada una de sus líneas es un objeto JSON con los datos o la modificación de los mismos. La primera vez que se ejecuta una consulta determinada almacenará todos los resultados en la base de datos RocksDB. A partir de entonces, solamente almacenará los cambios respecto a la última vez que se ejecutó la consulta.

Por defecto, el fichero de configuración en el caso de la instalación de OS X está en /var/osquery/osquery.conf o en los directorios /var/osquery/osquery.conf.d/*.conf. En caso de que esté en una ruta distinta puede pasarse el parámetro --config-path ruta especificando la ruta donde está dicho fichero. El formato del fichero de configuración es JSON. En casa una de las claves principales, se configura las opciones, las consultas que se quieren realizar, la comprobación de integridad de ficheros y los packs, que son conjuntos de consultas que permiten tener información del sistema que estamos monitorizando.

{
  "options": {
    ...
  },
  "schedule": {
    ...
  },
  "file_paths": {
    ...
  },
  "packs": {
    ...
  }
}

Bajo la clave options se definen varios parámetros de configuración de osqueryd. Todos estos parámetros de configuración tienen valores por defecto, por lo que en principio no sería necesario definirlos. Pero si estamos haciendo un despliegue en multitud de nodos usando alguna herramienta como Ansible o Puppet se querrá establecer algunos paramétros de configuración por defecto.

En la configuración por defecto, osqueryd leerá las consultas a realizar del fichero de los ficheros de configuración y almacenará los resultados de las mismas en un fichero en texto plano en el disco duro. Cada línea de dicho fichero es un objecto JSON. Una funcionalidad interesante que tiene osqueryd es que se puede crear un fichero de configuración mínima que utilice una conexión protegida por TLS para que baje la configuración y envié los resultados de las consultas que se hagan en el sistema a un punto central donde puedan consolidarse y analizarse. En los ejemplos que voy a utilizar en esta entrada toda la configuración y el registro se hará sobre el sistema de ficheros.

Un ejemplo de las opciones que se pueden configurar es el siguiente

{
  "options": {
    "host_identifier": "baldurgate",
    "schedule_splay_percent": 10,
    "config_plugin": "filesystem",
    "logger_plugin": "filesystem",
    "logger_path": "/var/osquery/logs"
  }
}

Configuramos algunas de las opciones que no nos interesa por defecto de osqueryd. El nombre del host (host_identifier), un tiempo que se añade a cada query para evitar lanzar varias a la vez en el mismo instante (schedule_splay_percent), el sistema que se va a usar para almacenar los registros (logger_plugin) y la ruta donde se van a almacenar, puesto que el logger_plugin es filesystem.

Pero la parte importante son las consultas que se quieren realizar sobre el sistema para que nos de la información que necesitamos monitorizar. La configuración normal hace que se ejecute la consulta la primera vez y luego sólo se almacene las diferencias de las mismas respecto a la ejecución anterior. Estas diferencias también son escritas a través del plugin de registro que se haya seleccionado. En la web del proyecto pueden verse las diferentes tablas que pueden consultarse. Cada clave que haya dentro de la sección schelude debe ser única, definiendo la consulta y cual debe ser la periodicidad con la cual se debe de ejecutar.

{
  "schedule": {
    "macosx_alf" :{
      "query": "SELECT * from alf",
      "interval": 60
    },
    "macosx_alf_excpetions": :{
      "query": "SELECt * from alf_exceptions",
      "interval": 60
    },
    "macosx_alf_explicit_auths": :{
      "query": "SELECT * from alf_explicit_auths",
      "interval": 60
    },
  }
}

Estas tres consultas obtienen información del sistema cada sesenta segundos. Es importante cuando se definen las consultas en osquery comprobar cual es el rendimiento que tienen la máquina, ya que podría ocurrir que se gastara demasiados recursos en las mismas, teniendo que modificar tanto la programación como el número de consultas para no ahogar la máquina.

El comportamiento por defecto del osqueryd es mandar al plugin de registro tanto las filas de la consulta que se han añadido como las que se han quitado. Sin embargo, hay consultas en las cuales dicho comportamiento no tiene sentido. Por ejemplo, consultas que devuelvan resultados relacionados con el tiempo o contadores de rendimiento. Puesto que osquery mandará la línea añadida y quitará la que no existe, se puede usar la clave removed a false para que esa información no se almacene. Por ejemplo

Por otro lado, si se quiere los datos en un punto determinado de tiempo de una consulta se puede hacer con snapshot a true, en vez de registrar las diferencias. Por ejemplo, la siguente consulta almacenaría la información de cada punto de montaje de manera periódica (mismo ejemplo que está en la documentación de osquery)

  "schedule": {
    "mounts": {
      "query": "select * from mounts",
      "interval": 3600,
      "snapshot": true
    }
  }

Una de las funcionalidades más interesantes incluidas en osquery es la posibilidad de actual como un host IDS, analizando los directorios y ficheros que se programen para avisar en caso de que exista algún cambio. Por ejemplo, si se desea monitorizar posibles cambios en todos los directorios bajo /etc se podría usar una configuración como la siguiente:

  "schedule": {
    "query": "select * from file_events;",
    "removed": false,
    "interval": 300
  },
  "file_paths": {
    "etc": [
      "/etc/%%"
    ]
  }

Los posibles eventos que se generen debido a las modificaciones que se produzcan en los ficheros y directorios especificados en file_paths se almacenarán en la tabla file_events, la cual se podrá consultar para ver las modificaciones que se han ido produciendo.

Por último hablar de los packs que no son más que conjuntos de consultas definidas para realizar una determinada labor (por ejemplo obtener una foto de la máquina en un momento dado o para gestión de vulnerabilidades). La instalación de OS X por defecto tiene cuatro packs que se instalan en /var/osquery/packs. Un ejemplo de como configurar uno de ellos es el siguiente:

  "packs": {
    "vuln_management": "/var/osquery/packs/vuln-management.conf"
  }

Esto es un primer vistazo a las posibilidades que tiene osquery para utilizarlo como herramienta de inventariado, monitorización y conformidas en máquinas Linux y OS X. Hay más opciones de las que no he hablado, como la posibilidad de usar reglas yara para detectar malware, la posibilidad de usar herramientas remotas para configurar osquery o centralizar los registros de los eventos que vaya creando el sistema.

No hay comentarios: