-
Notifications
You must be signed in to change notification settings - Fork 913
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #56 from terraform-google-modules/cos-squid
Add squid container to cloud-config module
- Loading branch information
Showing
9 changed files
with
337 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
# Containerized Squid on Container Optimized OS | ||
|
||
This module manages a `cloud-config` configuration that starts a containerized [Squid](http://www.squid-cache.org/) proxy on Container Optimized OS. The default configuration creates a filtering proxy that only allows connection to a whitelisted set of domains. | ||
|
||
The resulting `cloud-config` can be customized in a number of ways: | ||
|
||
- a custom squid.conf configuration can be set using the `squid_config` variable | ||
- additional files (e.g. additional acls) can be passed in via the `files` variable | ||
- a completely custom `cloud-config` can be passed in via the `cloud_config` variable, and additional template variables can be passed in via `config_variables` | ||
|
||
The default instance configuration inserts iptables rules to allow traffic on TCP port 3128. | ||
|
||
Logging and monitoring are enabled via the [Google Cloud Logging driver](https://docs.docker.com/config/containers/logging/gcplogs/) configured for the Squid container, and the [Node Problem Detector](https://cloud.google.com/container-optimized-os/docs/how-to/monitoring) service started by default on boot. | ||
|
||
The module renders the generated cloud config in the `cloud_config` output, to be used in instances or instance templates via the `user-data` metadata. | ||
|
||
For convenience during development or for simple use cases, the module can optionally manage a single instance via the `test_instance` variable. If the instance is not needed the `instance*tf` files can be safely removed. Refer to the [top-level README](../README.md) for more details on the included instance. | ||
|
||
## Examples | ||
|
||
### Default Squid configuration | ||
|
||
This example will create a `cloud-config` that allows any client in the 10.0.0.0/8 CIDR to use the proxy to connect github.com or any subdomain of github.com. | ||
|
||
```hcl | ||
module "cos-squid" { | ||
source = "./modules/cos-container/squid" | ||
whitelist = [".github.com"] | ||
clients = ["10.0.0.0/8"] | ||
} | ||
# use it as metadata in a compute instance or template | ||
resource "google_compute_instance" "default" { | ||
metadata = { | ||
user-data = module.cos-squid.cloud_config | ||
} | ||
``` | ||
|
||
### Test Squid instance | ||
|
||
This example shows how to create the single instance optionally managed by the module, providing all required attributes in the `test_instance` variable. The instance is purposefully kept simple and should only be used in development, or when designing infrastructures. | ||
|
||
```hcl | ||
module "cos-squid" { | ||
source = "./modules/cos-container/squid" | ||
whitelist = ["github.com"] | ||
clients = ["10.0.0.0/8"] | ||
test_instance = { | ||
project_id = "my-project" | ||
zone = "europe-west1-b" | ||
name = "cos-squid" | ||
type = "f1-micro" | ||
network = "default" | ||
subnetwork = "https://www.googleapis.com/compute/v1/projects/my-project/regions/europe-west1/subnetworks/my-subnet" | ||
} | ||
} | ||
``` | ||
|
||
<!-- BEGIN TFDOC --> | ||
## Variables | ||
|
||
| name | description | type | required | default | | ||
|---|---|:---: |:---:|:---:| | ||
| *clients* | List of CIDRs from which Squid will allow connections | <code title="list(string)">list(string)</code> | | <code title="">[]</code> | | ||
| *cloud_config* | Cloud config template path. If null default will be used. | <code title="">string</code> | | <code title="">null</code> | | ||
| *config_variables* | Additional variables used to render the cloud-config and Squid templates. | <code title="map(any)">map(any)</code> | | <code title="">{}</code> | | ||
| *file_defaults* | Default owner and permissions for files. | <code title="object({ owner = string permissions = string })">object({...})</code> | | <code title="{ owner = "root" permissions = "0644" }">...</code> | | ||
| *files* | Map of extra files to create on the instance, path as key. Owner and permissions will use defaults if null. | <code title="map(object({ content = string owner = string permissions = string }))">map(object({...}))</code> | | <code title="">{}</code> | | ||
| *squid_config* | Squid configuration path, if null default will be used. | <code title="">string</code> | | <code title="">null</code> | | ||
| *test_instance* | Test/development instance attributes, leave null to skip creation. | <code title="object({ project_id = string zone = string name = string type = string network = string subnetwork = string })">object({...})</code> | | <code title="">null</code> | | ||
| *test_instance_defaults* | Test/development instance defaults used for optional configuration. If image is null, COS stable will be used. | <code title="object({ disks = map(object({ read_only = bool size = number })) image = string metadata = map(string) nat = bool service_account_roles = list(string) tags = list(string) })">object({...})</code> | | <code title="{ disks = {} image = null metadata = {} nat = false service_account_roles = [ "roles/logging.logWriter", "roles/monitoring.metricWriter" ] tags = ["ssh"] }">...</code> | | ||
| *whitelist* | List of domains Squid will allow connections to | <code title="list(string)">list(string)</code> | | <code title="">[]</code> | | ||
|
||
## Outputs | ||
|
||
| name | description | sensitive | | ||
|---|---|:---:| | ||
| cloud_config | Rendered cloud-config file to be passed as user-data instance metadata. | | | ||
| test_instance | Optional test instance name and address | | | ||
<!-- END TFDOC --> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
#cloud-config | ||
|
||
# Copyright 2020 Google LLC | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# https://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
# TODO: switch to the gcplogs logging driver, and set driver labels | ||
|
||
users: | ||
- name: squid | ||
uid: 2000 | ||
|
||
write_files: | ||
- path: /var/lib/docker/daemon.json | ||
permissions: 0644 | ||
owner: root | ||
content: | | ||
{ | ||
"live-restore": true, | ||
"storage-driver": "overlay2", | ||
"log-opts": { | ||
"max-size": "1024m" | ||
} | ||
} | ||
- path: /etc/squid/squid.conf | ||
permissions: 0644 | ||
owner: root | ||
content: | | ||
${indent(6, squid_config)} | ||
- path: /etc/squid/whitelist.txt | ||
permissions: 0644 | ||
owner: root | ||
content: | | ||
${indent(6, join("\n", whitelist))} | ||
- path: /etc/squid/clients.txt | ||
permissions: 0644 | ||
owner: root | ||
content: | | ||
${indent(6, join("\n", clients))} | ||
# squid container service | ||
- path: /etc/systemd/system/squid.service | ||
permissions: 0644 | ||
owner: root | ||
content: | | ||
[Unit] | ||
Description=Start squid container | ||
After=gcr-online.target docker.socket | ||
Wants=gcr-online.target docker.socket docker-events-collector.service | ||
[Service] | ||
Environment="HOME=/home/squid" | ||
ExecStartPre=/usr/bin/docker-credential-gcr configure-docker | ||
ExecStart=/usr/bin/docker run --rm --name=squid \ | ||
--log-driver=gcplogs --network host \ | ||
-v /etc/squid:/etc/squid \ | ||
gcr.io/pso-cft-fabric/squid:0.10 | ||
ExecStop=/usr/bin/docker stop squid | ||
ExecStopPost=/usr/bin/docker rm squid | ||
%{ for path, data in files } | ||
- path: ${path} | ||
owner: ${lookup(data, "owner", "root")} | ||
permissions: ${lookup(data, "permissions", "0644")} | ||
content: | | ||
${indent(4, data.content)} | ||
%{ endfor } | ||
|
||
bootcmd: | ||
- systemctl start node-problem-detector | ||
|
||
runcmd: | ||
- iptables -I INPUT 1 -p tcp -m tcp --dport 3128 -m state --state NEW,ESTABLISHED -j ACCEPT | ||
- systemctl daemon-reload | ||
- systemctl start squid |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
../instance.tf |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
/** | ||
* Copyright 2019 Google LLC | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
locals { | ||
cloud_config = templatefile(local.template, merge(local.config_variables, { | ||
squid_config = templatefile(local.squid_config, local.config_variables) | ||
files = local.files | ||
})) | ||
squid_config = ( | ||
var.squid_config == null ? "${path.module}/squid.conf" : var.squid_config | ||
) | ||
files = { | ||
for path, attrs in var.files : path => { | ||
content = attrs.content, | ||
owner = attrs.owner == null ? var.file_defaults.owner : attrs.owner, | ||
permissions = ( | ||
attrs.permissions == null | ||
? var.file_defaults.permissions | ||
: attrs.permissions | ||
) | ||
} | ||
} | ||
template = ( | ||
var.cloud_config == null | ||
? "${path.module}/cloud-config.yaml" | ||
: var.cloud_config | ||
) | ||
config_variables = merge(var.config_variables, { | ||
whitelist = var.whitelist | ||
clients = var.clients | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
../outputs-instance.tf |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
/** | ||
* Copyright 2019 Google LLC | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
output "cloud_config" { | ||
description = "Rendered cloud-config file to be passed as user-data instance metadata." | ||
value = local.cloud_config | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
# bind to port 3128 | ||
http_port 0.0.0.0:3128 | ||
|
||
# only proxy, don't cache | ||
cache deny all | ||
|
||
acl ssl_ports port 443 | ||
acl safe_ports port 80 | ||
acl safe_ports port 443 | ||
acl CONNECT method CONNECT | ||
|
||
# read clientd cidr from clients.txt | ||
acl clients src "/etc/squid/clients.txt" | ||
|
||
# read whitelisted domains from whitelist.txt | ||
acl whitelist dstdomain "/etc/squid/whitelist.txt" | ||
|
||
# deny access to anything other than ports 80 and 443 | ||
http_access deny !safe_ports | ||
|
||
# deny CONNECT if connection is not using ssl | ||
http_access deny CONNECT !ssl_ports | ||
|
||
# deny acccess to cachemgr | ||
http_access deny manager | ||
|
||
# deny access to localhost though the proxy | ||
http_access deny to_localhost | ||
|
||
# allow connection from allowed clients only to the whitelisted domains | ||
http_access allow clients whitelist | ||
|
||
# deny everything else | ||
http_access deny all |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
../variables-instance.tf |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
/** | ||
* Copyright 2019 Google LLC | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
variable "cloud_config" { | ||
description = "Cloud config template path. If null default will be used." | ||
type = string | ||
default = null | ||
} | ||
|
||
variable "config_variables" { | ||
description = "Additional variables used to render the cloud-config and Squid templates." | ||
type = map(any) | ||
default = {} | ||
} | ||
|
||
variable "squid_config" { | ||
description = "Squid configuration path, if null default will be used." | ||
type = string | ||
default = null | ||
} | ||
|
||
variable "file_defaults" { | ||
description = "Default owner and permissions for files." | ||
type = object({ | ||
owner = string | ||
permissions = string | ||
}) | ||
default = { | ||
owner = "root" | ||
permissions = "0644" | ||
} | ||
} | ||
|
||
variable "files" { | ||
description = "Map of extra files to create on the instance, path as key. Owner and permissions will use defaults if null." | ||
type = map(object({ | ||
content = string | ||
owner = string | ||
permissions = string | ||
})) | ||
default = {} | ||
} | ||
|
||
variable "whitelist" { | ||
description = "List of domains Squid will allow connections to" | ||
type = list(string) | ||
default = [] | ||
} | ||
|
||
variable "clients" { | ||
description = "List of CIDRs from which Squid will allow connections" | ||
type = list(string) | ||
default = [] | ||
} |