apiVersion: influxdata.com/v2alpha1 kind: Label metadata: name: endpoint-security-state spec: name: Endpoint Security State color: '#7A65F2' --- apiVersion: influxdata.com/v2alpha1 kind: Label metadata: name: telegraf spec: color: '#C9D0FF' name: Telegraf --- apiVersion: influxdata.com/v2alpha1 kind: Label metadata: name: outputs-influxdb-v2 spec: color: '#108174' name: outputs.influxdb_v2 --- apiVersion: influxdata.com/v2alpha1 kind: Label metadata: name: security spec: color: '#F95F53' name: security --- apiVersion: influxdata.com/v2alpha1 kind: Label metadata: name: solution spec: color: '#FFD255' name: Solution --- apiVersion: influxdata.com/v2alpha1 kind: Dashboard metadata: name: endpoint-security-state spec: associations: - kind: Label name: telegraf - kind: Label name: outputs-influxdb-v2 - kind: Label name: security - kind: Label name: solution charts: - colors: - hex: '#ffffff' name: white type: text fieldOptions: - displayName: Endpoint fieldName: Endpoint visible: true - displayName: AuthenticationOn fieldName: AuthenticationOn visible: true - displayName: AuthenticationWorks fieldName: AuthenticationWorks visible: true - displayName: Available fieldName: Available visible: true - displayName: Certificate fieldName: Certificate visible: true height: 4 kind: Table name: Endpoints State queries: - query: |- from(bucket: v.bucket) |> range(start: v.timeRangeStart, stop: v.timeRangeStop) |> filter(fn: (r) => ( r._measurement == "http_response" and r._field == "http_response_code" ) or ( r._measurement == "x509_cert" and r._field == "expiry" and exists r.san and exists r.common_name ) ) |> drop(columns: ["method","result","_field","common_name","issuer_common_name","organizational_unit","public_key_algorithm","san","serial_number","signature_algorithm","country","locality","province","organization","verification","server","source"]) |> map(fn: (r) => ({ r with authon: 0, authwork: 0, available: 0, expires: 0})) |> group(columns: ["_start","_stop","_time","Endpoint"]) |> map(fn: (r) => ({ r with available: if ( r._measurement == "http_response" and exists r.status_code ) and ( ( r._value >= 400 and r._value < 500 ) or ( r._value == 200 ) ) then r.available + 1 else r.available + 0, authon: if ( r._measurement == "http_response" and exists r.status_code ) and ( ( r._value >= 400 and r._value < 500 ) or ( r._value == 200 ) ) then r.authon + 1 else r.authon + 0, authwork: if ( r._measurement == "http_response" and exists r.status_code ) and r._value == 200 then r.authwork + 1 else r.authwork + 0, expires: if ( r._measurement == "x509_cert" ) then r._value / 86400 else 0 })) |> group(columns: ["Endpoint"]) |> drop(columns: ["_time","_start","_stop","_measurement","status_code","_value"]) |> reduce( identity: {aosum: 0, awsum: 0, avsum: 0, exsum: 0}, fn: (r, accumulator) => ({ aosum: r.authon + accumulator.aosum, awsum: r.authwork + accumulator.awsum, avsum: r.available + accumulator.avsum, exsum: r.expires + accumulator.exsum }) ) |> map(fn: (r) => ({ r with AuthenticationOn: if r.aosum >= 1 then "โ " else "๐ด", AuthenticationWorks: if r.awsum >= 1 then "โ " else "๐ด", Available: if r.avsum >= 1 then "โ " else "๐ด", Certificate: if r.exsum > 30 then "โ " else if r.exsum > 2 then "๐ก" else if r.exsum > 0 then "๐ด" else "โ" })) |> drop(columns: ["aosum","avsum","awsum","exsum"]) |> group() tableOptions: sortBy: Endpoint verticalTimeAxis: true timeFormat: YYYY/MM/DD HH:mm:ss width: 12 name: Endpoint Security State --- apiVersion: influxdata.com/v2alpha1 kind: Variable metadata: name: bucket spec: name: bucket associations: - kind: Label name: endpoint-security-state language: flux query: |- buckets() |> filter(fn: (r) => r.name !~ /^_/) |> rename(columns: {name: "_value"}) |> keep(columns: ["_value"]) type: query --- apiVersion: influxdata.com/v2alpha1 kind: Telegraf metadata: name: endpoint-security-state-checks spec: name: Endpoint Security State associations: - kind: Label name: endpoint-security-state config: | [agent] ## Default data collection interval for all inputs interval = "12h" ## Rounds collection interval to 'interval' ## ie, if interval="10s" then always collect on :00, :10, :20, etc. round_interval = false ## Telegraf will send metrics to outputs in batches of at most ## metric_batch_size metrics. ## This controls the size of writes that Telegraf sends to output plugins. metric_batch_size = 10 ## For failed writes, telegraf will cache metric_buffer_limit metrics for each ## output, and will flush this buffer on a successful write. Oldest metrics ## are dropped first when this buffer fills. ## This buffer only fills when writes fail to output plugin(s). metric_buffer_limit = 100 ## Collection jitter is used to jitter the collection by a random amount. ## Each plugin will sleep for a random time within jitter before collecting. ## This can be used to avoid many plugins querying things like sysfs at the ## same time, which can have a measurable effect on the system. collection_jitter = "0s" ## Default flushing interval for all outputs. Maximum flush_interval will be ## flush_interval + flush_jitter flush_interval = "10s" ## Jitter the flush interval by a random amount. This is primarily to avoid ## large write spikes for users running a large number of telegraf instances. ## ie, a jitter of 5s and interval 10s means flushes will happen every 10-15s flush_jitter = "0s" ## By default or when set to "0s", precision will be set to the same ## timestamp order as the collection interval, with the maximum being 1s. ## ie, when interval = "10s", precision will be "1s" ## when interval = "250ms", precision will be "1ms" ## Precision will NOT be used for service inputs. It is up to each individual ## service input to set the timestamp at the appropriate precision. ## Valid time units are "ns", "us" (or "ยตs"), "ms", "s". precision = "" ## Logging configuration: ## Run telegraf with debug log messages. debug = false ## Run telegraf in quiet mode (error log messages only). quiet = false ## Specify the log file name. The empty string means to log to stderr. logfile = "" ## Override default hostname, if empty use os.Hostname() hostname = "" ## If set to true, do no set the "host" tag in the telegraf agent. omit_hostname = true [[outputs.influxdb_v2]] ## The URLs of the InfluxDB cluster nodes. ## ## Multiple URLs can be specified for a single cluster, only ONE of the ## urls will be written to each interval. ## urls exp: http://127.0.0.1:9999 urls = ["$INFLUX_HOST"] ## Token for authentication. token = "$INFLUX_TOKEN" ## Organization is the name of the organization you wish to write to; must exist. organization = "$INFLUX_ORG" ## Destination bucket to write into. bucket = "telegraf" ############################################################################### # INPUT PLUGINS # ############################################################################### # # We must include the port for all of the URLs ( urls[] and sources[] ) below. # x509_cert requires this and we need the URLs ( endpoints ) to match for # display correlation # [[inputs.x509_cert]] sources = [ "https://test.example.com:443/" ] [[inputs.http_response]] urls = [ "https://test.example.com:443/" ] [[inputs.http_response]] urls = [ "https://test.example.com:443/" ] username = "testuser" password = "testpassword" ############################################################################### # PROCESSOR PLUGINS # ############################################################################### [[processors.regex]] [[processors.regex.tags]] key = "source" pattern = "^(.*)$" replacement = "${1}" result_key = "Endpoint" [[processors.regex.tags]] key = "server" pattern = "^(.*)$" replacement = "${1}" result_key = "Endpoint"