<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>intercept &#8211; Blog of Kliment Andreev &#8211; A place so I won&#039;t forget things</title>
	<atom:link href="https://blog.andreev.it/tag/intercept/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.andreev.it</link>
	<description></description>
	<lastBuildDate>Wed, 12 Aug 2020 01:08:45 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	
	<item>
		<title>AWS: squid transparent proxy for DNS filtering/whitelisting</title>
		<link>https://blog.andreev.it/2019/11/aws-squid-transparent-proxy-for-dns-filtering-whitelisting/</link>
					<comments>https://blog.andreev.it/2019/11/aws-squid-transparent-proxy-for-dns-filtering-whitelisting/#respond</comments>
		
		<dc:creator><![CDATA[Kliment Andreev]]></dc:creator>
		<pubDate>Sun, 17 Nov 2019 22:38:01 +0000</pubDate>
				<category><![CDATA[AWS]]></category>
		<category><![CDATA[CentOS]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[centos]]></category>
		<category><![CDATA[intercept]]></category>
		<category><![CDATA[splice]]></category>
		<category><![CDATA[squid]]></category>
		<category><![CDATA[ssl bump]]></category>
		<category><![CDATA[transparent proxy]]></category>
		<guid isPermaLink="false">https://blog.andreev.it/?p=6035</guid>

					<description><![CDATA[If you have some instances running in AWS, most likely they are in the&#8230;]]></description>
										<content:encoded><![CDATA[<div id="bsf_rt_marker"></div><p>If you have some instances running in AWS, most likely they are in the private subnet and to access Internet they use the Internet Gateway. By default, they can access everything and that&#8217;s a big no-no. You don&#8217;t want to be an open SMTP relay or a Bitcoin node if your instance is compromised. But the Internet Gateway can&#8217;t do the filtering for you. You are able to access everything. Granted, you can modify the rules in the Network ACL, but you can only deny access to IPs, not URLs. The problem with this scenario is that many update sites have IPs that change from time to time or they use CDN networks with a tons of IPs behind. If you whitelist these IPs, then technically you are whitelisting every single site that&#8217;s behind the CDN network such as akamai.<br />
One of the solutions is to use <a href="http://www.squid-cache.org/" rel="noopener noreferrer" target="_blank">squid</a>. squid can act as a cache server and transparent proxy. Transparent proxy means that the instances that are accessing the Internet are not aware that they are behind a proxy, you don&#8217;t have to specify any settings on the instance that&#8217;s accessing the Internet. A transparent proxy is much more easier for the end user/client, they don&#8217;t have to configure anything on their end.<br />
I&#8217;ll show you how to configure a squid transparent proxy that sits in a public subnet in AWS and the instances that are in the private subnets will use squid to access Internet. I&#8217;ll implement whitelisting ACL which means that only allowed sites will be reachable. The rest is blocked. This solution is not for your home/lab network where you want to access everything. With this solution most sites will not show properly unless you whitelist all the dependencies. For example, some sites have their CSS scripts in a separate domain, so if you whitelist amazon.com, you&#8217;ll be able to access it, but it will look garbled because their CSS is on awsstatic.com. So, you have to whitelist this site. I&#8217;ll explain how to find that as well if you encounter these problems.<br />
Before I begin, these are the pre-requisites and the expectations. We&#8217;ll use CentOS 7 (with SELinux disabled) as a squid server that runs in a public subnet and the instances that want to access the Internet are in a private subnet. squid constantly evolves, so whatever works now might not work tomorrow, because of the nature of how we access SSL sites (related to TLS 1.3). I&#8217;ll use CentOS 7 and squid 4.9. If you use a different version, this might not work. Also, subsequent updates might break this solution. If you want an Enterprise solution, you might want to look somewhere else.<br />
Here is my architectural diagram. I&#8217;ll explain every detail. If you have your VPCs, subnets, routes ready, you might want to skip this, but pay attention on the routing.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/11/P139-14.jpg"><img fetchpriority="high" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/11/P139-14.jpg" alt="" width="1792" height="1063" class="aligncenter size-full wp-image-6060" srcset="https://blog.andreev.it/wp-content/uploads/2019/11/P139-14.jpg 1792w, https://blog.andreev.it/wp-content/uploads/2019/11/P139-14-300x178.jpg 300w, https://blog.andreev.it/wp-content/uploads/2019/11/P139-14-1024x607.jpg 1024w, https://blog.andreev.it/wp-content/uploads/2019/11/P139-14-768x456.jpg 768w, https://blog.andreev.it/wp-content/uploads/2019/11/P139-14-1536x911.jpg 1536w, https://blog.andreev.it/wp-content/uploads/2019/11/P139-14-1170x694.jpg 1170w, https://blog.andreev.it/wp-content/uploads/2019/11/P139-14-585x347.jpg 585w" sizes="(max-width: 1792px) 100vw, 1792px" /></a></p>
<h1>VPC, subnets, public route and Internet Gateway</h1>
<p>I&#8217;ll create a new VPC called vpcSquid and I&#8217;ll carve that VPC with two subnets, one private and one public. Each will accommodate 256 hosts.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/11/P139-01.png"><img decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/11/P139-01.png" alt="" width="690" height="326" class="aligncenter size-full wp-image-6039" srcset="https://blog.andreev.it/wp-content/uploads/2019/11/P139-01.png 690w, https://blog.andreev.it/wp-content/uploads/2019/11/P139-01-300x142.png 300w, https://blog.andreev.it/wp-content/uploads/2019/11/P139-01-585x276.png 585w" sizes="(max-width: 690px) 100vw, 690px" /></a><br />
Let&#8217;s create the two subnets. Go to the <strong>VPC </strong>menu and from the <strong>Subnets </strong>submenu click on <strong>Create subnet</strong>.<br />
The first one is the public subnet where squid server will reside.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/11/P139-02.png"><img decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/11/P139-02.png" alt="" width="696" height="401" class="aligncenter size-full wp-image-6040" srcset="https://blog.andreev.it/wp-content/uploads/2019/11/P139-02.png 696w, https://blog.andreev.it/wp-content/uploads/2019/11/P139-02-300x173.png 300w, https://blog.andreev.it/wp-content/uploads/2019/11/P139-02-585x337.png 585w" sizes="(max-width: 696px) 100vw, 696px" /></a><br />
Create the private subnet.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/11/P139-03.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/11/P139-03.png" alt="" width="696" height="406" class="aligncenter size-full wp-image-6041" srcset="https://blog.andreev.it/wp-content/uploads/2019/11/P139-03.png 696w, https://blog.andreev.it/wp-content/uploads/2019/11/P139-03-300x175.png 300w, https://blog.andreev.it/wp-content/uploads/2019/11/P139-03-585x341.png 585w" sizes="(max-width: 696px) 100vw, 696px" /></a><br />
Now go to the <strong>Route tables</strong> menu and you&#8217;ll see that you have a route there already. This route was created when you created the VPC. It refers to the public subnet, but it&#8217;s not associated yet.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/11/P139-04.jpg"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/11/P139-04.jpg" alt="" width="583" height="283" class="aligncenter size-full wp-image-6044" srcset="https://blog.andreev.it/wp-content/uploads/2019/11/P139-04.jpg 583w, https://blog.andreev.it/wp-content/uploads/2019/11/P139-04-300x146.jpg 300w" sizes="(max-width: 583px) 100vw, 583px" /></a><br />
Click one the <strong>Subnet associations</strong> tab and then click on <strong>Edit subnet assications</strong> button. Select the public subnet and click <strong>Save</strong>.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/11/P139-05.jpg"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/11/P139-05.jpg" alt="" width="490" height="197" class="aligncenter size-full wp-image-6045" srcset="https://blog.andreev.it/wp-content/uploads/2019/11/P139-05.jpg 490w, https://blog.andreev.it/wp-content/uploads/2019/11/P139-05-300x121.jpg 300w" sizes="(max-width: 490px) 100vw, 490px" /></a><br />
Before we create a route to the Internet for the public subnet, we need an Internet Gateway. Click on the <strong>Internet Gateways</strong> menu on the left and click <strong>Create Internet Gateway</strong>. I named mine gwSquid. Select the newly created <strong>Internet Gateway</strong> and then click on the <strong>Actions </strong>button and click on <strong>Attach to VPC</strong>. Assign the VPC that we created.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/11/P139-06.jpg"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/11/P139-06.jpg" alt="" width="408" height="242" class="aligncenter size-full wp-image-6046" srcset="https://blog.andreev.it/wp-content/uploads/2019/11/P139-06.jpg 408w, https://blog.andreev.it/wp-content/uploads/2019/11/P139-06-300x178.jpg 300w" sizes="(max-width: 408px) 100vw, 408px" /></a><br />
Now, go back to the <strong>Route tables</strong>, then select the public route again and click on the <strong>Routes </strong>tab. Click on <strong>Edit routes</strong> button, then click on <strong>Add route</strong>.<br />
Add a route to the Internet (0.0.0.0/0) over the Internet gateway that we just created. Click on <strong>Save routes</strong>.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/11/P139-07.jpg"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/11/P139-07.jpg" alt="" width="849" height="253" class="aligncenter size-full wp-image-6047" srcset="https://blog.andreev.it/wp-content/uploads/2019/11/P139-07.jpg 849w, https://blog.andreev.it/wp-content/uploads/2019/11/P139-07-300x89.jpg 300w, https://blog.andreev.it/wp-content/uploads/2019/11/P139-07-768x229.jpg 768w, https://blog.andreev.it/wp-content/uploads/2019/11/P139-07-585x174.jpg 585w" sizes="(max-width: 849px) 100vw, 849px" /></a></p>
<h1>squid instance</h1>
<p>Let&#8217;s create the instance now. Choose CentOS 7 image, deploy it in the VPC that we just created. Make sure it&#8217;s in the public subnet and that you have a public IP.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/11/P139-08.jpg"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/11/P139-08.jpg" alt="" width="653" height="147" class="aligncenter size-full wp-image-6048" srcset="https://blog.andreev.it/wp-content/uploads/2019/11/P139-08.jpg 653w, https://blog.andreev.it/wp-content/uploads/2019/11/P139-08-300x68.jpg 300w, https://blog.andreev.it/wp-content/uploads/2019/11/P139-08-585x132.jpg 585w" sizes="(max-width: 653px) 100vw, 653px" /></a><br />
For storage, choose whatever you like. If you want to use squid as a cache server, then choose more than the default 8GB. For example, if you choose 20GB disk, you can also restrict squid to keep only 12GB of cache for example. Your choice.<br />
Assign a security group that allows port 22 (SSH). In my case I allowed access from everywhere (0.0.0.0/0), but it&#8217;s wisely to choose only certain IPs or subnets. This is a test instance, so I&#8217;ll proceed with 0.0.0.0/0.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/11/P139-09.jpg"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/11/P139-09.jpg" alt="" width="865" height="264" class="aligncenter size-full wp-image-6049" srcset="https://blog.andreev.it/wp-content/uploads/2019/11/P139-09.jpg 865w, https://blog.andreev.it/wp-content/uploads/2019/11/P139-09-300x92.jpg 300w, https://blog.andreev.it/wp-content/uploads/2019/11/P139-09-768x234.jpg 768w, https://blog.andreev.it/wp-content/uploads/2019/11/P139-09-585x179.jpg 585w" sizes="(max-width: 865px) 100vw, 865px" /></a><br />
Finally choose your key and launch the instance. While the instance spins up, go back to the <strong>VPC | Route tables</strong> menu.</p>
<h1>Private route</h1>
<p>Click on <strong>Create Route table</strong> button and enter the name of the private route and associate it the the VPC. Click the <strong>Create </strong>button.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/11/P139-10.jpg"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/11/P139-10.jpg" alt="" width="718" height="211" class="aligncenter size-full wp-image-6050" srcset="https://blog.andreev.it/wp-content/uploads/2019/11/P139-10.jpg 718w, https://blog.andreev.it/wp-content/uploads/2019/11/P139-10-300x88.jpg 300w, https://blog.andreev.it/wp-content/uploads/2019/11/P139-10-585x172.jpg 585w" sizes="(max-width: 718px) 100vw, 718px" /></a><br />
Select the private route and click on the <strong>Subnet Associations</strong> tab. Click <strong>Edit subnet associations</strong> button and select the private subnet.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/11/P139-11.jpg"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/11/P139-11.jpg" alt="" width="839" height="198" class="aligncenter size-full wp-image-6051" srcset="https://blog.andreev.it/wp-content/uploads/2019/11/P139-11.jpg 839w, https://blog.andreev.it/wp-content/uploads/2019/11/P139-11-300x71.jpg 300w, https://blog.andreev.it/wp-content/uploads/2019/11/P139-11-768x181.jpg 768w, https://blog.andreev.it/wp-content/uploads/2019/11/P139-11-585x138.jpg 585w" sizes="(max-width: 839px) 100vw, 839px" /></a><br />
Then click on the <strong>Routes </strong>tab and click on <strong>Edit routes</strong>. Click <strong>Add route</strong>. For <strong>Destination </strong>type 0.0.0.0/0, for the target select <strong>Instance </strong>and select the instance that we just created. Click <strong>Save routes</strong> button. What we just did is we told AWS to route the Internet request in the private subnet through our squid instance. So, the Internet request will go to the instance first and then through the Internet gateway.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/11/P139-12.jpg"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/11/P139-12.jpg" alt="" width="858" height="270" class="aligncenter size-full wp-image-6052" srcset="https://blog.andreev.it/wp-content/uploads/2019/11/P139-12.jpg 858w, https://blog.andreev.it/wp-content/uploads/2019/11/P139-12-300x94.jpg 300w, https://blog.andreev.it/wp-content/uploads/2019/11/P139-12-768x242.jpg 768w, https://blog.andreev.it/wp-content/uploads/2019/11/P139-12-585x184.jpg 585w" sizes="(max-width: 858px) 100vw, 858px" /></a></p>
<h1>Source/Destination Check</h1>
<p>At this point, the only thing remaining is to go to the instance and change the <strong>Source/Destination Check</strong> setting. Select the instance, click the <strong>Actions </strong>button, then select <strong>Networking </strong>and then <strong>Select Source/Dest. Check</strong>. Click on <strong>Yes, Disable</strong>.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/11/P139-13.jpg"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/11/P139-13.jpg" alt="" width="593" height="196" class="aligncenter size-full wp-image-6053" srcset="https://blog.andreev.it/wp-content/uploads/2019/11/P139-13.jpg 593w, https://blog.andreev.it/wp-content/uploads/2019/11/P139-13-300x99.jpg 300w, https://blog.andreev.it/wp-content/uploads/2019/11/P139-13-585x193.jpg 585w" sizes="(max-width: 593px) 100vw, 593px" /></a></p>
<h1>Install squid from source</h1>
<p>SSH to the instance using <strong>centos </strong>as user and your key as password. Type <strong>sudo su</strong> to get the root prompt. CentOS comes with squid 3.5, but we&#8217;ll install squid 4.9 from the source.<br />
First, install the pre-requisites.</p>
<pre class="brush: bash; title: ; notranslate">
yum install -y perl gcc-c++ autoconf automake make wget
yum install -y libxml2-devel libecap-devel openssl-devel openldap-devel pam-devel libdb-devel
</pre>
<p>Then, create a user that will run the squid daemon.</p>
<pre class="brush: bash; title: ; notranslate">
adduser squid -r -s /sbin/nologin -m
</pre>
<p>Go to the /tmp folder, download the squid tarball, extract it and go to that directory.</p>
<pre class="brush: bash; title: ; notranslate">
cd /tmp
wget http://www.squid-cache.org/Versions/v4/squid-4.9.tar.gz
tar xzvf squid-4.9.tar.gz
cd squid-4.9
</pre>
<p>Configure the squid with all helpers. Click the plus sign to expand the source.</p>
<pre class="brush: bash; collapse: true; light: false; title: ; toolbar: true; notranslate">
./configure --build=x86_64-redhat-linux-gnu --host=x86_64-redhat-linux-gnu \
--program-prefix= --prefix=/usr --exec-prefix=/usr \
--bindir=/usr/bin --sbindir=/usr/sbin --sysconfdir=/etc \
--datadir=/usr/share --includedir=/usr/include \
--libdir=/usr/lib64 --libexecdir=/usr/libexec \
--sharedstatedir=/var/lib --mandir=/usr/share/man \
--infodir=/usr/share/info \
--exec_prefix=/usr --libexecdir=/usr/lib64/squid \
--localstatedir=/var --datadir=/usr/share/squid \
--sysconfdir=/etc/squid --with-logdir=/var/log/squid \
--with-pidfile=/var/run/squid.pid --enable-auth \
--enable-auth-basic=DB,LDAP,NCSA,NIS,PAM,POP3,RADIUS,SASL,SMB,getpwnam,fake \
--enable-auth-ntlm=fake --enable-auth-digest=file,LDAP,eDirectory \
--enable-auth-negotiate=kerberos,wrapper \
--enable-external-acl-helpers=file_userip,LDAP_group,time_quota,delayer,SQL_session,session,unix_group,wbinfo_group,kerberos_ldap_group \
--enable-cache-digests --enable-cachemgr-hostname=localhost \
--enable-delay-pools --enable-epoll --enable-icap-client --enable-ident-lookups \
--enable-linux-netfilter --enable-removal-policies=heap,lru \
--enable-snmp --enable-storeio=aufs,diskd,rock,ufs --enable-wccpv2 \
--enable-esi --enable-ecap --with-aio \
--enable-security-cert-generators --enable-security-cert-validators \
--enable-icmp --with-filedescriptors=16384 --disable-arch-native --without-nettle \
--disable-dependency-tracking --enable-eui --enable-follow-x-forwarded-for \
--with-default-user=squid --enable-ssl-crtd --with-included-ltdl \
--with-dl --with-openssl --with-pthreads --disable-arch-native 
</pre>
<p>Compile and install. It takes about 20 mins on 2 CPU, 2GB RAM t3 instance.</p>
<pre class="brush: bash; title: ; notranslate">
make &amp;&amp; make install
</pre>
<p>While the installation runs, open up a new session and <strong>sudo su</strong> again as root. We have to create the systemd startup scripts. Just copy and paste these three commands. It will create three files.</p>
<pre class="brush: bash; collapse: true; light: false; title: ; toolbar: true; notranslate">
cat &lt;&lt; 'EOF' &gt; /usr/lib/systemd/system/squid.service
&#x5B;Unit]
Description=Squid caching proxy
After=syslog.target network.target nss-lookup.target

&#x5B;Service]
Type=forking
LimitNOFILE=16384
EnvironmentFile=/etc/sysconfig/squid
ExecStartPre=/usr/libexec/squid/cache_swap.sh
ExecStart=/usr/sbin/squid $SQUID_OPTS -f $SQUID_CONF
ExecReload=/usr/sbin/squid $SQUID_OPTS -k reconfigure -f $SQUID_CONF
ExecStop=/usr/sbin/squid -k shutdown -f $SQUID_CONF
TimeoutSec=0

&#x5B;Install]
WantedBy=multi-user.target
EOF
</pre>
<pre class="brush: bash; collapse: true; light: false; title: ; toolbar: true; notranslate">
cat &lt;&lt; 'EOF' &gt; /etc/sysconfig/squid
# default squid options
SQUID_OPTS=&quot;&quot;

# Time to wait for Squid to shut down when asked. Should not be necessary
# most of the time.
SQUID_SHUTDOWN_TIMEOUT=100

# default squid conf file
SQUID_CONF=&quot;/etc/squid/squid.conf&quot;
EOF
</pre>
<pre class="brush: bash; collapse: true; light: false; title: ; toolbar: true; notranslate">
mkdir /usr/libexec/squid
cat &lt;&lt; 'EOF' &gt; /usr/libexec/squid/cache_swap.sh
#!/bin/bash
if &#x5B; -f /etc/sysconfig/squid ]; then
        . /etc/sysconfig/squid
fi

SQUID_CONF=${SQUID_CONF:-&quot;/etc/squid/squid.conf&quot;}

CACHE_SWAP=`sed -e 's/#.*//g' $SQUID_CONF | \
        grep cache_dir | awk '{ print $3 }'`

for adir in $CACHE_SWAP; do
        if &#x5B; ! -d $adir/00 ]; then
                echo -n &quot;init_cache_dir $adir... &quot;
                squid -N -z -F -f $SQUID_CONF &gt;&gt; /var/log/squid/squid.out 2&gt;&amp;1
        fi
done
EOF
chmod +x /usr/libexec/squid/cache_swap.sh
</pre>
<p>Once the compilation and installation ends, execute these lines to allow the squid user to access the log directory and enable the auto-start on boot. Also, make sure SELinux is disabled and change <strong>/etc/selinux/config</strong> file to <strong>SELINUX=permissive</strong> or <strong>SELINUX=disabled</strong>.</p>
<pre class="brush: bash; title: ; notranslate">
chown -R squid:squid /var/log/squid
systemctl enable squid
setenforce 0
</pre>
<p>Feel free to start squid, but it will run with the default config and in non-transparent proxy mode.</p>
<pre class="brush: bash; title: ; notranslate">
# Optional
systemctl start squid
systemctl status squid -l
tail /var/log/squid/cache.log
</pre>
<p>If you like you can test. Log to an instance in a private subnet and set the proxy. Change the IP below to the IP of your squid server and make sure the squid server has a security group that allows port 3128 from 10.10.51.0/24 subnet.</p>
<pre class="brush: bash; title: ; notranslate">
# Optional, do this on the client instance
export http_proxy=10.10.50.235:3128
export https_proxy=10.10.50.235:3128
</pre>
<p>If you do <strong>curl -v https://wordpress.org</strong> you&#8217;ll get their page back in HTML/CSS.</p>
<pre class="brush: bash; title: ; notranslate">
unset http_proxy
unset https_proxy
</pre>
<p>If you reset the proxy settings to nothing and if you do culr again, you&#8217;ll see that it will time-out. Even with the proxy set, you can&#8217;t use yum because yum uses proxy settings specified in <strong>/etc/yum.conf</strong>. That&#8217;s why a transparent proxy is much more superior. You don&#8217;t have to worry about configuring the proxy on the instances.<br />
<strong>NOTE</strong>: Make sure you unset the proxy settings if you already exported them.<br />
Now that we have pretty-much everything ready, let&#8217;s create the config file. It&#8217;s using SSLBump peek and splice config. For more info click <a href="https://wiki.squid-cache.org/Features/SslPeekAndSplice" rel="noopener noreferrer" target="_blank">here</a>.<br />
Just copy and paste the snippet below. It will create the config for you.</p>
<pre class="brush: bash; title: ; notranslate">
cat &lt;&lt; 'EOF' &gt; /etc/squid/squid.conf
cache deny all
# HTTP
http_port 3128
http_port 3129 intercept
acl http-whitelist dstdomain &quot;/etc/squid/whitelist.txt&quot;
http_access allow http-whitelist

# HTTPS
https_port 3130 cert=/etc/squid/ssl/squid.pem ssl-bump intercept
acl sslport port 443
http_access allow sslport
acl https-whitelist ssl::server_name &quot;/etc/squid/whitelist.txt&quot;
acl step1 at_step SslBump1
acl step2 at_step SslBump2
acl step3 at_step SslBump3
ssl_bump peek step1 all
ssl_bump peek step2 https-whitelist
ssl_bump splice step3 https-whitelist
ssl_bump terminate step2 all
http_access deny all
EOF
</pre>
<p>And for the whitelist file, create a file with your allowed domains. Everything else will be blocked. You can put IPs here as well.</p>
<pre class="brush: bash; title: ; notranslate">
cat &lt;&lt; 'EOF' &gt; /etc/squid/whitelist.txt
.amazon.com
.amazonaws.com
.wordpress.org
.api.google.com
EOF
</pre>
<p>If squid is running, stop it with <strong>systemctl stop squid</strong> and execute these lines to create an internal self-signed certificate. More info on why this is needed, in the link that I&#8217;ve presented above.</p>
<pre class="brush: bash; title: ; notranslate">
mkdir /etc/squid/ssl
cd /etc/squid/ssl
openssl genrsa -out squid.key 4096
openssl req -new -key squid.key -out squid.csr -subj &quot;/C=US/ST=NJ/L=squid/O=squid/CN=squid&quot;
openssl x509 -req -days 3650 -in squid.csr -signkey squid.key -out squid.crt
cat squid.key squid.crt &gt;&gt; squid.pem  
</pre>
<p>Initialize the SSL database.</p>
<pre class="brush: bash; title: ; notranslate">
/usr/lib64/squid/security_file_certgen -c -s /var/cache/squid/ssl_db -M 4MB
</pre>
<p>&#8230;otherwise you&#8217;ll receive these errors in <strong>/var/log/squid/cache.log</strong>.</p>
<pre class="brush: bash; title: ; notranslate">
2019/11/17 15:44:19 kid1| WARNING: /usr/lib64/squid/security_file_certgen -s /var/cache/squid/ssl_db -M 4MB #Hlpr1 exited
2019/11/17 15:44:19 kid1| Too few /usr/lib64/squid/security_file_certgen -s /var/cache/squid/ssl_db -M 4MB processes are running (need 1/32)
</pre>
<p>Change the permission of this file&#8230;</p>
<pre class="brush: bash; title: ; notranslate">
chmod 4755 /usr/lib64/squid/pinger 
</pre>
<p>&#8230;otherwise you&#8217;ll receive these errors in <strong>/var/log/squid/cache.log</strong>.</p>
<pre class="brush: bash; title: ; notranslate">
2019/11/17 15:38:47| pinger: Initialising ICMP pinger ...
2019/11/17 15:38:47| Open  icmp_sock: (1) Operation not permitted
2019/11/17 15:38:47| pinger: Unable to start ICMP pinger.
</pre>
<p>If you start squid now, you&#8217;ll get something like this in <strong>/var/log/squid/cache.log</strong>. If you still get errors like the ones above (pinger: Unable to start ICMP pinger), reboot one more time.</p>
<pre class="brush: bash; collapse: true; light: false; title: ; toolbar: true; notranslate">
2019/11/17 15:49:17| Created PID file (/var/run/squid.pid)
2019/11/17 15:49:17 kid1| Current Directory is /
2019/11/17 15:49:17 kid1| Starting Squid Cache version 4.9 for x86_64-redhat-linux-gnu...
2019/11/17 15:49:17 kid1| Service Name: squid
2019/11/17 15:49:17 kid1| Process ID 3705
2019/11/17 15:49:17 kid1| Process Roles: worker
2019/11/17 15:49:17 kid1| With 16384 file descriptors available
2019/11/17 15:49:17 kid1| Initializing IP Cache...
2019/11/17 15:49:17 kid1| DNS Socket created at &#x5B;::], FD 5
2019/11/17 15:49:17 kid1| DNS Socket created at 0.0.0.0, FD 9
2019/11/17 15:49:17 kid1| Adding domain ec2.internal from /etc/resolv.conf
2019/11/17 15:49:17 kid1| Adding nameserver 10.10.50.2 from /etc/resolv.conf
2019/11/17 15:49:17 kid1| helperOpenServers: Starting 5/32 'security_file_certgen' processes
2019/11/17 15:49:17 kid1| Logfile: opening log daemon:/var/log/squid/access.log
2019/11/17 15:49:17 kid1| Logfile Daemon: opening log /var/log/squid/access.log
2019/11/17 15:49:17 kid1| Local cache digest enabled; rebuild/rewrite every 3600/3600 sec
2019/11/17 15:49:17 kid1| Store logging disabled
2019/11/17 15:49:17 kid1| Swap maxSize 0 + 262144 KB, estimated 20164 objects
2019/11/17 15:49:17 kid1| Target number of buckets: 1008
2019/11/17 15:49:17 kid1| Using 8192 Store buckets
2019/11/17 15:49:17 kid1| Max Mem  size: 262144 KB
2019/11/17 15:49:17 kid1| Max Swap size: 0 KB
2019/11/17 15:49:17 kid1| Using Least Load store dir selection
2019/11/17 15:49:17 kid1| Current Directory is /
2019/11/17 15:49:17 kid1| Finished loading MIME types and icons.
2019/11/17 15:49:17 kid1| HTCP Disabled.
2019/11/17 15:49:17 kid1| Pinger socket opened on FD 26
2019/11/17 15:49:17 kid1| Squid plugin modules loaded: 0
2019/11/17 15:49:17 kid1| Adaptation support is off.
2019/11/17 15:49:17 kid1| Accepting HTTP Socket connections at local=&#x5B;::]:3128 remote=&#x5B;::] FD 22 flags=9
2019/11/17 15:49:17 kid1| Accepting NAT intercepted HTTP Socket connections at local=&#x5B;::]:3129 remote=&#x5B;::] FD 23 flags=41
2019/11/17 15:49:17 kid1| Accepting NAT intercepted SSL bumped HTTPS Socket connections at local=&#x5B;::]:3130 remote=&#x5B;::] FD 24 flags=41
2019/11/17 15:49:17| pinger: Initialising ICMP pinger ...
2019/11/17 15:49:17| pinger: ICMP socket opened.
2019/11/17 15:49:17| pinger: ICMPv6 socket opened
2019/11/17 15:49:18 kid1| storeLateRelease: released 0 objects
</pre>
<p>If you see my <strong>squid.conf</strong>, you&#8217;ll see that I am not using squid as cache server (<strong>cache deny all</strong>). If you want to cache your responses, replace that line with this one. 100 means 100MB. See <a href="http://www.squid-cache.org/Doc/config/cache_dir/" rel="noopener noreferrer" target="_blank">here </a>for more explanation.</p>
<pre class="brush: bash; title: ; notranslate">
cache_dir ufs /var/cache/squid 100 16 256
</pre>
<p>In order to run in transparent proxy mode, we have to make some firewall changes and redirect the traffic on ports 80 and 443 to squid which will listen on 3129 and 3130 (for https). Do this on the squid server. You don&#8217;t have to do anything on the clients.</p>
<pre class="brush: bash; title: ; notranslate">
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 3129
iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 3130
</pre>
<p>If we reboot the server, the iptables changes will be lost, so we have to save them.</p>
<pre class="brush: bash; title: ; notranslate">
yum -y install iptables-services
systemctl enable iptables
systemctl start iptables
service iptables save
</pre>
<p>Reboot to make sure everything comes back. Check the redirects. Lines 4 and 5 should be as below.</p>
<pre class="brush: bash; highlight: [1]; title: ; notranslate">
iptables --table nat --list
Chain PREROUTING (policy ACCEPT)
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
MASQUERADE  all  --  anywhere             anywhere
</pre>
<h1>Test</h1>
<p>In order to test, we&#8217;ll build a small Linux instance in the private subnet and test from there. Do not assign a public IP to this instance. If you don&#8217;t have a VPN or Direct Connect to your private subnets, you&#8217;ll have to use the squid server to access the instance. Copy the key (PEM) file to the squid instance and SSH to the private instance using <strong>ssh -i key.pem internal_IP_of_test_instance</strong>. You have to <strong>chmod 600 key.pem</strong> first. The key file is the one that you use to connect to the squid instance. That&#8217;s in my case. If you have multiple key files, then copy the key file that you used when you created the instance in the private subnet. Assign a security group that allows SSH from the squid server instance, or use the same one that I used when created the squid server which allows access from everywhere on port 22. You have to rectify this later. Don&#8217;t allow access from everywhere in any circumstances. This is just for test.<br />
Make sure that you have a new security group created for the squid server instance. This security group should allow ports 80 and 443 from the private subnet only (10.10.51.0/24). Attach this security group to the squid server so it allows HTTP/HTTPS ports from the client instances.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/11/P139-15.jpg"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/11/P139-15.jpg" alt="" width="793" height="133" class="aligncenter size-full wp-image-6073" srcset="https://blog.andreev.it/wp-content/uploads/2019/11/P139-15.jpg 793w, https://blog.andreev.it/wp-content/uploads/2019/11/P139-15-300x50.jpg 300w, https://blog.andreev.it/wp-content/uploads/2019/11/P139-15-768x129.jpg 768w, https://blog.andreev.it/wp-content/uploads/2019/11/P139-15-585x98.jpg 585w" sizes="(max-width: 793px) 100vw, 793px" /></a><br />
On the client instance, make sure you have <strong>unset http_proxy</strong> and <strong>https_proxy</strong> variables. If you try to access a site that&#8217;s not listed in the whitelist.txt, you&#8217;ll get an Access Denied page from squid or sometimes you&#8217;ll get some SSL errors. For the sites that are listed, you might get them to show properly, but sometimes they&#8217;ll be garbled. If you look at the source of the page, you&#8217;ll see what URLs is the main site trying to access. Most likely there are some JavaScripts hosted on different domains. You&#8217;ll have to whitelist these as well if you want proper rendering. But sometimes, you might want to connect to an update server and you won&#8217;t be able to see the HTML rendering, e.g. CentOS update sites. In those cases <a href="https://www.telerik.com/fiddler" rel="noopener noreferrer" target="_blank">Fiddler </a>might be able to help.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.andreev.it/2019/11/aws-squid-transparent-proxy-for-dns-filtering-whitelisting/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
