社内勉強会で発表した資料です https://github.com/kurochan/oidc-wireguard-vpn/
WireGuardとOpenID Connectの連携をGoで実装してみた株式会社サイバーエージェント AI事業本部黒崎 優太 (@kuro_m )
View Slide
黒崎 優太• 株式会社サイバーエージェントAI事業本部 アプリ運⽤センター• ⼩売業界 x DXの事業をやっています• バックエンドエンジニア直近はAWSとかGCPとかセキュリティまわりの仕事をしていました@kuro_m @kurochan #times_kurochan
VPNを作ってみました
VPNサーバが欲しくなった経緯• AI事業本部内のDX本部に異動しました• 詳しくはこれを⾒てください• https://speakerdeck.com/kurochan/retail-dx-project
聞こえてくる会話• 🧑💻「xxxのシステムにアクセスするために出社しないといけないんですよね…」
聞こえてくる会話• 🧑💻「xxxのシステムにアクセスするために出社しないといけないんですよね…」• 👩💻「固定IPじゃないといけないらしくて、⾃宅のIPはすぐ変わっちゃうし…」
聞こえてくる会話• 🧑💻「xxxのシステムにアクセスするために出社しないといけないんですよね…」• 👩💻「固定IPじゃないといけないらしくて、⾃宅のIPはすぐ変わっちゃうし…」• 🧑💻「xxxのスマホアプリの検証にもIPアドレス制限が…」
VPNサーバの需要があるらしい• 様々な企業やシステムと連携しつつ開発する業態• 何かしらの認証/暗号化 + IPアドレス制限という仕組みはよく出てくる• 個⼈的にはIPアドレス制限に頼りすぎずゼロトラストな環境は作っていきたい
VPNサーバを作ってみる• VPNサーバの実現⽅法は⾊々ありそう• OSSもあるし、商⽤VPNもありそう• アカウントの棚卸し業務をやりたくない• サイバーエージェントには内製の認証基盤がある• OpenID Connectもあるよ• アプリ運⽤センターに異動してきてGo⾔語を書く必要が• 直近広告事業で6年半くらいScalaを書いていた• Go⾔語よく知らない…• Go⾔語の勉強がてら作ってみる
作ったものの概要
WireGuard + OpenID Connect• 簡単に構築ができて、社内のID基盤とも連携できるのを⽬指す• 固定IP + 通信の暗号化のためにWireGuard VPN• 社内のID基盤を使った認証をするためにOpenID Connect• https://github.com/kurochan/oidc-wireguard-vpn/
WireGuard• [CB ] WireGuard:次世代耐乱⽤性カーネルネットワークトンネル by JasonDonenfeld• https://www.slideshare.net/codeblue_jp/cb -donenfeld-ja
WireGuard• https://www.slideshare.net/codeblue_jp/cb -donenfeld-ja
WireGuard• Linux, Windows, iOS, Androidで動くOSSのVPN• 最近のLinuxだとカーネルに組み込まれています• 構築, 設定も簡単• 単体で使うのももちろんおすすめ
OpenID Connect• OAuth . (認可) + 認証のしくみ• WEBサイトの間でのIDを連携するのに特化• シングルサインオンが実現できます
OpenID Connect CIBA Flow• OpenID Connectは「Webサイト」に特化している• WireGuardのように、ブラウザアプリケーションではないアプリも認証したい• CIBA = Client Initiated Backchannel Authentication• クライアント側から認証を開始して、裏側(何かしらの⽅法)で認証/認可をする• VPN接続しようとしたらSlack経由で認証/認可のリクエストが⾶んでくるなど
WireGuardに追加の認証を挟む• WireGuardは⾮常にシンプルなVPNなので、処理をフックするような仕組みはありません!💥• WireGuardで認証したあと、VPNの接続は確⽴したが、通信はブロックするという状態を作る• OpenID Connectで認証認可が成功したら通信を通す認証認可前
WireGuardに追加の認証を挟む• WireGuardは⾮常にシンプルなVPNなので、処理をフックするような仕組みはありません!💥• WireGuardで認証したあと、VPNの接続は確⽴したが、通信はブロックするという状態を作る• OpenID Connectで認証認可が成功したら通信を通す認証認可後
nftables• Linuxのネットワークファイアウォールであるnetfliterを管理する• iptablesを置き換えるフレームワーク• iptablesも裏側でnetfliterを使っている場合も
WireGuard + OpenID Connect + nftables• なんかいけそう!• WireGuardのVPNが通ったとしても、退職や部署異動するとOpenID Connectで認可されなくなる• WireGuardのサーバ側の設定は定期棚卸しくらいでよくなる
使い⽅(ユーザ向け)• クライアントの設定する• PCもスマホもだいたい⼀緒
使い⽅(ユーザ向け)• VPN接続する
使い⽅(ユーザ向け)• Slackに通知がくるので認可する
VPN経由で通信ができる
実装の紹介
netlink• github.com/vishvananda/netlink• Linuxのネットワークインターフェイスを作ったり設定をいじる仕組み
WireGuard• github.com/WireGuard/wgctrl-go• WireGuardのインターフェイスの詳細設定をする• 秘密鍵やVPNクライアントの公開鍵のペアなど
WireGuardで新規接続を検知する• 最後にセッション(鍵交換など)を更新した時間がわかるので、その時刻の⽐較をすると新規接続を検知できそう
追加認証をしていない⼈の通信をブロックする• github.com/google/nftables• nftablesでフィルタルールを動的に制御する
nftables• ルールの追加の例
OpenID Connect CIBA Flow• github.com/okzk/go-ciba• OIDC CIBA Flowを簡単に実現できる• 社内IdPとここで連携しています
追加認証をしていない⼈の通信を許可する• nftablesのセットを操作する
gracefulなシャットダウン• プロセスを停⽌させた時に余計なネットワークの設定などが残っていてほしくない• プロセス停⽌のシグナルをフックする• シグナルもチャネルとして扱える• シグナルを何かしら受け取るまで無限にブロックさせておいて、シグナルを受け取ったらシャットダウン処理をする
作ってみた感想• 便利そうな気がするので育てていきたい• yamlファイルで設定しないでDBを使うとweb UIとかから設定投⼊ができそう• Linuxと連携させる部分はScalaよりだいぶ書きやすかった• テストの書き⽅や⾒通しのいい設計はプロダクト開発をやりつつ勉強していきたい