I recently encountered some websites that restrict which content I could view based on the region I am located in. This is a brief tutorial on using Amazon EC2 and Squid to bypass those restrictions.

STARTING A NEW EC2 INSTANCE

I chose to use Ubuntu 12.10 Server for my instance. AMI identifiers vary per-region, so if you want a different operating system or are creating an instance in a different region, you should search the Ubuntu Amazon EC2 AMI Locator for a different AMI.

Start a new instance in the eu-west-1 region using AMI ami-e9eded9d:

ec2-run-instances ami-e9eded9d --region eu-west-1 --instance-type t1.micro -k [keypair]

ACCESSING THE EC2 INSTANCE

Determine the external address of your instance and then SSH to it. The default username on an Ubuntu instance is ubuntu.

ec2-describe-instances --region eu-west-1
ssh -i [private_key] ubuntu@[instance]

INSTALL SQUID

sudo apt-get -y install squid

This configuration is specifically tailored to consume very few resources. Also, the configuration limits which headers will be passed through the proxy in an effort to anonymize the origin of the request.

Replace /etc/squid3/squid.conf with the following code block:

http_port 8080

acl to_localhost dst 127.0.0.0/8 0.0.0.0/32 ::1

acl allowed_hosts src 127.0.0.1/32 ::1
acl allowed_hosts src 10.10.10.10/32

http_access deny to_localhost
http_access deny !allowed_hosts
http_access allow all

cache_mem 768 MB
cache_replacement_policy heap LRU
client_db off
coredump_dir /var/spool/squid3
forwarded_for off
fqdncache_size 8192
half_closed_clients off
request_header_replace User-Agent Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1309.0 Safari/537.17
httpd_suppress_version_string on
ignore_expect_100 on
ignore_unknown_nameservers on
ipcache_size 8192
maximum_object_size 250 MB
maximum_object_size_in_memory 1 MB
memory_pools on
memory_replacement_policy heap GDSF
minimum_object_size 0 KB
pipeline_prefetch on
positive_dns_ttl 16 day
read_ahead_gap 1 MB
request_header_max_size 256 KB
shutdown_lifetime 0 second
unique_hostname localhost
visible_hostname localhost

# comment these lines if you uncomment the debugging lines
access_log none
cache_store_log none

# uncomment these lines to enable logging
#logformat combined %>a %[ui %[un [%tl] "%rm %ru HTTP/%rv" %>Hs %<st "%{Referer}>h" "%{User-Agent}>h" %Ss:%Sh
#access_log /var/log/squid3/access.log combined
#cache_store_log /var/log/squid3/store.log

cache_log /var/log/squid3/cache.log

log_icp_queries off
log_mime_hdrs on

request_header_access Allow allow all
request_header_access Accept allow all
request_header_access Accept-Charset allow all
request_header_access Accept-Encoding allow all
request_header_access Accept-Language allow all
request_header_access Authorization allow all
request_header_access Cache-Control allow all
request_header_access Connection allow all
request_header_access Content-Encoding allow all
request_header_access Content-Language allow all
request_header_access Content-Length allow all
request_header_access Content-Type allow all
request_header_access Cookie allow all
request_header_access Date allow all
request_header_access Expires allow all
request_header_access Host allow all
request_header_access If-Modified-Since allow all
request_header_access Last-Modified allow all
request_header_access Location allow all
request_header_access Mime-Version allow all
request_header_access Pragma allow all
request_header_access Proxy-Authenticate allow all
request_header_access Proxy-Authorization allow all
request_header_access Proxy-Connection allow all
request_header_access Retry-After allow all
request_header_access Title allow all
request_header_access User-Agent allow all
request_header_access WWW-Authenticate allow all
request_header_access All deny all

PROXY AUTO-CONFIGURATION (OPTIONAL)

Proxy auto-configuration works by serving a file to your browser periodically that tells the browser which destinations should use the proxy and which should bypass the proxy. Proxy auto-configuration is not a requirement, however it does allow for changing proxy rules without modifying the client.

If you don’t want to use proxy auto-configuration, skip this section.

Install nginx:

sudo apt-get -y install nginx

Replace /usr/share/nginx/www/proxy.pac with the following code block.

You will also need to modify the PROXY line to reflect the public IP address of your instance. You can fine the current public IP address of your instance by using curl (see the comment in the proxy.pac file below).

function FindProxyForURL(url, host) {
  if ( shExpMatch(host, "*.netflix.com") ||
       shExpMatch(host, "*.nflxext.com") ||
       shExpMatch(host, "*.nflxvideo.net") ||
       isInNet(host, "37.77.0.0",  "255.255.0.0") )
  {
    // to get the public ipv4 address of this instance:
    // curl http://169.254.169.254/latest/meta-data/public-ipv4
    return "PROXY 46.137.55.57:8080; DIRECT";
  }

  return "DIRECT";
}

Replace /etc/nginx/sites-enabled/default with the following code block:

server {
  server_name localhost;
  root /usr/share/nginx/www;

  location = /favicon.ico {
    return 204;
    access_log off;
    log_not_found off;
  }

  location ~ /\.ht {
    deny all;
  }

  location / {
    allow 127.0.0.1;
    allow 10.10.10.10;
    deny all;

    try_files $uri $uri/ /index.html;
  }
}

LOCK IT DOWN!

Having an open proxy server on the internet is probably not your intention.

You will need to change the allowed_hosts ACL in the /etc/squid3/squid.conf file to add your clients IP address/netmask so they can access the proxy.

If you are using proxy auto-configuration, you will need to change the location / directive in the /etc/nginx/sites-enabled/default to add your clients IP address/netmask so they can access the proxy auto-configuration file.

You should probably also delete the example references to 10.10.10.10 from both locations.

MODIFY THE INSTANCE SECURITY GROUP

By default, instances only permit inbound. In addition to telling our applications which clients to allow, we must tell EC2 as well.

Determine which security group your instance is using. You are specifically looking for a label that looks like sg-12345678.

ec2-describe-instances --region eu-west-1

Assuming you are using the security group sg-12345678:

ec2-authorize --region eu-west-1 sg-12345678 -p 8080

If you are using proxy auto-configuration, you need to open up tcp/80 as well.

ec2-authorize --region eu-west-1 sg-12345678 -p 80

Verify the security group is correct:

ec2-describe-group --region eu-west-1 sg-12345678

CLIENTS USING PROXY AUTO-CONFIGURATION

CLIENTS USING MANUAL PROXY SETTINGS