收集 Fingerprint 日志
解析器版本: 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 端点网址 。
网址格式为:
https://{region}-chronicle.googleapis.com/v1/{parent}/logs:import其中,
{region}是 Google SecOps 实例的区域(例如us、europe或asia-southeast1),{parent}是资源路径,格式为projects/<PROJECT_ID>/locations/<LOCATION>/instances/<INSTANCE_ID>/logTypes/<LOG_TYPE>。保存此网址,以在后续步骤中使用。
点击完成 。
创建 Google Cloud API 密钥
Chronicle 需要 API 密钥进行身份验证。在 Google Cloud Console 中创建受限 API 密钥。
创建 API 密钥
- 前往 Google Cloud 控制台的“凭据”页面。
- 选择您的项目(与您的 Chronicle 实例关联的项目)。
- 点击创建凭据 > API 密钥。
- 系统会创建 API 密钥,并在对话框中显示该密钥。
- 点击 Edit API key (修改 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://{region}-chronicle.googleapis.com/v1/{parent}/logs:import?key=AIzaSyD...
在 FingerprintJS 信息中心内创建 Webhook
- 登录 FingerprintJS 信息中心 。
- 前往信息中心 > Webhook。
- 点击 Add webhook 。
- 提供以下配置详细信息:
- 网址:粘贴包含 API 密钥的完整端点网址(如上所示)。
- 环境 (可选):如果您选择环境,Webhook 将仅报告来自匹配环境的事件。留空即可接收来自所有环境的事件。
- 基本身份验证 (可选):如果您想添加其他身份验证,请展开基本身份验证 。对于 Chronicle 集成,您可以将此字段留空,因为身份验证是通过 API 密钥和密钥处理的。
- 点击 Create Webhook 。
- 成功模式会显示 Webhooks created 。
- 重要提示:如果您使用的是 Webhook 签名(仅限企业版方案),请复制并保存成功模式中显示的加密密钥。该密钥仅显示一次。
向 Webhook 添加 Chronicle 密钥
FingerprintJS 在创建 Webhook 期间不支持自定义 HTTP 标头。您必须将 Chronicle 密钥作为查询参数添加到网络钩子网址中。
更新网络钩子网址以包含密钥:
<ENDPOINT_URL>?key=<API_KEY>&secret=<SECRET_KEY>示例:
https://{region}-chronicle.googleapis.com/v1/{parent}/logs:import?key=AIzaSyD...&secret=abcd1234...
如需更新网络钩子网址,请执行以下操作:
- 在 FingerprintJS 信息中心内,前往信息中心 > Webhook。
- 在表格中找到您的 Webhook,然后点击修改 图标。
- 使用包含 API 密钥和密钥的完整网址更新 URL 字段。
- 点击 Edit webhook 。
测试 Webhook
- 在 FingerprintJS 信息中心内,前往信息中心 > Webhook。
- 在表格中找到您的 Webhook。
- 点击 Send test event 。
- 等待确认测试事件已成功发送。
验证 Webhook 是否显示成功传送状态。
身份验证方法参考
Chronicle Webhook Feed 支持多种身份验证方法。FingerprintJS Webhook 使用查询参数进行身份验证。
查询参数方法
FingerprintJS 在创建 Webhook 期间不支持自定义 HTTP 标头,因此必须将凭据附加到网址。
网址格式:
<ENDPOINT_URL>?key=<API_KEY>&secret=<SECRET_KEY>示例:
https://{region}-chronicle.googleapis.com/v1/{parent}/logs:import?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 不为空,则取自 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 | 转换为浮点数 |
| path | 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 | 从根据源字段创建的标签合并 |
| url | target.url | 直接复制值 |
| metadata.product_name | 设置为“FINGERPRINT_JS” | |
| metadata.vendor_name | 设置为“FINGERPRINT_JS” |
更新日志
需要更多帮助?获得社区成员和 Google SecOps 专业人士的解答。