Friday, 15 June 2018

Oracle Cloud: howto access the public web from private networks via Squid proxy

Building up on my howto guide 'Run a bastion host with ssh-forwarding on Oracle Cloud Infrastructure', this guide is for the opposite direction. Say you have a server in a private subnet, only accessible through the bastion host. If that host needs access to the public internet, a proxy in a public subnet of the VCN (Virtual Compute Network) could be a solution.

The situation is the same as in the former guide. Two hosts, one named bastion in a public subnet and one named webserver in a private subnet. The webserver host has no access to the internet, but needs to access some information from a public URL, so a proxy on the bastionhost needs to be set up.

  • Install and setup Squid on a host in the public subnet
  • Create an ingress rule for the public subnet to allow traffic to the Squid port
  • Create an egress rule to allow egress traffic for the private subnet
  • Open the Squid port on the Linux firewall of the Squid host
  • Set http_proxy to the Squid host:port
Step-by-step guide

This guide uses Apache Squid, but only uses it as a proxy server. So first install it via yum:

[root@bastion ~] yum install squid

Start Squid and check it's status:

[root@bastion ~] systemctl start squid
[root@bastion ~] systemctl status squid
● squid.service - Squid caching proxy
   Loaded: loaded (/usr/lib/systemd/system/squid.service; disabled; vendor preset: disabled)
   Active: active (running) since Thu 2018-06-14 12:34:49 GMT; 10s ago
  Process: 11307 ExecStart=/usr/sbin/squid $SQUID_OPTS -f $SQUID_CONF (code=exited, status=0/SUCCESS)
  Process: 11301 ExecStartPre=/usr/libexec/squid/ (code=exited, status=0/SUCCESS)
 Main PID: 11309 (squid)
   CGroup: /system.slice/squid.service
           ├─11309 /usr/sbin/squid -f /etc/squid/squid.conf
           ├─11311 (squid-1) -f /etc/squid/squid.conf
           └─11312 (logfile-daemon) /var/log/squid/access.log

Jun 14 12:34:49 bastion systemd[1]: Starting Squid caching proxy...
Jun 14 12:34:49 bastion squid[11309]: Squid Parent: will start 1 kids
Jun 14 12:34:49 bastion squid[11309]: Squid Parent: (squid-1) process 11311...ed
Jun 14 12:34:49 bastion systemd[1]: Started Squid caching proxy.
Hint: Some lines were ellipsized, use -l to show in full.

If everything is fine, enable automatic Squid startup at boot. If you get errors, run a complete yum update and try again. That fixed my problems with startup.

[root@bastion ~] systemctl enable squid
Created symlink from /etc/systemd/system/ to /usr/lib/systemd/system/squid.service.

To test it from the system Squid is running on, set the HTTP proxy to the Squid default port, which is 3128.

[opc@bastion ~]$ export http_proxy= 
[opc@bastion ~]$ export https_proxy=

Then open a page with curl or lynx, eg.

[opc@bastion ~]$ lynx

That should return the text version of that page.

Check that the proxy has been used in the squid access log.

[root@bastion ~]# tail -f /var/log/squid/access.log
1528980628.887     45 TCP_MISS/200 3125 GET - HIER_DIRECT/ text/html
1528980661.842      5 TCP_MISS/301 314 GET - HIER_DIRECT/ -

Now that the squid proxy works and is accessible locally, create a security role on OCI to give the webserver host access to the Squid proxy on the bastionhost.

Find the public subnet in your VCN and click on the security list.

Click on 'Edit all rules' and add the network CIDR block of the webserver subnet (alternatively only the host IP address).

After clicking on 'Save Security List Rules', these should be listed in the Security List.

Also make sure, that in the private networks security list egress traffic is allowed at least for port 3128 to the private network, or like in this case allow all egress traffic. In the default security list, egress traffic is allowed. If you have created your own security list, you might need to add an egress rule.

firewall-cmd --new-zone=webapp --permanent
firewall-cmd --reload
firewall-cmd --zone=webapp --add-source= --permanent
firewall-cmd --zone=webapp --add-port=3128/tcp --permanent
firewall-cmd --reload

The last step is to open the Squid port on the public host in the Linux firewall.

[opc@webserver ~]$ curl
[opc@webserver ~]$ export http_proxy=
[opc@webserver ~]$ curl
<!doctype html><html itemscope="" itemtype="" lang="en"><head><meta content="Search the world's information, including webpages, images, videos and more. Google has many special features to help you find exactly what you're looking for." name="description">....

Now check, if everything works. Try to open any public URL, eg. with curl. That should not work. Wait for the timeout or CTRL-C. Set the proxy to the Squid server and port and try again. That should work now, if not double-check all settings.
So now, the server in the private network with no access to the public internet can access the web through the Squid proxy in a public subnet of your VPN.