Edited at

Rails4のforce_sslでELBからのヘルスチェックを除外する

More than 3 years have passed since last update.

AWSを使っていて


  • ELBでSSL Terminationを行い、APPサーバはHTTPアクセスのみ

  • サイトは基本SSLで、HTTPアクセスはforce_sslでHTTPSにリダイレクト

  • ELBのヘルスチェックではRailsの稼働まで確認したい

という時に、ELBのヘルスチェックまでforce_sslでHTTPSにリダイレクトされると困る。

Rails3の時はssl_optionsのexcludeで対応してたんですが、


config/environments/production.rb

  config.force_ssl = true

config.ssl_options = { exclude: proc { |env| !env['HTTP_X_FORWARDED_FOR'] } }

Rails4だとこのオプションが効かなくなっていたので、対応方法をメモ。

基本的にはconfigではなく、controllerのforce_sslメソッドを使ってifオプションでELBからのヘルスチェックを除外する。


その1. HTTP_X_FORWARDED_FORを見る

ELB経由のアクセスの場合はHTTP_X_FORWARDED_FORヘッダが付与されるので、それがない場合はELBからのヘルスチェックだと見なす


app/controllers/application_controller.rb

class ApplicationController < ActionController::Base

force_ssl if: :use_ssl?

def use_ssl?
Rails.env.production? && request.env['HTTP_X_FORWARDED_FOR'].present?
end
end



その2. ヘルスチェック用のコントローラを作る

ヘルスチェック用のコントローラを作り、そこだけHTTPでもアクセスできるようにする


app/controllers/application_controller.rb

class ApplicationController < ActionController::Base

force_ssl if: :use_ssl?

def use_ssl?
Rails.env.production?
end
end



app/controllers/healthcheck_controller.rb

class HealthcheckController < ApplicationController

def index
render text: 'Healthy!'
end

def use_ssl?
false
end
end