设置显式 Squid 代理
Squid 🔓 是一个用于 Web 的缓存代理,支持 HTTP、HTTPS、FTP 等。它通过缓存和重用频繁请求的网页来减少带宽并提高响应时间。Squid 具有广泛的访问控制,并且是一个出色的服务器加速器。它在 GNU GPL 许可下获得许可。
如果您正在寻找设置透明 squid 代理,请参阅此页面
术语
客户端
客户端通常被认为是 PC 或类似系统的用户,但更准确地说,客户端是个人用来访问网页和其他资源的应用程序,以及它们运行的操作系统。
代理
代理 是代表客户端建立连接的设备。如果我们考虑一个常见的 TCP 连接,则在客户端(源)和代理之间存在一个 TCP 连接,在代理和服务器(目标)之间存在另一个 TCP 连接。考虑一下这个精美的图表
Client<---------->|PROXY|<------------>Server A B
点 A 是客户端连接,点 B 是服务器端连接。
这些是单独的、不同的连接,因此例如客户端可以是加密的,而服务器端可以是明文的(未加密的),或者客户端可以使用浏览器用户代理标头 x,而服务器端连接可以使用浏览器用户代理标头 y。
代理有效地充当客户端的服务器,以及服务器(OCS)的客户端。如果没有代理,连接将只是从客户端到服务器。目标服务器通常被称为“OCS”或“源内容服务器”——这仅仅意味着托管客户端请求的对象(例如您想要的网页)的服务器。
以上当然是简化版本。其他因素,例如客户端浏览器的 HTTP 版本,或代理上缓存中是否存在对象,都会影响创建多少服务器端连接。
显式转发代理
显式代理是指客户端显式配置为使用代理的代理,因此客户端知道网络上代理的存在。当客户端向显式代理发送数据包时,它们被寻址到代理服务器监听地址和端口。Squid 通常在 TCP 端口 3128 上侦听显式流量,但 TCP 端口 8080 是常见的显式代理侦听端口。显式代理部署是转发代理部署,其中客户端可以在发出出站请求时利用代理的缓存和优化功能。显式代理可以参与客户端的身份验证,通常通过发出 407 HTTP 响应。通过显式代理连接到 HTTPS 站点将使用 CONNECT HTTP 方法。本文讨论了这种类型的代理部署。
透明转发代理
透明代理,也称为拦截代理,不需要客户端进行任何配置更改,因为流量是透明地发送到代理的,通常是通过路由器的流量重定向。当客户端发送数据包时,它们被寻址到目标服务器。透明服务器可以参与客户端身份验证;这通常会涉及将客户端重定向到虚拟域,通常带有 401 HTTP 响应。
反向代理
反向代理 位于诸如 Web 服务器之类的资源的前面,并回答来自客户端的查询,缓存来自服务器的内容并优化与其的连接。
缓存
缓存只是一个对象存储。代理通常会缓存客户端请求的对象(图像、html 文本、下载的文件等),这意味着将对象存储在代理的 RAM 中或磁盘上。这具有客户端能够从代理获取对象的好处,而无需等待代理连接到目标服务器 (OCS) 并再次下载对象,从而带来更好的客户端体验(“网页似乎加载更快”)和减少带宽(减少服务器端连接,特别是如果我们考虑重复请求的对象)。
缓存受代理配置(要缓存的内容)和许多 HTTP 标头(我是否可以缓存此对象?我应该缓存多久?)的影响,例如“Expires”、“Cache Control”、“If-Modified-Since”和“Last-Modified”。代理通常会通过独立于客户端对对象的请求而发出对缓存对象的请求来保持其缓存新鲜。
更多信息
您可能还希望查看 https://community.f5.com/t5/technical-articles/the-concise-guide-to-proxies/ta-p/285459,其中提供了有关各种代理类型的更多信息。
安装
安装 squid 软件包
apk add squid
如果您希望使用 Alpine Configuration Framework (ACF) 前端用于 squid,请安装 acf-squid 软件包
apk add acf-squid
然后您可以登录到设备 https://x.x.x.x (将 x.x.x.x 替换为您的服务器的 IPv4 地址) 并管理 squid 配置文件并停止/启动/重启守护程序等。
基本配置
配置文件
主配置文件是 /etc/squid/squid.conf。以“#”开头的行是注释。squid 应该已经带有一个基本的工作配置文件,但下面显示了一个示例配置文件,该文件将使您快速启动并运行,并且注释良好,但请更改 localnet 定义以获得更严格的定义
## Tested and working on squid 3.3.10-r0 and Alpine 2.7.1 (kernel 3.10.19-0-grsec), 64-bit ## Example rule allowing access from your local networks. ## Adapt to list your (internal) IP networks from where browsing ## should be allowed acl localnet src 10.0.0.0/8 # RFC1918 possible internal network acl localnet src 172.16.0.0/12 # RFC1918 possible internal network acl localnet src 192.168.0.0/16 # RFC1918 possible internal network ## Allow anyone to use the proxy (you should lock this down to client networks only!): # acl localnet src all ## IPv6 local addresses: acl localnet src fc00::/7 # RFC 4193 local private network range acl localnet src fe80::/10 # RFC 4291 link-local (directly plugged) machines 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 # waiss 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 acl QUERY urlpath_regex cgi-bin \? asp aspx jsp ## Prevent caching jsp, cgi-bin etc cache deny QUERY ## Only allow access to the defined safe ports whitelist http_access deny !Safe_ports ## Deny CONNECT to other than secure SSL ports http_access deny CONNECT !SSL_ports ## Only allow cachemgr access from localhost http_access allow localhost manager http_access deny manager ## We strongly recommend the following be uncommented to protect innocent ## web applications running on the proxy server who think the only ## one who can access services on "localhost" is a local user http_access deny to_localhost ## ## INSERT YOUR OWN RULE(S) HERE TO ALLOW ACCESS FROM YOUR CLIENTS ## ## 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 http_access deny all ## Squid normally listens to port 3128 http_port 3128 ## If you have multiple interfaces you can specify to listen on one IP like this: #http_port 1.2.3.4:3128 ## Uncomment and adjust the following to add a disk cache directory. ## 1024 is the disk space to use for cache in MB, adjust as you see fit! ## Default is no disk cache #cache_dir ufs /var/cache/squid 1024 16 256 ## Better, use 'aufs' cache type, see ##http://www.squid-cache.org/Doc/config/cache_dir/ for info. #cache_dir aufs /var/cache/squid 1024 16 256 ## Recommended to only change cache type when squid is stopped, and use 'squid -z' to ## ensure cache is (re)created correctly ## Leave coredumps in the first cache dir #coredump_dir /var/cache/squid ## Where does Squid log to? #access_log /var/log/squid/access.log ## Use the below to turn off access logging access_log none ## When logging, web auditors want to see the full uri, even with the query terms #strip_query_terms off ## Keep 7 days of logs #logfile_rotate 7 ## How much RAM, in MB, to use for cache? Default since squid 3.1 is 256 MB cache_mem 64 MB ## Maximum size of individual objects to store in cache maximum_object_size 1 MB ## Amount of data to buffer from server to client read_ahead_gap 64 KB ## Use X-Forwarded-For header? ## Some consider this a privacy/security risk so it is often disabled ## However it can be useful to identify misbehaving/problematic clients #forwarded_for on forwarded_for delete ## Suppress sending squid version information httpd_suppress_version_string on ## How long to wait when shutting down squid shutdown_lifetime 30 seconds ## Replace the User Agent header. Be sure to deny the header first, then replace it :) #request_header_access User-Agent deny all #request_header_replace User-Agent Mozilla/5.0 (Windows; MSIE 9.0; Windows NT 9.0; en-US) ## What hostname to display? (defaults to system hostname) #visible_hostname a_proxy ## Use a different hosts file? #hosts_file /path/to/file ## Add any of your own refresh_pattern entries above these. refresh_pattern ^ftp: 1440 20% 10080 refresh_pattern ^gopher: 1440 0% 1440 refresh_pattern -i (/cgi-bin/|\?) 0 0% 0 refresh_pattern . 0 20% 4320
注意:如果您更改了 squid 配置文件,则无需重启 squid 即可加载更改,只需使用此命令即可
squid -k reconfigure
测试
启动并检查 squid
启动 squid 服务
rc-service squid start
在启动时自动启动 squid
rc-update add squid
检查 squid 配置是否有错误
squid -k check
如果没有反馈,一切都很好!(这是一件好事)。
检查 squid 是否正在监听流量,例如使用 netstat
netstat -tl
您应该看到一行显示本地地址和监听端口(在上面的示例配置中,它设置为 3128)。如果您没有看到此行,请检查“http_port”指令是否在配置文件中设置并具有值。确保此端口未被系统上的其他内容使用。
请记住确保 squid 代理具有有效的 IP 配置,包括默认网关等。
配置客户端
每个使用代理的应用程序都必须配置为通过代理发送流量。如果我们假设我们的 squid 代理在 IP 地址 10.0.0.1、端口 3128 上运行,我们将按以下方式配置 Firefox 浏览器
- 工具>选项>高级>网络>设置...
- 选择手动代理配置并勾选“为此协议使用此代理服务器”框
- 在 HTTP 代理:下添加 squid 监听 IP 地址 10.0.0.1。在端口:部分中添加 squid 监听端口 3128
- 单击确定以保存更改。
现在浏览,您应该可以通过代理访问互联网!
许多操作系统允许设置系统代理。可以将 Firefox 设置为使用系统代理设置
- 工具>选项>高级>网络>设置...
- 选择使用系统代理设置
- 单击确定以保存更改。
系统代理设置 本身因系统而异,但在 Alpine 安装上,您可以简单地运行 setup-proxy 脚本。
也可以配置浏览器使用 PAC 文件。此文件通常托管在 Web 服务器上(也可能是代理,但不必是),它告诉浏览器哪些请求发送到代理,哪些请求直接发送(绕过代理)。
Squid FAQ 关于配置浏览器 提供了有关此主题的更多信息。
日志
如果您已将代理设置为记录访问日志,则可以查看这些日志以查看传入的客户端请求
tail -f /var/log/squid/access.log
使用 Ctrl-C 退出返回到提示符。
SSL 拦截或 SSL 碰撞
官方 squid 文档似乎更喜欢使用术语SSL 拦截来表示 透明 squid 部署,而使用 SSL 碰撞 来表示显式代理部署。尽管如此,这两种环境都使用 ssl_bump 配置指令(以及其他一些指令)在 /etc/squid/squid.conf
中进行配置。在一般术语中,SSL 拦截 通常用于描述这两种部署,这将是本文中使用的术语。当然,我们在这里处理的是显式转发代理配置。
不使用 SSL 拦截的行为
显式代理后面的客户端使用 'CONNECT' HTTP 方法。与代理端口的第一个连接使用 HTTP 并指定目标服务器(通常称为源内容服务器或 OCS)。此后,代理仅充当 隧道,并盲目地代理连接而不检查流量。
使用 SSL 拦截的行为
使用此方法,客户端仍然使用 CONNECT 方法。通常,服务器端连接首先建立,使用来自客户端的 CONNECT 请求中可用的信息(例如目标服务器和端口),这允许 Squid 欺骗证书。公用名 (CN) 将反映目标服务器,并且 Squid 证书将用于对其进行签名。然后,当客户端通过代理访问站点时,会将此欺骗证书呈现给客户端。
配置
添加软件包
添加 ca-certificates 软件包(信任常用证书颁发机构 (CA) 证书所需)和 openssl 软件包或 libressl 软件包(创建自签名证书或 CSR)。-U
选项确保我们首先更新软件包列表
apk -U add ca-certificates libressl
生成证书/密钥对
您显然不需要遵循接下来的两个部分。生成自签名证书或 CA 签名证书(您必须为后者付费),然后修改 squid 配置以启用 SSL 拦截并将其指向在这些步骤中生成的密钥/证书对。无论您使用的是 OpenSSL 还是 LibreSSL,“openssl”仍然是要使用的命令。
生成自签名证书
以下示例命令将生成一个可工作的证书/密钥对,并保存到 /etc/squid/squid.pem
openssl req -newkey rsa:4096 -x509 -keyout /etc/squid/squid.pem -out /etc/squid/squid.pem -days 365 -nodes
然后调整权限
chmod 400 /etc/squid/squid.pem
在上面的示例中,我们将证书和密钥保存到同一个文件中;如果您愿意,可以将它们保存到单独的文件中,只需相应地调整路径即可。
生成 CSR 以获取 CA 签名证书
使用语法 openssl genrsa -out <key_path_and_name> <keysize>
创建私钥
例如
openssl genrsa -out /etc/squid/squid.key 2048
使用语法 openssl req -new -key <key_path_and_name> -out <csr_path_and_name>
创建 CSR
例如
openssl req -new -key /etc/squid/squid.key -out /etc/squid/squid.csr
然后,您需要将 CSR(证书签名请求)提供给您的证书颁发机构 (CA)。不要将您的私钥发送给他们或任何其他人。它应该保持私密!
某些 CA 提供在线 CSR 检查器,因此您可以确保 CSR 在提供给他们之前有效。
一旦 CA 收到 CSR 并完成他们的工作,他们应该将 CA 签名的公钥发回给您。如果可能,请以 .pem 格式请求它(它是证书的广泛使用的标准)。然后,您需要将其复制回 Squid 代理,如果您遵循此处的示例,则复制到 /etc/squid/。
请记住修改 squid 配置 以指向私钥和 CA 签名证书的正确位置。
修改 /etc/squid/squid.conf
接下来,我们需要修改 squid 配置文件以使用 SSL 拦截。在下面的示例中,我们将添加几行,然后修改 http_port
指令,以便它仍然服务 HTTP 请求,但也对通过 HTTP 方法 CONNECT 建立的 HTTPS 连接执行 SSL 拦截。如果您愿意,您可以为每个使用单独的 http_port
,但请记住修改客户端配置以将 HTTPS 流量发送到备用端口。
## Use the below to avoid proxy-chaining always_direct allow all ## Always complete the server-side handshake before client-side (recommended) ssl_bump bump all ## Prior to squid 3.5 it was done like this: #ssl_bump server-first all ## Allow server side certificate errors such as untrusted certificates, otherwise the connection is closed for such errors sslproxy_cert_error allow all ## Or maybe deny all server side certificate errors according to your company policy #sslproxy_cert_error deny all ## Accept certificates that fail verification (should only be needed if using 'sslproxy_cert_error allow all') sslproxy_flags DONT_VERIFY_PEER ## Modify the http_port directive to perform SSL interception ## Ensure to point to the cert/key created earlier ## Disable SSLv2 because it isn't safe http_port 3128 ssl-bump cert=/etc/squid/squid.pem key=/etc/squid/squid.pem generate-host-certificates=on options=NO_SSLv2
您使用“sslproxy_cert_error”(以及可能的“sslproxy_flags”)选项做出的决定是,当遇到证书错误(例如呈现自签名、不受信任的证书)时关闭连接,或者将证书错误传递给客户端,以允许他们选择站点以及是否信任证书。
修复客户端 SSL 警告
您需要将自签名代理证书(在我们的示例中,我们将其保存到 /etc/squid/squid.pem)安装到所有客户端,否则他们可能会为他们通过 HTTPS 访问的每个域获得 SSL 错误。重要的是将证书作为证书颁发机构 (CA) 证书安装到客户端浏览器,以便正确建立信任。如果您使用的是 CA 签名证书(而不是自签名证书),则浏览器可能已经信任该证书,因此可能不需要此步骤。
对于 Internet Explorer,您可能可以双击 .pem 证书并使用证书导入向导将证书手动安装到受信任的根证书颁发机构证书存储中。
对于 Firefox,请使用工具>选项>高级>证书>查看证书。在机构选项卡下,使用导入...将证书添加为受信任的机构。将证书安装为任何其他类型的证书都会导致糟糕的用户体验。
注意:如果您看到错误此证书已作为证书颁发机构安装。请务必检查证书存在的所有位置并删除(删除)它。Firefox 喜欢将证书安装为服务器证书,而不是我们希望的 机构 下。删除证书的所有痕迹后,请务必重启 Firefox 并尝试再次导入证书。
禁用特定站点的 SSL 拦截
在某些情况下,您可能希望由于功能问题或隐私问题而禁用对某些目标的 SSL 拦截/SSL 碰撞。例如,Windows Dropbox 客户端拒绝建立安全连接,因为它不信任代理使用的自签名证书。或者,您可能希望在用户使用 hotmail.com 时保留用户隐私。在此示例中,我们将创建一个访问控制列表 (ACL) 以防止对 *.hotmail.com 和 *.dropbox.com 进行 SSL 拦截。请记住,规则顺序很重要,第一个匹配项获胜!因此,将更具体的规则放在顶部,将更一般的规则放在下面。
## Disable ssl interception for dropbox.com and hotmail.com (and localhost) acl no_ssl_interception dstdomain .dropbox.com .hotmail.com ssl_bump none localhost ssl_bump none no_ssl_interception ## Add the rest of your ssl-bump rules below ## e.g ssl_bump bump all ## etc
配置 HTTPS 拦截后 Squid 崩溃
配置 SSL 拦截后,Squid 可能会崩溃。该服务可能会报告为正在运行,但查看监听端口不再显示 Squid 正在监听。查看 /var/log/messages 可能会显示错误“ssl_crtd helpers are crashing too rapidly, need help!”
在这种情况下,请执行以下操作
rc-service squid stop rm -rf /var/lib/ssl_db /usr/lib/squid3/ssl_crtd -c -s /var/lib/ssl_db rc-service squid start
延伸阅读
广告拦截
有几种方法可以实现此目的,您可以简单地为已知的广告域名创建 ACL(有关如何执行此操作的指示,请参阅阻止域名)。另一种选择是使用特定于 squid 的 hosts 文件(即与系统 hosts 文件无关),这将把已知广告/恶意软件站点的流量定向到 localhost。然后,连接可能会失败(因为在 127.0.0.1:80 上没有 Web 服务器来服务由 hosts 文件重定向到 localhost 的请求),并且 squid 将显示标准错误,或者您可以运行一个 Web 服务器,该服务器将响应某种形式的“广告已阻止”页面。
阻止广告将节省带宽并应缩短页面加载时间。缺点是,如果没有广告,某些页面可能会显得不整洁或奇怪。
首先要做的是自己创建一个 hosts 文件,或者找到一个预配置的文件,例如 这个(请注意,此文件仅供个人使用免费使用,请参阅完整许可证 此处。
无论您选择哪种方法,都将 hosts 文件保存到本地文件系统,在我们的示例中保存到 /etc/squid/hosts.txt
然后,将 hosts_file
指令添加到 squid 配置
hosts_file /etc/squid/hosts.txt
请记住重新加载配置/重启 squid 服务以使更改生效。
阻止域名
如果您有大量要阻止的域名,最好创建一个单独的列表并在配置文件中引用它,而不是直接将它们添加到 squid 配置文件中。域名列表应每行列出一个域名。有一个示例列表(警告,此列表不会更新!)可在此处获得 here。在下面的示例中,我们将引用此列表。
- 创建您自己的域名列表,或下载一个域名列表并将其保存到 /etc/squid/porndomains.acl
- 如下所示修改 /etc/squid/squid.conf 中的 squid 配置文件:
# 基于 URL 过滤列表阻止色情域名 acl blacklistpr0n dstdomain "/etc/squid/porndomains.acl" http_access deny blacklistpr0n
- 检查 squid 配置是否有错误
squid -k check
如果没有任何错误,请应用更改
squid -k reconfigure
- 完成!列表中的域名现在应该被阻止。
您当然可以创建自己的域名列表,并根据上述示例将黑名单/白名单添加到您的配置中。当然,每个列表都应该有一个唯一的名称。
DNS 配置
由于默认情况下 Squid 将使用 /etc/resolv.conf 中的设置,因此无需额外的 DNS 配置。您可能希望为您的环境更改此行为或调整设置以提高性能,如下例所示。与我的示例一样,它进行了大量注释,请根据您的需要进行更改。
## Use DNS defined servers. Default is to use servers defined in /etc/resolv.conf #dns_nameservers 10.0.0.1 192.168.0.1 ## Should squid handle single-component names? Default is disabled #dns_defnames on ## How many DNS child processes to spawn? Values shown are defaults #dns_children 32 startup=1 idle=1 ## Enable EDNS. Default is no ("none"). Size is specified in bytes. #dns_packet_max none ## How often to retransmit DNS query? Default is 5 seconds, doubled every time all DNS servers have been tried. #dns_retransmit_interval 5 ## DNS query timeout. If no response is received to a DNS query within this time, ## all DNS servers for the queried domain are assumed to be unavailable. ## Default is 30 seconds #dns_timeout 30 seconds ## Default is to use IPv6 to connect to sites where available, over IPv4. ## Turning this feature on reverses this and prefers IPv4 connections over IPv6 #dns_v4_first on