A Squid transparent proxy server with Postfix configured as a SASL-authenticated SMTP relay to Amazon Simple Email Service (SES).
- See the root README for instructions on using Terraform modules.
- See variables.tf for all the variables you can set on this module.
- See outputs.tf for all outputs you can get from this module in a terraform_remote_state data source.
Let's Encrypt limits 5 new certificates per week per FQDN, and 50 certificates per week per registered domain.
See Rate Limits - Let's Encrypt - Free SSL/TLS Certificates to learn more.
Provide squid_backup_timestamp when provisioning to avoid this.
Squid is a caching and forwarding HTTP web proxy. It has a wide variety of uses, including speeding up a web server by caching repeated requests, caching web, DNS and other computer network lookups for a group of people sharing network resources, and aiding security by filtering traffic.
https://en.wikipedia.org/wiki/Squid_(software)
Postfix is a free and open-source mail transfer agent that routes and delivers electronic mail.
https://en.wikipedia.org/wiki/Postfix_(software)
Postfix is configured to provide SMTP via Implicit TLS (establish TLS connection before sending anything) on TCP/465. Why not explicit TLS (connect in plaintext, then upgrade using STARTTLS) on TCP/587? Many sites have published articles suggesting that TCP/465 is an incorrect port for SMTP unsupported by the IETF and should be discouraged. As of January 2018, they are incorrect as the IETF has issued RFC 8314 which clearly advises otherwise:
To encourage more widespread use of TLS and to also encourage greater consistency regarding how TLS is used, this specification now recommends the use of Implicit TLS for POP, IMAP, SMTP Submission, and all other protocols used between an MUA and an MSP.
https://tools.ietf.org/html/rfc8314#section-3
The ami variable requires a pre-build AMI with Squid and Postfix configured. Run Packer to build the AMI:
cd packer
# get actual from Github OAuth token from your password manager
export GITHUB_OAUTH_TOKEN='**********************'
export ssh_grunt_iam_role_arn="arn:aws:iam::$(aws-vault exec security -- aws sts get-caller-identity | jq '.Account' --raw-output):role/allow-ssh-iam-access-from-other-accounts"
function create-squid-ami {
environment="$1"
export squid_bucket="squid-allowlist-sbi-$environment"
export PACKER_VPC_ID="$(aws-vault exec "$environment" -- aws ec2 describe-vpcs --filters 'Name=tag:Name,Values=mgmt' --query 'Vpcs[].VpcId' --output text)"
export PACKER_SUBNET_ID="$(aws-vault exec "$environment" -- aws ec2 describe-subnets --filters 'Name=tag:Name,Values=mgmt-public-0' --query 'Subnets[].SubnetId' --output text)"
aws-vault exec "$environment" -- packer build squid-server.json
}
To build it for dev run the following:
create-squid-ami dev
To ensure everything is configured properly on the Squid server:
-
Run "iptables -t nat -L", you should see the proper nat statements.
target prot opt source destination REDIRECT tcp -- anywhere anywhere tcp dpt:http redir ports 3129 REDIRECT tcp -- anywhere anywhere tcp dpt:https redir ports 3130 Chain INPUT (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination Chain POSTROUTING (policy ACCEPT) target prot opt source destination
-
Verify Allow List is updating.
Go to cat /etc/squid/allowlist.txt. Should only have one entry, ".amazonaws.com". Create a text file called allowlist.txt with a new allowlist and upload to your squid bucket with the following entries.
.amazonaws.com .example.com
To do this, upload from the console. You MUST choose "AWS KMS master-key" for encryption and choose "cmk-dev". In one minute you should see the list automatically populate the /etc/squid/allowlist.txt file!
-
Test Squid Proxy:
SSH to instance using keypair. Sudo su. Run "systemctl status squid" and ensure it is actively running.
tail -f /var/log/squid/access.log
From another server that is using the squid server as the Subnet Default Gateway, use the following curl commands to verify:
curl 'http://www.example.com/' curl 'https://www.example.com/' curl 'http://s3.amazonaws.com/' curl 'https://s3.amazonaws.com/'
These sections explain how to interpret /var/log/squid/access.log output.
There are four possible types of results. Below is a list of the 4 types and what each will look like in the squid log.
1580355117.679 72 10.1.2.30 TCP_MISS/301 315 GET http://s3.amazonaws.com/ - ORIGINAL_DST/52.217.37.6 text/html
1580355347.533 519 10.1.2.30 TCP_TUNNEL/200 1533059 CONNECT s3.amazonaws.com - ORIGINAL_DST/52.217.37.6 - 1580355347.533 519 10.1.2.30 TCP_TUNNEL/200 1533059 CONNECT 52.217.37.6:443 - ORIGINAL_DST/52.217.37.6
1580355105.737 48 10.1.2.30 TCP_DENIED/403 3831 GET http://badssl.com/ - HIER_NONE/- text/html
1580355433.795 86 10.1.2.30 TAG_NONE/200 0 CONNECT badssl.com - HIER_NONE/- - 1580355433.795 86 10.1.2.30 TAG_NONE/200 0 CONNECT 104.154.89.105:443 - HIER_NONE/- -
Notice that the Access Denied HTTPS is identifiable by "TAG_NONE" and "HIER_NONE"
This expains to allow all HTTP and HTTPS traffic through Squid if required.
Replace the following two lines in /etc/squid/squid.conf:
To allow all HTTP, replace:
acl allowed_http_sites dstdomain "/etc/squid/allowlist.txt"
with:
acl allowed_http_sites dstdom_regex .*
To allow all HTTPS, replace:
acl allowed_https_sites ssl::server_name "/etc/squid/allowlist.txt"
with:
acl allowed_https_sites ssl::server_name_regex .*
Then run "squid -k parse" and "squid -k reconfigure" to load the new file without having to restart squid server.