This guide is for educational and testing purposes. Using a proxy may violate websites’ terms of service. Use a proxy at your own risk.
Sign in as root
# Update system packages
apt update && apt upgrade -y
# Install squid
apt install squid -y
Edit the file:
nano /etc/squid/squid.conf
http_access deny allhttp_access deny allhttp_access allow authenticated until later if you decide to use a username and passwordThe section looks like this when added (note: the order is important):
acl myip src <YOUR_IP_ADDRESS> # add this
http_access allow authenticated # add this later (if you want authentication)
http_access allow myip # add this
http_access deny all
Restart squid (this takes a while):
systemctl restart squid
tail -f /var/log/squid/access.log
systemctl list-units --type=service --state=running
Prompt for a username and password when the browser launches.
# Required password generator from squid
apt install apache2-utils
# Create the username and be prompted for a password
htpasswd -c /etc/squid/passwords <SQUID_USERNAME>
# Output hashed password
cat /etc/squid/passwords
Edit squid configuration file:
nano /etc/squid/squid.conf
Press Control + w and find the string INSERT YOUR OWN RULE.
Order matters! - Add these three lines so that it will look like the example below:
auth_param basic program /usr/lib/squid3/basic_ncsa_auth /etc/squid/passwords
auth_param basic realm proxy
acl authenticated proxy_auth REQUIRED
And then add this a little farther below:
http_access allow authenticated
Snippet of squid.conf after you added the lines:
#
# INSERT YOUR OWN RULE(S) HERE TO ALLOW ACCESS FROM YOUR CLIENTS
#
include /etc/squid/conf.d/*
auth_param basic program /usr/lib/squid3/basic_ncsa_auth /etc/squid/passwords
auth_param basic realm proxy
acl authenticated proxy_auth REQUIRED
# Example rule allowing access from your local networks.
# Adapt localnet in the ACL section to list your (internal) IP networks
# from where browsing should be allowed
#http_access allow localnet
http_access allow localhost
# And finally deny all other access to this proxy
# Allow rules for your public IP address
acl myip src <YOUR_IP_ADDRESS>
http_access allow authenticated
http_access allow myip
http_access deny all
# TAG: adapted_http_access
Restart squid (this takes a while):
systemctl restart squid
ufw status (use ufw delete <NUMBER> if needed)# Output firewall rules with a number next to it
ufw status numbered
# Allow only connections from your specified IP address to port 3128
ufw allow from <YOUR_IP_ADDRESS> to any port 3128
# Deny all other connections to port 3128
ufw deny 3128
This is what ufw status numbered looks like at the end:
To Action From
-- ------ ----
[ 1] 3128 ALLOW IN <YOUR_IP_ADDRESS>
[ 2] 3128 DENY IN Anywhere
[ 3] 5355 DENY IN Anywhere
[ 4] 22/tcp ALLOW IN <YOUR_IP_ADDRESS>
[ 5] 22/tcp DENY IN Anywhere
[ 6] 3128 (v6) DENY IN Anywhere (v6)
[ 7] 5355 (v6) DENY IN Anywhere (v6)
[ 8] 22/tcp (v6) DENY IN Anywhere (v6)
If you tried to connect via SSH and it timed out, your “22/tcp DENY IN from Anywhere” is probably above “22/tcp ALLOW IN from <YOUR_IP_ADDRESS>”.
For example, this will not allow you to connect because the rules are evaluated from top to bottom:
To Action From
-- ------ ----
[ 4] 22/tcp DENY IN Anywhere
[ 5] 22/tcp ALLOW IN <YOUR_IP_ADDRESS>
Your order may be different, but in this case, I execute two commands and then verify the order:
# Delete entry
ufw delete 5
# Re-add entry above position 4
ufw insert 4 allow from <YOUR_IP_ADDRESS> to any port 22 proto tcp
Install brute-force blocker:
apt install fail2ban
Edit the configuration file to increase penalties:
sudo nano /etc/fail2ban/jail.local
Add this:
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
findtime = 10m
bantime = 1w
bantime.increment = true
bantime.factor = 4
This configuration:
# Restart fail2ban
sudo systemctl restart fail2ban
# View banned IPs
sudo fail2ban-client status sshd
# View bans in real-time
tail -f /var/log/fail2ban.log
ufw allow from <YOUR_IP_ADDRESS> to any port 22 proto tcp
ufw deny 22/tcp
Deny connections from an IP address that has attempted to initiate 6 or more connections in the last 30 seconds.
ufw limit 22/tcp
# View results
journalctl -u ssh
# View last 50 results
journalctl -u ssh -n 50
# View results with search string
journalctl -u ssh --grep "Failed password"
Disable LLMNR (port 5355) - While useful for local network discovery, LLMNR can also be exploited for security vulnerabilities, such as poisoning and man-in-the-middle attacks.
sudo systemctl disable systemd-resolved
sudo systemctl stop systemd-resolved
Block port in ufw:
ufw deny 5355
ss is a command-line tool that provides socket stats and displays various information based on various protocols. It can display port stats, TCP, UDP, RAW, and more.
ss -tuln:
| Local Address:Port | Definition |
|---|---|
0.0.0.0:* | all IPv4 addresses on this system |
[::]:* | all IPv6 addresses on this system |
*:* | any address, any protocol family, any port |
This is what ss -tuln outputs. Note: 12.345.67.890:123 should be <YOUR_IP_ADDRESS>:
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
udp UNCONN 0 0 127.0.0.53%lo:53 0.0.0.0:*
udp UNCONN 0 0 0.0.0.0:68 0.0.0.0:*
udp UNCONN 0 0 12.345.67.890:123 0.0.0.0:*
udp UNCONN 0 0 127.0.0.1:123 0.0.0.0:*
udp UNCONN 0 0 0.0.0.0:123 0.0.0.0:*
udp UNCONN 0 0 0.0.0.0:5355 0.0.0.0:*
udp UNCONN 0 0 0.0.0.0:47020 0.0.0.0:*
udp UNCONN 0 0 *:42091 *:*
udp UNCONN 0 0 [fe80::5400:5ff:fec1:87ec]%enp1s0:123 [::]:*
udp UNCONN 0 0 [::1]:123 [::]:*
udp UNCONN 0 0 [::]:123 [::]:*
udp UNCONN 0 0 [::]:5355 [::]:*
tcp LISTEN 0 4096 0.0.0.0:5355 0.0.0.0:*
tcp LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:*
tcp LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
tcp LISTEN 0 4096 [::]:5355 [::]:*
tcp LISTEN 0 128 [::]:22 [::]:*
tcp LISTEN 0 256 *:3128 *:*
Create a sudo user
adduser <SUDO_USER>
usermod -aG sudo <SUDO_USER><SUDO_USER> : <SUDO_USER> sudogroups <SUDO_USER>IMPORTANT: Test if you can SSH with the new user.
Disable root (after confirming you can login via the new user)
nano /etc/ssh/sshd_config
Make sure these lines look like this (you may need to uncomment the line):
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
Restart ssh with one of these commands:
systemctl restart ssh
systemctl reload ssh
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_[YOUR_CUSTOM_NAME] -C "[YOUR_CUSTOM_DESCRIPTION]"
Create the path in your user directory first. You may need to create an empty file called authorized_keys in .ssh:
# Change file ownership of the .ssh contents to SUDO_USER only
sudo chown -R <SUDO_USER>:<SUDO_USER> /home/<SUDO_USER>/.ssh
# Change directory permissions (read, write, execute) to SUDO_USER only
sudo chmod 700 /home/<SUDO_USER>/.ssh
# Allow only SUDO_USER to read and modify the contents of authorized_keys
sudo chmod 600 /home/<SUDO_USER>/.ssh/authorized_keys
Then use this command to copy it from your local PC to the VPS server. Note: the .pub is the public one to copy:
ssh-copy-id -i ~/.ssh/id_ed25519_[YOUR_CUSTOM_NAME].pub user@<YOUR_VPS_IP_ADDRESS>
Connect to it using the private key on your local device:
ssh -i ~/.ssh/id_ed25519_[YOUR_CUSTOM_NAME] user@<YOUR_VPS_IP_ADDRESS>
If you want it to prompt for your private key passphrase when you use ssh user@<YOUR_VPS_IP_ADDRESS>, add this:
nano ~/.ssh/config
Host <YOUR_VPS_IP_ADDRESS>
User <username>
IdentityFile ~/.ssh/id_ed25519_[YOUR_CUSTOM_NAME]
IdentitiesOnly yes
I recommend Firefox or a fork (Waterfox, LibreWolf) since you can set the proxy settings to affect only that browser instead of all traffic on the computer if you set it in your operating system’s network settings.
There is no encryption between you and the VPS
If it is not available, verify Ask to save passwords is enabled in Firefox settings. I have experienced issues where it did not prompt me to save. Try restarting the browser, and when it asks you for the credentials the first time, cancel or close it. Then visit a website, and it will prompt you again, hopefully with the checkbox or pop-up in the address bar.