Squid Proxy
Squid is a caching proxy for HTTP, HTTPS and FTP, providing extensive access controls.
Concepts
There are different types of how you can configure your proxy server.
Standard
- configured in browser
- or gets deployed as
proxy.pac - configured by DHCP
- configured by Active Directory group policies
Transparent
- Port 80 & 443 getting redirected to the proxy server by the firewall
- Proxy has to be in
SpliceorInterceptmode - HTTPS scanning only works if the SSL certificate gets broken open by the proxy
URL Scan (splice mode)
- Proxy just sees the URL in the HTTPS traffic
- Sites can be blocked by the URL
- No virus scanning
Content Scan (intercepting mode)
- The client must have the proxy’s CA certificate in its certificate store
- The client “thinks” it’s communicating with the original web server
- Virus scanning is possible, also filtering by IDS / IPS systems
- It is a “Man-In-The-Middle-Attack” in fact.
Consult your respective
Data Protection Supervisorto be save here!
Installation
For transparent mode install:
1
apt install squid
For intercepting mode you need:
1
apt install squid-openssl
Configuration
Make a copy of the original provided squid.conf in /etc/squid.
1
2
cd /etc/squid
cp /etc/squid.conf{,.orig}
Just grab all lines that are not comments and put it squid.conf.
1
grep "^[^#]" squid.conf.orig > squid.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
...
# Accesslists
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
acl CONNECT method CONNECT
# HTTP Access
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access allow localhost manager
http_access deny manager
http_access allow localhost
http_access deny all
# Port squid is running on
http_port 3128
# If squid crashes a dump is written there
coredump_dir /var/spool/squid
# Caching behaviour
refresh_pattern ^ftp: 1440 20% 10080
refresh_pattern ^gopher: 1440 0% 1440
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0
refresh_pattern (Release|Packages(.gz)*)$ 0 20% 2880
refresh_pattern . 0 20% 4320
# Syntax: refresh_pattern [-i] regex min percent max [options]
| value | description |
|---|---|
| regex | means regular expression for that kind of requestes this rule matches |
| -i | regex by default is case-sensitive, not with -i |
| min | time in minutes in were objects are considerd “fresh” |
| percent | percent of objects are considered “fresh” |
| max | max-time in minutes were objects are considered “fresh” |
Usage
If you had just edited the configuration it’s always better to
reloadsquid instead ofrestartingit because it would take a huge amount of time to do that. Usually around 10 min.
1
systemctl reload squid.service
1
systemctl ( start | stop | restart ) squid.service
Troubleshooting
1
systemctl status squid.service
or to see squid in action:
1
tail -fn0 /var/log/squid/access.log
You’ll not see any user or passwords there. Just URLs and IPs.
Redirect traffic to squid with nftables
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
table ip nat {
chain prerouting {
type nat hook prerouting priority 0; policy accept;
# redirect HTTP to locally installed Squid instance
tcp dport 80 redirect to :3126
# redirect HTTPS to locally installed Squid instance
tcp dport 443 redirect to :3127
}
# enable nat for all packets going to the intenet through wan
chain postrouting {
type nat hook postrouting priority 100; policy accept;
oifname $wan_if masquerade
}
}
Access Control List Basics
ACLs, as they should, are checked in top to bottom order. So be careful where you place your rules.
Give access to LAN and DMZ network
This all happens in /etc/squid/squid.conf.
Build ACLs:
1
2
acl lan src 172.16.150.0/24
acl dmz src 10.40.115.0/24
Use ACLs:
1
2
http_access allow lan
http_access allow dmz
Restrict access to specific websites
1
2
acl facebook url_regex -i facebook
http_access deny facebook
You can also build blacklists or whitelists. Create a file called bad-sites.list.
1
2
3
facebook
telegram
whatsapp
Now build and use the ACL:
1
2
acl bad-sites url_regex -i "/etc/squid/bad-sites.list"
http_access deny bad-sites
squid ACL types
| value | description |
|---|---|
| src | source (client) IP addresses |
| dst | destination (server) IP addresses |
| myip | the local IP address of a client’s connection |
| arp | Ethernet (MAC) address matching |
| srcdomain | source (client) domain name |
| dstdomain | destination (server) domain name |
| srcdom_regex | source (client) regular expression pattern matching |
| dstdom_regex | destination (server) regular expression pattern matching |
| src_as | source (client) Autonomous System number |
| dst_as | destination (server) Autonomous System number |
| peername | name tag assigned to the cache_peer where request is expected to be sent |
| time | time of day, and day of week |
| url_regex | URL regular expression pattern matching |
| urlpath_regex | URL-path regular expression pattern matching, leaves out the protocol and hostname |
| port | destination (server) port number |
| myport | local port number that client connected to |
| myportname | name tag assigned to the squid listening port that client connected to |
| proto | transfer protocol (http, ftp, etc) |
| method | HTTP request method (get, post, etc) |
| http_status | HTTP response status (200 302 404 etc.) |
| browser | regular expression pattern matching on the request user-agent header |
| referer_regex | regular expression pattern matching on the request http-referer header |
| ident | string matching on the user’s name |
| ident_regex | regular expression pattern matching on the user’s name |
| proxy_auth | user authentication via external processes |
| proxy_auth_regex | regular expression pattern matching on user authentication via external processes |
| snmp_community | SNMP community string matching |
| maxconn | a limit on the maximum number of connections from a single client IP address |
| max_user_ip | a limit on the maximum number of IP addresses one user can login from |
| req_mime_type | regular expression pattern matching on the request content-type header |
| req_header | regular expression pattern matching on a request header content |
| rep_mime_type | regular expression pattern matching on the reply (downloaded content) content-type header. This is only usable in the http_reply_access directive, not http_access. |
| rep_header | regular expression pattern matching on a reply header content. This is only usable in the http_reply_access directive, not http_access. |
| external | lookup via external acl helper defined by external_acl_type |
| user_cert | match against attributes in a user SSL certificate |
| ca_cert | match against attributes a users issuing CA SSL certificate |
| ext_user | match on user= field returned by external acl helper defined by external_acl_type |
| ext_user_regex | regular expression pattern matching on user= field returned by external acl helper defined by external_acl_type |
Authentication
This is used and common in enterprise environments to control the access to the internet for specific kind of coworkers and/or restrict their access rights.
Installation
To accomplish that we need to install an additional package providing us htpasswd.
1
apt install apache2-utils
Add user (local authentication)
We have to create a password file (db) for all of our local users, for example /etc/squid/password_db.
1
htpasswd -B -c /etc/squid/password_db user
Be aware all passwords in this file are stored as hashes and
MD5is set to default which is very insecure.
| parameter | description |
|---|---|
| -m | Force MD5 hashing of the password (default) |
| -2 | Force SHA-256 hashing of the password (secure) |
| -5 | Force SHA-512 hashing of the password (secure) |
| -B | Force bcrypt hashing of the password (very secure) |
| -C | Set the computing time used for the bcrypt algorithm (default: 5, valid: 4 to 17) |
| -r | Set the number of rounds used for the SHA-256, SHA-512 algorithms (default: 5000) |
| -d | Force CRYPT hashing of the password (8 chars max, insecure) |
| -s | Force SHA-1 hashing of the password (insecure) |
| -p | Do not hash the password (plaintext, insecure) |
| -D | Delete the specified user |
| -v | Verify password for the specified user |
Configuration
Edit /etc/squid/squid.conf.
1
2
3
4
5
6
auth_param basic program /usr/lib/squid/basic_ncsa_auth /etc/squid/password_db
auth_param basic children 20 startup=0 idle=1
auth_param basic concurrency 0
auth_param basic credentialsttl 2 hours
auth_param basic realm user-access-password_db
auth_param basic casesensitive off
Add an ACL:
1
acl user-access-password_db proxy_auth REQUIRED
Add an access rule:
1
http_access allow user-access-password_db
User authentication against LDAP
Edit /etc/squid/squid.conf.
1
2
3
4
5
auth_param basic program /usr/lib/squid3/basic_ldap_auth -b "dc=local,dc=lan" -f "uid=%s" -h 10.12.0.2
auth_param basic children 50
auth_param basic realm user_access_ldap
auth_param basic credentialsttl 1 minute
auth_param basic casesensitive off
Add an ACL:
1
2
acl user_access_ldap proxy_auth REQUIRED
acl SSL_ports port 443
Add an access rule:
1
http_access allow user_access_ldap
Testing with LDAP
1
echo username ’password' | /usr/lib/squid3/basic_ldap_auth -b "dc=local,dc=lan" -f "uid=%s" -h 10.12.0.2
Password must be in single quotes
'because of using special characters. echo with double quotes"will operate differnet that way.
