CLI Custom Policies
This topic walks you through using the Lacework CLI to create a custom policy that checks for unrestricted ingress to TCP port 445.
If you are new to the Lacework CLI, see Get Started to learn about installing and configuring the CLI.
This walkthrough follows a basic end-to-end workflow to create a custom policy. For additional options when creating queries and policies, see LQL Queries and Policies.
Lacework Academy Course Available
If you want to learn more about Custom Policies and LQL, take the Custom Policies/LQL course from the Lacework Academy.
Policy Query Definition
What Datasources Are Available
The easiest way to learn about the LQL datasources is to discover the names of the datasources and then get details about the one you are interested in.
Run the command that corresponds to your cloud provider:
lacework query list-sources | grep AWS
lacework query list-sources | grep GCP
lacework query list-sources | grep AZURE
What Fields Can I Use from a Datasource
The examples use the following datasources:
- AWS datasource:
LW_CFG_AWS_EC2_SECURITY_GROUPS
- GCP datasource (currently in beta):
LW_CFG_GCP_COMPUTE_FIREWALL
- Azure datasource (currently in beta):
LW_CFG_AZURE_NETWORK_NETWORKSECURITYGROUPS
In order to learn which fields to use in your query, run the lacework query show-source
command for a description of the fields. For some datasources, you can run the lacework query preview-source
command (not available for all datasources).
The following command shows the details for the LW_CFG_AWS_EC2_SECURITY_GROUPS
datasource.
lacework query show-source LW_CFG_AWS_EC2_SECURITY_GROUPS
DATASOURCE DESCRIPTION
---------------------------------+---------------------------------
LW_CFG_AWS_EC2_SECURITY_GROUPS Results from AWS EC2
'describe-security-groups'
FIELD NAME DATA TYPE DESCRIPTION
-------------------+-----------+---------------------------------
BATCH_START_TIME Timestamp Beginning of time interval
BATCH_END_TIME Timestamp End of time interval
QUERY_START_TIME Timestamp Start time of query for this
resource
QUERY_END_TIME Timestamp End time of query for this
resource
ARN String ARN for the resource
API_KEY String Key describing the API used to
fetch data for this resource
SERVICE String Service this resource belongs
to
ACCOUNT_ID String AWS Account ID
ACCOUNT_ALIAS String User friendly alias for AWS
Account
RESOURCE_TYPE String Type of this resource
RESOURCE_ID String Identifier for this resource
RESOURCE_REGION String Region this resource belongs
to
RESOURCE_CONFIG JSON JSON Definition of this
resource
RESOURCE_TAGS JSON Tags associated with this
resource
The RESOURCE_CONFIG
field is frequently used in LQL. Because it is a JSON datasource, the LQL query must first convert the field using the array_to_rows()
function. To know exactly which JSON fields you need, you can either read the cloud provider's API documentation, or write an LQL query to explore the full content before writing the actual policy.
Explore Datasources Using LQL
This example explores the LW_CFG_AWS_EC2_SECURITY_GROUPS
datasource. Replace the datasource with LW_CFG_GCP_COMPUTE_FIREWALL
or LW_CFG_AZURE_NETWORK_NETWORKSECURITYGROUPS
respectively if using GCP or Azure.
Open your text editor, create a new file, and add the following content:
---
queryId: Explore_AWS_EC2_SECURITY_GROUPS
queryText: |-
{
source {
LW_CFG_AWS_EC2_SECURITY_GROUPS
}
return {
RESOURCE_CONFIG
}
}Save the file as YAML with the filename Explore_AWS_EC2_SECURITY_GROUPS.yaml. Note the file's location.
In the Lacework CLI, run this command:
lacework query run -f <path_to>/Explore_AWS_EC2_SECURITY_GROUPS.yaml
Response{
"RESOURCE_CONFIG": {
"Description": "default VPC security group",
"GroupId": "sg-000",
"GroupName": "default",
"IpPermissions": [
{
"IpProtocol": "-1",
"IpRanges": [],
"Ipv6Ranges": [],
"PrefixListIds": [],
"UserIdGroupPairs": [
{
"GroupId": "sg-000",
"UserId": "111"
}
]
}
],
"IpPermissionsEgress": [
{
"IpProtocol": "-1",
"IpRanges": [
{
"CidrIp": "0.0.0.0/0"
}
],
"Ipv6Ranges": [],
"PrefixListIds": [],
"UserIdGroupPairs": []
}
],
"OwnerId": "111",
"VpcId": "vpc-000"
}
}
Create a Query
Open your text editor, create a new file, and add the content that corresponds to your cloud provider:
AWS query---
queryId: LW_Custom_UnrestrictedIngressToTCP445
queryText: |-
{
source {
LW_CFG_AWS_EC2_SECURITY_GROUPS a,
array_to_rows(a.RESOURCE_CONFIG:IpPermissions) as (ip_permissions),
array_to_rows(ip_permissions:IpRanges) as (ip_ranges)
}
filter {
ip_permissions:IpProtocol = 'tcp'
and ip_permissions:FromPort = 445
and ip_permissions:ToPort = 445
and ip_ranges:CidrIp = '0.0.0.0/0'
}
return distinct {
ACCOUNT_ALIAS,
ACCOUNT_ID,
ARN as RESOURCE_KEY,
RESOURCE_REGION,
RESOURCE_TYPE,
SERVICE
}
}GCP query---
queryId: LW_Custom_UnrestrictedIngressToTCP445
queryText: |-
{
source {
LW_CFG_GCP_COMPUTE_FIREWALL firewall,
array_to_rows(firewall.RESOURCE_CONFIG:allowed) as (allowed),
array_to_rows(allowed:ports) as (ports),
array_to_rows(firewall.RESOURCE_CONFIG:sourceRanges) as (ranges)
}
filter {
RESOURCE_CONFIG:direction = 'INGRESS'
and allowed:IPProtocol = 'tcp'
and ports = '445'
and ranges = '0.0.0.0/0'
}
return distinct {
ORGANIZATION_ID,
PROJECT_NUMBER,
PROJECT_ID,
FOLDER_IDS,
URN as RESOURCE_KEY,
RESOURCE_REGION,
RESOURCE_TYPE,
SERVICE
}
}Azure query---
queryId: LW_Custom_UnrestrictedIngressToTCP445
queryText: |-
{
source {
LW_CFG_AZURE_NETWORK_NETWORKSECURITYGROUPS a,
array_to_rows(a.RESOURCE_CONFIG:securityRules) as (rules)
}
filter {
rules:"properties".access = 'Allow'
and rules:"properties".direction = 'Inbound'
and rules:"properties".protocol = 'Tcp'
and rules:"properties".destinationPortRange = '445'
and rules:"properties".sourceAddressPrefix = '*'
}
return distinct {
TENANT_ID,
TENANT_NAME,
SUBSCRIPTION_ID,
SUBSCRIPTION_NAME,
URN as RESOURCE_KEY,
RESOURCE_REGION,
RESOURCE_TYPE
}
}Save the file as YAML with the filename LW_Custom_UnrestrictedIngressToTCP445.yaml. Note the file's location.
In the Lacework CLI, run this command:
lacework query create -f <path_to>/LW_Custom_UnrestrictedIngressToTCP445.yaml
ResponseThe query LW_Custom_UnrestrictedIngressToTCP445 was created.
Test Using Collected Data
In the Lacework CLI, run this command:
lacework query run LW_Custom_UnrestrictedIngressToTCP445
[
{
"ACCOUNT_ALIAS": "",
"ACCOUNT_ID": "aaa",
"RESOURCE_KEY": "arn:aws:ec2:us-east-2:aaa:security-group/sg-bbb",
"RESOURCE_REGION": "us-east-2",
"RESOURCE_TYPE": "ec2:security-group",
"SERVICE": "ec2"
}
]
[
{
"FOLDER_IDS": [],
"ORGANIZATION_ID": "aaa",
"PROJECT_ID": "ccc",
"PROJECT_NUMBER": "bbb",
"RESOURCE_KEY": "gcp:bbb://compute.googleapis.com/projects/ccc/global/firewalls/ddd",
"RESOURCE_REGION": "global",
"RESOURCE_TYPE": "compute.googleapis.com/Firewall",
"SERVICE": "compute"
}
]
[
{
"RESOURCE_KEY": "/subscriptions/aaa/resourceGroups/bbb/providers/Microsoft.Network/networkSecurityGroups/ddd",
"RESOURCE_REGION": "westus",
"RESOURCE_TYPE": "microsoft.network/networksecuritygroups",
"SUBSCRIPTION_ID": "aaa",
"SUBSCRIPTION_NAME": "eee",
"TENANT_ID": "ccc",
"TENANT_NAME": "fff"
}
]
Create a Policy
Open your text editor, create a new file, and add the content that corresponds to your cloud provider:
AWS policy---
title: Security Groups Should Not Allow Unrestricted Ingress to TCP Port 445
enabled: false
policyType: Violation
alertEnabled: false
alertProfile: LW_CFG_AWS_DEFAULT_PROFILE.CFG_AWS_Violation
evalFrequency: Daily
queryId: LW_Custom_UnrestrictedIngressToTCP445
severity: high
description: Security groups should not allow unrestricted ingress to TCP port 445
remediation: Policy remediationGCP policy---
title: Security Groups Should Not Allow Unrestricted Ingress to TCP Port 445
enabled: false
policyType: Violation
alertEnabled: false
alertProfile: LW_CFG_GCP_DEFAULT_PROFILE.Violation
evalFrequency: Daily
queryId: LW_Custom_UnrestrictedIngressToTCP445
severity: high
description: Security groups should not allow unrestricted ingress to TCP port 445
remediation: Policy remediationAzure policy---
title: Network Security Groups Should Not Allow Unrestricted Ingress to TCP Port 445
enabled: false
policyType: Violation
alertEnabled: false
alertProfile: LW_CFG_AZURE_DEFAULT_PROFILE.Violation
evalFrequency: Daily
queryId: LW_Custom_UnrestrictedIngressToTCP445
severity: high
description: Network security groups should not allow unrestricted ingress to TCP port 445
remediation: Policy remediationSave the file as YAML with the filename UnrestrictedIngressToTCP445.yaml. Note the file's location.
In the Lacework CLI, run this command:
lacework policy create -f <path_to>/UnrestrictedIngressToTCP445.yaml
ResponseThe policy <policy_name> was created.
Enable Alerts
The policy you just created is not enabled and does not yet raise alerts when violations occur. The following enables alerts for the policy.
In your text editor, open the UnrestrictedIngressToTCP445.yaml file and update these fields:
enabled: false
toenabled: true
alertEnabled: false
toalertEnabled: true
Save your changes.
In the Lacework CLI, run this command:
lacework policy update -f <path_to>/UnrestrictedIngressToTCP445.yaml
ResponseThe policy <policy_name> was updated.