Capistranoでアップロードするファイルのハッシュをチェックするようにしてみた

2015.08.20

はじめに

好物はインフラとフロントエンドのかじわらゆたかです。
Capistranoでデプロイする際に、
ソース管理に載せるべきではないセンシティブな情報(DBのユーザー名・パスワード等)を
含んだ設定ファイル等を別途アップロードしたりすることはあるかと思います。

重要な情報のあるファイルならば、
デプロイする前に確認しろよといった声も聞こえてきそうですが、
手動で確認するのではなく、仕組みで確認させてみようと言うのが今回の趣旨となります。

実装

ハッシュチェック自体はRubyで実装してあります。
正常な設定ファイルのSHA1のハッシュ値保存しておき、
実際にアップロードするファイルのハッシュ値と比較するといった流れになります。
なお、ハッシュ値はJSONで格納することを想定しており、ファイル名をキーとしています。

ファイル名

equire 'digest/sha1'
require 'json'
fileHash = Digest::SHA1.hexdigest(File.open(ARGV[0],'rb').read)
open(ARGV[1],'r'){|fp|
  fp_json = JSON.parse(fp.read)
  targetHash = fp_json[File.basename(ARGV[0])]
  if fileHash==targetHash
    exit
  else
    STDERR.puts File.basename(ARGV[0]) + "'s hash is different."
    exit(-1)
  end
}

Capistranoからの呼び出し

上記のファイルチェックを行い、成功する例と失敗する例を確認してみたいと思います。

lib/tasks/fileCheck.rake

namespace :fileCheck do
    desc 'ハッシュチェックを実施します。'
    task :check do
        run_locally do
            execute "ruby ./hashChecker.rb ./sensitiveInfomation ./correctHash.json"
        end
    end

    desc 'ハッシュチェックを実施します。(ハッシュ不一致)'
    task :wrong_check do
        run_locally do
            execute "ruby ./hashChecker.rb ./sensitiveInfomation ./wrongHash.json"
        end
    end
end

correctHash.json

{
    "sensitiveInfomation" : "8b4025ff13a1c2ed4448e8c4669134fa41ad4644"
}

wrongHash.json

{
    "sensitiveInfomation" : "b4025ff13a1c2ed4448e8c4669134fa41ad4644"
}

実行例

以下でハッシュが一致した際はcapistranoのタスクが成功し、
不一致の際は失敗している事がわかります。

$ echo "kajiwara yutaka" >> sensitiveInfomation

$ bundle exec cap staging fileCheck:check
INFO [b8024319] Running /usr/bin/env ruby ./hashChecker.rb ./sensitiveInfomation ./correctHash.json as KAJIWARAYutaka@localhost
DEBUG [b8024319] Command: ruby ./hashChecker.rb ./sensitiveInfomation ./correctHash.json
INFO [b8024319] Finished in 0.396 seconds with exit status 0 (successful).

$ bundle exec cap staging fileCheck:wrong_check
INFO [a1b8960a] Running /usr/bin/env ruby ./hashChecker.rb ./sensitiveInfomation ./wrongHash.json as KAJIWARAYutaka@localhost
DEBUG [a1b8960a] Command: ruby ./hashChecker.rb ./sensitiveInfomation ./wrongHash.json
DEBUG [a1b8960a]    sensitiveInfomation's hash is different.
(Backtrace restricted to imported tasks)
cap aborted!

最後に

一時的に書き換えた設定ファイルを間違えてアップロードしない仕組みとして、上記を作ってみました。
皆様の平穏なデプロイ作業の一助になれば幸いです。