收集指纹日志
解析器版本:1.0
本文档介绍了如何配置 Fingerprint(以前称为 FingerprintJS),以使用 Webhook 将日志推送到 Google Security Operations。
Fingerprint 是一个设备智能平台,可提供访客身份识别和欺诈检测功能。它会生成唯一的访问者标识符,并提供智能信号,包括机器人检测、VPN 检测、无痕模式检测和其他设备智能数据洞见。当通过 FingerprintJS JavaScript 代理识别出访问者时,Webhook 可以实时将识别事件数据发送到 Google Security Operations。
准备工作
确保您满足以下前提条件:
- Google SecOps 实例
- 支持 Webhook 的 FingerprintJS 账号
- 对 Google Cloud Console 的访问权限(用于创建 API 密钥)
- 安装在您的网站或应用上的 FingerprintJS JavaScript 代理
在 Google SecOps 中创建 Webhook Feed
创建 Feed
- 依次前往 SIEM 设置 > Feed。
- 点击添加新 Feed。
- 在下一页上,点击配置单个 Feed。
- 在 Feed 名称字段中,输入 Feed 的名称(例如
FingerprintJS Identification Events)。 - 选择 Webhook 作为来源类型。
- 选择 FingerprintJS 作为日志类型。
- 点击下一步。
- 为以下输入参数指定值:
- 拆分分隔符(可选):留空。每个 Webhook 请求都包含一个识别事件。
- 资产命名空间:资产命名空间。
- 注入标签:要应用于此 Feed 中事件的标签。
- 点击下一步。
- 在最终确定界面中查看新的 Feed 配置,然后点击提交。
生成并保存密钥
创建 Feed 后,您必须生成用于身份验证的密钥:
- 在 Feed 详情页面上,点击生成密钥。
- 系统会显示一个对话框,其中包含密钥。
- 复制并妥善保存密钥。
重要提示:密钥只会显示一次,之后无法再检索。如果丢失,您必须生成新的密钥。
获取 Feed 端点网址
- 前往相应 Feed 的详细信息标签页。
- 在端点信息部分,复制 Feed 端点网址。
网址格式为:
https://malachiteingestion-pa.googleapis.com/v2/unstructuredlogentries:batchCreate或
https://<REGION>-malachiteingestion-pa.googleapis.com/v2/unstructuredlogentries:batchCreate保存此网址以供后续步骤使用。
点击完成。
创建 Google Cloud API 密钥
Chronicle 需要 API 密钥才能进行身份验证。在 Google Cloud Console 中创建受限 API 密钥。
创建 API 密钥
- 前往 Google Cloud 控制台的“凭据”页面。
- 选择您的项目(与您的 Chronicle 实例关联的项目)。
- 依次点击创建凭据> API 密钥。
- 系统会创建一个 API 密钥,并在对话框中显示该密钥。
- 点击修改 API 密钥以限制密钥。
限制 API 密钥
- 在 API 密钥设置页面中:
- 名称:输入一个描述性名称(例如
Chronicle FingerprintJS Webhook API Key)。
- 名称:输入一个描述性名称(例如
- 在 API 限制下:
- 选择限制密钥。
- 在选择 API 下拉菜单中,搜索并选择 Google SecOps API(或 Chronicle API)。
- 点击保存。
- 复制页面顶部 API 密钥字段中的 API 密钥值。
安全地保存 API 密钥。
配置 FingerprintJS Webhook
构建网络钩子网址
将 Chronicle 端点网址和 API 密钥组合在一起:
<ENDPOINT_URL>?key=<API_KEY>示例:
https://malachiteingestion-pa.googleapis.com/v2/unstructuredlogentries:batchCreate?key=AIzaSyD...
在 FingerprintJS 信息中心内创建 Webhook
- 登录 FingerprintJS 信息中心。
- 前往信息中心 > Webhook。
- 点击 Add webhook。
- 提供以下配置详细信息:
- 网址:粘贴包含 API 密钥的完整端点网址(如上所示)。
- 环境(可选):如果您选择环境,Webhook 将仅报告来自匹配环境的事件。留空可接收来自所有环境的事件。
- 基本身份验证(可选):如果您想添加其他身份验证,请展开基本身份验证。对于 Chronicle 集成,您可以将此字段留空,因为身份验证是通过 API 密钥和密钥来处理的。
- 点击创建 Webhook。
- 系统会显示一个成功模式框,其中包含“已创建 Webhook”消息。
- 重要提示:如果您使用的是 Webhook 签名(仅限企业版方案),请复制并保存成功模式框中显示的加密密钥。该密钥仅显示一次。
向网络钩子添加 Chronicle Secret 密钥
FingerprintJS 在创建 Webhook 期间不支持自定义 HTTP 标头。您必须将 Chronicle 密钥作为查询参数添加到网络钩子网址中。
更新网络钩子网址以包含密钥:
<ENDPOINT_URL>?key=<API_KEY>&secret=<SECRET_KEY>示例:
https://malachiteingestion-pa.googleapis.com/v2/unstructuredlogentries:batchCreate?key=AIzaSyD...&secret=abcd1234...
如需更新网络钩子网址,请执行以下操作:
- 在 FingerprintJS 信息中心内,前往信息中心 > Webhook。
- 在表格中找到您的 Webhook,然后点击修改图标。
- 使用包含 API 密钥和密钥的完整网址更新 网址 字段。
- 点击修改 Webhook。
测试网络钩子
- 在 FingerprintJS 信息中心内,前往信息中心 > Webhook。
- 在表格中找到您的 Webhook。
- 点击发送测试事件。
- 等待确认测试活动已成功发送。
验证 webhook 是否显示成功传送状态。
身份验证方法参考
Chronicle webhook Feed 支持多种身份验证方法。FingerprintJS 网络钩子使用查询参数进行身份验证。
查询参数方法
FingerprintJS 在创建 Webhook 期间不支持自定义 HTTP 标头,因此必须将凭据附加到网址。
网址格式:
<ENDPOINT_URL>?key=<API_KEY>&secret=<SECRET_KEY>示例:
https://malachiteingestion-pa.googleapis.com/v2/unstructuredlogentries:batchCreate?key=AIzaSyD...&secret=abcd1234...
请求格式:
POST <ENDPOINT_URL>?key=<API_KEY>&secret=<SECRET_KEY> HTTP/1.1 Content-Type: application/json { "visitorId": "3HNey93AkBW6CRbxV6xP", "requestId": "1708102555327.NLOjmg", "timestamp": 1582299576512 }
UDM 映射表
| 日志字段 | UDM 映射 | 逻辑 |
|---|---|---|
| rawDeviceAttributes.architecture.value、rawDeviceAttributes.audio.value、rawDeviceAttributes.colorDepth.value、rawDeviceAttributes.colorGamut.value、rawDeviceAttributes.contrast.value、rawDeviceAttributes.cookiesEnabled.value、rawDeviceAttributes.deviceMemory.value、rawDeviceAttributes.fonts.value、rawDeviceAttributes.forcedColors.value、rawDeviceAttributes.hardwareConcurrency.value、rawDeviceAttributes.hdr.value、rawDeviceAttributes.indexedDB.value、rawDeviceAttributes.localStorage.value、rawDeviceAttributes.math.value、rawDeviceAttributes.monochrome.value、rawDeviceAttributes.openDatabase.value、rawDeviceAttributes.pdfViewerEnabled.value、rawDeviceAttributes.reducedMotion.value、rawDeviceAttributes.screenFrame.value、rawDeviceAttributes.screenResolution.value、rawDeviceAttributes.sessionStorage.value、rawDeviceAttributes.touchSupport.value.maxTouchPoints、rawDeviceAttributes.languages.value、rawDeviceAttributes.vendorFlavors.value、rawDeviceAttributes.fontPreferences.value.apple、rawDeviceAttributes.fontPreferences.value.default、rawDeviceAttributes.fontPreferences.value.min、rawDeviceAttributes.fontPreferences.value.mono、rawDeviceAttributes.fontPreferences.value.sans、rawDeviceAttributes.fontPreferences.value.serif、rawDeviceAttributes.fontPreferences.value.system | additional.fields | 从根据源字段创建的标签合并而来 |
| has_principal、has_target、has_target_resource | metadata.event_type | 如果 has_principal 和 has_target 为 true,则设置为“NETWORK_CONNECTION”;否则,如果 has_target_resource 为 true,则设置为“USER_RESOURCE_ACCESS”;否则,如果 has_principal 为 true,则设置为“STATUS_UPDATE”;否则,设置为“GENERIC_EVENT” |
| source_type | metadata.product_event_type | 直接复制值 |
| requestId | metadata.product_log_id | 直接复制值 |
| browserDetails.userAgent | network.http.parsed_user_agent | 从 browserDetails.userAgent 解析 |
| browserDetails.browserName | network.http.parsed_user_agent.browser | 直接复制值 |
| browserDetails.browserFullVersion | network.http.parsed_user_agent.browser_version | 直接复制值 |
| browserDetails.device | network.http.parsed_user_agent.device | 直接复制值 |
| network.http.parsed_user_agent.family | 设置为“USER_DEFINED” | |
| browserDetails.os | network.http.parsed_user_agent.os | 直接复制值 |
| browserDetails.clientReferrer | network.http.referral_url | 直接复制值 |
| browserDetails.userAgent、userAgent | network.http.user_agent | 如果 userAgent 不为空,则返回 userAgent 中的值,否则返回 browserDetails.userAgent |
| tag.session | network.session_id | 直接复制值 |
| rawDeviceAttributes.vendor.value | principal.administrative_domain | 直接复制值 |
| ip | principal.asset.ip | 直接复制值 |
| ip | principal.ip | 直接复制值 |
| ipInfo.v4.geolocation.city.name | principal.location.city | 直接复制值 |
| ipInfo.v4.geolocation.country.name | principal.location.country_or_region | 直接复制值 |
| ipInfo.v4.geolocation.latitude | principal.location.region_coordinates.latitude | 转换为浮点数 |
| ipInfo.v4.geolocation.longitude | principal.location.region_coordinates.longitude | 转换为浮点数 |
| browserDetails.osVersion, rawDeviceAttributes.platform.value | principal.platform_version | 如果 rawDeviceAttributes.platform.value 不为空,则为该值;否则为 browserDetails.osVersion |
| ipInfo.v4.asn.asn、ipInfo.v4.asn.network、ipInfo.v4.asn.name、ipInfo.v4.geolocation.accuracyRadius、ipInfo.v4.geolocation.continent.name、ipInfo.v4.geolocation.timezone、ipInfo.v4.geolocation.subdivisions.isoCode、ipInfo.v4.geolocation.subdivisions.name | principal.resource.attribute.labels | 从根据源字段创建的标签合并而来 |
| bot.result、browserDetails.browserMajorVersion、confidence.score、confidence.revision、developerTools.result、highActivity.result、incognito、ipBlocklist.result、ipBlocklist.details.attackSource、ipBlocklist.details.emailSpam、visitorFound、visitorId、tag.request、privacySettings.result、proxy.result、suspectScore.result、tor.result、virtualMachine.result、tampering.anomalyScore、tampering.antiDetectBrowser、tampering.result、vpn.confidence、vpn.originCountry、vpn.originTimezone、vpn.result、vpn.methods.auxiliaryMobile、vpn.methods.osMismatch、vpn.methods.publicVPN、vpn.methods.timezoneMismatch、velocity.distinctCountry.intervals.1h、velocity.distinctCountry.intervals.24h、velocity.distinctCountry.intervals.5m、velocity.distinctIp.intervals.1h、velocity.distinctIp.intervals.24h、velocity.distinctIp.intervals.5m、velocity.events.intervals.1h、velocity.events.intervals.24h、velocity.events.intervals.5m、velocity.ipEvents.intervals.1h、velocity.ipEvents.intervals.24h、velocity.ipEvents.intervals.5m、rawDeviceAttributes.webGlBasics.value.renderer、rawDeviceAttributes.webGlBasics.value.rendererUnmasked、rawDeviceAttributes.webGlBasics.value.vendorUnmasked、rawDeviceAttributes.webGlBasics.value.shadingLanguageVersion、rawDeviceAttributes.webGlExtensions.value.contextAttributes、rawDeviceAttributes.webGlExtensions.value.extensions、rawDeviceAttributes.webGlExtensions.value.extensionParameters、rawDeviceAttributes.webGlExtensions.value.parameters、rawDeviceAttributes.webGlExtensions.value.shaderPrecisions、rawDeviceAttributes.mathML.value.bottom、rawDeviceAttributes.mathML.value.top、rawDeviceAttributes.mathML.value.left、rawDeviceAttributes.mathML.value.right、rawDeviceAttributes.mathML.value.width、rawDeviceAttributes.mathML.value.height、rawDeviceAttributes.mathML.value.font、rawDeviceAttributes.mathML.value.x、rawDeviceAttributes.mathML.value.y、rawDeviceAttributes.emoji.value.bottom、rawDeviceAttributes.emoji.value.top、rawDeviceAttributes.emoji.value.left、rawDeviceAttributes.emoji.value.right、rawDeviceAttributes.emoji.value.width、rawDeviceAttributes.emoji.value.height、rawDeviceAttributes.emoji.value.font、rawDeviceAttributes.emoji.value.x、rawDeviceAttributes.emoji.value.y、rawDeviceAttributes.canvas.value.Geometry、rawDeviceAttributes.canvas.value.Text、rawDeviceAttributes.canvas.value.Winding | security_result.detection_fields | 从根据源字段创建的标签合并而来 |
| rawDeviceAttributes.webGlBasics.value.vendor | target.administrative_domain | 直接复制值 |
| ipInfo.v6.address | target.asset.ip | 直接复制值 |
| ipInfo.v6.address | target.ip | 直接复制值 |
| ipInfo.v6.geolocation.city.name | target.location.city | 直接复制值 |
| ipInfo.v6.geolocation.country.name | target.location.country_or_region | 直接复制值 |
| ipInfo.v6.geolocation.latitude | target.location.region_coordinates.latitude | 转换为浮点数 |
| ipInfo.v6.geolocation.longitude | target.location.region_coordinates.longitude | 转换为浮点数 |
| 路径 | target.path | 直接复制值 |
| rawDeviceAttributes.webGlBasics.value.version | target.platform_version | 直接复制值 |
| ipInfo.v6.asn.asn、ipInfo.v6.asn.network、ipInfo.v6.asn.name、ipInfo.v6.geolocation.accuracyRadius、ipInfo.v6.geolocation.continent.name、ipInfo.v6.geolocation.timezone、ipInfo.v6.geolocation.subdivisions.isoCode、ipInfo.v6.geolocation.subdivisions.name | target.resource.attribute.labels | 从根据源字段创建的标签合并而来 |
| 网址 | target.url | 直接复制值 |
| metadata.product_name | 设置为“FINGERPRINT_JS” | |
| metadata.vendor_name | 设置为“FINGERPRINT_JS” |
更新日志
需要更多帮助?获得社区成员和 Google SecOps 专业人士的解答。