🔓

社内システムの脱 VPN 化をゆるっと進めている話

2023/12/23に公開

この記事は Fusic Advent Calendar 2023 の23日目の記事です。

みなさんこんにちは、株式会社 Fusic でエンジニアをしています k-masatany です。

普段は、AWS と PHP+Laravel を軸とした WEB アプリケーション開発業務に従事したり、社内バンド活動に勤しんでいます。
また、それとは別に社内のネットワーク関係を前任者から引き継ぎ、社内イントラのメンテナンス等を実施しています。

今回は、現在進行形で進めている、Fusic の脱 VPN 化について簡単に語りたいと思います。
自己署名証明書を利用しているという点においてあまり褒められた構成とは言えませんが、興味があれば、どうぞお付き合いください。

脱 VPN 化前の構成

構成図(前)

元々上記のような構成で運用されていたのですが、下記のような問題を抱えていました。

リモートワークの活発化による VPN トラフィックの増加

弊社もコロナ禍をきっかけにリモートワークが活発化し、社員のみ閲覧可能なコンテンツにアクセスするためには VPN が必要なものが大半であり、ネットワークを管理する上で VPN トラフィックを課題視するようになりました。

従業員数の増加

ありがたいことに社員が3年半で60人増え、それに伴ない、リモートワーク人口も増加。
VPN トラフィックがさらに増加する傾向に。

SSO システムの独自実装

まだまだ小さい会社だった頃に、弊社の社員が構築した SSO システムが、社内イントラの認証システムとして存在しており、独自実装ゆえの脆弱性の懸念や、2FA が利用出来ない等の理由があり、インターネットに全公開するのは憚られる状態でした。
(少しずつ Azure を利用した SSO に移行しつつありますが、まだ完全ではありません)

現在の構成

構成図(後)

この記事を書くにあたり調べた所、2020年11月頃から稼動しているので、約3年ほどこの構成で運用しているようです。
一部のシステムの脱 VPN 化を実施するにあたり、大きく2つの施策を実施しました。

  1. クライアント証明書の利用により IP 制限の撤廃
  2. 署名付き Cookie を利用した CloudFront コンテンツへのアクセス制限

クライアント証明書の利用により IP 制限の撤廃

あくまでも最終的なセキュリティはシステム側で担保をする、という前提に立ち、
自己署名認証局による各種証明書を作成して、社員に配布をして、それを利用することで非 VPN 通信においても、公開サーバに置かれた社内イントラにアクセス可能としました。

なお、最近では BounCA というオンラインで完結できるサービスもあるようで、これから似たようなことをやろうとしている人は、おそらく BounCA を利用するのが良いかと思っています。
現行システムについても、更新時期が来たら BounCA に乗り換えたいなと思っています。

STEP 1. 自己署名認証局によるクライアント証明書の導入

まずは自己署名認証局を作成します。
諸先輩方がインターネットに書き記してくれている記事がありますので、ここでは完結に手順だけを記載したいと思います。

1. 自己署名認証局用のキーペアの作成

認証局として機能させるための秘密鍵と公開鍵のペアを作成します。
有効期限については必要に応じて設定してください。

2. (optional)自己署名認証局の秘密鍵で署名したサーバー証明書の作成

サーバー証明書も自己署名のものを使う場合は、先程作成した自己署名認証局の秘密鍵を使って署名して作成します。
弊社の場合、サーバー証明書は正規の証明機関から購入したものを利用しています。

3. 自己署名認証局の秘密鍵で署名したクライアント証明書の発行

サーバー証明書と同様に、自己署名認証局の秘密鍵で署名したクライアント証明書を作成します。
このクライアント証明書を、社員の端末等にインストールしてもらい、非 VPN 環境からアクセスしてもらいます。

4. Nginx や Apache などに各種証明書を設定

サーバー証明書関係、自己署名認証局秘密鍵、を HTTP サーバーに設定して、TLS 通信およびクライアント証明書による認証設定を行います。
業務影響等を考えると、クライアント証明書によるアクセスおよび、VPN を利用しての特定 IP アドレスからのアクセスの2つの方法について許可をする設定にしておくと、クライアント証明書の期限切れが発生した時などでも、社内からのクレームが発生しにくいかと思います。

STEP 2. クライアント証明書を発行するためのシステムを構築

STEP 1 で作成したクライアント証明書の仕組みでは、自力でクライアント証明書を発行して配布するという辛い状況が発生します。
そこで、弊社ではクライアント証明書を発行するためのシステムを構築し、各社員が自分で発行してダウンロードできる環境としています。

社内には、アプリケーションが実装された社内システムとは別に、CloudFront + S3 で構成された静的な社内向けドキュメント等もあり、そちらも IP アドレスによる制限がかけられており、社外からアクセスする場合には VPN 接続が必要となっていました。

そこで、そちらについては、CloudFront を利用していることに着目して、署名付き Cookie によるアクセス制限を実施することで VPN 接続を不要としました。

1. CloudFront コンテンツのプライベートコンテンツ化

署名付き Cookie を利用してアクセスをさせる静的コンテンツを配信している CloudFront について、アクセス制限を行い、署名付き Cookie の無いリクエストについてはブロックするように設定します。
そして、署名付き Cookie を作成するためのキーペアを作成します。

この辺については、公式ドキュメント を見ていただくのが一番だと思います。

2. 署名システム側にキーペアを登録

クライアント証明書発行システムに、署名付き Cookie を発行する仕組みも実装し、先程作成したキーペアとサイトの情報を登録することで、署名付き Cookie を発行可能な状態にしておきます。

サイト閲覧者が CloudFront にアクセスをすると、署名付き Cookie が無いため、エラーページが表示されます。
エラーページは、署名システムにリダイレクトし、署名システム側でのユーザー認証に成功すると、自動的に署名付き Cookie を発行して再度 CloudFront 側にリダイレクトします。
この仕組みにより、ユーザーの負担を限りなく少なくした状態で署名付き Cookie によるアクセス制限を実現しました。

まとめ

VPN が完全に不要になった訳ではないということと、社員数が右肩上がりなため、クライアント証明書の導入により、どれくらいの効果があったかの測定は出来ていないのですが、社内からは「便利に使っている」という声をちらほらと聞くので、整備をした甲斐はあったのかなと思っています。

さらに非 VPN トラフィックの割合いを増やすために、認証付きプロキシの導入をしたいと思っています(出来れば実装したいと思っています)。

Fusic 技術ブログ

Discussion