Proxy server

A proxy server acts as a gateway to external networks for instances without a public IP address. When a proxy server is used as a single internet access point, traffic can be controlled efficiently, which enhances security and protects back-end servers from intrusions and attacks.

Contents

There are different ways to provide an instance with internet access: through a floating IP, a virtual IP or a proxy server. The latter has the advantage of being the most consistent and secure method, and the only solution in situations where a floating IP cannot be used.

In this scenario, there is a compute instance with a floating IP assigned, called the proxy server, and another instance without any floating IP, but connected to the same network, called the remote server. The port on the remote server can be a parent port of a trunk, for example.

Install Squid

Squid is an open source proxy server with cashing capabilities. On the proxy server machine, install Squid with

sudo apt update
sudo apt install squid

Two additional utilities are useful for testing of a modified configuration: netstat (in the APT installation package net-tools) and squidclient:

sudo apt install net-tools squidclient

The proxy server starts automatically after installation, which can be verified with

sudo systemctl status squid

To set the Squid service to start automatically whenever the server starts, do

sudo systemctl enable squid

Configure proxy

Squid uses access control lists (ACL) to filter out source IP addresses and ports from which requests will be allowed. The order of ACL declarations acl are important. This, together with the http_access rules and http_port directives, define the basic access control.

Access control lists

The Squid configuration file /etc/squid/squid.conf is a long text file, but only a few declarations are needed for a basic proxy server. By default, Squid denies all external requests, and trusted hosts have to be explicitly declared as allowed.

Make a copy of the file before editing with
sudo cp /etc/squid/squid.conf{,.bak}

The acl directive is used to define IP ranges (as localnet) from which requests are accepted and ports allowed for outgoing connections (Figure 1):

  • Safe_ports - defined ports to which Squid is allowed to establish a connection. For example, to configure the proxy so that clients only can make requests on port 21 (FTP), 80 (HTTP), and 443 (HTTPS), only these three declarations should remain in the configuration file together with http_access deny !Safe_ports to block traffic on other ports.

  • SSL_ports - by default this is port 443 only, but other ports can be declared as SSL ports as well. Together with the CONNECT ACL, the directive prevents misuse of SSL on safe ports which do not need it.

Figure 1. Squid ACL section in its configuration file.

The rule http_access sets the policy (allow/deny) on ACL. When the local IP range is covered by the acl definitions, the rule http_access allow localnet needs to be uncommented to allow requests.

The http_port defines the port (and optionally, the source IP) the proxy should listen to. The default is port 3128 given in the directive

http_port 3128

Squid can be instructed to listen to multiple ports by adding http_port lines. The directive can also be used to to specify IP addresses Squid should listen to. When the proxy has an external and an local interface, it should probably only accept requests from the local network. Squid can be restricted to listen only on an private IP address (the address of the remote server) by placing it in front of the port number, for example

http_port 192.168.0.100:3128

Alternatively, a list of allowed IP addresses can be put in a separate file, say /etc/squid/allowed_ips.txt, with the following structure:

192.168.0.100
# All other allowed IPs

The ACL directive to use this file is

acl allowed_ips src "/etc/squid/allowed_ips.txt"

Custom access controls (such as http_access allow allowed_ips) should usually be placed between the port declarations and the deny all.

http_access deny !Safe_ports
http_access deny CONNECT !SSL_Ports
...
http_access allow allowed_ips
...
http_access deny all

Warning: do NOT add port 25 to Safe_ports, as this can be a severe security risk.

Test configuration

The netstat command is used to display details about network connections and protocol-specific networking statistics. The command

netstat -tnlp

shows TCP connections - specifically the IP addresses and ports that the Squid is listening to (Figure 2).

Figure 2. The netstat command shows connections Squid is listening to.

The utility squidclient takes a URL and can be used similarly to curl to test HTTP connectivity, with the option to specify the source IP address and port to verify the Squid configuration. The switches -h and -p are used to modify the IP address and the port of the incoming request. Figure 3 shows a request from an unauthorized and an authorized IP address.

Figure 3. Using Squidclient to test proxy access rules.

Security groups and firewall

The proxy server has to have a security group which allows requests from remote servers, that is, TCP on the the subnet IP range.

If uncomplicated firewall UFW is enabled on the proxy server, its Squid profile needs to be enabled with

sudo ufw allow ‘Squid’

Log files

Squid uses two log files,

  • /var/log/squid/access.log

  • /var/log/squid/cache.log

The more informative of the two is access.log, which shows all sites accessed through the proxy. Note that the log files must be accessed as superuser (with sudo).

The access log contains, in addition to the accessed site URLs, a result code indicating how Squid handled a request (Figure 4). See Table 1 for some common result codes.

Figure 4. Example access log entries with Squid result codes.

Squid result code

Description

MISS

The requested document was not in cache, but could be fetched from the web server.

REFRESH_MODIFIED

A revalidation request was sent to the server, and a modified (new) object was returned.

REFRESH_UNMODIFIED

A revalidation request was sent to the server, and a 304 status (Not Modified) was returned.

MEM_HIT

The response delivered from memory cache.

TUNNEL

A binary tunnel was established for this transaction.

Table 1. Some common Squid result codes in the access log.

Configure remote server

Utilities on the remote server have to be configured to use the proxy server for external access. Note that this access is protocol-specific, so the ping utility cannot be used to test connectivity in general. HTTP connectivity can easily be tested with curl, which shows the HTML source code (Figure 5).

Figure 5. Using curl to test HTTP connectivity.

Access from terminal

Provided that the proxy server is configured to accept requests from the remote server, and its security group and firewall are set accordingly, internet access through the proxy from a terminal console is enabled by setting the environment variable

export http_proxy=”http://<proxy-ip>:<proxy-port>”

(when no password authentication is used). Here, <proxy-ip> is the private IP address of the proxy server, and <proxy-port> the port it is listening to (number 3128 by default).

To make variables persistent (loading at every new terminal session), the same lines are added to the .bashrc script, as shown in Figure 6.

Figure 6. Proxy environment variable in the bashrc script.

For SSL connections (encrypted data) between the remote and the proxy, the variable

export https_proxy=”http://<proxy-ip>:<proxy-port>”

is used. This variable is usually not needed: both http_proxy and https_proxy support proxy connections for either HTTP or HTTPS requests, and encryption is in general not required on the local network.

Other services supported by Squid are declared similarly, such as

export ftp_proxy="http://<proxy-ip>:<proxy-port>"

The variable declaring that localhost should not go through the proxy is expressed as

export no_proxy="localhost,127.0.0.1,::1"

Configure APT

Create a file proxy.conf for the APT proxy settings with

sudo nano /etc/apt/apt.conf.d/proxy.conf

and add the line (when no password authentication is used)

Acquire::http::Proxy "http://<proxy-ip>:<port>/";

The alternative format shown in Figure 7 can also be used

Figure 7. Proxy configuration file for APT.

Security best practices

It is vital to strengthen the security of the proxy server adequately. For some recommendations, some of which are applicable to HTTP as well, see https://pannet.atlassian.net/wiki/spaces/DocEng/pages/1428914372/Bastion+host#Security-best-practices

Additional resources

See squid-cache wiki for further details on Squid proxy configuration.