-
Notifications
You must be signed in to change notification settings - Fork 706
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #399 from breed808/adfs
Add adfs collector
- Loading branch information
Showing
4 changed files
with
243 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,190 @@ | ||
// +build windows | ||
|
||
package collector | ||
|
||
import ( | ||
"github.com/prometheus/client_golang/prometheus" | ||
) | ||
|
||
func init() { | ||
Factories["adfs"] = newADFSCollector | ||
} | ||
|
||
type adfsCollector struct { | ||
adLoginConnectionFailures *prometheus.Desc | ||
certificateAuthentications *prometheus.Desc | ||
deviceAuthentications *prometheus.Desc | ||
extranetAccountLockouts *prometheus.Desc | ||
federatedAuthentications *prometheus.Desc | ||
passportAuthentications *prometheus.Desc | ||
passiveRequests *prometheus.Desc | ||
passwordChangeFailed *prometheus.Desc | ||
passwordChangeSucceeded *prometheus.Desc | ||
tokenRequests *prometheus.Desc | ||
windowsIntegratedAuthentications *prometheus.Desc | ||
} | ||
|
||
// newADFSCollector constructs a new adfsCollector | ||
func newADFSCollector() (Collector, error) { | ||
const subsystem = "adfs" | ||
|
||
return &adfsCollector{ | ||
adLoginConnectionFailures: prometheus.NewDesc( | ||
prometheus.BuildFQName(Namespace, subsystem, "ad_login_connection_failures"), | ||
"Total number of connection failures to an Active Directory domain controller", | ||
nil, | ||
nil, | ||
), | ||
certificateAuthentications: prometheus.NewDesc( | ||
prometheus.BuildFQName(Namespace, subsystem, "certificate_authentications"), | ||
"Total number of User Certificate authentications", | ||
nil, | ||
nil, | ||
), | ||
deviceAuthentications: prometheus.NewDesc( | ||
prometheus.BuildFQName(Namespace, subsystem, "device_authentications"), | ||
"Total number of Device authentications", | ||
nil, | ||
nil, | ||
), | ||
extranetAccountLockouts: prometheus.NewDesc( | ||
prometheus.BuildFQName(Namespace, subsystem, "extranet_account_lockouts"), | ||
"Total number of Extranet Account Lockouts", | ||
nil, | ||
nil, | ||
), | ||
federatedAuthentications: prometheus.NewDesc( | ||
prometheus.BuildFQName(Namespace, subsystem, "federated_authentications"), | ||
"Total number of authentications from a federated source", | ||
nil, | ||
nil, | ||
), | ||
passportAuthentications: prometheus.NewDesc( | ||
prometheus.BuildFQName(Namespace, subsystem, "passport_authentications"), | ||
"Total number of Microsoft Passport SSO authentications", | ||
nil, | ||
nil, | ||
), | ||
passiveRequests: prometheus.NewDesc( | ||
prometheus.BuildFQName(Namespace, subsystem, "passive_requests"), | ||
"Total number of passive (browser-based) requests", | ||
nil, | ||
nil, | ||
), | ||
passwordChangeFailed: prometheus.NewDesc( | ||
prometheus.BuildFQName(Namespace, subsystem, "password_change_failed"), | ||
"Total number of failed password changes", | ||
nil, | ||
nil, | ||
), | ||
passwordChangeSucceeded: prometheus.NewDesc( | ||
prometheus.BuildFQName(Namespace, subsystem, "password_change_succeeded"), | ||
"Total number of successful password changes", | ||
nil, | ||
nil, | ||
), | ||
tokenRequests: prometheus.NewDesc( | ||
prometheus.BuildFQName(Namespace, subsystem, "token_requests"), | ||
"Total number of token requests", | ||
nil, | ||
nil, | ||
), | ||
windowsIntegratedAuthentications: prometheus.NewDesc( | ||
prometheus.BuildFQName(Namespace, subsystem, "windows_integrated_authentications"), | ||
"Total number of Windows integrated authentications (Kerberos/NTLM)", | ||
nil, | ||
nil, | ||
), | ||
}, nil | ||
} | ||
|
||
type perflibADFS struct { | ||
AdLoginConnectionFailures float64 `perflib:"AD login Connection Failures"` | ||
CertificateAuthentications float64 `perflib:"Certificate Authentications"` | ||
DeviceAuthentications float64 `perflib:"Device Authentications"` | ||
ExtranetAccountLockouts float64 `perflib:"Extranet Account Lockouts"` | ||
FederatedAuthentications float64 `perflib:"Federated Authentications"` | ||
PassportAuthentications float64 `perflib:"Microsoft Passport Authentications"` | ||
PassiveRequests float64 `perflib:"Passive Requests"` | ||
PasswordChangeFailed float64 `perflib:"Password Change Failed Requests"` | ||
PasswordChangeSucceeded float64 `perflib:"Password Change Successful Requests"` | ||
TokenRequests float64 `perflib:"Token Requests"` | ||
WindowsIntegratedAuthentications float64 `perflib:"Windows Integrated Authentications"` | ||
} | ||
|
||
func (c *adfsCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error { | ||
var adfsData []perflibADFS | ||
err := unmarshalObject(ctx.perfObjects["AD FS"], &adfsData) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
for _, adfs := range adfsData { | ||
ch <- prometheus.MustNewConstMetric( | ||
c.adLoginConnectionFailures, | ||
prometheus.CounterValue, | ||
adfs.AdLoginConnectionFailures, | ||
) | ||
|
||
ch <- prometheus.MustNewConstMetric( | ||
c.certificateAuthentications, | ||
prometheus.CounterValue, | ||
adfs.CertificateAuthentications, | ||
) | ||
|
||
ch <- prometheus.MustNewConstMetric( | ||
c.deviceAuthentications, | ||
prometheus.CounterValue, | ||
adfs.DeviceAuthentications, | ||
) | ||
|
||
ch <- prometheus.MustNewConstMetric( | ||
c.extranetAccountLockouts, | ||
prometheus.CounterValue, | ||
adfs.ExtranetAccountLockouts, | ||
) | ||
|
||
ch <- prometheus.MustNewConstMetric( | ||
c.federatedAuthentications, | ||
prometheus.CounterValue, | ||
adfs.FederatedAuthentications, | ||
) | ||
|
||
ch <- prometheus.MustNewConstMetric( | ||
c.passportAuthentications, | ||
prometheus.CounterValue, | ||
adfs.PassportAuthentications, | ||
) | ||
|
||
ch <- prometheus.MustNewConstMetric( | ||
c.passiveRequests, | ||
prometheus.CounterValue, | ||
adfs.PassiveRequests, | ||
) | ||
|
||
ch <- prometheus.MustNewConstMetric( | ||
c.passwordChangeFailed, | ||
prometheus.CounterValue, | ||
adfs.PasswordChangeFailed, | ||
) | ||
|
||
ch <- prometheus.MustNewConstMetric( | ||
c.passwordChangeSucceeded, | ||
prometheus.CounterValue, | ||
adfs.PasswordChangeSucceeded, | ||
) | ||
|
||
ch <- prometheus.MustNewConstMetric( | ||
c.tokenRequests, | ||
prometheus.CounterValue, | ||
adfs.TokenRequests, | ||
) | ||
|
||
ch <- prometheus.MustNewConstMetric( | ||
c.windowsIntegratedAuthentications, | ||
prometheus.CounterValue, | ||
adfs.WindowsIntegratedAuthentications, | ||
) | ||
} | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
# adfs collector | ||
|
||
The adfs collector exposes metrics about Active Directory Federation Services. Note that this collector has only been tested against ADFS 4.0 (2016). | ||
Other ADFS versions may work but are not tested. | ||
|
||
||| | ||
-|- | ||
Metric name prefix | `adfs` | ||
Data source | Perflib | ||
Counters | `AD FS` | ||
Enabled by default? | No | ||
|
||
## Flags | ||
|
||
None | ||
|
||
## Metrics | ||
|
||
Name | Description | Type | Labels | ||
-----|-------------|------|------- | ||
`wmi_adfs_ad_login_connection_failures` | Total number of connection failures between the ADFS server and the Active Directory domain controller(s) | counter | None | ||
`wmi_adfs_certificate_authentications` | Total number of [User Certificate](https://docs.microsoft.com/en-us/windows-server/identity/ad-fs/operations/configure-user-certificate-authentication) authentications. I.E. smart cards or mobile devices with provisioned client certificates | counter | None | ||
`wmi_adfs_device_authentications` | Total number of [device authentications](https://docs.microsoft.com/en-us/windows-server/identity/ad-fs/operations/device-authentication-controls-in-ad-fs) (SignedToken, clientTLS, PkeyAuth). Device authentication is only available on ADFS 2016 or later | counter | None | ||
`wmi_adfs_extranet_account_lockouts` | Total number of [extranet lockouts](https://docs.microsoft.com/en-us/windows-server/identity/ad-fs/operations/configure-ad-fs-extranet-smart-lockout-protection). Requires the Extranet Lockout feature to be enabled | counter | None | ||
`wmi_adfs_federated_authentications` | Total number of authentications from federated sources. E.G. Office365 | counter | None | ||
`wmi_adfs_passport_authentications` | Total number of authentications from [Microsoft Passport](https://en.wikipedia.org/wiki/Microsoft_account) (now named Microsoft Account) | counter | None | ||
`wmi_adfs_password_change_failed` | Total number of failed password changes. The Password Change Portal must be enabled in the AD FS Management tool in order to allow user password changes | counter | None | ||
`wmi_adfs_password_change_succeeded` | Total number of succeeded password changes. The Password Change Portal must be enabled in the AD FS Management tool in order to allow user password changes | counter | None | ||
`wmi_adfs_token_requests` | Total number of requested access tokens | counter | None | ||
`wmi_adfs_windows_integrated_authentications` | Total number of Windows integrated authentications using Kerberos or NTLM | counter | None | ||
|
||
### Example metric | ||
Show rate of device authentications in AD FS: | ||
``` | ||
rate(wmi_adfs_device_authentications)[2m] | ||
``` | ||
|
||
## Useful queries | ||
|
||
## Alerting examples | ||
**prometheus.rules** | ||
```yaml | ||
- alert: "HighExtranetLockouts" | ||
expr: "rate(wmi_adfs_extranet_account_lockouts)[2m] > 100" | ||
for: "10m" | ||
labels: | ||
severity: "high" | ||
annotations: | ||
summary: "High number of AD FS extranet lockouts" | ||
description: "High number of AD FS extranet lockouts may indicate a password spray attack.\n Server: {{ $labels.instance }}\n Number of lockouts: {{ $value }}" | ||
``` |