squid搭建代理服务器,实现在外访问家里设备,web代理
一、背景
当存在一个网站W,电脑A可以访问,但你现在使用的电脑B不可访问时,可以在A上搭建一个web代理,这样B就能访问W了
如果想在外访问家里的设备,如路由器,可以先参考我的这篇文章:《NameSilo的DDNS动态域名解析脚本》
为什么选择squid ?
-
安装相对简单
-
支持访问控制,身份认证,限制能访问的域名,限制发起请求的IP等等
如果只是web需求,相比之下,搭建那V个P什N么、v2[emm]ray之类的就太麻烦了
五大开源 Web 代理服务器横评:Squid、Privoxy、Varnish、Polipo、Tinyproxy
二、安装
2.1 yum安装
-
优点:方便快捷,安装后就是服务,可以用systemctl管理
-
缺点:不安全,版本较低,centos7是3.5,这是很老的版本了。squid老版本存在缓冲区溢出命令执行、整数溢出等,具体可以去查CVE。开放公网的话还是编译安装最新版吧,这玩意你浏览器直接访问代理IP+端口,就能拿到版本...http头部也有
yum install squid
如后续需设置通过用户密码认证来连接代理,那么需要检查是否有 htpasswd
htpasswd
没有的话需要安装 yum install httpd-tools
2.2 编译安装
-
优点:可以安装最新版本,相对安全
-
缺点:编译慢,需要大几十分钟。启动和关闭命令难记
# 官网下载 http://www.squid-cache.org/Versions/
wget http://www.squid-cache.org/Versions/v4/squid-4.15.tar.gz
tar -zxvf squid-4.15.tar.gz
cd squid-4.15
./configure
make -j8 # 根据CPU线程数而定,提高编译速度,为cpu核心数两倍
make install
三、配置
3.1 基本配置
编译安装的默认允许所有IP连接,yum安装似乎默认不开放公网,修改配置文件
vi /etc/squid/squid.conf
- 找到http_access deny all,改为 allow all 即可允许所有IP使用代理
而编译安装的配置文件在 /usr/local/squid/etc/squid.conf
二者找到 port 可以更改服务监听代理的端口
3.2 高隐配置
squid 默认是透明代理,也就是说你通过 squid 访问一个服务器,服务器知道你使用了代理,知道你代理的IP和你真实的IP或局域网出口的IP
想要完全隐藏你的代理信息和真实信息,可以追加以下配置
#
# HTTP head X-Forwarded-For
# http://www.squid-cache.org/Doc/config/forwarded_for/
#
forwarded_for delete
#
# HTTP head Via
# http://www.squid-cache.org/Doc/config/via/
#
via off
XFF用于代理时记录原始IP和每个代理服务器IP;via用来记录每个代理服务器的信息。关闭这两个请求头,代理信息就能被隐藏了。
不过报文看起来还是和正常请求有区别的,那就是多了诸如 X-Cache 的缓存相关头,不过无太大影响
暴力隐藏这些头可以参考 request_header_access 或是 reply_header_access,但是不推荐这样做,会影响功能的正常使用。
3.3 密码认证
squid支持多种认证方式,这里选Ncsa
首先生成密码文件
如果没有htpasswd
命令,安装httpd
yum安装: htpasswd -cb /etc/squid/passwd [用户名] [密码]
,一定要放在 /etc/squid/ ,博主最开始放在 /root/ 下,结果后来连接时怎么输用户名都不对,浏览器中反复要我输入账号密码
编译安装: htpasswd -cb /usr/local/squid/etc/passwd [用户名] [密码]
然后配置 squid ,修改配置文件,还是 http_access 那行,改为
# yum安装:auth_param basic program /usr/lib64/squid/basic_ncsa_auth /etc/squid/passwd
auth_param basic program /usr/local/squid/libexec/basic_ncsa_auth /usr/local/squid/etc/passwd
auth_param basic children 5
auth_param basic credentialsttl 10 minute
acl auth proxy_auth REQUIRED
http_access deny !auth
http_access allow auth
http_access deny all
配置前需检查 basic_ncsa_auth 可执行文件的路径是否正确,也有可能在 /usr/lib/squid、lib64/squid3 之类的目录下,否则启动时报错:
/usr/lib/squid/basic_ncsa_auth: (2) No such file or directory
官方参数说明 鉴于centos默认安装是3.5
四、使用
4.1 服务端启动
yum安装:
# start stop restart status -l
systemctl start squid
# 开机自启
systemctl enable squid
# 日志
vi /var/log/squid/access.log
start失败就status -l,上面排了两个坑,再说我遇到过的其它情况
起因是我不小心直接执行了 squid 命令,然后就运行起来了但我不知道,当我再start时最开始是报:Could not send signal 15 to process 6527: (13) Permission denied
我发现后台有在跑一个 squid,stop没用就直接kill了,然后再start报:FATAL: Ipc::Mem::Segment::create failed to shm_open(/squid-cf__metadata.shm): (17) File exists
遇事不决就重启,我直接reboot,解决了,听说删除 dev/shm/ 下的文件也能成功
编译安装:
首先你需要新建这两个文件才能启动
touch /usr/local/squid/var/logs/cache.log
# squid总以nobody用户运行,不更改文件权限无法写入
chown nobody /usr/local/squid/var/logs/cache.log && chgrp nobody /usr/local/squid/var/logs/cache.log
touch /usr/local/squid/var/logs/access.log
chown nobody /usr/local/squid/var/logs/access.log && chgrp nobody /usr/local/squid/var/logs/access.log
使用方法:
# 后台启动
/usr/local/squid/sbin/squid -s
# 查看是否运行
ps -ef|grep squid|grep -v grep
# 关闭
ps -ef|grep squid|grep -v grep|cut -c 9-16|xargs kill -9
几个没用的命令:
-k check
听说能检查是否运行,实测无反应
-k parse
听说能检查配置文件是否正确,实测好像不是这个作用
-k shutdown
字面意思是停止服务,实测无用
-k kill
能杀掉进程,但是杀得不干净
最后可以使用我的脚本模板设置开机自启
4.2客户端使用
浏览器直接设置,推荐一个代理管理插件 SwitchyOmega ,配置时选https,再设置密码,每次改密码后,重启浏览器,否则会有当你把密码改错后,仍使用之前的正确密码连接的情况
curl 验证代理情况可以使用
curl --proxy x.x.x.x:3128 --proxy-user admin:123456 http://mi.com
用了一万年的baidu.com测网通没通......现在再也不用了
五、传输安全
使用浏览器F12查看网络,我们可以看到使用代理后,我们的账号密码是base64编码后传输的
base64属于编码,不能称之为加密,解码就能出明文,这很不安全。如果你还访问加密做得不好的网站,那更不安全,容易被嗅探
网上看到有使用 stunnel+squid 加密的,stunnel负责加密传输中的数据,避免网络报文被嗅探,发生信息泄露等问题。缺点是stunnel是端到端传输,两端都需要安装应用,比较繁琐
博主想到用 nginx+squid 转发!
如果nginx在应用层转发的话,可以做https加密,还能自定义页面和http头部,这样别人甚至不知道你开放的是squid服务端口
想法很美好,事实是nginx转发http(s)只能转发正常的服务,他们的报文是GET /path
然而转发代理服务器的流量,报文是GET http://xxx
,nginx无法正常转发,导致squid收到的全是GET /
,squid无法正常代理
5.1 nginx ssl stream转发
那就在传输层转发,使用stream_ssl_module,这是:nginx安装教程
这是nginx.conf中squid的配置,证书最好是域名的证书,自己生成一个应该也能用
# https://www.cnblogs.com/yunmuq
stream {
# squid
server {
listen 8443 ssl;
ssl_certificate cert.pem;
ssl_certificate_key cert.key;
# squid端口
proxy_pass 127.0.0.1:8080;
}
}
上面的例子中,我们把8443开放公网,把8080隐藏即可
客户端使用时用wireshark嗅探一下,就能发现代理TLS v1.2协议,不是明文的了
如果没法加密传输,我们可以这样查看squid被拦截访问的情况
# 查看squid端口被直接访问的次数
grep 'GET /' /usr/local/squid/var/logs/access.log -c
# 查看使用squid代理但用户名或密码错误的次数
grep TCP_DENIED /usr/local/squid/var/logs/access.log -c
access.log的开头是时间戳,需要解析一下数值才能知道这条日志的时间,而且时间戳是带小数点的,小数点后是毫秒,有时可能需要去掉小数点才能解析,也可以不用小数点后面的数值
5.2 nginx下squid的配置注意项
使用nginx后,squid中的配置,把允许本地全删掉
因为通过nginx连接squid,squid会把连接当作都来自本地!
六、客户端使用
推荐浏览器插件SwitchyOmega
在插件设置中,有一个默认
的行,这代表着默认使用哪个协议的代理服务器
如果配置了nginx加密,那么默认就要选HTTPS