diff --git a/docker/.gitignore b/docker/.gitignore new file mode 100644 index 00000000..12d9bd97 --- /dev/null +++ b/docker/.gitignore @@ -0,0 +1,2 @@ +# Ignore .docker file +/.docker diff --git a/docker/Makefile.am b/docker/Makefile.am new file mode 100644 index 00000000..2e98768d --- /dev/null +++ b/docker/Makefile.am @@ -0,0 +1,43 @@ +DCMP = docker-compose +COMPOSE_SOURCE = docker-compose.yml elasticsearch/Dockerfile logstash/Dockerfile logstash/config/logstash.conf +COMPOSE_TARGET = .docker +ES_DATA_DIR = elasticsearch/data-dir +GEOIP_FILENAME = GeoLite2-City.mmdb +GEOIP_FILE_GZ = logstash/geoip/$(GEOIP_FILENAME).gz +GEOIP_FILE = logstash/geoip/$(GEOIP_FILENAME) + +$(GEOIP_FILE_GZ): + wget -N -O $(GEOIP_FILE_GZ) http://geolite.maxmind.com/download/geoip/database/$(GEOIP_FILENAME).gz + +$(GEOIP_FILE): $(GEOIP_FILE_GZ) + gunzip -c $(GEOIP_FILE_GZ) >$(GEOIP_FILE) + +$(COMPOSE_TARGET): $(COMPOSE_SOURCE) $(GEOIP_FILE) + $(DCMP) down + $(DCMP) build + touch $(COMPOSE_TARGET) + +build_image: $(COMPOSE_TARGET) + +start: + $(DCMP) up -d + +stop: + $(DCMP) stop + +kill: + $(DCMP) kill + +clean_elastic: stop + rm -rf $(ES_DATA_DIR)/* + rm $(COMPOSE_TARGET) + +clean_geoip: + rm -rf logstash/geoip/* + +clean_docker: + docker-compose down + +clean: clean_docker clean_geoip clean_elastic + +all: build_image start diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml new file mode 100644 index 00000000..6ad4c987 --- /dev/null +++ b/docker/docker-compose.yml @@ -0,0 +1,30 @@ +version: '2' +services: + logstash: + build: logstash + ports: + - "14501:4501/udp" + command: -f /etc/logstash/conf.d/ + volumes: + - ./logstash/config:/etc/logstash/conf.d + - ./logstash/geoip:/etc/logstash/geoip + - ./logstash/templates:/tmp/templates + links: + - elasticsearch + depends_on: + - elasticsearch + networks: + - docker_elk + elasticsearch: + build: elasticsearch + volumes: + - ./elasticsearch/data-dir:/usr/share/elasticsearch/data + ports: + - "9200:9200" + - "9300:9300" + networks: + - docker_elk + +networks: + docker_elk: + driver: bridge diff --git a/docker/elasticsearch/Dockerfile b/docker/elasticsearch/Dockerfile new file mode 100644 index 00000000..c0bc0c0b --- /dev/null +++ b/docker/elasticsearch/Dockerfile @@ -0,0 +1,3 @@ +FROM elasticsearch:5.2 +ENV ES_JAVA_OPTS="-Des.path.conf=/etc/elasticsearch" +CMD ["-E", "network.host=_site_", "-E", "discovery.zen.minimum_master_nodes=1"] diff --git a/docker/elasticsearch/data-dir/.gitignore b/docker/elasticsearch/data-dir/.gitignore new file mode 100644 index 00000000..443547b9 --- /dev/null +++ b/docker/elasticsearch/data-dir/.gitignore @@ -0,0 +1,2 @@ +# Ignore everything under this directory +/nodes diff --git a/docker/kibana/kibana_saved_objects.json b/docker/kibana/kibana_saved_objects.json new file mode 100644 index 00000000..9c2d10f2 --- /dev/null +++ b/docker/kibana/kibana_saved_objects.json @@ -0,0 +1,382 @@ +[ + { + "_id": "Per-User-Login-and-Abuse-Statistics", + "_type": "dashboard", + "_source": { + "title": "Per-User Login and Abuse Statistics", + "hits": 0, + "description": "", + "panelsJSON": "[{\"col\":1,\"id\":\"Successful-slash-Unsuccessful-Logins\",\"panelIndex\":1,\"row\":3,\"size_x\":6,\"size_y\":3,\"type\":\"visualization\"},{\"col\":7,\"id\":\"Distinct-Count-of-Passwords\",\"panelIndex\":2,\"row\":3,\"size_x\":6,\"size_y\":3,\"type\":\"visualization\"},{\"col\":1,\"id\":\"Distinct-Count-of-IPs-for-Successful-Logins\",\"panelIndex\":3,\"row\":6,\"size_x\":6,\"size_y\":3,\"type\":\"visualization\"},{\"col\":7,\"id\":\"Distinct-Count-of-IPs-for-Unsuccessful-Logins\",\"panelIndex\":4,\"row\":6,\"size_x\":6,\"size_y\":3,\"type\":\"visualization\"},{\"col\":1,\"id\":\"Distinct-Count-of-Devices-for-Successful-Logins\",\"panelIndex\":5,\"row\":9,\"size_x\":6,\"size_y\":3,\"type\":\"visualization\"},{\"col\":7,\"id\":\"Distinct-Count-of-Devices-for-Unsuccessful-Logins\",\"panelIndex\":6,\"row\":9,\"size_x\":6,\"size_y\":3,\"type\":\"visualization\"},{\"col\":1,\"id\":\"Login-Country-over-Time-(Successful-Logins)\",\"panelIndex\":7,\"row\":12,\"size_x\":6,\"size_y\":3,\"type\":\"visualization\"},{\"col\":7,\"id\":\"Login-Country-over-Time-(Unsuccessful-Logins)\",\"panelIndex\":8,\"row\":12,\"size_x\":6,\"size_y\":3,\"type\":\"visualization\"},{\"col\":1,\"id\":\"Per-User-Dashboard-Instructions\",\"panelIndex\":9,\"row\":1,\"size_x\":12,\"size_y\":2,\"type\":\"visualization\"},{\"col\":1,\"id\":\"Suspicious-IPs\",\"panelIndex\":10,\"row\":15,\"size_x\":6,\"size_y\":5,\"type\":\"visualization\"},{\"col\":7,\"id\":\"Suspicious-Device-Types\",\"panelIndex\":11,\"row\":15,\"size_x\":6,\"size_y\":5,\"type\":\"visualization\"},{\"col\":1,\"id\":\"Unsuccessful-Login-Map\",\"panelIndex\":12,\"row\":20,\"size_x\":12,\"size_y\":6,\"type\":\"visualization\"}]", + "optionsJSON": "{\"darkTheme\":false}", + "uiStateJSON": "{\"P-10\":{\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}},\"P-11\":{\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}},\"P-12\":{\"mapCenter\":[14.944784875088372,5.09765625]}}", + "version": 1, + "timeRestore": true, + "timeTo": "now", + "timeFrom": "now/d", + "refreshInterval": { + "display": "Off", + "pause": false, + "value": 0 + }, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"filter\":[{\"query\":{\"query_string\":{\"query\":\"*\",\"analyze_wildcard\":true}}}]}" + } + } + }, + { + "_id": "System-Wide-Login-Abuse", + "_type": "dashboard", + "_source": { + "title": "System-Wide Login Abuse", + "hits": 0, + "description": "", + "panelsJSON": "[{\"col\":1,\"id\":\"Unsuccessful-Login-Map\",\"panelIndex\":2,\"row\":11,\"size_x\":11,\"size_y\":5,\"type\":\"visualization\"},{\"col\":1,\"id\":\"Suspicious-Device-Types\",\"panelIndex\":3,\"row\":6,\"size_x\":6,\"size_y\":5,\"type\":\"visualization\"},{\"col\":1,\"id\":\"Suspicious-IPs\",\"panelIndex\":4,\"row\":1,\"size_x\":6,\"size_y\":5,\"type\":\"visualization\"},{\"col\":7,\"id\":\"Suspicious-slash-Compromised-Users\",\"panelIndex\":5,\"row\":1,\"size_x\":5,\"size_y\":5,\"type\":\"visualization\"},{\"id\":\"Successful-slash-Unsuccessful-Logins\",\"type\":\"visualization\",\"panelIndex\":6,\"size_x\":5,\"size_y\":5,\"col\":7,\"row\":6}]", + "optionsJSON": "{\"darkTheme\":false}", + "uiStateJSON": "{\"P-1\":{\"vis\":{\"legendOpen\":true}},\"P-2\":{\"mapCenter\":[14.944784875088372,6.328125]},\"P-3\":{\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}},\"P-4\":{\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}},\"P-5\":{\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}}}", + "version": 1, + "timeRestore": true, + "timeTo": "now", + "timeFrom": "now/d", + "refreshInterval": { + "display": "Off", + "pause": false, + "value": 0 + }, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"filter\":[{\"query\":{\"query_string\":{\"analyze_wildcard\":true,\"query\":\"*\"}}}]}" + } + } + }, + { + "_id": "Per-IP-Login-and-Abuse-Statistics", + "_type": "dashboard", + "_source": { + "title": "Per-IP Login and Abuse Statistics", + "hits": 0, + "description": "", + "panelsJSON": "[{\"col\":1,\"id\":\"Successful-slash-Unsuccessful-Logins\",\"panelIndex\":1,\"row\":4,\"size_x\":6,\"size_y\":3,\"type\":\"visualization\"},{\"col\":7,\"id\":\"Distinct-Count-of-Passwords\",\"panelIndex\":2,\"row\":4,\"size_x\":6,\"size_y\":3,\"type\":\"visualization\"},{\"col\":1,\"id\":\"Distinct-Count-of-Devices-for-Successful-Logins\",\"panelIndex\":5,\"row\":10,\"size_x\":6,\"size_y\":3,\"type\":\"visualization\"},{\"col\":7,\"id\":\"Distinct-Count-of-Devices-for-Unsuccessful-Logins\",\"panelIndex\":6,\"row\":10,\"size_x\":6,\"size_y\":3,\"type\":\"visualization\"},{\"col\":7,\"id\":\"Suspicious-Device-Types\",\"panelIndex\":11,\"row\":13,\"size_x\":6,\"size_y\":5,\"type\":\"visualization\"},{\"col\":1,\"id\":\"Per-IP-Dashboard-Instructions\",\"panelIndex\":13,\"row\":1,\"size_x\":12,\"size_y\":2,\"type\":\"visualization\"},{\"col\":1,\"id\":\"Distinct-Count-of-Successful-User-Logins-(Per-IP)\",\"panelIndex\":14,\"row\":7,\"size_x\":6,\"size_y\":3,\"type\":\"visualization\"},{\"col\":7,\"id\":\"Distinct-Count-of-Unsuccessful-User-Logins-(Per-IP)\",\"panelIndex\":15,\"row\":7,\"size_x\":6,\"size_y\":3,\"type\":\"visualization\"},{\"col\":9,\"id\":\"GeoIP-City-Name\",\"panelIndex\":16,\"row\":3,\"size_x\":4,\"size_y\":1,\"type\":\"visualization\"},{\"col\":1,\"id\":\"GeoIP-Country-Name\",\"panelIndex\":17,\"row\":3,\"size_x\":4,\"size_y\":1,\"type\":\"visualization\"},{\"col\":5,\"id\":\"GeoIP-Region-Name\",\"panelIndex\":18,\"row\":3,\"size_x\":4,\"size_y\":1,\"type\":\"visualization\"}]", + "optionsJSON": "{\"darkTheme\":false}", + "uiStateJSON": "{\"P-11\":{\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}}}", + "version": 1, + "timeRestore": true, + "timeTo": "now", + "timeFrom": "now/d", + "refreshInterval": { + "display": "Off", + "pause": false, + "value": 0 + }, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"filter\":[{\"query\":{\"query_string\":{\"analyze_wildcard\":true,\"query\":\"*\"}}}]}" + } + } + }, + { + "_id": "Unsuccessful-Login-Map", + "_type": "visualization", + "_source": { + "title": "Unsuccessful Login Map", + "visState": "{\"title\":\"Unsuccessful Login Map\",\"type\":\"tile_map\",\"params\":{\"mapType\":\"Scaled Circle Markers\",\"isDesaturated\":true,\"addTooltip\":true,\"heatMaxZoom\":16,\"heatMinOpacity\":0.1,\"heatRadius\":25,\"heatBlur\":15,\"heatNormalizeData\":true,\"legendPosition\":\"bottomright\",\"mapZoom\":2,\"mapCenter\":[15,5],\"wms\":{\"enabled\":false,\"url\":\"https://basemap.nationalmap.gov/arcgis/services/USGSTopo/MapServer/WMSServer\",\"options\":{\"version\":\"1.3.0\",\"layers\":\"0\",\"format\":\"image/png\",\"transparent\":true,\"attribution\":\"Maps provided by USGS\",\"styles\":\"\"}}},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}},{\"id\":\"2\",\"enabled\":true,\"type\":\"geohash_grid\",\"schema\":\"segment\",\"params\":{\"field\":\"geoip.location\",\"autoPrecision\":true,\"customLabel\":\"Unsuccessful Logins\"}}],\"listeners\":{}}", + "uiStateJSON": "{\"mapCenter\":[14.944784875088372,5.09765625]}", + "description": "", + "version": 1, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"index\":\"logstash-*\",\"query\":{\"query_string\":{\"query\":\"success: false\",\"analyze_wildcard\":true}},\"filter\":[]}" + } + } + }, + { + "_id": "Suspicious-IPs", + "_type": "visualization", + "_source": { + "title": "Suspicious IPs", + "visState": "{\"title\":\"Suspicious IPs\",\"type\":\"table\",\"params\":{\"perPage\":10,\"showPartialRows\":false,\"showMeticsAtAllLevels\":false,\"sort\":{\"columnIndex\":null,\"direction\":null},\"showTotal\":false,\"totalFunc\":\"sum\"},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{\"customLabel\":\"Count of Significant Terms\"}},{\"id\":\"2\",\"enabled\":true,\"type\":\"significant_terms\",\"schema\":\"bucket\",\"params\":{\"field\":\"remote.keyword\",\"size\":100,\"customLabel\":\"Suspicious IPs\"}}],\"listeners\":{}}", + "uiStateJSON": "{\n \"vis\": {\n \"params\": {\n \"sort\": {\n \"columnIndex\": null,\n \"direction\": null\n }\n }\n }\n}", + "description": "", + "version": 1, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"index\":\"logstash-*\",\"query\":{\"constant_score\":{\"filter\":{\"term\":{\"success\":false}}}},\"filter\":[]}" + } + } + }, + { + "_id": "Suspicious-slash-Compromised-Users", + "_type": "visualization", + "_source": { + "title": "Suspicious/Compromised Users", + "visState": "{\"title\":\"Suspicious/Compromised Users\",\"type\":\"table\",\"params\":{\"perPage\":10,\"showPartialRows\":false,\"showMeticsAtAllLevels\":false,\"sort\":{\"columnIndex\":null,\"direction\":null},\"showTotal\":false,\"totalFunc\":\"sum\"},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{\"customLabel\":\"Significant Terms\"}},{\"id\":\"2\",\"enabled\":true,\"type\":\"significant_terms\",\"schema\":\"bucket\",\"params\":{\"field\":\"login.keyword\",\"size\":100,\"customLabel\":\"Suspicious/Compromised Users\"}}],\"listeners\":{}}", + "uiStateJSON": "{\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}}", + "description": "", + "version": 1, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"index\":\"logstash-*\",\"query\":{\"constant_score\":{\"filter\":{\"term\":{\"success\":false}}}},\"filter\":[]}" + } + } + }, + { + "_id": "Suspicious-Device-Types", + "_type": "visualization", + "_source": { + "title": "Suspicious Device Types", + "visState": "{\"title\":\"Suspicious Device Types\",\"type\":\"table\",\"params\":{\"perPage\":6,\"showPartialRows\":false,\"showMeticsAtAllLevels\":false,\"sort\":{\"columnIndex\":null,\"direction\":null},\"showTotal\":false,\"totalFunc\":\"sum\"},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{\"customLabel\":\"Significant Terms\"}},{\"id\":\"2\",\"enabled\":true,\"type\":\"significant_terms\",\"schema\":\"bucket\",\"params\":{\"field\":\"device_id.keyword\",\"size\":10,\"customLabel\":\"Suspicious Device Types\"}}],\"listeners\":{}}", + "uiStateJSON": "{\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}}", + "description": "", + "version": 1, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"index\":\"logstash-*\",\"query\":{\"constant_score\":{\"filter\":{\"term\":{\"success\":false}}}},\"filter\":[]}" + } + } + }, + { + "_id": "Distinct-Count-of-IPs-for-Successful-Logins", + "_type": "visualization", + "_source": { + "title": "Distinct Count of IPs for Successful Logins", + "visState": "{\"title\":\"Distinct Count of IPs for Successful Logins\",\"type\":\"histogram\",\"params\":{\"shareYAxis\":true,\"addTooltip\":true,\"addLegend\":true,\"legendPosition\":\"right\",\"scale\":\"linear\",\"mode\":\"stacked\",\"times\":[],\"addTimeMarker\":false,\"defaultYExtents\":false,\"setYExtents\":false,\"yAxis\":{}},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"cardinality\",\"schema\":\"metric\",\"params\":{\"field\":\"remote.keyword\",\"customLabel\":\"Distinct Count of IPs\"}},{\"id\":\"2\",\"enabled\":true,\"type\":\"date_histogram\",\"schema\":\"segment\",\"params\":{\"field\":\"@timestamp\",\"interval\":\"auto\",\"customInterval\":\"2h\",\"min_doc_count\":1,\"extended_bounds\":{}}},{\"id\":\"3\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"group\",\"params\":{\"field\":\"remote.keyword\",\"include\":{\"pattern\":\"\"},\"size\":100,\"order\":\"desc\",\"orderBy\":\"_term\"}}],\"listeners\":{}}", + "uiStateJSON": "{}", + "description": "", + "version": 1, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"index\":\"logstash-*\",\"query\":{\"query_string\":{\"query\":\"success: true\",\"analyze_wildcard\":true}},\"filter\":[]}" + } + } + }, + { + "_id": "Distinct-Count-of-IPs-for-Unsuccessful-Logins", + "_type": "visualization", + "_source": { + "title": "Distinct Count of IPs for Unsuccessful Logins", + "visState": "{\"title\":\"Distinct Count of IPs for Unsuccessful Logins\",\"type\":\"histogram\",\"params\":{\"shareYAxis\":true,\"addTooltip\":true,\"addLegend\":true,\"legendPosition\":\"right\",\"scale\":\"linear\",\"mode\":\"stacked\",\"times\":[],\"addTimeMarker\":false,\"defaultYExtents\":false,\"setYExtents\":false,\"yAxis\":{}},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"cardinality\",\"schema\":\"metric\",\"params\":{\"field\":\"remote.keyword\",\"customLabel\":\"Distinct Count of IPs\"}},{\"id\":\"2\",\"enabled\":true,\"type\":\"date_histogram\",\"schema\":\"segment\",\"params\":{\"field\":\"@timestamp\",\"interval\":\"auto\",\"customInterval\":\"2h\",\"min_doc_count\":1,\"extended_bounds\":{}}},{\"id\":\"3\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"group\",\"params\":{\"field\":\"remote.keyword\",\"include\":{\"pattern\":\"\"},\"size\":100,\"order\":\"desc\",\"orderBy\":\"_term\"}}],\"listeners\":{}}", + "uiStateJSON": "{}", + "description": "", + "version": 1, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"index\":\"logstash-*\",\"query\":{\"query_string\":{\"query\":\"success: false\",\"analyze_wildcard\":true}},\"filter\":[]}" + } + } + }, + { + "_id": "Protocol-Used-over-Time-(Successful-Logins)", + "_type": "visualization", + "_source": { + "title": "Protocol Used over Time (Successful Logins)", + "visState": "{\"title\":\"Protocol Used over Time (Successful Logins)\",\"type\":\"histogram\",\"params\":{\"shareYAxis\":true,\"addTooltip\":true,\"addLegend\":true,\"legendPosition\":\"bottom\",\"scale\":\"linear\",\"mode\":\"stacked\",\"times\":[],\"addTimeMarker\":false,\"defaultYExtents\":false,\"setYExtents\":false,\"yAxis\":{}},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{\"customLabel\":\"Total Logins\"}},{\"id\":\"2\",\"enabled\":true,\"type\":\"date_histogram\",\"schema\":\"segment\",\"params\":{\"field\":\"@timestamp\",\"interval\":\"auto\",\"customInterval\":\"2h\",\"min_doc_count\":1,\"extended_bounds\":{}}},{\"id\":\"3\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"group\",\"params\":{\"field\":\"protocol.keyword\",\"size\":10,\"order\":\"desc\",\"orderBy\":\"1\",\"customLabel\":\"Login Protocol\"}}],\"listeners\":{}}", + "uiStateJSON": "{}", + "description": "", + "version": 1, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"index\":\"logstash-*\",\"query\":{\"query_string\":{\"query\":\"success: true\",\"analyze_wildcard\":true}},\"filter\":[]}" + } + } + }, + { + "_id": "Successful-slash-Unsuccessful-Logins", + "_type": "visualization", + "_source": { + "title": "Successful/Unsuccessful Logins", + "visState": "{\"aggs\":[{\"enabled\":true,\"id\":\"1\",\"params\":{},\"schema\":\"metric\",\"type\":\"count\"},{\"enabled\":true,\"id\":\"2\",\"params\":{\"customInterval\":\"2h\",\"extended_bounds\":{},\"field\":\"@timestamp\",\"interval\":\"auto\",\"min_doc_count\":1},\"schema\":\"segment\",\"type\":\"date_histogram\"},{\"enabled\":true,\"id\":\"3\",\"params\":{\"filters\":[{\"input\":{\"query\":{\"query_string\":{\"analyze_wildcard\":true,\"query\":\"success: true\"}}},\"label\":\"\"},{\"input\":{\"query\":{\"query_string\":{\"analyze_wildcard\":true,\"query\":\"success: false\"}}}}]},\"schema\":\"group\",\"type\":\"filters\"}],\"listeners\":{},\"params\":{\"addLegend\":true,\"addTimeMarker\":false,\"addTooltip\":true,\"defaultYExtents\":false,\"interpolate\":\"linear\",\"legendPosition\":\"top\",\"mode\":\"stacked\",\"scale\":\"linear\",\"setYExtents\":false,\"shareYAxis\":true,\"smoothLines\":false,\"times\":[],\"yAxis\":{}},\"title\":\"Successful/Unsuccessful Logins\",\"type\":\"area\"}", + "uiStateJSON": "{}", + "description": "", + "version": 1, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"index\":\"logstash-*\",\"query\":{\"query_string\":{\"analyze_wildcard\":true,\"query\":\"*\"}},\"filter\":[]}" + } + } + }, + { + "_id": "Protocol-Used-over-Time", + "_type": "visualization", + "_source": { + "title": "Protocol Used over Time", + "visState": "{\"title\":\"Protocol Used over Time\",\"type\":\"histogram\",\"params\":{\"shareYAxis\":true,\"addTooltip\":true,\"addLegend\":true,\"legendPosition\":\"bottom\",\"scale\":\"linear\",\"mode\":\"stacked\",\"times\":[],\"addTimeMarker\":false,\"defaultYExtents\":false,\"setYExtents\":false,\"yAxis\":{}},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{\"customLabel\":\"Total Logins\"}},{\"id\":\"2\",\"enabled\":true,\"type\":\"date_histogram\",\"schema\":\"segment\",\"params\":{\"field\":\"@timestamp\",\"interval\":\"auto\",\"customInterval\":\"2h\",\"min_doc_count\":1,\"extended_bounds\":{}}},{\"id\":\"3\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"group\",\"params\":{\"field\":\"protocol.keyword\",\"size\":10,\"order\":\"desc\",\"orderBy\":\"1\",\"customLabel\":\"Login Protocol\"}}],\"listeners\":{}}", + "uiStateJSON": "{}", + "description": "", + "version": 1, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"index\":\"logstash-*\",\"query\":{\"query_string\":{\"query\":\"*\",\"analyze_wildcard\":true}},\"filter\":[]}" + } + } + }, + { + "_id": "Protocol-Used-over-Time-(Unsuccessful-Logins)", + "_type": "visualization", + "_source": { + "title": "Protocol Used over Time (Unsuccessful Logins)", + "visState": "{\"title\":\"Protocol Used over Time (Unsuccessful Logins)\",\"type\":\"histogram\",\"params\":{\"shareYAxis\":true,\"addTooltip\":true,\"addLegend\":true,\"legendPosition\":\"bottom\",\"scale\":\"linear\",\"mode\":\"stacked\",\"times\":[],\"addTimeMarker\":false,\"defaultYExtents\":false,\"setYExtents\":false,\"yAxis\":{}},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{\"customLabel\":\"Total Logins\"}},{\"id\":\"2\",\"enabled\":true,\"type\":\"date_histogram\",\"schema\":\"segment\",\"params\":{\"field\":\"@timestamp\",\"interval\":\"auto\",\"customInterval\":\"2h\",\"min_doc_count\":1,\"extended_bounds\":{}}},{\"id\":\"3\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"group\",\"params\":{\"field\":\"protocol.keyword\",\"size\":10,\"order\":\"desc\",\"orderBy\":\"1\",\"customLabel\":\"Login Protocol\"}}],\"listeners\":{}}", + "uiStateJSON": "{}", + "description": "", + "version": 1, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"index\":\"logstash-*\",\"query\":{\"query_string\":{\"query\":\"success: false\",\"analyze_wildcard\":true}},\"filter\":[]}" + } + } + }, + { + "_id": "Distinct-Count-of-Passwords", + "_type": "visualization", + "_source": { + "title": "Distinct Count of Passwords", + "visState": "{\"title\":\"Distinct Count of Passwords\",\"type\":\"histogram\",\"params\":{\"addLegend\":true,\"addTimeMarker\":false,\"addTooltip\":true,\"defaultYExtents\":false,\"legendPosition\":\"top\",\"mode\":\"stacked\",\"scale\":\"linear\",\"setYExtents\":false,\"shareYAxis\":true,\"times\":[],\"yAxis\":{\"min\":1,\"max\":4096}},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"cardinality\",\"schema\":\"metric\",\"params\":{\"field\":\"pwhash.keyword\",\"customLabel\":\"Distinct Count of Passwords\"}},{\"id\":\"2\",\"enabled\":true,\"type\":\"date_histogram\",\"schema\":\"segment\",\"params\":{\"field\":\"@timestamp\",\"interval\":\"auto\",\"customInterval\":\"2h\",\"min_doc_count\":1,\"extended_bounds\":{}}}],\"listeners\":{}}", + "uiStateJSON": "{}", + "description": "", + "version": 1, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"index\":\"logstash-*\",\"query\":{\"query_string\":{\"query\":\"*\",\"analyze_wildcard\":true}},\"filter\":[]}" + } + } + }, + { + "_id": "Login-Country-over-Time-(Successful-Logins)", + "_type": "visualization", + "_source": { + "title": "Login Country over Time (Successful Logins)", + "visState": "{\"title\":\"Login Country over Time (Successful Logins)\",\"type\":\"histogram\",\"params\":{\"shareYAxis\":true,\"addTooltip\":true,\"addLegend\":true,\"legendPosition\":\"right\",\"scale\":\"linear\",\"mode\":\"stacked\",\"times\":[],\"addTimeMarker\":false,\"defaultYExtents\":false,\"setYExtents\":false,\"yAxis\":{}},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{\"customLabel\":\"Login Country (GeoIP)\"}},{\"id\":\"2\",\"enabled\":true,\"type\":\"date_histogram\",\"schema\":\"segment\",\"params\":{\"field\":\"@timestamp\",\"interval\":\"auto\",\"customInterval\":\"2h\",\"min_doc_count\":1,\"extended_bounds\":{}}},{\"id\":\"3\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"group\",\"params\":{\"field\":\"geoip.country_code2.keyword\",\"size\":10,\"order\":\"desc\",\"orderBy\":\"1\",\"customLabel\":\"Login Country (GeoIP)\"}}],\"listeners\":{}}", + "uiStateJSON": "{}", + "description": "", + "version": 1, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"index\":\"logstash-*\",\"query\":{\"query_string\":{\"query\":\"success: true\",\"analyze_wildcard\":true}},\"filter\":[]}" + } + } + }, + { + "_id": "Login-Country-over-Time-(Unsuccessful-Logins)", + "_type": "visualization", + "_source": { + "title": "Login Country over Time (Unsuccessful Logins)", + "visState": "{\"title\":\"Login Country over Time (Unsuccessful Logins)\",\"type\":\"histogram\",\"params\":{\"shareYAxis\":true,\"addTooltip\":true,\"addLegend\":true,\"legendPosition\":\"right\",\"scale\":\"linear\",\"mode\":\"stacked\",\"times\":[],\"addTimeMarker\":false,\"defaultYExtents\":false,\"setYExtents\":false,\"yAxis\":{}},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{\"customLabel\":\"Login Country (GeoIP)\"}},{\"id\":\"2\",\"enabled\":true,\"type\":\"date_histogram\",\"schema\":\"segment\",\"params\":{\"field\":\"@timestamp\",\"interval\":\"auto\",\"customInterval\":\"2h\",\"min_doc_count\":1,\"extended_bounds\":{}}},{\"id\":\"3\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"group\",\"params\":{\"field\":\"geoip.country_code2.keyword\",\"size\":10,\"order\":\"desc\",\"orderBy\":\"1\",\"customLabel\":\"Login Country (GeoIP)\"}}],\"listeners\":{}}", + "uiStateJSON": "{}", + "description": "", + "version": 1, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"index\":\"logstash-*\",\"query\":{\"query_string\":{\"query\":\"success: false\",\"analyze_wildcard\":true}},\"filter\":[]}" + } + } + }, + { + "_id": "Per-User-Dashboard-Instructions", + "_type": "visualization", + "_source": { + "title": "Per-User Dashboard Instructions", + "visState": "{\"title\":\"Per-User Dashboard Instructions\",\"type\":\"markdown\",\"params\":{\"markdown\":\"Type a username into the search box above to view stats for that user, for example:\\n* frank.black@domain,com\\n* frank.black\\n* login: frank.black@domain.com\\n\\nIf you do not type in a username, you will see system-wide stats, which are not very useful.\"},\"aggs\":[],\"listeners\":{}}", + "uiStateJSON": "{}", + "description": "", + "version": 1, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"query\":{\"query_string\":{\"analyze_wildcard\":true,\"query\":\"*\"}},\"filter\":[]}" + } + } + }, + { + "_id": "Distinct-Count-of-Devices-for-Unsuccessful-Logins", + "_type": "visualization", + "_source": { + "title": "Distinct Count of Devices for Unsuccessful Logins", + "visState": "{\"title\":\"Distinct Count of Devices for Unsuccessful Logins\",\"type\":\"histogram\",\"params\":{\"addLegend\":true,\"addTimeMarker\":false,\"addTooltip\":true,\"defaultYExtents\":false,\"legendPosition\":\"right\",\"mode\":\"stacked\",\"scale\":\"linear\",\"setYExtents\":false,\"shareYAxis\":true,\"times\":[],\"yAxis\":{}},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"cardinality\",\"schema\":\"metric\",\"params\":{\"field\":\"remote.keyword\",\"customLabel\":\"Distinct Count of Devices\"}},{\"id\":\"2\",\"enabled\":true,\"type\":\"date_histogram\",\"schema\":\"segment\",\"params\":{\"field\":\"@timestamp\",\"interval\":\"auto\",\"customInterval\":\"2h\",\"min_doc_count\":1,\"extended_bounds\":{}}},{\"id\":\"3\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"group\",\"params\":{\"field\":\"device_id.keyword\",\"include\":{\"pattern\":\"\"},\"size\":25,\"order\":\"desc\",\"orderBy\":\"_term\"}}],\"listeners\":{}}", + "uiStateJSON": "{}", + "description": "", + "version": 1, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"index\":\"logstash-*\",\"query\":{\"query_string\":{\"analyze_wildcard\":true,\"query\":\"success: false\"}},\"filter\":[]}" + } + } + }, + { + "_id": "Distinct-Count-of-Devices-for-Successful-Logins", + "_type": "visualization", + "_source": { + "title": "Distinct Count of Devices for Successful Logins", + "visState": "{\"title\":\"Distinct Count of Devices for Successful Logins\",\"type\":\"histogram\",\"params\":{\"shareYAxis\":true,\"addTooltip\":true,\"addLegend\":true,\"legendPosition\":\"right\",\"scale\":\"linear\",\"mode\":\"stacked\",\"times\":[],\"addTimeMarker\":false,\"defaultYExtents\":false,\"setYExtents\":false,\"yAxis\":{}},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"cardinality\",\"schema\":\"metric\",\"params\":{\"field\":\"remote.keyword\",\"customLabel\":\"Distinct Count of Devices\"}},{\"id\":\"2\",\"enabled\":true,\"type\":\"date_histogram\",\"schema\":\"segment\",\"params\":{\"field\":\"@timestamp\",\"interval\":\"auto\",\"customInterval\":\"2h\",\"min_doc_count\":1,\"extended_bounds\":{}}},{\"id\":\"3\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"group\",\"params\":{\"field\":\"device_id.keyword\",\"include\":{\"pattern\":\"\"},\"size\":25,\"order\":\"desc\",\"orderBy\":\"_term\"}}],\"listeners\":{}}", + "uiStateJSON": "{}", + "description": "", + "version": 1, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"index\":\"logstash-*\",\"query\":{\"query_string\":{\"query\":\"success: true\",\"analyze_wildcard\":true}},\"filter\":[]}" + } + } + }, + { + "_id": "Per-IP-Dashboard-Instructions", + "_type": "visualization", + "_source": { + "title": "Per-IP Dashboard Instructions", + "visState": "{\"title\":\"Per-IP Dashboard Instructions\",\"type\":\"markdown\",\"params\":{\"markdown\":\"Type an IP address into the search box above to view stats for that IP, for example:\\n* 212.33.12.81\\n* 2001:0db8:85a3:0000:0000:8a2e:0370:7334\\n* remote: 212.33.12.81\\n\\nIf you do not type in an IP address, you will see system-wide stats, which are not very useful.\"},\"aggs\":[],\"listeners\":{}}", + "uiStateJSON": "{}", + "description": "", + "version": 1, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"query\":{\"query_string\":{\"analyze_wildcard\":true,\"query\":\"*\"}},\"filter\":[]}" + } + } + }, + { + "_id": "GeoIP-City-Name", + "_type": "visualization", + "_source": { + "title": "GeoIP City Name", + "visState": "{\"title\":\"GeoIP City Name\",\"type\":\"tagcloud\",\"params\":{\"scale\":\"linear\",\"orientation\":\"single\",\"minFontSize\":12,\"maxFontSize\":24,\"hideLabel\":false},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}},{\"id\":\"2\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"segment\",\"params\":{\"field\":\"geoip.city_name.keyword\",\"size\":5,\"order\":\"desc\",\"orderBy\":\"_term\"}}],\"listeners\":{}}", + "uiStateJSON": "{}", + "description": "", + "version": 1, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"index\":\"logstash-*\",\"query\":{\"query_string\":{\"analyze_wildcard\":true,\"query\":\"*\"}},\"filter\":[]}" + } + } + }, + { + "_id": "GeoIP-Region-Name", + "_type": "visualization", + "_source": { + "title": "GeoIP Region Name", + "visState": "{\"title\":\"GeoIP Region Name\",\"type\":\"tagcloud\",\"params\":{\"scale\":\"linear\",\"orientation\":\"single\",\"minFontSize\":12,\"maxFontSize\":24},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}},{\"id\":\"2\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"segment\",\"params\":{\"field\":\"geoip.region_name.keyword\",\"size\":5,\"order\":\"desc\",\"orderBy\":\"_term\"}}],\"listeners\":{}}", + "uiStateJSON": "{}", + "description": "", + "version": 1, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"index\":\"logstash-*\",\"query\":{\"query_string\":{\"analyze_wildcard\":true,\"query\":\"*\"}},\"filter\":[]}" + } + } + }, + { + "_id": "GeoIP-Country-Name", + "_type": "visualization", + "_source": { + "title": "GeoIP Country Name", + "visState": "{\"title\":\"GeoIP Country Name\",\"type\":\"tagcloud\",\"params\":{\"scale\":\"linear\",\"orientation\":\"single\",\"minFontSize\":12,\"maxFontSize\":24},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}},{\"id\":\"2\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"segment\",\"params\":{\"field\":\"geoip.country_name.keyword\",\"size\":5,\"order\":\"desc\",\"orderBy\":\"_term\"}}],\"listeners\":{}}", + "uiStateJSON": "{}", + "description": "", + "version": 1, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"index\":\"logstash-*\",\"query\":{\"query_string\":{\"query\":\"*\",\"analyze_wildcard\":true}},\"filter\":[]}" + } + } + }, + { + "_id": "Distinct-Count-of-Successful-User-Logins-(Per-IP)", + "_type": "visualization", + "_source": { + "title": "Distinct Count of Successful User Logins (Per-IP)", + "visState": "{\"title\":\"Distinct Count of Successful User Logins (Per-IP)\",\"type\":\"histogram\",\"params\":{\"shareYAxis\":true,\"addTooltip\":true,\"addLegend\":true,\"legendPosition\":\"right\",\"scale\":\"linear\",\"mode\":\"stacked\",\"times\":[],\"addTimeMarker\":false,\"defaultYExtents\":false,\"setYExtents\":false,\"yAxis\":{}},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"cardinality\",\"schema\":\"metric\",\"params\":{\"field\":\"remote.keyword\",\"customLabel\":\"Distinct Count of Usernames\"}},{\"id\":\"2\",\"enabled\":true,\"type\":\"date_histogram\",\"schema\":\"segment\",\"params\":{\"field\":\"@timestamp\",\"interval\":\"auto\",\"customInterval\":\"2h\",\"min_doc_count\":1,\"extended_bounds\":{}}},{\"id\":\"3\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"group\",\"params\":{\"field\":\"login.keyword\",\"include\":{\"pattern\":\"\"},\"size\":100,\"order\":\"desc\",\"orderBy\":\"_term\"}}],\"listeners\":{}}", + "uiStateJSON": "{}", + "description": "", + "version": 1, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"index\":\"logstash-*\",\"query\":{\"query_string\":{\"query\":\"success: true\",\"analyze_wildcard\":true}},\"filter\":[]}" + } + } + }, + { + "_id": "Distinct-Count-of-Unsuccessful-User-Logins-(Per-IP)", + "_type": "visualization", + "_source": { + "title": "Distinct Count of Unsuccessful User Logins (Per-IP)", + "visState": "{\"title\":\"Distinct Count of Unsuccessful User Logins (Per-IP)\",\"type\":\"histogram\",\"params\":{\"shareYAxis\":true,\"addTooltip\":true,\"addLegend\":true,\"legendPosition\":\"right\",\"scale\":\"linear\",\"mode\":\"stacked\",\"times\":[],\"addTimeMarker\":false,\"defaultYExtents\":false,\"setYExtents\":false,\"yAxis\":{}},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"cardinality\",\"schema\":\"metric\",\"params\":{\"field\":\"remote.keyword\",\"customLabel\":\"Distinct Count of Usernames\"}},{\"id\":\"2\",\"enabled\":true,\"type\":\"date_histogram\",\"schema\":\"segment\",\"params\":{\"field\":\"@timestamp\",\"interval\":\"auto\",\"customInterval\":\"2h\",\"min_doc_count\":1,\"extended_bounds\":{}}},{\"id\":\"3\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"group\",\"params\":{\"field\":\"login.keyword\",\"include\":{\"pattern\":\"\"},\"size\":100,\"order\":\"desc\",\"orderBy\":\"_term\"}}],\"listeners\":{}}", + "uiStateJSON": "{}", + "description": "", + "version": 1, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"index\":\"logstash-*\",\"query\":{\"query_string\":{\"query\":\"success: false\",\"analyze_wildcard\":true}},\"filter\":[]}" + } + } + } +] diff --git a/docker/logstash/Dockerfile b/docker/logstash/Dockerfile new file mode 100644 index 00000000..a1ed59fb --- /dev/null +++ b/docker/logstash/Dockerfile @@ -0,0 +1,9 @@ +FROM logstash:5 + +RUN wget http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.mmdb.gz +RUN gunzip GeoLite2-City.mmdb.gz +RUN mv GeoLite2-City.mmdb /etc/logstash/GeoLiteCity.dat + +RUN logstash-plugin install logstash-input-udp +RUN logstash-plugin install logstash-output-elasticsearch +RUN logstash-plugin install logstash-filter-geoip diff --git a/docker/logstash/config/logstash.conf b/docker/logstash/config/logstash.conf new file mode 100644 index 00000000..f29380c9 --- /dev/null +++ b/docker/logstash/config/logstash.conf @@ -0,0 +1,19 @@ +input { + udp { + port => 4501 + codec => json + type => wforce_report + } +} +filter { + geoip { + database => "/etc/logstash/geoip/GeoLite2-City.mmdb" + source => "remote" + } + } +output { + elasticsearch { + hosts => "elasticsearch:9200" + index => "logstash-wforce-%{+YYYY.MM.dd}" + } +} diff --git a/docker/logstash/geoip/.gitignore b/docker/logstash/geoip/.gitignore new file mode 100644 index 00000000..084c1456 --- /dev/null +++ b/docker/logstash/geoip/.gitignore @@ -0,0 +1,2 @@ +# Ignore GeoIP files +/*mmdb*