Top / EBUG勉強会 / 20170211_SSLVPN

relayd + DeleGate + acme-client = SSLVPN

EBUG 第60回会合
2017年 2月11日、万代市民会館
川俣吉広、kaw@on.rim.or.jp

発端

本件の例では、以下の構成でSSL-VPNの運用を行っていた。

INTERNET                      || INTRANET LAN
https://gw.foobar.com/bee/*   || http://sv.inner.foobar.com/quux/baz/*
                              ||
                          +-----------+
                          |OpenBSD 5.8|
 [Web Browser]---HTTPS--->*DeleGate   *---HTTP--->[Web Server]
                         /|     9.9.13|
                        / +-----------+
                       /      ||
                  Basic       ||
                  Auth.       ||

このGWではDeleGateを用いて、以下のことをやっている;

  • (A) SSL/TLSの終端 (証明書はDeleGate内蔵の自己署名されたもの)
  • (B) ユーザの認証 (リバースプロキシのBasic認証)
  • (C) URLのリダイレクト(書換え)
#!/bin/sh

function dgcmd {
    /usr/fuguita/sbin/delegated \
        DGROOT=/home/delegated \
        OWNER=delegated/delegated \
        LOGDIR='log/[date+archived/%Y%m]' \
        "$@"
}

umask 0027

case X"$1" in
    Xstart)  dgcmd \
                -Pgw.foobar.com:443 \       <-(A)
                 SERVER=https \             <-(A)
                 FCL=sslway \               <-(A)
                 REMITTABLE="http,https" \                  <-許可するプロトコル
                 RELIABLE="*.jp,*.gfngfn.net" \             <-許可するアクセス元
                 REACHABLE="inner.foobar.com,google.com" \  <-許可するアクセス先
                 AUTH=proxy:pauth \                                                        <-(B)
                 AUTHORIZER='-list{guest:welcome772,kaw:op2p29eje,ouquser:pvs/neue288}' \  <-(B)
                 MOUNT='/proj1/* http://gwe1.inner.foobar.com/bd/proj1/*' \   <-(C)
                 MOUNT='/proj2/* http://iwf.inner.foobar.com/wf/ntp8x16/*' \  <-(C)
                 MOUNT='/* https://google.com/?q=*' ;;                        <-(C)
    Xstop)    dgcmd -Pfoobar.com:443 -Fkill ;;
    Xrestart) $0 stop; sleep 15; $0 start;;
    *)        echo "$0 start|stop|restart" >&2 ;;
esac

このサーバを更新し、OpenBSD 5.8 -> OpenBSD 6.0 に変更したところ、DeleGateがlibssl, libcryptoをロードしなくなった。
外部よりアクセスすると、ブラウザに

このサイトにアクセスできません
 foobar.com により途中で接続が切断されました。

と表示され(Google Chromeの場合)、接続できない。また、DeleGateのログでは、起動時に

--ERROR: can't link the SSL/Crypto library.

ブラウザ接続時、DeleGateのログに

[OpenBSD/6.0] not OOB: BrokenSocket[25] <= _-select.c91 ####

というエラーが記録される。

代替策として、SSL/TLSの終端を行う部分を他のソフトウェアで置き換えることとした。
候補としては、Squid, Nginx, Varnishなどのリバースプロキシがあるが、今回はOpenBSDネイティブのrelaydを使用した。

併せて、SSL/TLSのサーバ証明書を自己署名のものから、Let's Encryptから発行されたものに変更した。

relaydとは

OpenBSDネイティブなL7ゲートウェイ。これを使用してロードバランサを構築可能。

OpenBSDのウェブ関連daemonの系譜

[4.1]           [4.3]
hoststated------>relayd------+---------------->[6.0]
                             |
                             |
Customized                   V
Apache 1.3.x-------|Nginx---|+OpenBSD httpd--->[6.0]
[2.3]              [5.1]    [5.7]

relaydの機能

  • Incoming Connectionの中継
  • バックエンドのサーバへのロードバランス(HTTP, HTTPS, DNS)
  • 同、死活監視
  • SSL/TLS終端
  • HTTPのフィルタリング
  • ...etc
LBとしての動作例
                                             +--------+
                                        +--->|Web     |
                                  server|   /|Server 2|
                           health checks|  / +--------+
        +-GW-------------------------+  | /
        |               |relayd      *--+/
        |               ----*--------|  / 
        |     rdr rewriting/         | /|    +--------+
        |-----------------*----------|/ +--->|Web     |
------->| PF | rdr-anchor "relayd/*" *-------|Server 2|
Incoming+----------------------------+\ |    +--------+
Access                                 \|     
                                        \ 
                                        |\
                                        | \  +--------+
                                        +--\->Web     |
                                            \|Server 3|
                                             +--------+

PFを使わずに、relayd単体でも運用可能

Let's Encryptとacme-clientについて

Let's Encryptとは、SSL/TLSのサーバ証明書を発行するCA(Certificate Authority: 認証局)の一つ。

  • インターネット上のウェブサーバで、SSL/TLSを容易に導入・運用できるようにし、ウェブの安全性を高めることを目標とする。
  • 証明書の発行は、ACME (Automated Certificate Management Environment)というプロトコルを用いて自動で行う
    • 発行する証明書の種類はDV(Domain Validation: ドメイン認証)のみ、OV(Organization Validation: 組織認証)やEV(Extended Validation: 拡張認証)はサポートしていない。
    • 証明書の有効期間は90日。更新処理も自動で行う。

ACMEのクライアントプログラムは幾つもの実装があるacme-clientはmandocの作者でもあるKristaps DzonsonsによってC言語で作成されたもの。以前はletskencryptと称していた。acme-clientはOpenBSD 6.1ではベースシステムに加えられる予定。

SSL-VPNの再実装例

SSLの終端部分をrelaydで置き換え、以下のように構成を変更する。

INTERNET                      || INTRANET LAN
https://gw.foobar.com/bee/*   || http://sv.inner.foobar.com/quux/baz/*
                              ||
                          OpenBSD 6.0
                          +---------------+
 [Web Browser]---HTTPS--->*relayd         |
                          |----|----------|
                          |    v127.0.0.1 |
                          |----*----------|
                          |       DeleGate*---HTTP--->[Web Server]
                         /+---------------+
                        /     ||
                       /      ||
                  Basic       ||
                   Auth.      ||
  • rcctlにてrelayd起動設定
    # rcctl enable relayd
  • /etc/relayd.conf追加
    # $OpenBSD: relayd.conf,v 1.3 2014/12/12 10:05:09 reyk Exp $
    #
    # Macros
    #
    ext_addr="229.112.43.88"
    webhost1="127.0.0.1"
    
    #
    # Global Options
    #
    # interval 10
    # timeout 1000
    # prefork 5
    
    #
    # Each table will be mapped to a pf table.
    #
    table <webhosts> { $webhost1 }
    table <fallback> { 127.0.0.1 }
    
    #
    # Relay and protocol for HTTP layer 7 loadbalancing and SSL/TLS acceleration
    #
    http protocol https {
            match request header append "X-Forwarded-For" value "$REMOTE_ADDR"
            match request header append "X-Forwarded-By" \
                value "$SERVER_ADDR:$SERVER_PORT"
            match request header set "Connection" value "close"
    
            # Various TCP performance options
            tcp { nodelay, sack, socket buffer 65536, backlog 128 }
    
    }
    
    relay wwwtls {
            # Run as a SSL/TLS accelerator
            listen on $ext_addr port 443 tls
            protocol https
    
            # Forward to hosts in the webhosts table using a src/dst hash
            forward to <webhosts> port 10080 mode loadbalance
    }
  • acme-clientをインストールし、ACMEのチャレンジの置き場所をhttpd.confで設定する。
    # $OpenBSD: httpd.conf,v 1.14 2015/02/04 08:39:35 florian Exp $
    
    #
    # Macros
    #
    ext_addr="*"
    
    #
    # Global Options
    #
    # prefork 3
    
    #
    # Servers
    #
    
    # A minimal default server
    server "default" {
            listen on $ext_addr port 32180
    }
    
    # For acme-client challenge-response
    #
    server "acme-challenge" {
            listen on * port 80
    
            location "/.well-known/acme-challenge/*" {
                    root "/acme"
                    root strip 2
            }
    }
    
    # Include MIME types instead of the built-in ones
    types {
            include "/usr/share/misc/mime.types"
    }
  • relaydが参照するSSLの鍵及び証明書の作成・追加
    # acme-client -Nnv gw.foobar.com
    # ls -l /etc/acme /etc/ssl/acme /etc/ssl/acme/private
    /etc/acme:
    total 8
    -r--------  1 root  wheel  3272 Jan 30 11:53 privkey.pem
    
    /etc/ssl/acme:
    total 32
    -r--r--r--  1 root  wheel  2143 Jan 30 11:54 cert.pem
    -r--r--r--  1 root  wheel  1647 Jan 30 11:54 chain.pem
    -r--r--r--  1 root  wheel  3790 Jan 30 11:54 fullchain.pem
    drwx------  2 root  wheel    48 Jan 30 11:53 private
    
    /etc/ssl/acme/private:
    total 8
    -r--------  1 root  wheel  3272 Jan 30 11:53 privkey.pem
  • relaydが参照しようとする証明書をacme-clientが取得した証明書に合わせる。
    # ls -l /etc/ssl/*.crt /etc/ssl/private/*.key
    lrwxr-xr-x  1 root  wheel  18 Feb  2 07:53 /etc/ssl/229.112.43.88.crt
                                               -> acme/fullchain.pem
    lrwxr-xr-x  1 root  wheel  27 Jan 30 11:58 /etc/ssl/private/229.112.43.88.key
                                               -> ../acme/private/privkey.pem
  • 鍵更新のスクリプトをcronに登録する。
    # cat /root/sbin/update-acme.sh
    #!/bin/sh
    acme-client gw.foobar.com
    
    if [ $? -eq 0 ]; then
        rcctl restart relayd
    fi
  • /home/delegate/sbin/rc.delegate-sslvpnの変更
    • FCL=sslway削除
    • Listen Port変更(127.0.0.1/10080)
    • RELIABLEパラメータにlocalhost追加

まとめ

  • 従来のシステムと等価なものを構築できた。
  • Let's Encryptはできてしまえば簡単。ウェブサーバを運営されている方は、SHA-1→SHA-2移行、常時SSL化, HTTP/2普及の流れに合わせ、準備しておいて損はないかも。
  • 最近のdaemon類は設定が簡単。従来の定番ソフトからの移行も検討の価値あり。
  • POSTでフォームをサブミットした場合に、ブラウザがずっとレスポンス待ちの状態になることがある。要原因調査。(サーバ側ではPOSTデータのサブミット自体はされている)

Top / EBUG勉強会 / 20170211_SSLVPN

Reload  New Edit Freeze Diff Attach Copy Rename  Top Index Search Recent Backups  Help  RSS
Last-modified: 2017-02-11 (Sat) 11:41:40 (434d)