Skip to content

Commit 503ece0

Browse files
updates
1 parent 0c68572 commit 503ece0

File tree

5 files changed

+377
-0
lines changed

5 files changed

+377
-0
lines changed

mtls-terraform-example/README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# mtls demo
2+
You'll need to do two steps.
3+
4+
Run `terraform apply`
5+
Update DNS
6+
Uncomment the mtls configurations
7+
Run `terraform apply`

mtls-terraform-example/main.tf

Lines changed: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
# Configure the Fastly Provider
2+
provider "fastly" {
3+
api_key = var.FASTLY_API_KEY
4+
}
5+
6+
#### Fastly VCL Service - Start
7+
resource "fastly_service_vcl" "frontend-vcl-service" {
8+
name = "mtls demo - ${var.USER_VCL_SERVICE_DOMAIN_NAME}"
9+
10+
domain {
11+
name = var.USER_VCL_SERVICE_DOMAIN_NAME
12+
comment = "mtls demo"
13+
}
14+
backend {
15+
address = var.USER_VCL_SERVICE_BACKEND_HOSTNAME
16+
name = "vcl_service_origin"
17+
port = 443
18+
use_ssl = true
19+
ssl_cert_hostname = var.USER_VCL_SERVICE_BACKEND_HOSTNAME
20+
ssl_sni_hostname = var.USER_VCL_SERVICE_BACKEND_HOSTNAME
21+
override_host = var.USER_VCL_SERVICE_BACKEND_HOSTNAME
22+
}
23+
24+
#### Disable caching, but keep request collapsing https://www.fastly.com/documentation/reference/vcl/variables/backend-response/beresp-cacheable/#effects-on-request-collapsing
25+
snippet {
26+
name = "Disable caching"
27+
content = "set beresp.cacheable = false;"
28+
type = "fetch"
29+
priority = 9000
30+
}
31+
32+
#### Useful for debugging with response headers
33+
# snippet {
34+
# name = "Debug headers"
35+
# content = file("${path.module}/vcl/debug_headers.vcl")
36+
# type = "fetch"
37+
# priority = 120
38+
# }
39+
40+
#### NGWAF Dynamic Snippets - MANAGED BY FASTLY - Start
41+
dynamicsnippet {
42+
name = "ngwaf_config_init"
43+
type = "init"
44+
priority = 0
45+
}
46+
dynamicsnippet {
47+
name = "ngwaf_config_miss"
48+
type = "miss"
49+
priority = 9000
50+
}
51+
dynamicsnippet {
52+
name = "ngwaf_config_pass"
53+
type = "pass"
54+
priority = 9000
55+
}
56+
dynamicsnippet {
57+
name = "ngwaf_config_deliver"
58+
type = "deliver"
59+
priority = 9000
60+
}
61+
#### NGWAF Dynamic Snippets - MANAGED BY FASTLY - End
62+
63+
dictionary {
64+
name = "Edge_Security"
65+
}
66+
67+
# logging_honeycomb {
68+
# dataset = "NGWAF_EDGE_DATASET"
69+
# name = "NGWAF_EDGE_LOGS"
70+
# token = var.HONEYCOMB_API_KEY
71+
# format = file("${path.module}/ngwaf_honeycomb_logging_format.json")
72+
# }
73+
74+
# logging_splunk {
75+
# name = var.SPLUNK_LOGGING_NAME
76+
# token = var.SPLUNK_LOGGING_TOKEN
77+
# url = var.SPLUNK_LOGGING_URL
78+
# format_version = 2
79+
# format = file("${path.module}/ngwaf_splunk_logging_format.json")
80+
# tls_ca_cert = file("${path.module}/splunk_ca_cert.pem")
81+
# use_tls = true
82+
# }
83+
84+
force_destroy = true
85+
}
86+
87+
resource "fastly_service_dynamic_snippet_content" "ngwaf_config_init" {
88+
for_each = {
89+
for d in fastly_service_vcl.frontend-vcl-service.dynamicsnippet : d.name => d if d.name == "ngwaf_config_init"
90+
}
91+
92+
service_id = fastly_service_vcl.frontend-vcl-service.id
93+
snippet_id = each.value.snippet_id
94+
95+
content = "### Fastly managed ngwaf_config_init"
96+
97+
manage_snippets = false
98+
}
99+
100+
resource "fastly_service_dynamic_snippet_content" "ngwaf_config_miss" {
101+
for_each = {
102+
for d in fastly_service_vcl.frontend-vcl-service.dynamicsnippet : d.name => d if d.name == "ngwaf_config_miss"
103+
}
104+
105+
service_id = fastly_service_vcl.frontend-vcl-service.id
106+
snippet_id = each.value.snippet_id
107+
108+
content = "### Fastly managed ngwaf_config_miss"
109+
110+
manage_snippets = false
111+
}
112+
113+
resource "fastly_service_dynamic_snippet_content" "ngwaf_config_pass" {
114+
for_each = {
115+
for d in fastly_service_vcl.frontend-vcl-service.dynamicsnippet : d.name => d if d.name == "ngwaf_config_pass"
116+
}
117+
118+
service_id = fastly_service_vcl.frontend-vcl-service.id
119+
snippet_id = each.value.snippet_id
120+
121+
content = "### Fastly managed ngwaf_config_pass"
122+
123+
manage_snippets = false
124+
}
125+
126+
resource "fastly_service_dynamic_snippet_content" "ngwaf_config_deliver" {
127+
for_each = {
128+
for d in fastly_service_vcl.frontend-vcl-service.dynamicsnippet : d.name => d if d.name == "ngwaf_config_deliver"
129+
}
130+
131+
service_id = fastly_service_vcl.frontend-vcl-service.id
132+
snippet_id = each.value.snippet_id
133+
134+
content = "### Fastly managed ngwaf_config_deliver"
135+
136+
manage_snippets = false
137+
}
138+
139+
#### Fastly VCL Service - End
140+
141+
provider "sigsci" {
142+
corp = var.NGWAF_CORP
143+
email = var.NGWAF_EMAIL
144+
auth_token = var.NGWAF_TOKEN
145+
fastly_api_key = var.FASTLY_API_KEY
146+
}
147+
148+
resource "sigsci_edge_deployment" "ngwaf_edge_site_service" {
149+
# https://registry.terraform.io/providers/signalsciences/sigsci/latest/docs/resources/edge_deployment
150+
site_short_name = var.NGWAF_SITE
151+
}
152+
153+
resource "sigsci_edge_deployment_service" "ngwaf_edge_service_link" {
154+
# https://registry.terraform.io/providers/signalsciences/sigsci/latest/docs/resources/edge_deployment_service
155+
site_short_name = var.NGWAF_SITE
156+
fastly_sid = fastly_service_vcl.frontend-vcl-service.id
157+
158+
activate_version = true
159+
percent_enabled = 100
160+
161+
depends_on = [
162+
sigsci_edge_deployment.ngwaf_edge_site_service,
163+
fastly_service_vcl.frontend-vcl-service,
164+
fastly_service_dynamic_snippet_content.ngwaf_config_init,
165+
fastly_service_dynamic_snippet_content.ngwaf_config_miss,
166+
fastly_service_dynamic_snippet_content.ngwaf_config_pass,
167+
fastly_service_dynamic_snippet_content.ngwaf_config_deliver,
168+
]
169+
}
170+
171+
resource "sigsci_edge_deployment_service_backend" "ngwaf_edge_service_backend_sync" {
172+
site_short_name = var.NGWAF_SITE
173+
fastly_sid = fastly_service_vcl.frontend-vcl-service.id
174+
175+
fastly_service_vcl_active_version = fastly_service_vcl.frontend-vcl-service.active_version
176+
177+
depends_on = [
178+
sigsci_edge_deployment_service.ngwaf_edge_service_link,
179+
]
180+
}
181+
182+
#### Edge deploy and sync - End
183+
184+
output "live_waf_love_output" {
185+
value = <<tfmultiline
186+
187+
#### Click the URL to go to the Fastly VCL service ####
188+
https://cfg.fastly.com/${fastly_service_vcl.frontend-vcl-service.id}
189+
190+
#### Click the URL to go to the Fastly NGWAF service ####
191+
https://dashboard.signalsciences.net/corps/${var.NGWAF_CORP}/sites/${var.NGWAF_SITE}
192+
193+
#### Send a test request with curl. ####
194+
curl -i "https://${var.USER_VCL_SERVICE_DOMAIN_NAME}/anything/whydopirates?likeurls=theargs" -d foo=bar
195+
196+
#### Send an test as traversal with curl. ####
197+
curl -i "https://${var.USER_VCL_SERVICE_DOMAIN_NAME}/anything/myattackreq?i=../../../../etc/passwd" -d foo=bar
198+
199+
#### Send an test as XSS with curl. ####
200+
curl -i "https://${var.USER_VCL_SERVICE_DOMAIN_NAME}/anything/myattackreq?foo=%3Cscript%3E" -d foo=bar
201+
202+
#### Troubleshoot the logging configuration if necessary. ####
203+
https://docs.fastly.com/en/guides/setting-up-remote-log-streaming#troubleshooting-common-logging-errors
204+
curl https://api.fastly.com/service/${fastly_service_vcl.frontend-vcl-service.id}/logging_status -H fastly-key:$FASTLY_API_KEY
205+
206+
tfmultiline
207+
208+
description = "Output hints on what to do next."
209+
210+
depends_on = [
211+
sigsci_edge_deployment_service.ngwaf_edge_service_link
212+
]
213+
}
214+
215+
216+
provider "http" {}
217+
#### Edge deploy linked data - start
218+
data "http" "linked_fastly_services" {
219+
url = "https://dashboard.signalsciences.net/api/v0/corps/${var.NGWAF_CORP}/sites/${var.NGWAF_SITE}/edgeDeployment"
220+
221+
request_headers = {
222+
x-api-user = var.NGWAF_EMAIL
223+
x-api-token = var.NGWAF_TOKEN
224+
Content-Type = "application/json"
225+
}
226+
depends_on = [sigsci_edge_deployment_service.ngwaf_edge_service_link]
227+
}
228+
#### Edge deploy linked data - end
229+
230+
output "services_linked_to_ngwaf_output" {
231+
value = [for item in jsondecode(data.http.linked_fastly_services.response_body)["ServicesAttached"] : item.id]
232+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#### mTLS configuration - start
2+
3+
resource "null_resource" "generate_ca" {
4+
provisioner "local-exec" {
5+
command = <<EOT
6+
mkdir -p certs &&
7+
openssl genrsa 4096 > certs/ca-key.pem &&
8+
openssl req -new -x509 -nodes -days 3650 -key certs/ca-key.pem -subj "/CN=mtl-demo-ca" > certs/ca-cert.pem
9+
EOT
10+
}
11+
}
12+
13+
resource "null_resource" "generate_client_cert" {
14+
provisioner "local-exec" {
15+
command = <<EOT
16+
openssl req -newkey rsa:2048 -days 365 -nodes -keyout certs/client-key1.pem -subj "/CN=client1" > certs/client-req.pem &&
17+
openssl x509 -req -in certs/client-req.pem -days 365 -CA certs/ca-cert.pem -CAkey certs/ca-key.pem -set_serial 01 > certs/client-cert1.pem
18+
EOT
19+
}
20+
21+
depends_on = [null_resource.generate_ca]
22+
}
23+
24+
resource "fastly_tls_subscription" "certainly_tls" {
25+
domains = [for domain in fastly_service_vcl.frontend-vcl-service.domain : domain.name]
26+
certificate_authority = "certainly"
27+
}
28+
29+
resource "fastly_tls_subscription_validation" "certainly_tls" {
30+
subscription_id = fastly_tls_subscription.certainly_tls.id
31+
}
32+
33+
data "fastly_tls_configuration" "default" {
34+
default = true
35+
depends_on = [fastly_tls_subscription_validation.certainly_tls]
36+
}
37+
38+
data "fastly_tls_activation" "mtls_demo" {
39+
# domain = [for domain in fastly_service_vcl.frontend-vcl-service.domain : domain.name]
40+
domain = tolist(fastly_service_vcl.frontend-vcl-service.domain)[0].name
41+
}
42+
43+
resource "fastly_tls_mutual_authentication" "mtls_demo" {
44+
activation_ids = [data.fastly_tls_activation.mtls_demo.id]
45+
name = "mtls demo - mtls-demo.livewaflove.com"
46+
cert_bundle = file("${path.module}/certs/ca-cert.pem")
47+
enforced = false
48+
}
49+
50+
51+
#### mTLS config - end

mtls-terraform-example/providers.tf

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Terraform 0.13+ requires providers to be declared in a "required_providers" block
2+
# https://registry.terraform.io/providers/fastly/fastly/latest/docs
3+
terraform {
4+
required_providers {
5+
fastly = {
6+
source = "fastly/fastly"
7+
version = ">= 5.11.0"
8+
}
9+
sigsci = {
10+
source = "signalsciences/sigsci"
11+
version = ">= 3.3.0"
12+
}
13+
http = {
14+
source = "hashicorp/http"
15+
}
16+
}
17+
}

mtls-terraform-example/variables.tf

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# Fastly Edge VCL configuration
2+
variable "FASTLY_API_KEY" {
3+
type = string
4+
description = "This is API key for the Fastly VCL edge configuration."
5+
}
6+
7+
#### VCL Service variables - Start
8+
variable "USER_VCL_SERVICE_DOMAIN_NAME" {
9+
type = string
10+
description = "Frontend domain for your service."
11+
default = "ngwaf-tf-demo.global.ssl.fastly.net"
12+
}
13+
14+
variable "USER_VCL_SERVICE_BACKEND_HOSTNAME" {
15+
type = string
16+
description = "hostname used for backend."
17+
default = "http-me.glitch.me"
18+
}
19+
20+
#### VCL Service variables - End
21+
22+
#### NGWAF variables - Start
23+
24+
variable "NGWAF_CORP" {
25+
type = string
26+
description = "Corp name for NGWAF"
27+
}
28+
29+
variable "NGWAF_SITE" {
30+
type = string
31+
description = "Site name for NGWAF"
32+
}
33+
34+
variable "NGWAF_EMAIL" {
35+
type = string
36+
description = "Email address associated with the token for the NGWAF API."
37+
}
38+
variable "NGWAF_TOKEN" {
39+
type = string
40+
description = "Secret token for the NGWAF API."
41+
sensitive = true
42+
}
43+
#### NGWAF variables - End
44+
45+
#### External Logging - Start
46+
variable "HONEYCOMB_API_KEY" {
47+
# https://www.honeycomb.io/
48+
type = string
49+
description = "Secret token for the Honeycomb API."
50+
sensitive = true
51+
default = ""
52+
}
53+
54+
# Splunk
55+
variable "SPLUNK_LOGGING_NAME" {
56+
type = string
57+
default = "SPLUNK_LOGGING"
58+
}
59+
60+
variable "SPLUNK_LOGGING_TOKEN" {
61+
type = string
62+
sensitive = true
63+
default = ""
64+
}
65+
66+
variable "SPLUNK_LOGGING_URL" {
67+
type = string
68+
default = ""
69+
}
70+
#### External Logging - END

0 commit comments

Comments
 (0)