使用Squid与Stunnel构建安全的http代理服务器

Squid
使用Squid在服务器端打开一个http 验证的代理端口, 同时用服务器上的Stunnel进行转发, 与客户端的Stunnel通过SSL链接, 达到代理的目的.

也可以使用客户端的Stunnel与Squid通过SSL直接相连.

本方法使用前者.

1. 服务器端配置

服务器环境:

1
2
3
4
5
6
7
8
# lsb_release -a
LSB Version: :core-4.0-ia32:core-4.0-noarch:graphics-4.0-ia32:graphics-4.0-noarch:printing-4.0- ia32:printing-4.0-noarch
Distributor ID: CentOS
Description: CentOS Linux release 6.0 (Final)
Release: 6.0
Codename: Final
# uname -a
Linux jb1.archean.me 2.6.32-71.el6.i686 #1 SMP Fri Nov 12 04:17:17 GMT 2010 i686 i686 i386 GNU/Linux

1.1 安装Squid

下载squid 3.2.8

1
# wget http://www.squid-cache.org/Versions/v3/3.2/squid-3.2.8.tar.gz

可以使用CentOS的Yum安装工具, 不过我更喜欢编译安装(提前准备好编译环境, Gcc, openssl等):

1
2
3
4
5
# tar zxvf squid-3.2.8.tar.gz
# cd squid-3.2.8
# ./configure --prefix=/usr/local --enable-basic-auth-helpers=NCSA
# make
# make install

1.2 配置Squid

这个拓扑结构只需要Squid做简单的http代理, 所以无需SSL.

squid的配置文件在/usr/local/etc/squid.conf

备份之后, 将其按下面修改, 为防止被别的机器滥用, 只监听127.0.0.1:

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
38
39
40
41
42
43
44
45
46
47
48
###/usr/local/etc/squid.conf
###2013-1-27 19:56 v0.0.1 for squid 3.2.6
#Xu Zhang <zephyr422@gmail.com>

visible_hostname Archean.me
cache_mgr zephyr422@gmail.com
http_port 127.0.0.1:3177
icp_port 0
cache_mem 256 MB
dns_nameservers 8.8.8.8 8.8.4.4

coredump_dir /usr/local/var/cache/squid
access_log /usr/local/var/logs/squid_access.log
cache_log /usr/local/var/logs/squid_cache.log

auth_param basic program /usr/local/libexec/basic_ncsa_auth /usr/local/etc/squid.passwd #使用 HTTP 基本验证
auth_param basic children 5
auth_param basic realm Archean's GFW Breaker Proxy, to forward, please input "Username/Password".
auth_param basic credentialsttl 7 days
auth_param basic casesensitive off

acl password proxy_auth REQUIRED
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
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 # 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 allow password

http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access allow localnet
http_access allow localhost

http_access deny all

检查配置有没有问题:

1
# squid -k check

或者

1
# squid -k parse	

生成密码文件(-c), 创建账户. (如果没有htpasswd需要安装 httpd, 略)

1
2
3
# htpasswd -c /usr/local/etc/squid.passwd archean
new password
...

初始化cache目录

1
# squid -z

一旦你已经初始化cache目录,就可以在终端窗口里运行squid,将日志记录到标准错误。这样,就能轻易的定位任何错误或问题,并且确认squid是否成功启动。使用-N选项来保持squid在前台运行,-d1选项在标准错误里显示1级别的调试信息。

1
# squid -N -d1

启动squid:

1
# squid

检查是否启动成功, ps -ef | grep squidlsof -i:3177

模拟测试客户端连接:

1
# squidclient -p 3177 http://www.squid-cache.org/

如期返回了html信息, 说明Squid已成功启动.

1.3 安装Stunnel

下载稳定版Stunnel

1
# wget https://www.stunnel.org/downloads/stunnel-4.56.tar.gz

创建Stunnel用户:

1
2
# /usr/sbin/groupadd -g 122 stunnel
# /usr/sbin/useradd -c stunnel -d /nonexistent -m -g 122 -u 122 stunnel

安装:

1
2
3
4
5
# tar zxvf stunnel-4.56.tar.gz
# cd stunnel-4.56
# ./configure --prefix=/usr/local
# make
# makeinstall

安装过程通常会创建自签名证书, 会放到/usr/local/etc/stunnel/stunnel.pem可以直接使用(有效期一年). 使用下面的命令检查证书详细内容:

1
2
3
4
5
6
7
8
# openssl x509 -subject -dates -fingerprint -in stunnel.pem 
subject= /C=CN/ST=Beijing/L=Beijing/O=Archean Inc/OU=Archean Inc/CN=archean.me
notBefore=Apr 20 02:05:24 2013 GMT
notAfter=Apr 20 02:05:24 2014 GMT
SHA1 Fingerprint=87:F8:6E:05:B8:9C:BC:A1:EA:15:B7:C9:B4:B2:75:FF:8A:CA:C5:FA
-----BEGIN CERTIFICATE-----
xxx
-----END CERTIFICATE-----

给证书生成 Diffie-Hellman 部分

1
# openssl gendh 512>> stunnel.pem 

这在4.x版本的stunnel上好像是必须的.

如果想要自己生成证书, 命令如下:

1
# openssl req -new -x509 -days 365 -nodes -config openssl.cnf -out stunnel.pem -keyout stunnel.pem 

1.4 配置Stunnel

/usr/local/etc/stunnel/下创建stunnel.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
cert = /usr/local/etc/stunnel/stunnel.pem
CAfile = /usr/local/etc/stunnel/stunnel.pem
socket = l:TCP_NODELAY=1
socket = r:TCP_NODELAY=1

;;;chroot = /var/run/stunnel
pid = /tmp/stunnel.pid
verify = 3

;;; CApath = certs
;;; CRLpath = crls
;;; CRLfile = crls.pem

setuid = stunnel
setgid = stunnel

;;; client=yes
compression = zlib
;;; taskbar = no
delay = no
;;; failover = rr
;;; failover = prio
sslVersion = TLSv1
fips=no

debug = 7
syslog = no
output = stunnel.log

[sproxy]
accept = 34567
connect = 127.0.0.1:3177

此时便可启动stunnel:

1
# stunnel

检查是否运行:

1
2
# ps -ef | grep stunnel
# lsof -i:34567

1.5 将Squid和Stunnel加入开机启动项

2. 客户端配置

2.1 linux客户端使用stunnel与服务器进行安全连接

安装Stunnel

与服务器完全相同, 略.

2.2 配置客户端Stunnel

将服务器生成的证书传到客户端中:

1
2
# cd /usr/local/etc/stunnel
# scp root@jb1.archean.me:/usr/local/etc/stunnel/stunnel.pem ./

创建配置文件

1
# vim stunnel.conf

内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
id = /tmp/stunnel.pid
cert = /usr/local/etc/stunnel/stunnel.pem
socket = l:TCP_NODELAY=1
socket = r:TCP_NODELAY=1
verify = 2
CAfile = /usr/local/etc/stunnel/stunnel.pem
client=yes
compression = zlib
ciphers = AES256-SHA
delay = no
failover = prio
sslVersion = TLSv1
fips = no
[sproxy]
accept = 0.0.0.0:7071
connect = jb1.archean.me:34567

其中accept是本地代理监听地址, 如不对外提供服务则改为accept = 127.0.0.1:7071

启动stunnel:

1
# /usr/local/bin/stunnel

至此, 配置完全结束, 可以通过使用Client.IP.Address:7071代理上网

2.3 结语

参考资料:

Squid权威指南

使用Squid与Stunnel构建安全的http代理服务器

https://archeanz.com/2013/10/16/safe-http-proxy-over-squid-and-stunnel/

Author

Archean Zhang

Posted on

2013-10-16

Updated on

2022-07-11

Licensed under

Comments