どうも、39 歳の cloudpackかっぱ@inokara)です。おっさんです。

はじめに

HAProxy の acl 機能を利用して各種条件の振り分け設定についてメモってみます。

構成

HAProxyチートシート: 構成

振り分けを坦々(淡々)と…

acl を使って振り分け

HAProxy は機能大杉漣ですが、acl を使うことで柔軟でアクセスコントロールすることが出来ます。

以下 acl を使って幾つかの条件による振り分け設定例を試してみたいと思います。

ホストヘッダによる振り分け

frontend kappa-test
  bind 0.0.0.0:80
  acl hage hdr(host) -i hage.test.inokara.com
  acl pika hdr(host) -i pika.test.inokara.com
  use_backend hage_bk if hage
  use_backend pika_bk if pika

backend hage_bk
  server hage xxx.xxx.xxx.xxx:8001 check

backend pika_bk
  server pika xxx.xxx.xxx.xxx:8002 check

hdr はホストヘッダから該当のヘッダを指定します。

URI パスによる振り分け

frontend kappa-test
  bind 0.0.0.0:80
  acl hage path_beg /hage
  acl pika path_beg /pika
  use_backend hage_bk if hage
  use_backend pika_bk if pika

backend hage_bk
  server hage xxx.xxx.xxx.xxx:8001 check

backend pika_bk
  server pika xxx.xxx.xxx.xxx:8002 check

URL パスによる振り分けは上記の path_beg 以外にも以下のようにパスの指定方法によって使い分けることが出来るかと思います。

上記のドキュメントを読み込めていないので具体的な使い分けについては改めて纏めます。

Cookie 内の指定文字列による振り分け

frontend kappa-test
  bind 0.0.0.0:80
  acl hage hdr(cookie) atama=hage
  acl pika hdr(cookie) atama=pika
  use_backend hage_bk if hage
  use_backend pika_bk if pika

backend hage_bk
  server hage xxx.xxx.xxx.xxx:8001 check

backend pika_bk
  server pika xxx.xxx.xxx.xxx:8002 check

Cookie を指定して curl を叩く場合には以下のように叩くと良いようです。

curl -b cookie.txt http://xxx.xxx.xxx.xxx/

cookie.txt は以下のような内容です。

set-cookie: atama=pika;

set-cookie: に続いて KEY=VALUE で指定します。

リクエストヘッダを出力するように設定された URI に対してアクセスすると…

% curl -b cooke.txt http://test-2132892436.ap-northeast-1.elb.amazonaws.com/

以下のようなレスポンスが返ってきます。

{"HTTP_HOST"=>"test-2132892436.ap-northeast-1.elb.amazonaws.com", "HTTP_ACCEPT"=>"*/*", "HTTP_COOKIE"=>"atama=pika", "HTTP_USER_AGENT"=>"curl/7.30.0", "HTTP_X_FORWARDED_FOR"=>"xxx.xxx.xxx.xxx", "HTTP_X_FORWARDED_PORT"=>"80", "HTTP_X_FORWARDED_PROTO"=>"http", "HTTP_VERSION"=>"HTTP/1.1"}%

cookie の文字列も正しく取得出来ていますね。

ソース IP による振り分け

設定は以下のような設定ですが…

frontend kappa-test
  bind 0.0.0.0:80
  acl src_01 src xxx.xxx.xxx.xx1
  acl src_02 src xxx.xxx.xxx.xx2
  use_backend hage_bk if src_01
  use_backend pika_bk if src_02

backend hage_bk
  server hage xxx.xxx.xxx.xxx:8001 check

backend pika_bk
  server pika xxx.xxx.xxx.xxx:8002 check

ELB を挟んだ場合には以下のような状態になってしまいます。
HAProxyチートシート: ソースIPに寄る振り分け(ELB 挟んで必要な設定をしなかった場合)

ELB では X-Forwarded-For が付与されるので、src オプションよりも hdr_ip(X-Forwarded-For) を設定することで振り分けが出来ます。
HAProxyチートシート: ソースIPに寄る振り分け(ELB 挟んで必要な設定をした場合)

frontend kappa-test
  bind 0.0.0.0:80
  acl src_a hdr_ip(X-Forwarded-For) xxx.xxx.xxx.xx1
  acl src_b hdr_ip(X-Forwarded-For) xxx.xxx.xxx.xx2
  use_backend hage_bk if src_01
  use_backend pika_bk if src_02

ユーザーエージェントによる振り分け

frontend kappa-test
  bind 0.0.0.0:80
  acl mobile hdr_sub(User-Agent) -i iphone
  acl chrome hdr_sub(User-Agent) -i chrome
  use_backend hage_bk if mobile
  use_backend pika_bk if chrome

backend hage_bk
  server hage xxx.xxx.xxx.xxx:8001 check

backend pika_bk
  server pika xxx.xxx.xxx.xxx:8002 check

SSL のサポート

概要

  • HAProxy はバージョン 1.5 から SSL を正式にサポートしています
  • 但し、SSL を有効にしてビルドする必要があります
  • SSL 周りの仕様についてはビルド時に利用される OpenSSL のバージョンに依存すると思われます

ビルド

ソースコードを展開した際に含まれる haproxy.spec を以下のように修正します。

--- haproxy.spec.bk     2014-11-06 12:26:58.421708430 +0900
+++ haproxy.spec        2014-11-06 12:27:08.714748339 +0900
@@ -33,7 +33,7 @@
 %define __perl_requires /bin/true

 %build
-%{__make} USE_PCRE=1 DEBUG="" ARCH=%{_target_cpu} TARGET=linux26
+%{__make} USE_PCRE=1 DEBUG="" ARCH=%{_target_cpu} TARGET=linux26 USE_OPENSSL=1

 %install
 [ "%{buildroot}" != "/" ] && %{__rm} -rf %{buildroot}
 

尚、SSL の状態に限らずですが HAProxy のビルドの詳細情報を見るには以下のように -v オプションをつけて実行します。

haproxy -v

以下のように出力されます。

HA-Proxy version 1.5.8 2014/10/31
Copyright 2000-2014 Willy Tarreau <w@1wt.eu>

Build options :
  TARGET  = linux26
  CPU     = generic
  CC      = gcc
  CFLAGS  = -m64 -march=x86-64 -O2 -g -fno-strict-aliasing
  OPTIONS = USE_OPENSSL=1 USE_PCRE=1

Default settings :
  maxconn = 2000, bufsize = 16384, maxrewrite = 8192, maxpollevents = 200

Encrypted password support via crypt(3): yes
Built without zlib support (USE_ZLIB not set)
Compression algorithms supported : identity
Built with OpenSSL version : OpenSSL 1.0.1e-fips 11 Feb 2013
Running on OpenSSL version : OpenSSL 1.0.1e-fips 11 Feb 2013
OpenSSL library supports TLS extensions : yes
OpenSSL library supports SNI : yes
OpenSSL library supports prefer-server-ciphers : yes
Built with PCRE version : 7.8 2008-09-05
PCRE library supports JIT : no (USE_PCRE_JIT not set)
Built with transparent proxy support using: IP_TRANSPARENT IP_FREEBIND

Available polling systems :
      epoll : pref=300,  test result OK
       poll : pref=200,  test result OK
     select : pref=150,  test result OK
Total: 3 (3 usable), will use epoll.

[root@ip-172-31-29-194 haproxy-1.5.8]# haproxy -v
HA-Proxy version 1.5.8 2014/10/31
Copyright 2000-2014 Willy Tarreau <w@1wt.eu>

設定

以下のように設定します。

frontend kappa-test-ssl
  bind 0.0.0.0:443 ssl crt /path/to/server.pem

中間証明書、クロスルート証明書に関しても以下のような順番で一つに纏めることで利用することが可能です。

-----BEGIN CERTIFICATE-----
証明書
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
中間証明書
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
クロスルート証明書
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
秘密鍵
-----END RSA PRIVATE KEY-----

chipers の指定

証明書の指定以外にも chipers を指定することも可能です。

frontend kappa-test-ssl
  bind 0.0.0.0:443 ssl crt /path/to/server.pem ciphers ECDHE+aRSA+AES256+GCM+SHA384:ECDHE+aRSA+AES128+GCM+SHA256:ECDHE+aRSA+AES256+SHA384:ECDHE+aRSA+AES128+SHA256:ECDHE+aRSA+RC4+SHA:ECDHE+aRSA+AES256+SHA:ECDHE+aRSA+AES128+SHA:AES256+GCM+SHA384:AES128+GCM+SHA256:AES128+SHA256:AES256+SHA256:DHE+aRSA+AES128+SHA:RC4+SHA:HIGH:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS

振り分けアルゴリズム

ドキュメント

種類

振り分けは以下のような種類があります。

  • roundrobin
  • static-rr
  • leastconn
  • first
  • source
  • uri
  • url_param
  • hdr()
  • rdp-cookie
  • rdp-cookie()

各々については追記していく予定ですが良く使われるのが roundrobin ではないかと思いますが…いかがでしょうか…。

お疲れ様でした

acl による各種条件での振り分け設定を中心にまとめてみました。それぞれについては随時追記してしてく予定です。
ということで、HAProxy の奥深さには改めて驚いたエントリでした。

元記事はこちらです。
俺のメモ – HAProxy チートシート(acl や SSL サポート等)