Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding DNS API calls to secure-internet-traffic learning path #18388

Draft
wants to merge 23 commits into
base: production
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
9279651
Initial code commit
tcerqueira-cf Nov 23, 2024
3c7697a
Fixed typos
tcerqueira-cf Nov 25, 2024
09414ca
Added terraform code
tcerqueira-cf Nov 25, 2024
e3975b6
Fixed typo
tcerqueira-cf Nov 25, 2024
0a78d47
Added API and Terraform code to create the allow list policy
tcerqueira-cf Nov 27, 2024
19c71bf
Added terraform and API code for the All-DNS-Domain-Allowlist rule
tcerqueira-cf Nov 27, 2024
566551a
Fixed JSON capitalization
tcerqueira-cf Nov 27, 2024
2a360ce
Fixed missing import
tcerqueira-cf Nov 27, 2024
5c42de6
Fixed styling issue
tcerqueira-cf Nov 27, 2024
df6ab87
Added API and terraform code for Quarantined users restricted access …
tcerqueira-cf Nov 27, 2024
141c95a
Fixed typo
tcerqueira-cf Nov 27, 2024
f0dc556
Added terraform and API code for the country geolocation block rule
tcerqueira-cf Nov 27, 2024
4ac36e6
Added Terraform and API code for the misuesed TLD block rule
tcerqueira-cf Nov 27, 2024
16c8ba0
Fixed small typo
tcerqueira-cf Nov 27, 2024
f8199f5
Added terraform and API code for the Domain Phishing block rule
tcerqueira-cf Nov 28, 2024
dbf54f2
Added tf and API code for the DNS Resolved IP Blocklist rule
tcerqueira-cf Nov 28, 2024
a061c44
Modified enforce-device-posture partial to add terraform and API code
tcerqueira-cf Nov 28, 2024
1ab4823
Fixed typo
tcerqueira-cf Nov 28, 2024
a15df8f
Fixed typo
tcerqueira-cf Nov 28, 2024
a977605
Fixed small typo
tcerqueira-cf Nov 28, 2024
0adca5b
Fixed typo
tcerqueira-cf Nov 28, 2024
7f40cc7
Merge branch 'production' into origin/tcerqueira/defense-in-depth-api…
maxvp Dec 30, 2024
95be41f
Fix formatting
maxvp Dec 30, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,55 @@ sidebar:

---

import { Tabs, TabItem } from "~/components"

In the context of DNS filtering, a blocklist is a list of known harmful domains or IP addresses. An allowlist is a list of allowed domains or IP addresses, such as the domains of essential corporate applications.

Gateway supports creating [lists](/cloudflare-one/policies/gateway/lists/) of URLs, hostnames, or other entries to use in your policies.

## Example list policy

<Tabs syncKey="dashPlusAPI">
<TabItem label="Dashboard">
The following DNS policy will allow access to all approved corporate domains included in a list called **Corporate Domains**.

| Selector | Operator | Value | Action |
| -------- | -------- | ------------------- | ------ |
| Domain | in list | *Corporate Domains* | Allow |
</TabItem>
<TabItem label="API">
```sh
curl --request POST \
--URL https://api.cloudflare.com/client/v4/accounts/{account_id}/gateway/rules \
--header 'Content-Type: application/JSON' \
--header "Authorization: Bearer <API TOKEN>" \
--data '{
"name": "All-DNS-CorporateDomain-AllowList",
"description": "Allow access to the corporate domains defined under the Corporate Domains list",
"precedence": 1,
"enabled": false,
"action": "allow",
"filters": [
"dns"
],
"traffic": "any(dns.domains[*] in $<Corporate Domains List UUID>)"
}'

```
</TabItem>
<TabItem label="Terraform">
To create a new DNS policy using **Terraform** to allow access to all approved corporate domains included in a list called **Corporate Domains**.
```tf
resource "cloudflare_zero_trust_gateway_policy" "allow_corporate_domain_access" {
account_id = var.account_id
name = "All-DNS-CorporateDomain-AllowList"
description = "Allow access to the corporate domains defined under the Corporate Domains list"
precedence = 1
enabled = false
action = "allow"
filters = ["dns"]
traffic = "any(dns.domains[*] in $<Corporate Domains List UUID>)"
}
```
</TabItem>
</Tabs>
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,16 @@ sidebar:
order: 1
---

import { Render } from "~/components";
import { Tabs, TabItem, Render } from "~/components"

DNS policies determine how Gateway should handle a DNS request. When a user sends a DNS request, Gateway matches the request against your filters and either allows the query to resolve, blocks the query, or responds to the query with a different IP.

You can filter DNS traffic based on query or response parameters (such as domain, source IP, or geolocation). You can also filter by user identity if you connect your devices to Gateway with the [WARP client or Cloudflare One Agent](/learning-paths/secure-internet-traffic/connect-devices-networks/install-agent/).

To create a new DNS policy:

<Tabs syncKey="dashPlusAPI">
<TabItem label="Dashboard">
1. In [Zero Trust](https://one.dash.cloudflare.com/), go to **Gateway** > **Firewall policies**.
2. In the **DNS** tab, select **Add a policy**.
3. Name the policy.
Expand All @@ -25,3 +27,48 @@ To create a new DNS policy:
6. Select **Create policy**.

For more information, refer to [DNS policies](/cloudflare-one/policies/gateway/dns-policies/).
</TabItem>
<TabItem label="API">
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I investigated if it was possible to add this to the partial referenced for the dashboard (gateway/policies/block-security-categories), however, this partial is being re-used for HTTP and DNS policies. Considering that in the API/Terraform you need different wirefilter expressions for HTTP and DNS, I would love to know if there's a way to modify the partial so that it also contains the API and Terraform code when it's inserted.
Following up on this note, on the DNS policies, the selector is in fact "Security Categories", while in the HTTP tab, the selector is "Security Risks". I'm not sure if this alone warrants for splitting this partial into one that is applied to DNS and another that is applied to HTTP, to which it would then make sense to add the API and TF code for the respective traffic type

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Files that reference the mentioned partial:
src/content/docs/cloudflare-one/policies/gateway/initial-setup/http.mdx
src/content/docs/cloudflare-one/policies/gateway/initial-setup/dns.mdx
src/content/docs/learning-paths/cybersafe/gateway-onboarding/gateway-create-test-policy.mdx
src/content/docs/learning-paths/secure-internet-traffic/build-dns-policies/create-policy.mdx
src/content/docs/learning-paths/secure-internet-traffic/build-dns-policies/test-policy.mdx
src/content/docs/learning-paths/secure-internet-traffic/build-dns-policies/recommended-dns-policies.mdx
src/content/partials/cloudflare-one/gateway/policies/recommended-dns-policies.mdx

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can create flexible partials that accept parameters for different use cases (e.g. if a selector is used in both DNS and HTTP policies, you can use either dns or http.conn in the API value depending on the page). Since the API sections are much longer than a string, it may be easier to break them out into their own partials.

To create a new DNS policy using **cURL**:
```sh
curl --request POST \
--url https://api.cloudflare.com/client/v4/accounts/{account_id}/gateway/rules \
--header 'Content-Type: application/JSON' \
--header "Authorization: Bearer <API_TOKEN>" \
--data '{
"name": "All-DNS-SecurityCategories-Blocklist",
"description": "Block known security risks based on Cloudflare's threat intelligence",
"precedence": 0,
"enabled": false,
"action": "block",
"filters": [
"dns"
],
"traffic": "any(dns.security_category[*] in {68 178 80 83 176 175 117 131 134 151 153})",
"rule_settings": {
"block_page_enabled": true,
"block_reason": "This domain was blocked due to being classified as a security risk to the organisation"
}
}'
```
</TabItem>
<TabItem label="Terraform">
To create a new DNS policy using **Terraform**:
```tf
resource "cloudflare_zero_trust_gateway_policy" "security_risks_dns_policy" {
account_id = var.account_id
name = "All-DNS-SecurityCategories-Blocklist"
description = "Block known security risks based on Cloudflare's threat intelligence"
precedence = 0
enabled = false
action = "block"
filters = ["dns"]
traffic = "any(dns.security_category[*] in {68 178 80 83 176 175 117 131 134 151 153})"
rule_settings {
block_page_enabled = true
block_page_reason = "This domain was blocked due to being classified as a security risk to the organisation"
}
}
```
</TabItem>
</Tabs>
Original file line number Diff line number Diff line change
Expand Up @@ -6,34 +6,115 @@ sidebar:

---

import { Details, Render } from "~/components"
import { Details, Render, Tabs, TabItem } from "~/components"

We recommend you add the following DNS policies to build an Internet and SaaS app security strategy for your organization.


<Details header="All-DNS-Domain-Allowlist">

<Tabs syncKey="dashPlusAPI">
Allowlist any known domains and hostnames. With this policy, you ensure that your users can access your organization's domains even if the domains fall under a blocked category, such as **Newly Seen Domains** or **Login Screens**.

<TabItem label="Dashboard">
| Selector | Operator | Value | Logic | Action |
| -------- | -------- | --------------- | ----- | ------ |
| Domain | in list | *Known Domains* | Or | Allow |
| Host | in list | *Known Domains* | | |


</TabItem>
<TabItem label="API">
```sh
curl --request POST \
--url https://api.cloudflare.com/client/v4/accounts/{account_id}/gateway/rules \
--header 'Content-Type: application/JSON' \
--header "Authorization: Bearer <API TOKEN>" \
--data '{
"name": "All-DNS-Domain-Allowlist",
"description": "Organization-wide whitelist. Explicitly allow resolution of these DNS domains",
"precedence": 0,
"enabled": false,
"action": "allow",
"filters": [
"dns"
],
"traffic": "any(dns.domains[*] in $<Global Whitelist UUID>) or dns.fqdn in $<Global Whitelist UUID>"
}'
```
</TabItem>
<TabItem label="Terraform">
```tf
resource "cloudflare_zero_trust_gateway_policy" "dns_whitelist_policy" {
account_id = var.account_id
name = "All-DNS-Domain-Allowlist"
description = "Organization-wide whitelist. Explicitly allow resolution of these DNS domains"
precedence = 0
enabled = false
action = "allow"
filters = ["dns"]
traffic = "any(dns.domains[*] in ${"$"}${cloudflare_zero_trust_list.domain_whitelist.id}) or dns.fqdn in ${"$"}${cloudflare_zero_trust_list.domain_whitelist.id}"
}
```
</TabItem>
</Tabs>
</Details>


<Details header="Quarantined-Users-DNS-Restricted-Access">

<Render file="zero-trust/blocklist-restricted-users" />

| Selector | Operator | Value | Logic | Action |
| ---------------- | -------- | ------------------- | ----- | ------ |
| Domain | in list | *Known Domains* | Or | Block |
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@maxvp I'm not 100% sure I understood this mock rule. From what I understood from the description of this rule, it appears that you are attempting to restrict Quarantined users to specific domains for remediation, is this correct? If so, this wouldn't work because it would block the domains allowed for remediation. I proposed a change to this, and from a policy standpoint it should work. Let me know if my reasoning is correct.

It also came to mind that this policy was meant to block quarantined users from accessing known malicious domains, but that wouldn't make much sense, as if the domains/hosts are known to be malicious, you would want that to be blocked organisation-wide

Let me know your thoughts on this.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

| Host | in list | *Known Domains* | And | |
| User Group Names | in | *Quarantined Users* | | |

<Tabs>
<TabItem label="Dashboard">
| Selector | Operator | Value | Logic | Action |
| ---------------- | ------------ | --------------------------------- | ----- | ------ |
| Domain | not in list | *Allowed Remediation Domains* | Or | Block |
| Host | not in list | *Allowed Remediation Domains* | And | |
| User Group Names | in | *Quarantined Users* | | |
</TabItem>
<TabItem label="API">
```sh
curl --request POST \
--URL https://api.cloudflare.com/client/v4/accounts/{account_id}/gateway/rules \
--header 'Content-Type: application/JSON' \
--header "Authorization: Bearer <API TOKEN>" \
--data '{
"name": "Quarantined-Users-DNS-Restricted-Access",
"description": "Restrict quarantined users traffic to corporate policy remediation domains, so that quarantined users can obtain help and/or remediate their security posture",
"precedence": 10,
"enabled": false,
"action": "block",
"filters": [
"dns"
],
"traffic": "not(any(dns.domains[*] in $<Allowed Remediation Domains list UUID>)) or not(any(dns.domains[*] in $<Allowed Remediation Domains list UUID>))",
"identity": "any(identity.groups.name[*] in {\"Quarantined Users\"})",
"rule_settings": {
"block_page_enabled": true,
"notification_settings": {
"enabled": true
}
}'
```
</TabItem>
<TabItem label="Terraform">
```tf
resource "cloudflare_zero_trust_gateway_policy" "dns_restrict_quarantined_users" {
account_id = var.account_id
name = "Quarantined-Users-DNS-Restricted-Access"
description = "Restrict quarantined users traffic to corporate policy remediation domains, so that quarantined users can obtain help and/or remediate their security posture"
precedence = 10
enabled = false
action = "block"
filters = ["dns"]
traffic = "not(any(dns.domains[*] in $<Allowed Remediation Domains list UUID>)) or not(any(dns.domains[*] in $<Allowed Remediation Domains list UUID>))"
identity = "any(identity.groups.name[*] in {\"Quarantined Users\"})"
rule_settings {
block_page_enabled = true
notification_settings {
enabled = true
}
}
}
```
</TabItem>
</Tabs>

</Details>

Expand Down Expand Up @@ -120,4 +201,4 @@ Block specific IP addresses that are malicious or pose a threat to your organiza
<Render file="zero-trust/blocklist-domain-host" params={{ one: "DNS" }} />


</Details>
</Details>
Loading