web-dev-qa-db-ja.com

HAProxy SSLターミネーションの最適化(UbuntuのNginxバックエンドを使用)

UbuntuのNginxバックエンドへのSSLターミネーションでHAProxyを最適化するにはどうすればよいですか?

セットアップは正常に機能し、正しくルーティングされます。ただし、HAProxyを使用してSSL終了を実行すると、パフォーマンスが大幅に低下します(以下のテスト)。キーは4096ビットrsaです。 HAProxyは、検証のためにHTTPSを強制し、SSLを終了し、HTTPをバックエンドのNginxサーバーに通信します。 Nginxサーバーは同一であり、192.168.1.xx/page1.html、192.168.1.xx/page2.htmlなどの複数の静的ページを提供します(システムを完全にするためにNodeJSを含めましたが、1ミリ秒未満の遅延しか追加しません。NodeJS無視できます。)

セットアップ、構成、および現在のテストは次のとおりです。各仮想マシン(VM)はUbuntu 14.04を実行しており、さまざまな量のCPUとRAMを搭載できます。

  • HAProxy(1.5.14):192.168.1.10
  • Nginx-1:192.168.1.20
  • Nginx-2:192.168.1.21
  • Nginx-3:192.168.1.22
  • NodeJS-1:192.168.1.30

HAProxyの設定は次のとおりです。

    global
            maxconn 40000
            tune.ssl.default-dh-param 2048
            log /dev/log    local0
            log /dev/log    local1 notice
            chroot /var/lib/haproxy
            stats socket /run/haproxy/admin.sock mode 660 level admin
            stats timeout 30s
            user haproxy
            group haproxy

            # Default SSL material locations
            ca-base /etc/ssl/certs
            crt-base /etc/ssl/private

            # Default ciphers to use on SSL-enabled listening sockets.
            # For more information, see ciphers(1SSL). This list is from:
            #  https://hynek.me/articles/harding-your-web-servers-ssl-ciphers/
            ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS
            ssl-default-bind-options no-sslv3


    defaults
            option forwardfor
            option http-server-close
            stats enable
            stats uri /stats
            stats realm Haproxy\ Statistics
            stats auth user:password
            log     global
            mode    http
            option  httplog
            option  dontlognull
            timeout connect 5000
            timeout client 50000
            timeout server 50000
            errorfile 400 /etc/haproxy/errors/400.http
            errorfile 403 /etc/haproxy/errors/403.http
            errorfile 408 /etc/haproxy/errors/408.http
            errorfile 500 /etc/haproxy/errors/500.http
            errorfile 502 /etc/haproxy/errors/502.http
            errorfile 503 /etc/haproxy/errors/503.http
            errorfile 504 /etc/haproxy/errors/504.http


    frontend www-http
            bind 192.168.1.10:80
            reqadd X-Forwarded-Proto:\ http
            default_backend www-backend

    frontend www-https
            bind 192.168.1.10:443 ssl crt /etc/ssl/private/company.pem
            reqadd X-Forwarded-Proto:\ https
            use_backend node-backend if { path_beg /socket.io }
            default_backend www-backend

    backend www-backend
            redirect scheme https if !{ ssl_fc }
            server www-1 192.168.1.20:80 check
            server www-2 192.168.1.21:80 check
            server www-3 192.168.1.22:80 check

    backend node-backend
            server node-1 192.168.1.30:8888 check

Nginxサーバーの1つに対するApacheBench(ab)テストは次のとおりです。

    $ ab -c 200 -n 10000 http://192.168.1.20/

    Server Software:        nginx/1.4.6
    Server Hostname:        192.168.1.20
    Server Port:            80

    Document Path:          /
    Document Length:        3130 bytes

    Concurrency Level:      200
    Time taken for tests:   2.257 seconds
    Complete requests:      10000
    Failed requests:        0
    Total transferred:      33720000 bytes
    HTML transferred:       31300000 bytes
    Requests per second:    4430.21 [#/sec] (mean)
    Time per request:       45.145 [ms] (mean)
    Time per request:       0.226 [ms] (mean, across all concurrent requests)
    Transfer rate:          14588.55 [Kbytes/sec] received

    Connection Times (ms)
                  min  mean[+/-sd] median   max
    Connect:        4   27 104.3     16    1187
    Processing:     4   18   8.2     16     358
    Waiting:        3   18   7.9     16     334
    Total:          9   45 105.8     32    1225

    Percentage of the requests served within a certain time (ms)
      50%     32
      66%     41
      75%     43
      80%     44
      90%     49
      95%     52
      98%     55
      99%     57
     100%   1225 (longest request)

Httpを使用したHAProxyへのApacheBench(ab)テストは次のとおりです。

    $ ab -c 200 -n 10000 http://192.168.1.10/

    Server Software:        nginx/1.4.6
    Server Hostname:        192.168.1.10
    Server Port:            80

    Document Path:          /
    Document Length:        3130 bytes

    Concurrency Level:      200
    Time taken for tests:   1.918 seconds
    Complete requests:      10000
    Failed requests:        0
    Total transferred:      33720000 bytes
    HTML transferred:       31300000 bytes
    Requests per second:    5215.09 [#/sec] (mean)
    Time per request:       38.350 [ms] (mean)
    Time per request:       0.192 [ms] (mean, across all concurrent requests)
    Transfer rate:          17173.14 [Kbytes/sec] received

    Connection Times (ms)
                  min  mean[+/-sd] median   max
    Connect:        3   18   3.5     18      32
    Processing:     7   20   3.5     19      36
    Waiting:        7   20   3.4     19      36
    Total:         15   38   4.2     37      57

    Percentage of the requests served within a certain time (ms)
      50%     37
      66%     38
      75%     39
      80%     40
      90%     44
      95%     46
      98%     50
      99%     51
     100%     57 (longest request)

Httpsを使用したHAProxyへのApacheBench(ab)テストは次のとおりです。

    $ ab -c 200 -n 10000 https://192.168.1.10/

    Server Software:        nginx/1.4.6
    Server Hostname:        192.168.1.10
    Server Port:            443
    SSL/TLS Protocol:       TLSv1,DHE-RSA-AES256-SHA,2048,256

    Document Path:          /
    Document Length:        3130 bytes

    Concurrency Level:      200
    Time taken for tests:   566.303 seconds
    Complete requests:      10000
    Failed requests:        0
    Total transferred:      33720000 bytes
    HTML transferred:       31300000 bytes
    Requests per second:    17.66 [#/sec] (mean)
    Time per request:       11326.069 [ms] (mean)
    Time per request:       56.630 [ms] (mean, across all concurrent requests)
    Transfer rate:          58.15 [Kbytes/sec] received

    Connection Times (ms)
                  min  mean[+/-sd] median   max
    Connect:      483 8982 3326.6  11090   14031
    Processing:    16 2255 3313.0     43   11399
    Waiting:       14 2186 3253.3     35   11252
    Total:       5648 11237 879.1  11212   22732

    Percentage of the requests served within a certain time (ms)
      50%  11212
      66%  11274
      75%  11308
      80%  11321
      90%  11395
      95%  11641
      98%  11847
      99%  14063
     100%  22732 (longest request)

これは、HAProxyVMでのOpenSSLテストです。

    $ openssl speed rsa

                      sign    verify    sign/s verify/s
    rsa  512 bits 0.000081s 0.000006s  12314.6 179042.8
    rsa 1024 bits 0.000277s 0.000017s   3603.7  60563.8
    rsa 2048 bits 0.001852s 0.000058s    539.8  17231.3
    rsa 4096 bits 0.013793s 0.000221s     72.5   4517.4

したがって、私が見ているように、HAProxyは72.5符号/秒、4517.4検証/秒のopenssl速度テストを上回ることはできません。ただし、SSLターミネーションを使用するHAProxyは、約17リクエスト/秒を実行しています。もちろん、全体的なパフォーマンスを向上させるために小さなキーを取得することはできますが、openssl速度テストからHAProxyへの約4.5倍の速度向上の問題(問題が存在する場合)は解決されません。

したがって、この情報を前提として、パフォーマンスを向上させる最適なHAProxy構成はありますか?たとえば、ユーザーが初めてページにアクセスしたときに、「署名」する必要があるのは1回だけであり、ページへの同時リクエストはすべて「確認」するだけです。その場合、ABテストはそれを適切に測定していません(間違っている場合は訂正してください)。そして、これが発生するために、ユーザーは同じNginxサーバーにアクセスする必要がありますか?もしそうなら、それはスティックセッションを必要としますか?

私自身の質問に答えようとして、この投稿からスティッキーセッションを追加してみました: SSLおよびスティッキーセッションを使用したHAProxy そしてSiegeを使用して複数のURLでテストしました。ただし、それでもパフォーマンスの向上は見られませんでした。

    $ siege -c 100 -r 10 -b -f urls.txt

    Transactions:               1000 hits
    Availability:             100.00 %
    Elapsed time:              22.56 secs
    Data transferred:           2.84 MB
    Response time:              2.17 secs
    Transaction rate:          44.33 trans/sec
    Throughput:             0.13 MB/sec
    Concurrency:               96.06
    Successful transactions:        1000
    Failed transactions:               0
    Longest transaction:            8.96
    Shortest transaction:           0.16

Urls.txtはどこにありますか

    URL=https://192.168.1.10/
    $(URL)
    $(URL)page1.html
    $(URL)page2.html

それで、私はこのパフォーマンスで立ち往生していますか?一部の場所では、4096ビットキーのリクエストあたり約75ミリ秒の同様のリクエストレートについて言及しています。 https://certsimple.com/blog/measuring-ssl-rsa-keys

または、HAProxyの設定が不十分で、SSL 2xをどこかで処理していますか? ServerFault:/ questions/574582/nginx-ssl-termination-slow

1

考慮すべきことの1つは、多くのHTTPクライアント(ブラウザーを含む)が、複数のHTTP要求でSSLハンドシェイクのコストを償却しようとすることです。つまり、サーバーへの1つのTCP接続を確立し、SSLハンドシェイクを実行してから、そのTCP接続(SSLセッションを使用))を複数の要求に再利用します。リクエストごとにSSLハンドシェイクを実行するのではなく、/ responses。

セットアップでこの種のシナリオ/テストを有効にするには、フロントエンド HTTPリクエスト用にab-kコマンドラインオプションを含めることができます。

もう1つの考慮事項は、option http-server-closeHAproxy設定の使用です。これは、haproxyに新しいバックエンドを作成するように指示しますTCP接続、フロントエンドHTTPリクエストごと。これにより、バックエンドネットワークに応じて、独自の40〜100ミリ秒(それ以上ではない場合)を追加できます。HAproxyを許可した場合これらのバックエンドTCP接続を開いたままにしてください。これも、abによって報告されるリクエストごとのレイテンシを減らす可能性があります。

予想されるSSLセッションの数によっては、SSLセッションキャッシュのメモリ割り当てを増やすことも可能です(HAproxyのtune.ssl.cachesize設定、おそらくキャッシュタイムアウトを増やすためのtune.ssl.lifetimeと組み合わせて、セッションキャッシュの再利用の可能性)により、より再開されたSSLセッション(およびより高速で計算量の少ないSSLハンドシェイク)が可能になります。

しかし、キープアライブ(-k)を使用する場合、abによって報告される数値は、同じSSLセッションを(同じTCP接続を介して)再利用することの効果をよりよく示すと思います。多くのHTTPリクエスト。

お役に立てれば!

1
Castaglia

アップルとアップルを比較してください。

ベンチマークopenssl speed rsaは、エフェメラルキーを使用しないため、おそらくDHE時間を測定しません。これは、DHEアルゴリズムと比較して安全性の低いアルゴリズムをテストすることを意味します。後者は低速ですが、一方で、完全転送秘密(PFS)を提供します。

しかし、DHEは非常に古く、効果がなく、最新のブラウザーは通常、より優れたECDHE(またはECDSA)を使用します。

ECDHE-RSA-AES128-SHA256を適用するには、abベンチマークを設定する必要があると思います。 openssl s_client -cipher ECDHE-RSA-AES128-SHA256のループを使用するようにopensslベンチマークをプログラムする必要があると思います(単純なopenssl speedの代わりに)。

0
kubanczyk