Chefでhttpsのlistenポートを変更する

chefで作成したhttps対応の仮想ホストですが、実際にはTCP/443ではなくて、TCP/74343でlistenさせています。chefで仮想ホストを作成する場合、デフォルトの80,443ならなんの苦労もないのですが、httpsのポートを変更するのに一苦労でした。

attributeに書いてみる

昨日のエントリと同じ環境が前提です。listenポートを変更するにはlisten_portsっていうattribute値があればいいよってことなので追記。
site-cookbook/apache22/attributes/default.rb

default['apache']['contact'] = "webmaster@example.com"
default['apache']['listen_ports'] = [7080,7443]

ports.confがおかしい

これでcookしてみる。

$ knife solo cook server_name -o apache22

なにやらサーバが起動できないとかっていうエラー。どうも443ポートがコンフリクトしている様子です。作業対象サーバはすでにapache2.4がssl付きで動作しているのでそのポートと衝突したようです。

設定ファイルを調べてみると、port.confがこんな感じ。
/etc/httpd/ports.conf

# This file was generated by Chef for server_name.
# Do NOT modify this file by hand!

Listen *:7080
NameVirtualHost *:7080
Listen *:7443
NameVirtualHost *:7443
Listen *:443
NameVirtualHost *:443

後ろの二行いらんなぁ。

apache2::mod_ssl が悪さしているみたい

だれが追加してるんだ?調べるとmod_sslのレシピで443ポートがないと追加するからねってコードになっていました。

cookbooks/apache2/recipes/mod_ssl.rb

unless node['apache']['listen_ports'].include?('443')
  node.set['apache']['listen_ports'] = node['apache']['listen_ports'] + ['443']
end

apache2 cookbookのドキュメントにもそう書いてありました。

Besides installing and enabling mod_ssl, this recipe will append port 443 to the node['apache']['listen_ports'] attribute array and update the ports.conf.

余計なことをするな。

じゃあ消すことにする

ソースを見る限りなにがなんでも追加するようなので、じゃあこっちで消すことにする。まず、上記mod_ssl.rbで参照しているテンプレートファイルをローカルのcookbook以下へコピー*1

$ cp cookbooks/apache2/template/default/ports.conf.erb site-cookbooks/apache22/template/default

でもってレシピに443を削除するコードを追加。
site-cookbooks/apache22/recipes/default.rb

if node['apache']['listen_ports'].include?('443')
  node.set['apache']['listen_ports'] = node['apache']['listen_ports'] - ['443']
end

template 'ssl_ports.conf' do
  path "#{node['apache']['dir']}/ports.conf"
  source 'ports.conf.erb'
  mode '0644'
  notifies :restart, 'service[apache2]', :delayed
end

ports.confはこれでOK。

まだあった

これで動くだろうとおもったらまだありました。昨日のエントリで作成したレシピでできあがるhttps対応仮想ホストの設定ファイルの頭がこんなになっていました。

<VirtualHost *:443>
  ServerAdmin webmaster@example.com
  ServerName sslsite.example.com
  DocumentRoot /home/hoge/htdocs
  RewriteEngine On
(後略)

これは簡単。レシピ中のlistenportの指定を追記すればOK。

include_recipe 'apache2::mod_ssl'
web_app "ssl_site" do
  cookbook "ssl_certificate"
  @params[:port] = "7443" < これ
  server_name node['apache22']['site_fqdn']
  docroot "/home/hoge/htdocs"
  ssl_key my_key_path
  ssl_cert my_cert_path
  ssl_chain my_chain_path
end

*1:本当はmod_sslのテンプレートファイルを参照したいのですが、別cookbookのテンプレートファイルって参照できるのかな