Sometimes you need to setup a proxy server so that you can mask your IP address for making web requests using your browser. In some situations, you may want to intercept every web request and reject some requests such as rejecting social media websites at work. Sometimes you want only authorized users to access the internet at your workplace and want to monitor their web access. One may also need to cache web requests to build their own content delivery network. In such scenarios, you can install a web proxy like Squid on Linux.
Setting it up on a Debian or Ubuntu system is very easy and this post will show you how. However, this post is limited to setting up the Squid proxy server only as a HTTP/FTP proxy and not for caching. That would be a different post for the future.
+================+ +==============+ | | | | | BROWSER |<=====>|||| HTTP/FTP PACKETS ||||<=====>| PROXY SERVER |<=====>|||| INTERNET WEBSITE | | | | +================+ +==============+
If you want to run a web proxy, you need a server that is publicly visible on the internet. So for this example, you can use a Linode nanode which is $5 per month or a DigitalOcean VM.
Once you have setup the latest Debian (Buster as of this writing) or Ubuntu (2022.01 as of this writing) you can install the
squid software. Once it installs it starts up, but we need to configure it so we shut it down.
$ sudo su - root root$ apt update && apt upgrade && apt -y install squid root$ systemctl stop squid
Now let’s configure the software. Edit the
/etc/squid/squid.conf file that has been setup by the operating system during installation. Most of the defaults are fine. In our case we only want to support HTTP, HTTPS and FTP protocols so the ports that we want to allow are 80, 443 and 21, respectively.
So your access control list (
acl) should look like below, where you comment out every other port that you do not want to support.
acl SSL_ports port 443 acl Safe_ports port 80 # http acl Safe_ports port 21 # ftp acl Safe_ports port 443 # https #acl Safe_ports port 70 # gopher #acl Safe_ports port 210 # wais #acl Safe_ports port 1025-65535 # unregistered ports #acl Safe_ports port 280 # http-mgmt #acl Safe_ports port 488 # gss-http #acl Safe_ports port 591 # filemaker #acl Safe_ports port 777 # multiling http
Now let’s create a custom file for our usage and place it in
/etc/squid/conf.d/ and let’s call it
local.conf and add the following to it. Below is the content of
/etc/squid/conf.d/local.conf. Replace the
MY_EXTERNAL_IP_ADDRESS with your network’s external IP address, if you want to restrict access to Squid to
just your network. This is important for security. If you want to add several IP addresses, you must create one new line for each IP address and have the same
acl name so that the
http_access allow will work on that name.
## digest authentication - dumb but password is encrypted auth_param digest program /usr/lib/squid/digest_file_auth -c /etc/squid/private/digest_authentication auth_param digest children 32 startup=0 idle=1 ## use any realm name here but it will be needed to generate the authentication token auth_param digest realm MySquid Digest Authentication auth_param digest nonce_garbage_interval 5 minutes auth_param digest nonce_max_duration 30 minutes auth_param digest nonce_max_count 50 acl authenticatedusers proxy_auth REQUIRED # deny anyone who has not authenticated http_access deny !authenticatedusers ### setup IP based access http_access allow localhost acl mybrowser src MY_EXTERNAL_IP_ADDRESS http_access allow mybrowser ## change this to the hostname you want to use in the error messages visible_hostname squid01 via off forwarded_for off request_header_access Allow allow all request_header_access Authorization allow all request_header_access WWW-Authenticate allow all request_header_access Proxy-Authorization allow all request_header_access Proxy-Authenticate allow all request_header_access Cache-Control allow all request_header_access Content-Encoding allow all request_header_access Content-Length allow all request_header_access Content-Type 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 Pragma 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 Content-Language allow all request_header_access Mime-Version allow all request_header_access Retry-After allow all request_header_access Title allow all request_header_access Connection allow all request_header_access Proxy-Connection allow all request_header_access User-Agent allow all request_header_access Cookie allow all request_header_access All deny all cache deny all
Now that you have saved this file as
/etc/squid/conf.d/local.conf we need to create the authentication file
/etc/squid/private/digest_authentication for Squid to use as a list of username and passwords.
root$ mkdir -p /etc/squid/private/ ## setup the password and choose a username root$ htdigest -c /etc/squid/private/digest_authentication 'MySquid Digest Authentication' <username> Adding password for <username> in realm MySquid Digest Authentication New password: Re-type new password: root$ chown -R proxy:proxy /etc/squid/private/ root$ chmod go-rwx /etc/squid/private/
Now you can restart the server:
root$ systemctl start squid root$ netstat -vnatp | grep squid | grep LISTEN tcp6 0 0 :::3128 :::* LISTEN 11111/(squid-1)
To secure the connection, it makes sense to setup a firewall such as
ufwor use Linode’s cloud firewall setup to allow only connections from known IP addresses. If you want to allow global access, you must use a very strong password and keep your server up to date since you will see bot attacks. In my case, I have restricted access to the Squid server to my home IP and manually adjust the firewall when the IP changes.
You can also add the IP address to the
local.conffile and let Squid reject other IP addresses.
Using username/password authentication you can allow multiple users to access Squid and restrict access.
You can look at the logs present in
/var/log/squid/access.logto see which websites were accessed by which user and from which IP address.
CONNECTING TO THE WEB PROXY
We can use
curl to test the proxy access first.
$ curl -v --proxy-digest -U <username>:<password> -x http://<IP ADDRESS>:3128 https://www.vikaskumar.org/
password are the ones you had setup using the
htdigest command above.
The IP address is the external IP address of the server on which you are running the Squid proxy and 3128 is the default port.
You can then try to reach a website like https://www.ipinfo.io to verify that you are pretending to send your request from the Squid proxy server’s IP address.
On Firefox you must setup the proxy settings by following instructions.
You can select the
Manual Proxy Configuration and setup the same IP address for the HTTP(s) and FTP fields, and port 3128 for the port. Then when you try to access a website it will prompt you for a username and password, and you can enter the credentials you had setup earlier.
With this we come to the end of setting up an external web proxy server that allows you to have applications hide their IP address when they make HTTP(s) requests.