Self-Hosted Proxy Server on Ubuntu: Tinyproxy and Squid

Data Crawling By hi3n

Cover Image

Self-Hosted Proxy Server on Ubuntu: Tinyproxy and Squid

Build a self-hosted proxy server on Ubuntu with Tinyproxy or Squid. This guide uses SSH tunnels to keep proxy ports private and encrypt the client-to-server connection. Choose Tinyproxy for a small personal setup, or Squid for more detailed access rules and per-user logging. You will need basic comfort with SSH and apt.

TL;DR: Bind the proxy to 127.0.0.1 on the VPS, forward its port through SSH, and point your client at the local forwarded port. Squid adds separate proxy credentials. Do not expose ports 8888 or 3128 to the public internet for these examples.

Before You Start: Ubuntu, SSH, and the Firewall

The examples target Ubuntu 24.04 LTS with sudo access, SSH key login, and distribution packages. Check the Ubuntu release lifecycle when choosing an image; Ubuntu 20.04 has left standard security maintenance. These are documentation-checked examples, not a benchmark or a claim of deployment testing.

Use a fresh VPS or back up existing configurations. On the VPS, install UFW and preserve SSH access before enabling the firewall. The example assumes SSH uses TCP port 22. If yours differs, substitute that port first. Keep your current SSH session open and verify a second login after applying the rules.

sudo apt update
sudo apt install -y ufw
sudo ufw allow 22/tcp
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw enable
sudo ufw status numbered

For these tunnel-only examples, remove any existing inbound rules exposing 8888 or 3128, and keep both ports closed in the provider firewall too. On an existing server, preserve rules needed by other services. See Ubuntu’s UFW documentation for rule management.

Option A: Tinyproxy Through an SSH Tunnel

Tinyproxy describes itself as a light-weight HTTP/HTTPS proxy daemon for POSIX systems. Small footprint, fast, few resources. It does one job with minimal moving parts, which makes it a good fit for personal use and single-server scraping.

Install and start it:

# install + enable tinyproxy on Ubuntu
sudo apt update && sudo apt install -y tinyproxy
sudo systemctl enable --now tinyproxy

Back up /etc/tinyproxy/tinyproxy.conf, then edit the existing directives below instead of appending duplicate settings. Keep the package’s user, group, and logging settings. Remove other Allow or Deny entries so only loopback clients are allowed:

Port 8888
Listen 127.0.0.1
Timeout 600
Allow 127.0.0.1
ConnectPort 443

Restart on the VPS with sudo systemctl restart tinyproxy, then check sudo systemctl status tinyproxy --no-pager. On your own computer, open the tunnel below. Replace SSH_USER and YOUR_VPS_IP with your SSH account and VPS address, and leave the command running:

ssh -N -o ExitOnForwardFailure=yes -L 127.0.0.1:8888:127.0.0.1:8888 SSH_USER@YOUR_VPS_IP

In another local terminal, test:

curl --noproxy "" --proxy http://127.0.0.1:8888 -I https://example.com

A successful CONNECT response followed by the destination’s HTTP response confirms the path. Point your browser or scraper at http://127.0.0.1:8888 while the tunnel remains open. OpenSSH documents this mechanism as local port forwarding. The forwarded connection reaches Tinyproxy from the VPS loopback interface, matching Allow 127.0.0.1.

Tinyproxy also supports BasicAuth; authentication is not exclusive to Squid. This example relies on SSH access instead. Choose Squid when you need more elaborate access policies and authenticated access logs. Local processes on either machine may reach its loopback listener, so use this personal setup on machines you trust.

Option B: Squid With Authentication Over SSH

Squid combines proxy authentication, access policies, and request logs. This example targets the Squid 6 package on Ubuntu 24.04 and keeps the proxy listener local. Each trusted user needs an SSH tunnel plus their own proxy credentials.

sudo apt update
sudo apt install -y squid apache2-utils
sudo cp /etc/squid/squid.conf /etc/squid/squid.conf.bak

Create the password file only if it does not already exist. These commands assume the Ubuntu package’s proxy service group and authentication helper path:

sudo htpasswd -c /etc/squid/passwd scraper1
sudo chown root:proxy /etc/squid/passwd
sudo chmod 640 /etc/squid/passwd

For later users or password changes, run sudo htpasswd /etc/squid/passwd scraper2 without -c. That flag recreates the file and can discard existing users; see the htpasswd manual.

For this dedicated proxy, replace the active contents of /etc/squid/squid.conf with the following small configuration. Do not paste an allow rule below an existing deny-all or retain an earlier http_access allow localhost rule that bypasses authentication.

http_port 127.0.0.1:3128

acl tunnel_clients src 127.0.0.1/32
acl Safe_ports port 80 443
acl SSL_ports port 443
acl CONNECT method CONNECT
acl manager proto cache_object
acl private_targets dst 0.0.0.0/8 10.0.0.0/8 100.64.0.0/10 127.0.0.0/8 169.254.0.0/16 172.16.0.0/12 192.168.0.0/16 ::/128 ::1/128 fc00::/7 fe80::/10

auth_param basic program /usr/lib/squid/basic_ncsa_auth /etc/squid/passwd
auth_param basic realm PrivateProxy
acl authenticated proxy_auth REQUIRED

http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access deny manager
http_access deny private_targets
http_access allow tunnel_clients authenticated
http_access deny all

These ordered rules deny non-web ports, restrict CONNECT to 443, and block common internal and link-local destinations before granting access. They are a baseline for trusted clients, not isolation for hostile tenants. Review Squid’s access-rule documentation before adapting them to your network.

Check configuration syntax before restarting:

sudo squid -k parse && sudo systemctl restart squid
sudo systemctl enable squid
sudo systemctl status squid --no-pager

On your computer, open a tunnel and leave it running:

ssh -N -o ExitOnForwardFailure=yes -L 127.0.0.1:3128:127.0.0.1:3128 SSH_USER@YOUR_VPS_IP

From another local terminal, run the first command without credentials; expect a 407 Proxy Authentication Required response. Then run the second command, which prompts for the proxy password, and confirm you receive the destination response:

curl --noproxy "" --proxy http://127.0.0.1:3128 -I https://example.com
curl --noproxy "" --proxy http://127.0.0.1:3128 --proxy-user scraper1 -I https://example.com

Check /var/log/squid/access.log for request outcomes and authenticated usernames. SSH-forwarded clients appear to come from loopback, so source IP alone cannot identify individual users. The Squid authentication guide explains how authentication and access controls work together.

Verify Access and Troubleshoot Failures

  • Check the listener: on the VPS, run sudo ss -ltnp. The configured proxy should listen on 127.0.0.1:8888 or 127.0.0.1:3128, not a wildcard or public address.

  • Test public access: from another machine, try curl --connect-timeout 5 --noproxy "" --proxy http://YOUR_VPS_IP:3128 -I https://example.com (8888 for Tinyproxy). This should fail to connect. A proxy response means the port is reachable and needs investigation.

  • Connection refused locally: check that the SSH tunnel is still running, its local port is free, and the proxy service started. Read sudo journalctl -u tinyproxy -n 50 --no-pager or the equivalent for Squid.

  • Squid returns 407 with credentials: verify the username, password-file permissions, and helper path. A 403 usually points to an access rule; inspect the requested destination and port.

  • Keep the encryption boundary clear: HTTPS CONNECT protects the destination session when TLS verification succeeds. Basic proxy credentials sent to a plain HTTP proxy are not protected by that destination TLS session. The SSH tunnel protects the client-to-VPS leg in these examples. Plain HTTP remains unencrypted between the VPS and destination.

  • Maintain access: patch the VPS, review logs, and revoke both SSH access and proxy credentials when someone leaves. An SSH shell account provides broader access than proxy authentication alone. Use a separately designed VPN or restricted forwarding setup for users who should not have shell access.

Which Option Should You Pick?

Choose Tinyproxy for a personal endpoint and Squid for more detailed policy and user accounting. A proxy changes the exit IP of configured clients; it does not route every application automatically, guarantee anonymity, or make a datacenter IP equivalent to a residential proxy.

Pair this with good scraping hygiene from Automated Data Collection Tools in 2026: What Actually Works. Rotation, headers, and rate limits matter as much as the proxy itself. And if proxies are one piece of a lead-generation pipeline, the Google Maps scraping lead guide shows the full workflow this server can power. When outgrowing self-hosted volume, compare managed options in Best Web Scraping APIs 2026.

FAQ

How much does a self-hosted proxy cost?

Your costs depend on the VPS plan, included bandwidth, transfer overages, and maintenance time. Compare those with your actual proxy usage before assuming self-hosting saves money.

Can I use this proxy for web scraping?

Yes, for collection you are authorized to perform. Point the HTTP client at the local forwarded port and keep the tunnel running. Follow the destination’s access rules and rate limits; changing an IP does not grant permission or guarantee access.

Does a proxy give me permission to collect a website’s data?

No. A proxy provides a network route. It does not grant access rights or override a website’s policies.

Before using the proxy for real work, confirm that an authorized request succeeds and a direct public connection fails. For Squid, also confirm that a request without credentials is rejected. Keep those checks with your configuration backup so you can repeat them after changes.

Author

hi3n

More to read

Related posts