Squid + GnuTLS 不支援 Intermediate Certificate 的問題

先前在「架設 Proxy over TLS」這邊提到了我用 Squid 架 Proxy over TLS 的服務起來用,本來在家裡跑得好好的,但到了公司發現卻不能用,追蹤後發現是目前 Ubuntu 裡面包的 Squid + GnuTLS 沒有辦法支援 intermediate certificate 的問題,而且有人問過了:「[squid-users] HTTPS_PORT AND SSL CERT」。

這邊先講測試的方法,然後後面再講解法。

測試的方式可以用 openssl s_client -connect hostname:port 測,正常的情況會可以看到兩層。

在這邊的例子裡,R3 簽了 home.gslin.orgDST Root CA X3 簽了 R3,而 DST Root CA X3 則在 root certificate 名單中:

$ openssl s_client -connect home.gslin.org:443
depth=2 O = Digital Signature Trust Co., CN = DST Root CA X3
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = R3
verify return:1
depth=0 CN = home.gslin.org
verify return:1
CONNECTED(00000003)
---
Certificate chain
 0 s:CN = home.gslin.org
   i:C = US, O = Let's Encrypt, CN = R3
 1 s:C = US, O = Let's Encrypt, CN = R3
   i:O = Digital Signature Trust Co., CN = DST Root CA X3
---

如果沒有送出 Intermediate Certificate 的話就會導致信任鏈無法建立,像是我故意設計的 nointermediate.gslin.com 這樣,R3 簽了 nointermediate.gslin.com,但 R3 並沒有在 root certificate 的名單中:

$ openssl s_client -connect nointermediate.gslin.com:443
CONNECTED(00000003)
depth=0 CN = nointermediate.gslin.com
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 CN = nointermediate.gslin.com
verify error:num=21:unable to verify the first certificate
verify return:1
depth=0 CN = nointermediate.gslin.com
verify return:1
---
Certificate chain
 0 s:CN = nointermediate.gslin.com
   i:C = US, O = Let's Encrypt, CN = R3                                
---

而想到的解法就是重新包一份 Squid 出來用,把本來的 --with-gnutls 改成 --with-openssl

這邊會先裝 Build-Depends 裡面指定的東西,然後加裝 libssl-dev,接著換掉 --with-gnutls 後編譯,最後產生 .deb

sudo apt install -y ed libltdl-dev pkg-config build-essential cdbs debhelper dpkg-dev lsb-release dh-apparmor libcppunit-dev libcap2-dev libdb-dev libecap3-dev libexpat1-dev libgnutls28-dev libkrb5-dev comerr-dev libldap2-dev libnetfilter-conntrack-dev libpam0g-dev libsasl2-dev libxml2-dev nettle-dev libssl-dev
apt-get source squid
cd squid/squid-4.10
sed -i -e 's/--with-gnutls/--with-openssl/' debian/rules
cd ..
dpkg-buildpackage -rfakeroot -uc -b

編好的 .deb 就可以拿到其他機器上裝了,然後就可以吐出 intermediate certificate 了...

Leave a Reply

Your email address will not be published.