fbpx

[和訳] CentOSとFedoraのBento Boxの更新 #getchef

この記事は1年以上前に投稿されました。情報が古い可能性がありますので、ご注意ください。

本稿は Bento Box Update for CentOS and Fedora (2015/02/26) の和訳です。

これは緊急ではありませんが、直接Vagrantを利用していたり、test kitchenでVagrantを利用しているときにSSL検証エラーに遭遇するかもしれません。

この問題の解決のために協力してくれたPackage CloudJoe Damatoに感謝します。

要約すると、VeriSignの証明書が上流のcurlプロジェクトによって削除されたため、CentOS 5.11、CentOS 6.6、Fedora 21の「bento」boxのopensslとyumでAWS S3のSSL検証が行えないというバグを発見しました。ローカルのboxは更新してください。まずvagrant box removeでboxを削除し、test kitchenやvagrantを再実行してください。

Chef Server 12パッケージはPackage Cloudというすばらしいホステッドパッケージレポジトリプロバイダにて公開しています。それらはSSLやGPG、受け入れ可能なすべての暗号化によって、安全に正しく設定されたyumやaptレポジトリを提供しています。Package Cloudからパッケージを取得するchef-server Cookbookをテストしていて、bentoで作成したCentOS 5.11と6.6のboxで問題があることを発見しました。


[2015-02-25T19:54:49+00:00] ERROR: chef_server_ingredient[chef-server-core] (chef-server::default line 18) had an error: Mixlib::ShellOut::ShellCommandFailed: packagecloud_repo[chef/stable/] (/tmp/kitchen/cache/cookbooks/chef-server-ingredient/libraries/chef_server_ingredients_provider.rb line 44) had an error: Mixlib::ShellOut::ShellCommandFailed: execute[yum-makecache-chef_stable_] (/tmp/kitchen/cache/cookbooks/packagecloud/providers/repo.rb line 109) had an error: Mixlib::ShellOut::ShellCommandFailed: Expected process to exit with [0], but received '1'
---- Begin output of yum -q makecache -y --disablerepo=* --enablerepo=chef_stable_ ----
...SNIP
File "/usr/lib64/python2.4/urllib2.py", line 565, in http_error_302
...SNIP
File "/usr/lib64/python2.4/site-packages/M2Crypto/SSL/Connection.py", line 167, in connect_ssl
return m2.ssl_connect(self.ssl, self._timeout)
M2Crypto.SSL.SSLError: certificate verify failed

何が起きているのでしょうか?

ここではPackage Cloudレポジトリの設定を追加し、yumキャッシュを再構築しようとしています。次がそのyum設定です。


[chef_stable_]
name=chef_stable_
baseurl=https://packagecloud.io/chef/stable/el/5/$basearch
repo_gpgcheck=0
gpgcheck=0
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-packagecloud_io
sslverify=1
sslcacert=/etc/pki/tls/certs/ca-bundle.crt

baseurlがhttpsであることに注目してください。ほとんどのパッケージレポジトリはhttpを使うので、そうなっていません。このため、Package Cloudが正当なSSL証明書を持っているにもかかわらず、証明書チェーンの検証に失敗してしまいます。OpenSSLでこれを見てみましょう。


$ openssl s_client -CAfile /etc/pki/tls/certs/ca-bundle.crt -connect packagecloud.io:443
CONNECTED(00000003)
depth=3 /C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root
verify return:1
depth=2 /C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority
verify return:1
depth=1 /C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA
verify return:1
depth=0 /OU=Domain Control Validated/OU=EssentialSSL/CN=packagecloud.io
verify return:1
... SNIP
SSL-Session:
Verify return code: 0 (ok)

オーケー、問題ないように見えるのに、どうしてyumでは失敗するのでしょうか? これを解く鍵はyumのpythonスタックトレースにあります。


File "/usr/lib64/python2.4/urllib2.py", line 565, in http_error_302

Package Cloudは実際にはパッケージをS3に格納しているので、packagecloud-repositories.s3.amazonaws.comというバケットにリダイレクトしています。opensslで証明書を確認してみましょう。


$ openssl s_client -CAfile /etc/pki/tls/certs/ca-bundle.crt -connect packagecloud-repositories.s3.amazonaws.com:443
depth=2 /C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=(c) 2006 VeriSign, Inc. - For authorized use only/CN=VeriSign Class 3 Public Primary Certification Authority - G5
verify error:num=20:unable to get local issuer certificate
verify return:0
---
Certificate chain
0 s:/C=US/ST=Washington/L=Seattle/O=Amazon.com Inc./CN=*.s3.amazonaws.com
i:/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=Terms of use at https://www.verisign.com/rpa (c)10/CN=VeriSign Class 3 Secure Server CA - G3
1 s:/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=Terms of use at https://www.verisign.com/rpa (c)10/CN=VeriSign Class 3 Secure Server CA - G3
i:/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=(c) 2006 VeriSign, Inc. - For authorized use only/CN=VeriSign Class 3 Public Primary Certification Authority - G5
2 s:/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=(c) 2006 VeriSign, Inc. - For authorized use only/CN=VeriSign Class 3 Public Primary Certification Authority - G5
i:/C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority
...SNIP
SSL-Session:
Verify return code: 20 (unable to get local issuer certificate)

yumが失敗してしまったのは何故かという問題の根本がこれです。どうして失敗してしまったのでしょうか? curlプロジェクトが同梱している最新のCA証明書で、AWSのhttps://s3.amazonaws.comで用いられている2つのVeriSign証明書を削除したためです。

ちょっと待って、どうしてそれが問題なのでしょうか? CentOSはopensslパッケージ由来のca-bundle.crtファイルを用いているはずでは?


$ rpm -qf ca-bundle.crt
openssl-0.9.8e-27.el5_10.4

その通りです。では、何が起きたんでしょうか?


$ sudo rpm -V openssl
S.5....T c /etc/pki/tls/certs/ca-bundle.crt

あれ、どうしてファイルが違ってるの? ここで本記事冒頭の要約に戻ってみます。CentOSのbento boxでは、ks.cfgに次のような1行があります。


wget -O/etc/pki/tls/certs/ca-bundle.crt http://curl.haxx.se/ca/cacert.pem

これは過去のもので、影響するプラットフォームでks.cfgからこの行を削除し、boxを再構築しています。CentOS 5.10 boxではこの問題が起きなかったので、最初はこの問題を特に複雑にしていました。5.10のboxを構築した時点ではcacert.pemはVeriSignの証明書を同梱していて、5.11と6.6のboxを構築するときに取得したcacert.pemではVeriSignの証明書が削除されていたのです。

何故そこからファイルを取得していたのでしょうか? 言いにくいのですが、このwget行はbentoレポジトリのためのks.cfgにずっとありました。ある時点で、ディストリビューションのデフォルトパッケージに不正な証明書が含まれていたり、他の問題があったりする場合の回避策として含まれたものでしょう。ディストリビューションのパッケージが正しい証明書を持っていることが重要で、それを使いたいのです。

では、何をする必要があるでしょうか? opscode-centos vagrant boxを削除し、再度追加してください。次のようにします。


for i in opscode-centos-5.10 opscode-centos-5.11 opscode-centos-6.6 opscode-centos-7.0 opscode-fedora-20
do
vagrant box remove $i
done

そして、これらのboxを使っているどのプロジェクトでも、例えばtest-kitchenでテストしているCookbookなどで、単にtest kitchenを再実行して、更新されたboxをダウンロードします。

まず最初にboxが影響を受けているか確認したければ、test-cacert Cookbookを使うこともできます。ChefDK 0.4.0では次のようにします。


% git clone https://github.com/jtimberman/test-cacert-cookbook test-cacert
% cd test-cacert
% kitchen test default

新規CTA