モダンなcipher suiteに対応していないHTTPSクライアントを搭載したロードバランサが存在する問題について

実は一般的に知られている問題なのかもしれないものの,最近知ったのでメモ.

概要

  • 一部のロードバランサアプライアンスにおいて,搭載されているHTTPSクライアントが所謂"モダンな"暗号スイートに対応していないものが存在する
  • このため,特定条件下において意図せずヘルスチェックに失敗し,場合によってはVIPがdownする
  • 現時点では直ぐに影響が出る訳では無いものの,気に留めておかないと近い将来痛い目を見そう

背景

DSR構成のロードバランサでSSL(TLS)を使用する場合,SSLの終端はロードバランサではなくリアルサーバの仕事になる*1

この環境下においてリアルサーバの死活監視にLayer 7方式を使用するパターンを考える.このパターンでは,ロードバランサからリアルサーバにSSLで接続し,HTTP GETないしHEADリクエストを投げて意図したレスポンスが返ってくれば,リアルサーバは正常動作しているとみなされる*2

f:id:yunazuno:20150227225611p:plain

問題となるケース

リアルサーバ上で稼働しているWebサーバ(Apache, Nginx等)において,セキュリティの要件上Mozillaが言うところの所謂"モダンな"cipher suiteのみ使用可能にする (=RC4や3DESに依存したCipher suiteを使用不可にする) ケースを考える.

この時,ロードバランサがヘルスチェックに使用するHTTPS Clientが先に述べたモダンなcipher suiteに非対応だと,リアルサーバとのHandshakeに失敗してしまう.その結果,実際は正常動作しているリアルサーバが死んでいると誤認識されてしまい,意図せずリアルサーバないしVIPがdownする.

どう対応するか

ぱっと思い付く対応策はこんな感じ:

  1. Layer 7ヘルスチェックを諦めてLayer 4ないしLayer 3でのヘルスチェックに切り替える
  2. 要件を曲げてCipher suiteの制約を緩める
  3. ロードバランサ側をモダンなCipher suiteに対応させる
    • ベンダに機能追加してもらう,対応OSにバージョンアップする,対応LBに入れ替える,など

商用サービスでモダンもの限定にするケースはまだレアだとは思うものの,気に留めておく必要がありそう.特に,現在使用しているCipher suiteがある時点から安全でなくなる可能性を考慮すると,上述したケースでどういう対応を取るか,ぐらいは考えておいたほうが良さそう.

また,今回のHTTPS Client側cipher suiteの問題に限らず,ロードバランサでSSLを終端した場合のCipher suiteやTLSバージョンの対応状況等,ロードバランサ+SSLには諸々のハマりどころが存在するようなので,運用している人は頑張りましょう.

*1:一般的なプロキシ構成下では,SSLはロードバランサで終端する

*2:プロキシ構成下では,リアルサーバへの接続にSSLは不要

grepcidr: IPアドレスをサブネットで一括grep

あるファイルに含まれるIPアドレスgrepしたいとき,/32なり/128なりのIPアドレスそのものではなく,サブネットでgrepできると便利な場面が多々ある.それらしき物が無いか探したところ,grepcidrというツールがあったのでメモ.

導入

単純にソースコードをダウンロードして make & make install するだけ.

$ wget http://www.pc-tools.net/files/unix/grepcidr-2.0.tar.gz
$ tar xvf grepcidr-2.0.tar.gz
$ cd grepcidr-2.0
$ make
# make install

使い方

たとえば下のようなファイルがあるとする.

$ cat ipaddr.txt
192.0.2.0/24
192.0.2.0/25
192.0.2.128/25
192.0.2.254/32

2001:db8::/32
2001:db8:a:1::/64
2001:db8:a:2::/64
2001:db8:a:1::1/128

これが色々なpatternでgrepできる.

$ grepcidr 192.0.2.0/24 ipaddr.txt
192.0.2.0/24
192.0.2.0/25
192.0.2.128/25
192.0.2.254/32
$ grepcidr 192.0.2.1/25 ipaddr.txt
192.0.2.0/24
192.0.2.0/25
$ grepcidr 192.0.2.128/25 ipaddr.txt
192.0.2.128/25
192.0.2.254/32
$ grepcidr 2001:db8:a::/48 ipaddr.txt
2001:db8:a:1::/64
2001:db8:a:2::/64
2001:db8:a:1::1/128

かなり便利.

SSHの踏み台有り・無しを,ネットワーク的居場所に応じて自動で切り替える

SSHで何がしかのホストに入るとき,自ホストのネットワーク的な居場所に応じて踏み台使用の有無を自動で切り替えるようなものを書いてみた.

やりたいこと

自分の居場所に関係無く,同一コマンドでSSHできるようにすることが最終的なゴール.

あるネットワークAからは踏み台無しでSSHできるけども,それ以外のネットワークからは踏み台を通さないとSSHできないようなホストがあるとする.

今までは,$HOME/.ssh/configに

Host univ-server1
    Host server1.example.jp
Host univ-server1-outside
    Host server1.example.jp
    ProxyCommand ssh univ-proxy nc %h %p
Host univ-proxy
    Host proxy.example.jp

と書いておいて,ネットワークAからは

$ ssh univ-server1

ネットワークA以外からは

$ ssh univ-server1-outside

と叩くようにしていた.


これを,自分の居場所に関係無く

$ ssh univ-server1

と叩けば入れるような状況にしたい.使い分けが面倒だし.

方法

$HOME/.ssh/configを以下のような感じで書く.ssh-autoproxy.pyはgithubから持ってきて適当にパスの通った場所へ.

Host univ-server*
    ProxyCommand ssh-autoproxy.py univ-proxy %h %p 192.0.2.0/24 198.51.100.0/24
Host univ-server1
    Host server1.example.jp
Host univ-server2
    Host server2.example.jp
Host univ-proxy
    Host proxy.example.jp

上記の例では,192.0.2.0/24と198.51.100.0/24以外からは踏み台が必要なホストを想定している.

これで,踏み台使用の有無に関係なく,

$ ssh univ-server1

を叩けば入れるようになる.

Know issue

  • インターネット接続性が無いと,アレな挙動を見せる
  • v4/v6 dual stackな環境だと,アレな挙動を見せる

Code

githubからどうぞ.ipaddrモジュールはPEP 3144版が必要なので注意.