Dies ist eine alte Version des Dokuments!
Elasticsearch ist eine Open-Source-Such- und Analyselösung in Java, die hauptsächlich für das Durchsuchen und Analysieren großer Mengen von Daten in Echtzeit verwendet wird. Es wurde ursprünglich von der Firma Elastic entwickelt und ist ein wichtiger Bestandteil des sogenannten ELK-Stacks (Elasticsearch, Logstash und Kibana), der häufig zur Verarbeitung und Visualisierung von Logdaten eingesetzt wird. Elasticsearch basiert auf Apache Lucene, einer leistungsstarken, Open-Source-Textsuchbibliothek.
Siehe auch OpenSearch
X-Pack ist eine Plugin-Suite und bietet eine Sammlung von kommerziellen Erweiterungen und Funktionen, um die Fähigkeiten von Elasticsearch zu erweitern. X-Pack bietet verschiedene Module in den Bereichen Sicherheit, Überwachung, Reporting und maschinelles Lernen.
Elasticsearch, „shards“ sind die grundlegenden Einheiten, in die ein Index aufgeteilt wird, um die Daten zu speichern und zu verteilen. Elasticsearch ist ein verteiltes Such- und Analysetool, das entwickelt wurde, um große Mengen strukturierter oder unstrukturierter Daten zu verwalten und abzufragen. Sharding ist eine Schlüsselkomponente dieses verteilten Ansatzes.
Lucene ist für die Indexierung, das Durchsuchen und das Abrufen von Dokumenten in einem Shard verantwortlich. Elasticsearch organisiert und verteilt diese Shards über verschiedene Knoten in einem Cluster, um eine skalierbare und zuverlässige Suchinfrastruktur bereitzustellen.
Ein Elasticsearch-Index kann aus einer oder mehreren „Primary Shards“ bestehen. Jeder Primary Shard ist eine eigenständige Einheit, die eine Teilmenge der Indexdaten enthält. Diese Daten werden über verschiedene Server oder Knoten im Elasticsearch-Cluster verteilt, wodurch die Last auf verschiedene Hardware-Ressourcen verteilt wird und die Suche und Abfrage parallelisiert werden können.
Jede Primary Shard kann auch über eine konfigurierbare Anzahl von „Replica Shards“ verfügen. Replika-Shards sind Kopien der Primary Shards und dienen dazu, die Hochverfügbarkeit und Ausfallsicherheit des Indexes zu gewährleisten. Wenn ein Knoten ausfällt oder nicht mehr erreichbar ist, können die Replika-Shards auf anderen Knoten weiterhin abgefragt werden.
GET /myIndex/_search { "size": 10, "query": { "wildcard": { "data.win.eventdata.authenticationPackageName": "NTLM" } } } GET /myIndex/_search { "size": 10, "query": { "wildcard": { "data.win.eventdata.authenticationPackageName": "NTLM" } }, "sort": [{ "@timestamp": "asc" }], "search_after": ["2025-03-04T18:56:45.890+0000"] } GET /myIndex/_search { "size": 10, "query": { "wildcard": { "data.win.eventdata.authenticationPackageName": "NTLM" } }, "sort": [{ "@timestamp": "asc" }] } GET /myIndex/_search { "query": { "bool": { "must": [ { "match": { "data.win.eventdata.targetUserName": "dom_docusnap" } }, { "wildcard": { "data.win.system.message": "*logged on*" } } ] } } }
Passwort für user „elastic“ wird beim ersten Start in der Console angezeigt. Auch der Enrollment-Token.
#add user curl -X POST "https://localhost:9200/_security/user/manuel" -H "Content-Type: application/json" -d "{ \"password\": \"s3cr3t\", \"roles\": [\"superuser\"], \"full_name\": \"Manuel Zarat\" }" -u elastic:xxx #delete user curl -X DELETE "https://localhost:9200/_security/user/manuel" -u elastic:xxx # create index curl -X PUT "https://localhost:9200/mein_index" -H "Content-Type: application/json" -d "{ \"settings\": { \"number_of_shards\": 5, \"number_of_replicas\": 2}, \"mappings\": { \"properties\": { \"field1\": { \"type\": \"text\" }, \"field2\": { \"type\": \"text\" } } } }" -u elastic:xxx #list indices curl -X GET "https://localhost:9200/_cat/indices?v" -u elastic:xxx #delete index curl -X DELETE "https://localhost:9200/mein_index" -u elastic:xxx #add entry curl -X POST "https://localhost:9200/mein_index/_doc" -H "Content-Type: application/json" -d "{\"field1\": \"testname\", \"field2\": \"testkeyword\"}" -u elastic:xxx #search entry curl -X GET "https://localhost:9200/mein_index/_search" -H "Content-Type: application/json" -d "{ \"query\": { \"match\": { \"field1\": \"testname\" } } }" -u elastic:xxx curl -X GET "https://localhost:9200/mein_index/_search" -H "Content-Type: application/json" -d "{ \"query\": { \"wildcard\": { \"field1\": \"test*\" } } }" -u elastic:xxx # As Text curl -X GET "https://localhost:9200/_sql?format=txt" -H "Content-Type: application/json" -d "{\"query\": \"SELECT * FROM mein_index WHERE MATCH(field1,'hund') AND NOT MATCH(field2, 'katze')\"}" --insecure -u elastic:xxx # As JSON curl -X GET "https://localhost:9200/_sql?format=json" -H "Content-Type: application/json" -d "{\"query\": \"SELECT * FROM mein_index WHERE MATCH(field1,'hund') AND NOT MATCH(field2, 'katze')\"}" --insecure -u elastic:xxx # For LIKE the field must be a "keyword" curl -X GET "http://localhost:9200/_sql?format=txt" -H "Content-Type: application/json" -d "{\"query\": \"SELECT * FROM mein_index WHERE field1 LIKE 'D:\\Musik\\Hip%%'\"}" --insecure -u elastic:xxx curl -X GET "http://localhost:9200/_sql?format=txt" -H "Content-Type: application/json" -d "{\"query\": \"SELECT * FROM mein_index WHERE field1 RLIKE 'D:\\Mus.*\\Hip.*'\"}" --insecure -u elastic:xxx
from elasticsearch import Elasticsearch # Initialisiere Elasticsearch-Verbindung es = Elasticsearch( ['http://localhost:9200'], basic_auth=("elastic", "PqGVK*4uj4r8_kUzmyWA"), verify_certs=False ) # Definiere den Query ohne Scroll und sende den ersten Search-Request data = { "size": 1000, # Maximale Anzahl an Ergebnissen pro Anfrage "query": { "match_all": {} } } # Erster Scroll-Request response = es.search(index="test", body=data, scroll="1m") # Holen Sie sich den Scroll-ID aus der ersten Antwort scroll_id = response['_scroll_id'] res_c = 0 # Solange es Ergebnisse gibt, hole weitere Ergebnisse while True: # Hole den nächsten Scroll-Chunk response = es.scroll(scroll_id=scroll_id, scroll="1m") # Wenn keine Treffer mehr vorhanden sind, beende die Schleife if len(response['hits']['hits']) == 0: break # Verarbeite die Treffer for hit in response['hits']['hits']: res_c += 1 print("%(FolderPath)s %(IdentityReference)s: %(FileSystemRights)s" % hit["_source"]) # Wenn du fertig bist, rufe clear_scroll auf, um den Scroll-Context zu löschen es.clear_scroll(scroll_id=scroll_id) print("We had ", res_c, " results")
class ElasticsearchQueryBuilder: def __init__(self): self.query = { "query": { "bool": { "must": [], "should": [], "must_not": [] } } } def add_condition(self, method, field, value): """ Add a condition to the query. The method is one of: 'match', 'wildcard', 'term', 'range' """ if method == "match": return {"match": {field: value}} elif method == "wildcard": return {"wildcard": {field: value}} elif method == "term": return {"term": {field: value}} elif method == "range": return {"range": {field: {"gte": value}}} else: raise ValueError(f"Unsupported method: {method}") def build_query(self, conditions, operator="AND", sort_field=None, sort_order="asc"): """ Build the query with the provided conditions, logical operator, and optional sorting. 'AND' means all conditions must match, 'OR' means any condition can match. """ if operator == "AND": self.query["query"]["bool"]["must"] = conditions elif operator == "OR": self.query["query"]["bool"]["should"] = conditions self.query["query"]["bool"]["minimum_should_match"] = 1 else: raise ValueError("Operator must be 'AND' or 'OR'") # Füge die Sortierung hinzu, falls ein Sortierfeld angegeben wurde if sort_field: self.query["sort"] = [{sort_field: {"order": sort_order}}] return self.query def display_query(self): """Print the generated query in a pretty JSON format.""" import json print(json.dumps(self.query, indent=2)) def add_nested_condition(self, method, field, value): """ Add a nested condition, creating a bool query within another bool query. """ nested_condition = { "bool": { "must": [self.add_condition(method, field, value)] } } return nested_condition # Beispielnutzung def main(): # Initialisierung des Query Builders builder = ElasticsearchQueryBuilder() # Verschachtelte Bedingungen erstellen must_conditions = [] must_conditions.append(builder.add_condition("match", "data.win.eventdata.authenticationPackageName", "NTLM")) must_conditions.append(builder.add_condition("wildcard", "data.win.eventdata.targetUserName", "*")) # Eine verschachtelte "bool" Abfrage innerhalb der "must" Bedingungen nested_condition = builder.add_nested_condition("term", "data.win.eventdata.lmPackageName", "NTLM V1") must_conditions.append(nested_condition) # Die Bedingungen zur Query hinzufügen (Operator AND) query = builder.build_query(must_conditions, operator="AND", sort_field="timestamp", sort_order="desc") # Die erzeugte Query ausgeben builder.display_query() if __name__ == "__main__": main()
elastic-search-users useradd manuel -p ToPsEcRet elasticsearch-users roles manuel -a superuser elasticsearch-users roles manuel -r superuser
#!/bin/bash # Elasticsearch-Server-URL ES_HOST="https://localhost:9200" INDEX="wazuh-alerts*" USER="admin" PASS="SecretPassword" # Erste Suchanfrage mit Scroll response=$(curl -X POST "$ES_HOST/$INDEX/_search?scroll=1m" -u "$USER:$PASS" -H "Content-Type: application/json" -d '{ "size": 10, "query": { "match_all": {} } }' --insecure) # Scroll-ID extrahieren scroll_id=$(echo "$response" | jq -r '._scroll_id') # Anzahl der Treffer zählen res_c=0 # Loop über die Ergebnisse while true; do read -p "Press enter to continue" # Treffer verarbeiten hits=$(echo "$response" | jq -c '.hits.hits[]?') # Wenn keine Treffer mehr vorhanden sind, abbrechen if [[ -z "$hits" ]]; then break fi # Treffer ausgeben echo "$hits" | while read -r hit; do #folder_path=$(echo "$hit" | jq -r '._source.FolderPath // empty') echo $hit |jq ((res_c++)) done # Nächste Scroll-Anfrage senden response=$(curl -X POST "$ES_HOST/_search/scroll" -u "$USER:$PASS" -H "Content-Type: application/json" -d "{ \"scroll\": \"1m\", \"scroll_id\": \"$scroll_id\" }" --insecure) # Neuen Scroll-ID extrahieren scroll_id=$(echo "$response" | jq -r '._scroll_id') done # Scroll-Context aufräumen curl -s -X DELETE "$ES_HOST/_search/scroll" -u "$USER:$PASS" -H "Content-Type: application/json" -d "{ \"scroll_id\": \"$scroll_id\" }" > /dev/null echo "We had $res_c results"