#topicpath *relayd + DeleGate + acme-client = SSLVPN [#f6ff4c62] RIGHT:EBUG 第60回会合 ~ 2017年 2月11日、万代市民会館 ~ 川俣吉広、kaw@on.rim.or.jp **発端 [#ab0755fb] 本件の例では、以下の構成で[[SSL-VPNの運用>SslVpn]]を行っていた。 本件の実以前、従来は以下の構成で[[SSL-VPNの運用>SslVpn]]を行っていた。 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とは [#b1d506bc] OpenBSDネイティブなL7ゲートウェイ。これを使用してロードバランサを構築可能。 -http://www.slideshare.net/GiovanniBechis/relayd-a-load-balancer-for-openbsd とか 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について [#pd5f684f] [[Let's Encrypt>https://letsencrypt.org/]]とは、SSL/TLSのサーバ証明書を発行するCA(Certificate Authority: 認証局)の一つ。 - インターネット上のウェブサーバで、SSL/TLSを容易に導入・運用できるようにし、ウェブの安全性を高めることを目標とする。 - 証明書の発行は、ACME (Automated Certificate Management Environment)というプロトコルを用いて[[自動で行う>https://letsencrypt.org/how-it-works/]]。 --発行する証明書の種類はDV(Domain Validation: ドメイン認証)のみ、OV(Organization Validation: 組織認証)やEV(Extended Validation: 拡張認証)はサポートしていない。 --証明書の有効期間は90日。更新処理も自動で行う。 [[ACMEのクライアントプログラムは幾つもの実装がある>https://letsencrypt.org/docs/client-options/]]。[[acme-client>https://kristaps.bsd.lv/acme-client/]]はmandocの作者でもあるKristaps DzonsonsによってC言語で作成されたもの。以前はletskencryptと称していた。acme-clientはOpenBSD 6.1ではベースシステムに加えられる予定。 **SSL-VPNの再実装例 [#s0949dd2] 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追加 **まとめ [#pe1c57b5] -従来のシステムと等価なものを構築できた。 -Let's Encryptはできてしまえば簡単。ウェブサーバを運営されている方は、SHA-1→SHA-2移行、常時SSL化, HTTP/2普及の流れに合わせ、準備しておいて損はないかも。 -最近のdaemon類は設定が簡単。従来の定番ソフトからの移行も検討の価値あり。 -POSTでフォームをサブミットした場合に、ブラウザがずっとレスポンス待ちの状態になることがある。要原因調査。(サーバ側ではPOSTデータのサブミット自体はされている) ---- #topicpath