Select Page

NETWAYS Blog

OSMC 2023 | Experiments with OpenSearch and AI

Last year’s Open Source Monitoring Conference (OSMC) was a great experience. It was a pleasure to meet attendees from around the world and participate in interesting talks about the current and future state of the monitoring field.

Personally, this was my first time attending OSMC, and I was impressed by the organization, the diverse range of talks covering various aspects of monitoring, and the number of attendees that made this year’s event so special.

If you were unable to attend the congress, we are being covering some of the talks presented by the numerous specialists.
This blog post is dedicated to this year’s Gold Sponsor Eliatra and their wonderful speakers Leanne Lacey-Byrne and Jochen Kressin.

Could we enhance accessibility to technology by utilising large language models?

This question may arise when considering the implementation of artificial intelligence in a search engine such as OpenSearch, which handles large data structures and a complex operational middleware.

This idea can also be seen as the starting point for Eliatra’s experiments and their findings, which is the focus of this talk.

 

Working with OpenSearch Queries

OpenSearch deals with large amounts of data, so it is important to retrieve data efficiently and reproducibly.
To meet this need, OpenSearch provides a DSL which enables users to create advanced filters to define how data is retrieved.

In the global scheme of things, such queries can become very long and therefore increase the complexity of working with them.

What if there would be a way of generating such queries by just providing the data scheme to a LLM (large language model) and populate it with a precise description of what data to query? This would greatly reduce the amount of human workload and would definitely be less time-consuming.

 

Can ChatGPT be the Solution?

As a proof-of-concept, Leanne decided to test ChatGPT’s effectiveness in real-world scenarios, using ChatGPT’s LLM and Elasticsearch instead of OpenSearch because more information was available on the former during ChatGPT’s training.

The data used for the tests were the Kibana sample data sets.

Leanne’s approach was to give the LLM a general data mapping, similar to the one returned by the API provided by Elasticsearch, and then ask it a humanised question about which data it should return. Keeping that in mind, this proof of concept will be considered a success if the answers returned consist of valid search queries with a low failure rate.

 

Performance Analysis

Elasticsearch Queries generated by ChatGPT (Result Overview)

Source: slideshare.net (slide 14)

As we can see, the generated queries achieved only 33% overall correctness. And this level was only possible by feeding the LLM with a number of sample mappings and the queries that were manually generated for them.

Now, this accuracy could be further improved by providing more information about the mapping structures, and by submitting a large number of sample mappings and queries to the ChatGPT instance.
This would however result in much more effort in terms of compiling and providing the sample datasets, and would still have a high chance of failure for any submitted prompts that deviate from the trained sample data.

 

Vector Search: An Abstract Approach

Is there a better solution to this problem? Jochen presents another approach that falls under the category of semantic search.
Large language models can handle various inputs, and the type of input used can significantly impact the results produced by such a model.
With this in mind, we can transform our input information into vectors using transformers.
The transformers are trained LLM models that process specific types of input, for example video, audio, text, and so on.
They generate n-dimensional vectors that can be stored in a vector database.
Illustration about the usage of vector transformers

Source: slideshare.net (slide 20)

When searching a vector-based database, one frequently used algorithm for generating result sets is the ‘K-NN index’
(k-nearest-neighbour index). This algorithm compares stored vectors for similarity and provides an approximation of their relevance to other vectors.
For instance, pictures of cats can be transformed into a vector database. The transformer translates the input into a numeric, vectorized format.
The vector database compares the transformed input to the stored vectors using the K-NN algorithm and returns the most fitting vectors for the input.

 

Are Vectors the Jack of all Trades?

There are some drawbacks to the aforementioned approach. Firstly, the quality of the output heavily depends on the suitability between the transformer and the inputs provided.
Additionally, this method requires significantly more processing power to perform these tasks, which in a dense and highly populated environment could be the bottleneck of such an approach.
It is also difficult to optimize and refine existing models when they only output abstract vectors and are represented as black boxes.
What if we could combine the benefits of both approaches, using lexical and vectorized search?

 

Retrieval Augmented Generation (RAG)

Retrieval Augmented Generation (RAG) was first mentioned in a 2020 paper by Meta. The paper explains how LLMs can be combined with external data sources to improve search results.
This overcomes the problem of stagnating/freezing models, in contrast to normal LLM approaches. Typically, models get pre-trained with a specific set of data.
However, the information provided by this training data can quickly become obsolete and there may be a need to use a model that also incorporates current developments, the latest technology and currently available information.
Augmented generation involves executing a prompt against an information database, which can be of any type (such as the vector database used in the examples above).
The result set is combined with contextual information, for example the latest data available on the Internet or some other external source, like a flight plan database.
This combined set could then be used as a prompt for another large language model, which would produce the final result against the initial prompt.
In conclusion, multiple LLMs could be joined together while using their own strengths and giving them access to current data sources and that could in turn generate more accurate and up to date answers for user prompts.
Overview of the RAG (Retrieval Augmented Generation)

Source: slideshare.net (slide 36)

Noé Costa
Noé Costa
Developer

Noé ist als Schweizer nach Deutschland ausgewandert und unterstützt das Icinga Team seit Oktober 2023 als Developer im Bereich der Webentwicklung. Er wirkt an der Weiterentwicklung der Webmodule von Icinga mit und ist sehr interessiert am Bereich des Monitorings und dessen Zukunft. Neben der Arbeit kocht er gerne, verbringt Zeit mit seiner Partnerin, erweitert sein Wissen in diversen Gebieten und spielt ab und an auch Computerspiele mit Bekanntschaften aus aller Welt.

Datensicherheit mit OpenSearch Machine Learning

This entry is part 5 of 5 in the series OpenSearch Security

OpenSearch bringt von Haus aus die Möglichkeit mit, Machine Learning zu nutzen und hierfür pre-trained aber auch untrained Modelle zu nutzen. Den Status deiner Modelle kannst du bequem in OpenSearch Dashboards sehen.

Wie du OpenSearch Machine Learning zum Laufen bringst, zeige ich dir in diesem Blogbeitrag. Wie bei vielen neuen und sich schnell weiterentwickelnden Projekten kann es jedoch sein, dass bis zum Release dieses Blogposts der ganze Prozess noch einmal einfacher geworden ist.

Der Prozess, um OpenSearch für Machine Learning vorzubereiten, besteht aus diesen Bausteinen:

  • Vorbereitung
  • Upload des Modells
  • Modell-Gruppe erstellen
  • Model auf die Gruppe registrieren
  • Deployment
  • Machine Learning nutzen.

Ursprünglich bin ich dieser Anleitung gefolgt. Du arbeitest am bequemsten direkt unter den Developer Tools (Management-> Dev Tools), kannst deine Befehle aber wie immer auch einfach via curl gegen die API senden:

Vorbereitung von Open Search auf Machine Learning

Zunächst habe ich für alle in meinem Beispiel genutzten Modelle URL-Registrierung zugelassen:

PUT _cluster/settings
{
    "persistent" : {
        "plugins.ml_commons.allow_registering_model_via_url" : true
    }
}

Außerdem habe ich das Zeitintervall der Synchronisation erhöht.
Denn “ML Commons will run a regular sync up job to sync up newly loaded or unloaded models on each node”:

PUT /_cluster/settings
{
    "persistent": {
        "plugins.ml_commons.sync_up_job_interval_in_seconds": 600
    }
}

Ab hier musst du einige Python-Libraries laden. Viele Modelle basieren auf der Pytorch-Library. So auch Sentence-Transformers, welches für einige der OpenSearch Modelle benötigt wird.

pip install -U sentence-transformers

Prinzipiell werden ML-Tasks nur auf den eigens dafür zugewiesenen OpenSearch Knoten ausgeführt und hierfür habe ich in meiner opensearch.yml folgende Einträge gesetzt:

node.roles: [ data, cluster_manager,  ml ]
plugins.security.restapi.roles_enabled: ["all_access","ml", "security_rest_api_access"]

Machine Learning Modell bereitstellen

Vorab: Über Task-IDs checkt man, ob die vorherigen Schritte durchgingen und besorgt sich notwendige Informationen zum weiter zuordnen.

Um Machine Learning Modelle in OpenSearch bereitzustellen, legt man einfach eine Gruppe an. Anschließend lädt man das Modell, fügt das Modell der Gruppe hinzu, deployt es über die Modell-ID an die gewünschten Knoten und hat anschließend die Möglichkeit, Machine Learning zu nutzen. Diese einzelnen Schritte zeige ich dir jetzt aber noch einmal detailliert.

Schritt 1: Modell Gruppe hinzufügen.

Bevor Modelle einer Gruppe hinzugefügt werden können, muss eine solche Gruppe angelegt werden. In meinem Beispiel habe ich sie “my-ml-group” genannt. Am einfachsten werden die Gruppen per API-Call hinzugefügt:

POST /_plugins/_ml/model_groups/_register
{
    "name": "my-ml-group",
    "description": "This is a public model group"
}

Es wird Success/Fail-Status sowie Gruppen-ID zurückgegeben, die benötigt wird: z.B. gprKIYoBmWoi9V5-T2Pb

Schritt 2: Das Modell wird von Huggingface geladen. (In meinem Beispiel verwende ich das Modell “all-MiniLM-L12-v2”)

POST /_plugins/_ml/models/_upload
{
  "name": "huggingface/sentence-transformers/all-MiniLM-L12-v2",
  "version": "1.0.1",
  "model_format": "TORCH_SCRIPT"
}

Schritt 3: Das all-MiniLM-L12-v2 Modell wird auf die vorherige Gruppen-ID meiner my-ml-group registriert:

POST /_plugins/_ml/models/_register
{
"name": "huggingface/sentence-transformers/all-MiniLM-L12-v2",
"version": "1.0.1",
"model_format": "TORCH_SCRIPT",
"model_group_id": "gprKIYoBmWoi9V5-T2Pb"
}

Hier bekommt man wieder den Success/Error-State, sowie eine Task ID zurück. In meinem Beispiel ist das die MprLIYoBmWoi9V5-o5Ix.

Schritt 4: Model-ID besorgen

Nutzt man die Task-ID vom registrierten Modell, sieht man Modell ID sowie Error-State:

GET /_plugins/_ml/tasks/MprLIYoBmWoi9V5-o5Ix
{
  "model_id": "RJrLIYoBmWoi9V5-o5LW",
  "task_type": "REGISTER_MODEL",
  "function_name": "TEXT_EMBEDDING",
  "state": "COMPLETED",
  "worker_node": [
    "KmfjhwWjS7eepv4PnUMKWw"
  ],
  "create_time": 1692784108336,
  "last_update_time": 1692784119285,
  "is_async": true
}

Die Modell-ID wird nun für das nachfolgende Deployment benötigt.

Schritt 5: Auf den Model-Nodes deployen

Zum eigentlichen Deployment braucht es Modell-ID und Knoten. Damit kann ich es auf all meinem Machine Learning-Knoten ausrollen:

POST /_plugins/_ml/models/RJrLIYoBmWoi9V5-o5LW/_load

Als Antwort bekommen ich den Task-Type: “Deploy“, sowie den State: “Completed

{
  "model_id": "RJrLIYoBmWoi9V5-o5LW",
  "task_type": "DEPLOY_MODEL",
  "function_name": "TEXT_EMBEDDING",
  "state": "COMPLETED",
  "worker_node": [
    "KmfjhwWjS7eepv4PnUMKWw"
  ],
  "create_time": 1692785563893,
  "last_update_time": 1692785582120,
  "is_async": true
}

Schritt 6: Prediction testen

Hierzu braucht es die Modell ID aus Schritt 5 des Deployments. Mit folgendem Call kannst du die Prediction testen:

POST /_plugins/_ml/_predict/text_embedding/RJrLIYoBmWoi9V5-o5LW
{
    "text_docs": [ "today is sunny" ],
    "return_number": true,
    "target_response": [ "sentence_embedding" ]
}

Ab hier wird es spannend, denn hat man mehrere OpenSearch Cluster läuft das Ganze direkt verteilt und auch alle Logs wie z.B. die von Icinga, Graylog uvm. sind im selben Backend. Dadurch wäre es möglich, mit allen vorhandenen Logs gleichzeitig zu trainieren!

Kannst du dir schon vorstellen, was du damit alles machen möchtest und vor allem da alles lokal bei dir stattfinden kann, was es bedeutet, dass du die volle Kontrolle über Datensicherheit hast?

OpenSearch: Dashboards Plugins einfach installieren

This entry is part 4 of 5 in the series OpenSearch Security

OpenSearch ist in seiner Vanilla Version schon sehr umfangreich. Doch erst mit den OpenSearch Plugins kannst du deine Experience personalisieren und das Maximum aus dem Elastic-Fork herausholen.
Eines vorab, bevor ich richtig ins Thema einsteige: die Geschwindigkeit, in der sich das Projekt aktuell weiterentwickelt ist extrem positiv. Deshalb kann man aktuell davon ausgehen, dass die Plugins beim Release des Blogposts noch mal besser geworden sind oder es noch mehr Regeln geben wird.

OpenSearch Plugins für Backend und Dashboards

Nun aber hinein ins Thema OpenSearch Plugins!
Hier muss direkt zwischen dem Backend “OpenSearch” und den OpenSearch Dashboards unterschieden werden.

Das Backend kommt schon pre-Bundled mit einer Menge nützlicher Plugins. Diese vorinstallierten Plugins kannst du dir mit einem einfachen Befehl anzeigen lassen:

/usr/share/opensearch/bin/opensearch-plugin list

opensearch-alerting
opensearch-anomaly-detection
opensearch-asynchronous-search
opensearch-cross-cluster-replication
opensearch-geospatial
opensearch-index-management
opensearch-job-scheduler
opensearch-knn
opensearch-ml
opensearch-neural-search
opensearch-notifications
opensearch-notifications-core
opensearch-observability
opensearch-performance-analyzer
opensearch-reports-scheduler
opensearch-security
opensearch-security-analytics
opensearch-sql

Im Gegensatz dazu steht das Frontend OpenSearch Dashboards. Hier gibt es out-of-the-box keine Plugins und du kannst, darfst oder musst hier selbst Hand anlegen. Dadurch haben Anpassungen an deine individuellen Bedürfnisse jedoch nur die Grenze der Software.

Auch wenn du alle Plugins selbst installieren musst, ist dort so schnell viel in Bewegung gekommen, dass es leicht geworden ist, Plugins zu installieren. Und das Ganze ohne sich um Versionen / Git-Repositories kümmern zu müssen.

WICHTIGER HINWEIS: Es wird NICHT empfohlen, nachfolgende Skripte als Root auszuführen. Der Vollständigkeit halber habe ich die Flagge als Kommentar auskommentiert im Skript stehen lassen, solltest du das doch tun wollen.
Zum Installieren von Plugins habe ich mir folgendes “./deploy-plugins.sh“-Skript gebaut, das einfach mit dem Pfad der Binärdatei eine Installation über die Namen der Plugins macht:

#!/bin/bash

PLUGINS=(
alertingDashboards
anomalyDetectionDashboards
customImportMapDashboards
ganttChartDashboards
indexManagementDashboards
mlCommonsDashboards
notificationsDashboards
observabilityDashboards
queryWorkbenchDashboards
reportsDashboards
searchRelevanceDashboards
securityAnalyticsDashboards
securityDashboards
)

for PLUGIN in "${PLUGINS[@]}"
do
    /usr/share/opensearch-dashboards/bin/opensearch-dashboards-plugin install $PLUGIN # --allow-root
done

Mit diesem kleinen, von mir geschriebenen Skript ist es schnell und unkompliziert möglich, mehrere OpenSearch Dashboard Plugins gleichzeitig zu installieren.

Da man Plugins in den meisten Fällen nicht nur installieren, sondern auch einmal entfernen will, habe ich dazu ebenfalls ein kleines Skript geschrieben. Es hört auf den Namen “./remove-plugins.sh“:

#!/bin/bash

PLUGINS=(
alertingDashboards
anomalyDetectionDashboards
customImportMapDashboards
ganttChartDashboards
indexManagementDashboards
mlCommonsDashboards
notificationsDashboards
observabilityDashboards
queryWorkbenchDashboards
reportsDashboards
searchRelevanceDashboards
securityAnalyticsDashboards
securityDashboards
)

for PLUGIN in "${PLUGINS[@]}"
do
    /usr/share/opensearch-dashboards/bin/opensearch-dashboards-plugin remove $PLUGIN # --allow-root
done
systemctl restart opensearch && systemctl restart opensearch-dashboards

Mit dem letzten Befehl startest du OpenSearch und OpenSearch Dashboards neu. Nur so können wir sichergehen, dass die Installation oder Deinstallation von Plugins auch angenommen wird.

OpenSearch Dashboards: Plugin Überblick

Wenn du mein Skript verwendet hast, um Plugins für das Dashboard zu installieren, solltest du jetzt eine größere Seiten-Leiste haben als zuvor. Denn irgendwie musst du ja auch auf die Plugins zugreifen.
Damit du weißt, welche OpenSearch Plugins ich in meinem Skript verwende, folgt hier nun für jedes Plugin eine kurze Beschreibung sowie ein Screenshot, um dir die visuelle Darstellung vorzustellen.

Query Workbench:
Mit diesem Plugin kannst du in SQL und PPL Abfragen machen. Interessant finde ich vor allem die Explain-Funktion, die die Darstellung im JSON-Format zurückgibt.

Reporting:
Mit Reporting lassen sich bequem alle relevanten Daten, zum Beispiel deine individuell angelegten Dashboards, aber auch viele weitere Daten exportieren. Der Export kann natürlich auch mit Schedulern automatisiert werden.
Ich kann mir vorstellen, das exportiere Reportings in den Formaten PDF und PNG in vielen Business-Umgebungen eine sinnvolle Erweiterung darstellen.

Alerting:
Hiermit kannst du für alle Parameter, die du überwachst, etwa Anomalien in deinen Datensätzen, Schwellwerte setzen und Aktionen auslösen lassen. Stark sind hier die vielen Möglichkeiten, die geboten werden. Du kannst dich zum Beispiel benachrichtigen lassen, wenn ein “whoami” eingegeben wird oder ein Icinga2Host ausfällt! Die Grenzen sind sehr weit gefasst, dass sicher auch für deinen Use Case das passende Alerting einstellbar ist.

Stark sind vor allem mitgelieferten Notification Channels und das freundliche UI!

Anomaly Detection:
Hier wird der Nutzer mit mehr Neugier, Statistikwissen und tieferer Kenntnis seiner Daten (sowie, deren Felder) besseren Nutzen rausholen können.
In meinem Screenshot siehst du ein kleines Beispiel der Anomalien der Event Codes eines Active Directories der letzten 30 Tage. Solche Möglichkeiten sind natürlich genial für alle Admins, Data Scientists oder Analysten die projizieren und erkennen wollen:

Maps:
Richtig spannend wird es, wenn dir Geodaten zur Verfügung stehen. Im OpenSearch Dashboards Plugin Maps kannst du dann aus mehreren visuellen Layern auswählen. Damit kann man schnell beeindrucken und mit den unterschiedlichen Layern sogar seine präferierte Ansicht wählen.

Security Analytics:
Vielleicht hast du mittlerweile auch ähnliche Gedankengänge wie ich zum Zeitpunkt, als ich OpenSearch getestet habe. Einer der prominentesten Gedanken bei mir war “Okay cool. Und das ist wirklich alles umsonst?”. Die einfache Antwort: Yes!

Aber als ich dann bei Security Analytics mit einem Klick einen Detector anlegen wollte, war ich dann einfach nur (positiv) schockiert. Hier sind massig Sigma Regeln eingebunden und das komplett umsonst!
Allein die Auswahl an Providern ist der Wahnsinn.

Fast 1600 Sigma-Regeln für Windows?! Wow!

Die Auswahl an Linux-Regeln ist auch stark und auch wenn es nicht viele sind, scheint man sich mit der Auswahl sehr viel Gedanken gemacht zu haben, um eine breite Trickkiste abzufangen:

Also ist hier alles perfekt? Sehr gut, ja, aber nicht perfekt. Denn ein kleiner Haken im Vergleich zu Graylog und Elastic, die fertig eingerichtet kommen, ist, dass du die Detector-Regeln erst mal an die Felder der Indices anpassen musst. Dafür benötigst du schon einiges an Wissen und Zeit. Das heißt aber nicht, dass das so bleiben muss / wird!

Kaum am Laufen und minimale Anpassungen später hatte ich direkt einen simulierten Treffer in einem Honeypot-AD von mir:

Index Management & Snapshot Management:
Snapshots sind für viele Admins und Entwickler wichtig. Ebenso wichtig sind Rollups mit denen man abbilden kann, wie lange die Daten der einzelnen Indizes verwahrt werden sollen.
In meinem Anwendungsbeispiel lege ich mir einfach einen neuen Index an und schiebe den alten dort hinein. Das Feld ist zusätzlich noch zeitgesteuert, womit man sehr viel Customization erhält:

Search Relevance:
Mit diesem Plugins sich verschiedene Suchen vergleichen. Ziemlich hilfreich, um schnell Daten, etwas Felder aus verschiedenen Indizes miteinander zu vergleichen. Das setzt natürlich voraus, sich einmal mit der OpenSearch Query DSL auseinanderzusetzen.

Maschine Learning:
Um dieses Plugin einzusetzen, willst du genug Cluster haben, mit genug CPU & GPU Power. Dabei ist auch die Frage, wo du die Arbeit verrichten lassen willst, denn Logging braucht so schon genug Leistung und du brauchst auch extra Libraries.
Den Einsatz dieses OpenSearch Dashboard Plugins solltest du also etwas genauer planen. Auch Maschine Learning Modell-Deployments habe ich im Rahmen meiner OpenSearch Analyse genauer unter die Lupe genommen. Dieser Abschnitt würde jedoch den Rahmen dieses Blogbeitrags sprengen. Deshalb werde ich zum Thema OpenSearch Machine Learnung einen gesonderten Blogpost schreiben.

Ich hoffe, ich konnte dir mit diesem Blogpost ein paar Beispiele für die vielfältigen Plugins in OpenSearch zeigen und freue mich auf dein Feedback!

Maximale Datenkontrolle: OpenSearch Dashboards und Icinga Integration

This entry is part 3 of 5 in the series OpenSearch Security

Moderne Unternehmens-IT erfordert nicht nur eine zuverlässige Überwachung. Eine tiefgehende Analyse der Daten hilft dabei, relevante Erkenntnisse zu erhalten und damit die Leistungsfähigkeit des Systems kontinuierlich zu verbessern. Die Integration von Icinga in OpenSearch hilft dir dabei, dieses Ziel zu erreichen und dabei Leistung, Sicherheit und Analysemöglichkeiten deiner IT-Umgebung zu steigern.

Mit dem Elasticsearchwriter (als Fork von Elastic funktioniert das Tool auch in OpenSearch) kannst du OpenSearch zum Beispiel um Check Ergebnisse, Metriken und Performanz-Daten ergänzen. Icingabeat erweitert das Ganze um nahezu alle Ergebnisse deiner Checkresults, Downtimes, Notifications, Acknowledgements, um nur ein paar Parameter zu nennen. Damit bekommst du noch mehr Spielraum für Customization, Visualisierung, Data-Science Analytics und Alarmierung.
Im besten Fall ist bei dir Icinga Version 2.14 im Einsatz. Falls du Hilfe bei der Installation und Konfiguration von Icinga auf Ubuntu oder RHEL benötigst, empfehle ich dir einen Blick in unsere Guides zu werfen.

Sicherheit ist das Kernthema dieses Artikels, denn bei der Integration zweier Systeme ist es umso wichtiger, dass deine Daten auf dem Transportweg sicher verschlüsselt sind (Stichwort TLS-Verschlüsselung). Das macht vor allem bei verteilten Setups mit mehreren Netzwerken Sinn.

OpenSearch – Icinga Integration: Zertifikate vorbereiten

Um die sichere Kommunikation von OpenSearch und Icinga zu ermöglichen, müssen zunächst vertrauenswürdige Zertifikate erstellt werden, die bei der TLS-Verschlüsselung zum Einsatz kommen.
Für eine umfassende und ausführliche Erklärung zur Erstellung von Zertifikaten in OpenSearch kannst du einfach den Schritten der offiziellen Dokumentation folgen.

Um dir diese Arbeit abzunehmen und direkt eine in der Praxis von mir getestete Lösung zur Verfügung zu stellen, teile ich für dir für diese Task meine Zertifikatsgenerierung.
In diesem Beispiel heißt meine CA-Stelle graylog-root-ca und der Client Icinga2Opensearch.lan. Wenn du andere Bezeichnungen nutzt oder nutzen willst, musst du sie an den entsprechenden Stellen anpassen.

# 1. Generierung Beispiel-Ordner zum Ablegen der Zertifikate
mkdir -p /etc/ssl/certs/graylog/Icinga2OpenSearch

# 2. Generierung des Icinga2Opensearch Client-Keys
openssl genpkey -algorithm RSA -out /etc/ssl/certs/graylog/Icinga2OpenSearch/Icinga2OpenSearch.key -pkeyopt rsa_keygen_bits:4096

# 3. Template um die Alt Names zu setzen
# 3. Start
cat << EOF > /etc/ssl/certs/graylog/Icinga2OpenSearch/Icinga2OpenSearch_openssl.cnf
[ req ]
default_bits       = 4096
default_keyfile    = /etc/ssl/certs/graylog/Icinga2OpenSearch/Icinga2OpenSearch.key
distinguished_name = req_distinguished_name
req_extensions     = req_ext
prompt             = no

[ req_distinguished_name ]
countryName                     = de
stateOrProvinceName             = by
localityName                    = nbg
organizationName                = nw
organizationalUnitName          = nps
commonName                      = Icinga2OpenSearch.lan

[ req_ext ]
subjectAltName = @alt_names

[alt_names]
DNS.1 = Icinga2OpenSearch.lan
IP.1 = 6.6.6.6
EOF
#3. Ende

#4. Generieren des CSRs
openssl req -new -key /etc/ssl/certs/graylog/Icinga2OpenSearch/Icinga2OpenSearch.key -out /etc/ssl/certs/graylog/Icinga2OpenSearch/Icinga2OpenSearch.csr -config /etc/ssl/certs/graylog/Icinga2OpenSearch/Icinga2OpenSearch_openssl.cnf

#5. Signieren des CSRs
openssl x509 -req -days 3650 -in /etc/ssl/certs/graylog/Icinga2OpenSearch/Icinga2OpenSearch.csr -CA /etc/graylog/server/graylog-ca-root.crt -CAkey /etc/ssl/certs/graylog/central/graylog-ca-key.pem -out /etc/ssl/certs/graylog/Icinga2OpenSearch/Icinga2OpenSearch.crt

#6. Graylog-CA mitkopieren
cp /etc/ssl/certs/graylog/central/graylog-ca-root.crt /etc/ssl/certs/graylog/Icinga2OpenSearch/


#7. In den Ordner wechseln und Packen um danach SCP zum Ziel-Icinga2-Server
cd /etc/ssl/certs/graylog/Icinga2OpenSearch && tar-czvf Icinga2OpenSearch.gz Icinga2OpenSearch.crt Icinga2OpenSearch.key graylog-ca-root.crt

#8. Nach dem SCP auf den RHEL-Icinga2-Server User & Permissions anpassen
chown -Rv icinga:icinga /etc/icinga2/Icinga2OpenSearch
chmod -Rv 750 /etc/icinga2/Icinga2OpenSearch

Mit dem ElasticsearchWriter Daten an OpenSearch schicken

Nachdem die Vorbereitungen für eine sichere Kommunikation zwischen Icinga und OpenSearch abgeschlossen sind, kann nun die eigentliche Kommunikationsschnittstelle eingerichtet werden. Damit du mit dem ElasticsearchWriter die gewünschten Daten übertragen kannst, benötigt es nur ein paar kleine Einstellungen in der elasticsearch.conf aufseiten von Icinga.

Füge Host und Port, einen Namen für deinen Index sowie deinen Service-/Benutzer-Account (wie du diesen anlegst, erkläre ich in einem anderen Blogpost) hinzu. Zudem gibst du den Pfad zu den vorher angelegten Zertifikaten an und fügst eine Aktivierungsflagge hinzu. Damit sind alle relevanten Informationen in der Konfigurationsdatei verfügbar.

Wenn du noch keine Erfahrung mit dem ElasticsearchWriter hast und mehr darüber erfahren willst, empfehle ich dir den entsprechenden Abschnitt in der offiziellen Icinga Dokumentation. Darin sind Handhabung und weitere Details gut beschrieben.

vim /etc/icinga2/features-available/elasticsearch.conf
object ElasticsearchWriter "elasticsearch" {
  
  host = "opensearch.lan"
  port = 9200
  index = "icingabeat-7.17.4"
  enable_send_perfdata = true
  flush_threshold = 1024
  flush_interval = 10s
  
  username = "Icinga2Opensearch_Service_Account"
  password = "Icinga2Opensearch_Service_Password"

  ca_path = "/etc/icinga2/Icinga2OpenSearch/graylog-ca-root.crt"
  cert_path = /"etc/icinga2/Icinga2OpenSearch/Icinga2OpenSearch.crt"
  key_path = "/etc/icinga2/Icinga2OpenSearch/Icinga2OpenSearch.key"

  # Je nachdem ob self-signed oder nicht sowie die Hostnames/IPs passen hier auf true/false
  insecure_noverify = false

  enable_tls = true
}

Nun aktivierst du das Feature mit dem Befehl icinga2 feature enable elasticsearch. Anschließend kannst du via tail -f /var/log/icinga2/icinga2.log sehen, ob alles funktioniert.
Hast du den Icingabeat Index richtig referenziert, solltest du (wie in meinem Screenshot erkennbar) im Discover die Daten fließen sehen.

OpenSearch und Icingabeat

Damit Icingabeat und OpenSearch überhaupt miteinander sprechen können, müssen die Zugriffsrechte seitens Icinga freigegeben werden. Dazu erstellst du unter /etc/icinga2/features-available/api.conf ein ApiUser Objekt mit entsprechenden Rechten, beispielsweise mit dem Namen icingabeat.

object ApiListener "api" {
  accept_config = true
  accept_commands = true
  ticket_salt = "my_salt"
}

object ApiUser "icingabeat" {
  password = "icingabeat_service_password"
  permissions = ["events/*", "status/query"]
}

Wie bei allen Beats werden Logs ausgelesen und entweder über Mittelsmänner wie Logstash weitergeleitet oder direkt an Elasticsearch gesendet.

Bei OpenSearch ist es aktuell allerdings so, dass ein “direkter” Sendeweg nur über einen Mittelsmann wie Logstash oder Graylog geht. Von hier werden die Daten anschließend an OpenSearch weitergegeben.
Es gibt also zwei Optionen, aus denen man wählen kann. Ich zeige dir zuerst einen Graylog-Input und danach einen Logstash Input.

Icingabeat Konfiguration

Bevor ich genauer auf die beiden Möglichkeiten eingehe, zeige ich dir zunächst die Icingabeat Konfiguration. Hier arbeitest du in einem Konfigurationsfile, das an einen Beat angelehnt ist. Du kannst nach Interesse verschiedene Eventstreams auswählen, denen du wie zuvor Host-IP, Service-Passwörter für OpenSearch, Zeitintervalle und Zertifikate mitgibst.

vim /etc/icingabeat/icingabeat.yml
icingabeat:
 host: "127.0.0.1"
 user: "icingabeat_opensearch_service_account"
 password: "icingabeat_opensearch_service_password"
 ssl.verify: false 
 ssl.certificate_authorities: ["/var/lib/icinga2/ca//ca.crt"] 

 eventstream.types:
   - CheckResult 
   - StateChange 
   - Notification 
   - AcknowledgementSet 
   - AcknowledgementCleared 
   - CommentAdded 
   - CommentRemoved 
   - DowntimeAdded 
   - DowntimeRemoved 
   - DowntimeStarted 
   - DowntimeTriggered 

eventstream.filter: "" 
eventstream.retry_interval: 10s 
statuspoller.interval: 60s 

# Graylog Output Variante: 
  output.logstash: 
   hosts: ["graylog.lan"] 
   ssl.enable: true 
   ssl.verification_mode: "certificate" 

   ssl.certificate_authorities: ["/etc/icinga2/Icinga2OpenSearch/graylog-ca-root.crt"] 
   ssl.certificate: "/etc/icinga2/Icinga2OpenSearch/Icinga2OpenSearch.crt" 
   ssl.key: "/etc/icinga2/Icinga2OpenSearch/Icinga2OpenSearch.key"

Graylog Input an OpenSearch

Hier vergebe ich einen Graylog-Input Namen, eine Listener Bind-Addresse und gebe ein eigenes Graylog-CA-Server Zertifikat an. Für dieses Beispiel habe ich ein extra ein Clientzertifikat namens 5044 angelegt. In meinem Screenshot siehst du, wie das komplett ausgefüllte Eingabe-Formular aussehen sollte:

Icingabeat sendet seine Informationen an den Graylog-Input, der diesen Input verarbeitet und anschließend entsprechend der Graylog-Dokumentation, weiter an OpenSearch sendet.
Damit der zweite Schritt möglich ist, musst du in /etc/graylog/server/server.conf den Weg von Graylog zu OpenSearch angeben:

"elasticsearch_hosts = https://my_graylog_service_account:my_graylog_service_password@opensearch.lan:9200"

Icingabeat Input via Logstash-OSS

In Möglichkeit Nummer 2 benutzt du das Logstash-OSS Paket von Elasticsearch auf das Amazon referenziert, und machst dir so einen Logstash-Input, der einen Output auf OpenSearch hat:

Nachdem du das Paket geladen hast, kannst du dir die verfügbaren Plugins ansehen und sichergehen, dass die benötigten Input und Output Plugins vorhanden sind:

/usr/share/logstash/bin/logstash-plugin list --verbose
/usr/share/logstash/bin/logstash-plugin install logstash-input-beats
/usr/share/logstash/bin/logstash-plugin install logstash-output-opensearch

Bedenke, dass du aus historischen Gründen zuerst deinen Logstash-Schlüssel des Inputs in das PKCS8-Format bringen musst:

# Beispiel PKCS8-mit Passphrase
openssl pkcs8 -in logstash-oss.key -topk8 -out logstash-oss-pkcs8.key

# Beispiel PKCS8-ohne Passphrase
openssl pkcs8 -in logstash-oss.key -topk8 -nocrypt -out logstash-oss-pkcs8.key

Jetzt legst du dir eine neue Pipeline an, z.B. /etc/logstash/conf.d/icingabeat-pipeline.conf. Hier legst du Beats-Input und Opensearch-Output Einstellungen fest, die via /etc/logstash/pipelines.yml angezogen werden.

Folgende Parameter müssen angegeben werden:

Input:

  • Input Port
  • SSL-Aktivierungsflaggen
  • Privater Logstash-Schlüssel im PKCS8 Format
  • CA mitgegeben

Output:

  • das OpenSearch-Backend mit IP und Port
  • Index-Format
  • Zertifikate
  • Zugangsdaten der/des Service-Accounts
input {
  beats {
  # id => "icingabeat"
    port => "5044"
    ssl => "true"
    ssl_key => '/etc/logstash/logstash-oss-pkcs8.key'
  #  ssl_key_passphrase => 'deine_passphrase_hier_falls_vorhanden' 
    ssl_certificate => '/etc/logstash/logstash-oss.crt'
    ssl_certificate_authorities => ["/etc/logstash/graylog-ca-root.crt"]
  }
}

output {
  opensearch {
    hosts => ["https://10.3.0.171:9200"]
    index => "%{[@metadata][beat]}-%{[@metadata][version]}"
    cacert => '/etc/logstash/opensearch.crt'
    ssl => "true"
    ssl_certificate_verification => "true"
    user => "logstash_oss_service_opensearch_pass""
    password => "logstash_oss_service_opensearch_pass"
  }
}

Da du Logstash-OSS als Vermittler nutzt, muss die icingabeat.yml ebenso angepasst werden. Statt auf Graylog wird nun auf Logstash-OSS referenziert, alle anderen Einstellungen bleiben unverändert:

# Logstash OSS Output Variante

output.logstash:
  hosts: ["logstash.lan"]

  ssl.enable: true
  ssl.verification_mode: "certificate"
  ssl.certificate_authorities: ["/etc/icinga2/Icinga2OpenSearch/graylog-ca-root.crt"]
  ssl.certificate: "/etc/icinga2/Icinga2OpenSearch/Icinga2OpenSearch.crt"
  ssl.key: "/etc/icinga2/Icinga2OpenSearch/Icinga2OpenSearch.key"

Bedenke, dass deine Schlüssel und Zertifikate für Icingabeat & Logstash mit den passenden File-Berechtigungen ausgestattet sind (sie müssen lesbar sein) und deine weiteren Parameter fehlerfrei sind. Sollten dennoch Fehler auftreten oder du willst alles vor dem Einsatz überprüfen, kannst du sowohl Logstash-OSS als auch Icingabeat mit den folgenden Befehlen einfach debuggen:

tail -f /var/log/logstash/logstash-*.log
/usr/local/bin/icingabeat -c /etc/icingabeat/icingabeat.yml -e -d "*"

OpenSearch und Icinga erfolgreich verknüpft

An dieser Stelle hast du die Verknüpfung von OpenSearch und Icinga erfolgreich durchgeführt. Du kannst nun komplett frei und nach deinen Interessen und Bedürfnissen Felder für die Anzeige auswählen.
Um in den vollen Genuss von Open Source Customization zu kommen, kannst du dir Dashboards so anlegen, wie du sie brauchst. Ab diesem Punkt kannst du mit deinen Icinga-Daten mehr Data Science in OpenSearch durchführen. Mir hat es sehr viel Spaß gemacht, verschiedene Trends oder Anomalien zu erkennen und der Ursache auf den Grund zu gehen.

Falls dich mein Anwendungsbeispiel zur Verknüpfung von OpenSearch und Icinga inspiriert hat, diese Möglichkeit selbst zu testen, wünsche ich dir viel Spaß dabei! Solltest du bei deiner Konfiguration jedoch auf Probleme stoßen, freue ich mich auf eine Nachricht von dir.
Neben OpenSearch bieten meine Kolleg:innen und ich auch Consulting und Support für andere hier genannte und verwendete Tools, zum Beispiel GraylogElastic oder Icinga an.

Wir helfen dir gerne weiter!

OpenSearch Dashboards: TLS, Konten & Datensicherheit

This entry is part 2 of 5 in the series OpenSearch Security

Du hast dich auch schon gefragt, wie du die einzelnen Komponenten von OpenSearch sicher verknüpfen kannst? Dann bist du auf die gleichen Probleme gestoßen wie ich. Damit du nicht auch mehrere Tage mit der Lösungsfindung verbringen musst, habe ich meine Lösungen für dich zusammengetragen.

In diesen Blogpost gehe ich auf die Lösung folgender Probleme ein:

  • OpenSearch Dashboards sicher verwenden
  • Wie deaktiviere ich Accounts, wie füge ich neue hinzu?
  • Wie kann ich mehr aus OpenSearch Dashboards herausholen und beispielweise Powershell Befehle überwachen?

OpenSearch Indexe referenzieren, Discover testen, und Dashboards verwenden

Im Vergleich zu Elasticsearch wird das Indexmanagement in OpenSearch als “Dashboard Management”. Hier muss man via “Index Patterns” auf den gewünschten Index für die DiscoverAnzeige referenzieren, z.b. via “graylog*”

Dashboards lassen sich bequem via Visualize -> Create Visualization erstellen. Mich interessieren vor allem SSH Zugriffe und neue Nutzer Sessions.

OpenSearch Dashboards mit TLS

Im Idealfall stellst du sicher, dass die gesamte Kommunikation von OpenSearch zu den OpenSearch Dashboards über den gesamten Transportweg hinweg verschlüsselt ist. Hier werden schließlich sämtliche (auch vertrauliche) Daten ausgetauscht.
Gleichzeitig ist es wichtig, dass auch die Verbindung von deinem Browser zu den OpenSearch Dashboards verschlüsselt ist.

Um dir ein aktiv genutztes Beispiel für die Verschlüsselung zu geben, zeige ich eine von mir getestete (minimalistische) TLS-Konfiguration, die du unter “/etc/opensearch-dashboards/opensearch_dashboards.yml” anpassen kannst.

Du siehst die Hostnamen deiner OpenSearch-Server, die genutzten Ports, Zugriffsrechte sowie die Zertifikate für den Transportweg und den Browser.
Zusätzlich benötigst du einen Zugriffsaccount. Beachte, dass teilweise standardmäßige Standardpasswörter aktiv sind. Wie du Service- und Benutzernamen änderst, erfährst du im nächsten Abschnitt.

server.name: "opensearch-dashboards"
opensearch.hosts: ["https://opensearch.lan:9200"]

opensearch.requestHeadersAllowlist: [ authorization,securitytenant ]
opensearch_security.readonly_mode.roles: [kibana_read_only]

server.ssl.enabled: true
server.ssl.certificate: /etc/opensearch-dashboards/opensearch-dashboards.crt
server.ssl.key: /etc/opensearch-dashboards/opensearch-dashboards.key

opensearch.ssl.certificate: /etc/opensearch-dashboards/opensearch-dashboards.crt
opensearch.ssl.key: /etc/opensearch-dashboards/opensearch-dashboards.key

opensearch.ssl.certificateAuthorities: [ "/etc/opensearch-dashboards/graylog-ca-root.crt" ]
opensearch.ssl.verificationMode: certificate

opensearch.username: my_dasbhboards_service_acc 
opensearch.password: my_dasbhboards_secure_pass

OpenSearch Accounts ändern via Securityadmin

Um Service-Passwörter zu verändern, musst du sie direkt auf deinem OpenSearch Server anpassen. Das geht aktuell nur über die internal_users.yml welche du unter /etc/opensearch/opensearch-security/internal_users.yml findest.
Die Passwörter sind idealerweise gehasht. OpenSearch stellt ein Tool zum Hashen von Passwörtern zur Verfügung. Das entsprechende Skript findest du hier:

/usr/share/opensearch/plugins/opensearch-security/tools/hash.sh

 

Willst du statt Passwörtern lieber Benutzer ändern, geht aktuell (soll aber deprecated werden) über das Securityadmin.sh Skript, indem du den korrekten Client-Key, das Client-Zertifikat, plus CA-Zertifikat gegen die OpenSearch-Instanz verifizierst.
Genau das tue ich, indem ich auf das Skript verweise. Dabei nutze ich das internal_users-File sowie Client-Key und Zertifikate, einschließlich der CA (Graylog-ca-Root). Zusätzlich gebe ich den FQDN meines OpenSearch an, gegen den ich das Skript ausführe.

bash /usr/share/opensearch/plugins/opensearch-security/tools/securityadmin.sh -f /etc/opensearch/opensearch-security/internal_users.yml -cert /etc/opensearch/opensearch.crt -key /etc/opensearch/opensearch.key -cacert /etc/opensearch/graylog-ca-root.crt -h opensearch.lan

Windows Command Line Logging

Ich finde, wir sind jetzt bereit, dafür weitere Felder der Indizes zu erkunden. Beispielsweise das Command-Line-Logging von Windows-Servern.

Nxlog zeigt in einem interessanten Audit, wie man unabhängig vom Active Directory schnell Command-Line Logging aktivieren kann. Ich habe das ganze ein bisschen erweitert und in ein Ansible Playbook gepackt.
Bitte beachte dabei, dass für diese Maßnahme aus datenschutzrechtlichen Gründen die Erlaubnis des betroffenen Clients erforderlich ist.

In diesem Prozess aktiviere ich die Auditpolicies für “Process Create”, “RPC Events”, “Process Terminate” und “DPAPI”. Die Ergebnisse werden anschließend direkt im Winlogbeat erkennbar sein.

---
- hosts: windows
  tasks:
  - name: Configure Audit Policy for Process Creation
    win_shell: auditpol /set /subcategory:"Process Creation" /success:enable /failure:enable

  - name: Configure Audit Policy for RPC Events
    win_shell: auditpol /set /subcategory:"RPC Events" /success:enable /failure:enable

  - name: Configure Audit Policy for Process Termination
    win_shell: auditpol /set /subcategory:"Process Termination" /success:enable /failure:enable

  - name: Configure Audit Policy for DPAPI Activity
    win_shell: auditpol /set /subcategory:"DPAPI Activity" /success:enable /failure:enable

  - name: Configure Audit Policy for PNP Activity
    win_shell: auditpol /set /subcategory:"Plug and Play Events" /success:enable /failure:enable

  - name: Enable Command Line in Process Creation Event
    win_shell: Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit" -Name ProcessCreationIncludeCmdLine_Enabled -Value 1

  - name: Reboot the system
    win_reboot:

Opensearch Discover

Zum Abschluss werfen wir noch einmal einen Blick in OpenSearch Discover. Im Bereich “Selected Fields” siehst du nun die von mir ausgewählten Winlogbeat-Felder sowie einige erfasste Eingaben der “Windows Command Line”. Durch einen Klick auf das Plus-Symbol neben den “Available Fields” werden diese zu “Selected Fields” hinzugefügt. So einfach kann die getroffene Auswahl kenntlich gemacht werden.

Bist du nun ebenfalls bereit, deine Log-Management-Strategie zu optimieren und Security mehr in den Fokus zu rücken? Falls du Hilfe bei der Implementierung von OpenSearchElastic oder Graylog benötigst, stehen dir ich und meine Kolleg:innen von NETWAYS gerne zur Seite. Mit unserer Erfahrung sorgen wir für eine für dich maßgeschneiderte Log-Management Lösung. Wir freuen uns auf deine Nachricht.