背景
最近需要使用nodeJs訪問一個歷史久遠的網站,那個網站的服務器證書是錯誤的,且使用的協議是TLSv1.0。瀏覽器上不得不使用IE并關閉各種安全設置和設置為兼容模式才能正常訪問。Nodejs的新版本已經不支持這種不安全的協議,所以需要搭建一個代理服務進行訪問。剛開始使用的是mitmproxy ,當時的最新版本對于SSL錯誤會報錯,所以將源碼中校驗部分去掉就可以正常使用了。但部署到生產環境,會出現cpu占用過高的情況。所以后面換了Squid。
部署Squid參考了一篇文章,原文:here,下面是簡單翻譯。
正文
Squid是個很強大的Web代理,它可以應用于無線認證、重定向、用戶身份驗證、日志記錄等。但其在SSL方面一直存在局限性。在3.2版本之前,Squid的策略只是簡單地傳遞SSL加密流量,因為它無法校驗受信任的SSL鏈接。對于每個SSL連接也無法給用戶做預警。但3.5版本后允許更多的控制,但要注意仍然無法校驗受信任的SSL鏈接。
這里不會過多地介紹使用SSL Bump配置Squid以外的知識,對于編譯和配置squid的細節你最好看下官方文檔。 如果通過代理自動監測,通知瀏覽器連接到代理服務器,這樣是挺簡單的。但有些用戶可能會試圖規避這一點,并嘗試直接連接。 在這種情況下,我們需要強制這些用戶通過截取流量來使用代理。SSL Bumping的前提是中間人攻擊,但由于這是在您的用戶清楚所有流量都是檢查過的環境中完成的,因此這并不是真正的攻擊,這只是一種策略。Squid用于執行SSL Bumping有一些新方法,但是我會總結出最具實戰性的方法:Squid收到一個https請求,然后為用戶建立安全連接。 遠程連接建立后,Squid會重新加密所有流量; 這時候的加密使用的是本地私鑰,以及本地證書頒發機構即時創建出來的證書。
所以我們首先要確保的是你已經安裝了3.5或更高版本的Squid。盡管3.2,3.3以及3.4版本也能實現,但3.5版本后SSL Bump的指令有了些顯著變化。另外,編譯Squid時需要帶上‘–with-openssl’參數。
在CentOS我使用以下參數來編譯Squid(foam:我帶上–enable-ipf-transparent參數會報錯,所以我是去掉再編譯的)
./configure \
--prefix=/usr \
--exec-prefix=/usr \
--includedir=/usr/include \
--datadir=/usr/share \
--libdir=/usr/lib64 \
--libexecdir=/usr/lib64/squid \
--localstatedir=/var \
--sysconfdir=/etc/squid \
--sharedstatedir=/var/lib \
--with-logdir=/var/log/squid \
--with-pidfile=/var/run/squid.pid \
--with-default-user=squid \
--enable-silent-rules \
--enable-dependency-tracking \
--with-openssl \
--enable-icmp \
--enable-delay-pools \
--enable-useragent-log \
--enable-esi \
--enable-follow-x-forwarded-for \
--enable-ipf-transparent \
--enable-auth
接下來我們需要生成本地的SSL證書,這里我使用的是簡單的命令,沒有在意怎么去加密。
# Generate Private Key
openssl genrsa -out example.com.private 2048
然后是創建Certificate Signing Request(CSR),即證書注冊請求。
# Create Certificate Signing Request
openssl req -new -key example.com.private -out example.com.csr
Country Name (2 letter code) [XX]:US
State or Province Name (full name) []:Illinois
Locality Name (eg, city) [Default City]:Chicago
Organization Name (eg, company) [Default Company Ltd]:Example Company LTD.
Organizational Unit Name (eg, section) []:Information Technology
Common Name (eg, your name or your server's hostname) []:Example Company LTD.
Email Address []:
Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []:
An optional company name []:Example Company LTD.
請注意,我并沒有給‘Common Name’ 設置一個域名。因為Squid會在用戶請求時,使用當前訪問的域名動態生成證書。接下來,我們給CSR生成個簽名證書。
# Sign Certificate
openssl x509 -req -days 3652 -in example.com.csr -signkey example.com.private -out example.com.cert
完成以上操作后,請將私鑰和證書復制到Squid能夠訪問的目錄。另外,請確保存放私鑰的目錄是安全的。Squid代理用戶需要擁有訪問證書的權限,并作為受信任的根證書安裝到每個用戶的計算機上。 這是我沒有使用*或一個域名作為‘Common Name’的真正原因,因為當作為證書頒發機構加載時,該屬性就會被固定了。
下面來看看Squid的配置,以下配置只與主題相關,并不是完整的。ps:請按照下面的順序配置。
# Proxy Aware (non-intercepted traffic)
http_port 192.168.0.1:3128 ssl-bump cert=/etc/squid/example.com.cert key=/etc/squid/example.com.private generate-host-certificates=on version=1 options=NO_SSLv2,NO_SSLv3,SINGLE_DH_USE
# Intercepted Traffic
https_port 192.168.0.1:3130 cert=/etc/squid/example.com.cert key=/etc/squid/example.com.private ssl-bump intercept generate-host-certificates=on version=1 options=NO_SSLv2,NO_SSLv3,SINGLE_DH_USE
# SSL Bump Config
ssl_bump stare all
ssl_bump bump all
下面作些說明:
http_port: 讓Squid在ssl_bump模式下監聽192.168.0.1的3130端口。這里我拒絕了SSLv2以及SSLv3的鏈接,并使用SINGLE_DH_USE。使用http_port時,瀏覽器是知道自己在與代理連接的。
https_port: 讓Squid在ssl_bump攔截模式下監聽192.168.0.1的3128端口。這里我同樣拒絕了SSLv2以及SSLv3的鏈接,并使用SINGLE_DH_USE。使用https_port時,瀏覽器并不知道自己在連接代理,也就是說此時是透明代理。
ssl_bump stare:必需指令,關乎證書的正確生成。下面有更詳細的介紹。
ssl_bump bump:執行bump的方法。
Squid的3.5版本有多種bump的方法和層次:
splice:舊的方式,并沒有涉及到證書。
bump:自動生成證書并對流量重新加密,這正是我們想要的。
peek:可以參與連接,并允許在后續拼接流量。
stare:可以參與連接,并允許在后續對其bump。
為了能夠成功攔截流量并生成證書,我們需要知道用來生成證書的域。 如果瀏覽器知道它正在使用代理,倒是沒問題。 但如果我們僅僅是通過攔截流量來獲取信息,就會使用遠程服務器的IP地址來生成證書,這樣是行不通的。 所以我們必須先’stare’ 連接。這樣我們就可以獲得域并用其生成正確的證書。
看到這里,你應該知道怎么做了。 但請注意,這本質上是打破了SSL信任機制。 你控制并影響了用戶的信任策略(對某些人來說可能是一件好事),并默認信任代理服務器。 此配置的強大功能可以讓您充分利用Squid強大的功能,如破解SSL保護的站點來過濾一些內容。
Notes 我在CentOS上編譯時遇到一個問題,這通過修改 USE_SOLARIS_IPFILTER__MINOR_T_HACK 的定義來解決。大概在38725行。
#define USE_SOLARIS_IPFILTER_MINOR_T_HACK 0
以上為原文翻譯,下面貼出我用于訪問那個老舊網站的配置
#
# Recommended minimum configuration:
#
# 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
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
#
# Recommended minimum Access Permission configuration:
#
# Deny requests to certain unsafe ports
#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
#忽略證書錯誤
sslproxy_cert_error allow all
sslproxy_flags DONT_VERIFY_PEER
#使用TLSv1.0連接
sslproxy_version 4
sslproxy_options ALL
# 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 allow all
# Squid normally listens to port 3128
http_port 127.0.0.1:8888 ssl-bump cert=/etc/squid/my.cert key=/etc/squid/my.private generate-host-certificates=on
ssl_bump stare all
ssl_bump bump all
# Uncomment and adjust the following to add a disk cache directory.
#cache_dir ufs /var/cache/squid 100 16 256
# Leave coredumps in the first cache dir
coredump_dir /var/cache/squid
#
# 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
- 本文固定鏈接: http://zoufeng.net/2017/09/23/squid-proxy-with-ssl-bump/
- 轉載請注明: foam 2017年09月23日于 foam 發表