Last Updated on March 11, 2022


Squid is an HTTP proxy that offers a rich set of traffic optimization features to cache frequently accessed content and save bandwidth. This open-source software is widely used by companies and is even embedded in some firewall devices. If you are not familiar with the concept of proxy servers, I recommend that you look at my previous article about HTTP proxies.

In this article, I will show you how to install and configure Squid as a forward proxy on an Ubuntu 18.04 server, and then configure your client machine to use the proxy server.

Squid configured as a forward proxy
Squid configured as a forward proxy

Pre-requisites

For this demo session, we will install Squid on an Ubuntu server. You will need the following materials for this hands-on lab:

  • A server machine running Ubuntu operating system (ideally, Ubuntu 18.04 or later).
  • A client machine running Windows 10. You can use Windows server 2016 or later if you don’t have a Windows 10 machine. In addition, you can install Wireshark on the client machine to analyze the network traffic.

For the sake of this tutorial, I am using 2 virtual machines in the cloud (i.e. I am using Microsoft Azure, but you can use any other cloud provider). If you want to use Microsoft Azure as well, you can create your free Azure account here: Microsoft usually offers 12 months of free services for new accounts.

Install and configure Squid on Ubuntu 18.04

Here are the steps for this hands-on session.

Step 1 – Open an SSH session with your Ubuntu server

You need to open a command-line session with your Ubuntu server. For this purpose, you can use Putty to open an SSH session with the server. I highly recommend using a public key authentication mechanism. If you create an Ubuntu VM in the cloud, you should be able to create a user with “sudo” privileges, generate and download a private key for that user. After downloading the PEM file, here are the steps to follow in order to open an SSH session with your server:

  1. You first need to convert the PEM file to a PPK file. In order to achieve that, you need to load the PEM file in PuttyGen and then save the private key as a PPK file.
Open the PEM file with Putty Key Generator.
PuttyGen - Press on Save private key button to export PEM file in PPK format

2. Open Putty and update the configuration to use the PPK file. Then enter the server information and click on the “open” button to start a new SSH session.

Putty - Set PPK file for SSH authentication
Putty - Enter host name and open SSH connection

Step 2 – Update the list of available packages

Make sure that you have the latest packages by running the following command:

sudo apt-get update
Download latest packages with apt-get update
Download latest packages with apt-get update

Step 3 – Install Squid

Install Squid by running the following command:

sudo apt-get install squid
Install Squid
Install Squid

Step 4 – Backup Squid configuration file before editing it

In the upcoming step, you will change some settings in the Squid configuration file. Therefore, you need to make sure that you have a backup of this file in case you want to go back to the original version of the file.

Run the following command to create a copy of the configuration file:

sudo cp /etc/squid/squid.conf /etc/squid/squid.conf.initial

And then update permissions on the backup to set it to Read-Only.

sudo chmod 444 /etc/squid/squid.conf.initial  

This update will make sure that nobody can accidentally modify the backup file.




Step 5 – Configure the proxy server port and ACL

In order to configure the server, you need to open the configuration file with a file editor. In this example, we are using the well-known text editor, nano.

sudo nano /etc/squid/squid.conf
Open Squid configuration file with Nano

Here are the changes that we will do in this file:

  1. We will change the HTTP port to 8080. Actually, you can set it to whatever port you want. The default port for Squid is 3128. 
Configure Squid port
Configure Squid port

2. Make sure the server accepts TCP connections on the selected port. If you are using Microsoft Azure, you can configure the inbound ports in the networking page of the VM.

Proxy Virtual Machine Inbound Rules
Proxy Virtual Machine Inbound Rules

3. We will create an access control permission with the IP address of the client machine that will connect to this HTTP Proxy. Since it’s not recommended to give permission to everybody to use your server, you can register the IP addresses or the subnet of client machines that you want to allow:

#In squid.conf
acl proxyclient src 20.49.57.241 #test client

Here 20.49.57.241 is the public IP address of the test VM that will connect to this proxy.

4. We will enforce proxy authentication. Basically, users trying to use the server need to be authenticated:

#In squid.conf
acl authenticated proxy_auth REQUIRED
http_access allow proxyclient authenticated
Squid ACL configuration - Definition of our custom ACL
Squid ACL configuration – Definition of our custom ACL

Squid ACL configuration - Allowing predefined ACL
Squid ACL configuration – Allowing predefined ACL

Step 6 – Configure the proxy authentication module

In the previous step, we added an access control permission that allows only authenticated users from a specific IP address. However, Squid supports different authentication types such as Basic, Digest, and OAuth 2.0. Each authentication type is handled by a dedicated module that must be installed on top of the proxy software.

In a nutshell, Squid will just forward the authentication request to the configured module. For this demo, we will use Basic authentication with the htpasswd module, which is part of the Apache utils package in the Ubuntu repositories.

Therefore, run the following command to install Apache2 utilities:

sudo apt-get install apache2-utils
Install Apache utilities
Install Apache utilities

And then create a new user with htpasswd. You need to create a password for that user. The -c option is necessary to create the etc/squid/passwd file if it does not exist. In this example, we are creating a user named “proxyuser”.

sudo htpasswd -c /etc/squid/passwd proxyuser
Create a proxy user
Create a proxy user

After this step, edit the squid.conf file to add the following settings:

#In squid.conf
auth_param basic program /usr/lib/squid/basic_ncsa_auth /etc/squid/passwd
auth_param basic children 5 startup=5 idle=1
auth_param basic realm Squid proxy server
auth_param basic credentialsttl 2 hours
Configure Squid authentication type
Configure Squid authentication type

This is basically telling Squid that the module in charge of Basic authentication is located at /usr/lib/squid/basic_ncsa_auth and the proxy users’ list is located at /etc/squid/passwd. The second line sets the maximum number of authentication processes to spawn( i.e which is 5 in this case). Moreover, once a user is authenticated, the result is kept in cache for a TTL of 2 hours.

Step 7 – Restart Squid

In order for these configuration to take place, you need to restart Squid by running this command:

sudo systemctl restart squid

Then, you can run the following commands to check the status of the process and make sure that it’s listening on the specified port (8080):

sudo systemctl status squid
netstat -lnp | grep 8080

Configure the client machine to use the Squid proxy server

On the client machine, you need to configure the system-wide proxy settings on Windows. This way, all HTTP or HTTPS requests on that machine will go through the proxy server. Here is an example:

Manually configure the proxy settings on the client machine
Manually configure the proxy settings on the client machine

Analyze HTTP requests through the proxy server

In order to analyze the traffic between the client machine and the proxy server, you need to install Wireshark on the client machine.

HTTP 407 – Proxy Authentication Required

Now, let’s run Wireshark on the client machine to capture all HTTP requests on both port 80 and port 8080, which is our proxy server port. Once Wireshark is configured, you can open a browser and try to navigate to an HTTP website, like http://www.httpvshttps.com/.

You should see the outgoing requests in Wireshark:

Network traces when browsing to an HTTP website on the client machine
Network traces when browsing to an HTTP website on the client machine

Proxy server returns HTTP response 407 (Proxy Authentication Required)
Proxy server returns HTTP response 407 (Proxy Authentication Required)

We can see in these traces that the browser sends an HTTP GET request to the proxy server for the website http://www.httpvshttps.com/. Then the proxy server replies with an HTTP response code 407 (Proxy authentication required). This is due to the fact that we enabled Proxy authentication on the Squid server. Basically, when this option is enabled, all clients need to authenticate themselves to the proxy server before being able to access the internet. After receiving HTTP response code 407, the browser displays a popup window to ask for the proxy credentials.

Authentication window displayed by the browser
Proxy authentication window displayed by the browser

Proxy-Authorization Header

After providing the credentials, the proxy gets the web page on behalf of the client and then sends back the response to the browser. Here are the Wireshark traces once we provided the username/password for the proxy authentication.

Browser resends the HTTP request with a Proxy-Authorization header
Browser resends the HTTP request with a Proxy-Authorization header

The browser sends an HTTP GET request containing the proxy credentials in the Proxy-Authorization header. As shown in the screenshot, the proxy credentials are in the Base64 format just after the Basic authentication scheme. And as expected, the proxy server validates the credentials and then returns an HTTP 200 response with the requested website content.

Proxy server returns the HTTP response
Proxy server returns the requested page

NB: Since the proxy server is using Basic authentication over HTTP, the authentication requests to the proxy server are sent in clear text. Therefore, in this example, the authentication data is not sent over an encrypted channel. If you are using Basic authentication, it is better to configure Squid with HTTPS and install the proxy certificate in the client certificate store.

Analyze HTTPS requests through the proxy server

Well, let’s say we keep the proxy configuration as is, on port 8080 and the client decides to browse to an HTTPS website. Basically, the goal of using HTTPS is to make sure that clients are contacting a legitimate server and that the communication is encrypted with TLS. Therefore, when the client browses to an HTTPS website, we need to make sure the HTTP proxy will not compromise or weaken the TLS connection. For this reason, HTTP proxies use a mechanism called HTTP tunneling to carry HTTPS traffic in a transparent manner.

In a nutshell, the client contacts the HTTP Proxy in order to open a communication tunnel to the HTTPS server that he wants to contact. Once the tunnel is opened, all communication between the two parties is simply forwarded by the proxy without any modification. Furthermore, the proxy does not see the content of the data exchange because of the encryption layer provided by TLS.

HTTP Tunneling with CONNECT method

Now, let’s browse to the website https://www.httpvshttps.com. Here are the Wireshark traces that we captured on the client machine.

Network traces when browsing to an HTTPS website on the client machine
Network traces when browsing to an HTTPS website on the client machine

This trace shows that the browser is sending a CONNECT message to the proxy server with the destination server name and the port. When the proxy receives this request, it will simply send a DNS query to find the IP address of the server www.httpvshttps.com and then open a TCP connection to port 443 of the machine that possesses the IP address returned by the DNS. Then the proxy sends an HTTP 200 message to the browser saying that the connection is established.

Proxy server returns HTTP 200 to indicate that the tunnel is opened
Proxy server returns HTTP 200 to indicate that the tunnel is opened

Furthermore, the client sends a Client Hello message to start the TLS handshake. When the proxy server receives this message, it will just forward it to the TCP connection previously opened for this hostname/port combination. After this step, the server replies with a Server Hello message of the TLS handshake, which in turn will be forwarded back to the client. This is how the TLS connection will be established transparently through the proxy server. In the end, the communication between the client machine and the webserver happens through the encrypted channel.

TLS interception with Squid

Note that it’s also possible to configure Squid for TLS interception. In such a case, Squid will act like a man in a middle of a secure connection and see the content of the TLS connection. Basically, a first TLS connection is established between the client and the proxy server, and a second TLS connection is created between the proxy server and the webserver hosting the website requested by the client.

Many organizations leverage TLS interception to inspect the content of the TLS communication, mostly to detect malware or to leverage some of the advantages of HTTP Proxies (i.e caching., content filtering).

In addition, one of the pre-requisites for TLS interception is to install the root CA certificate of the proxy software on client machines. This certificate will be used by the proxy server to generate server certificates on the fly for the visited websites. Therefore, it’s not a straightforward interception mechanism.

For more information about the TLS interception procedure, you can read this documentation on the squid website.

That concludes the lab!

By following the steps described in this article, you have successfully installed and configure Squid as a forward proxy on Ubuntu 18.04.

After this hands-on session, if you are looking for a forward proxy to install in your network or in your lab environment for testing purposes, it will take you only 30 minutes to deploy and configure Squid on a VM. Furthermore, you can also explore other open-source forward proxies, like Apache Traffic Server and Apache http mod_proxy.