ヤフーにおけるWebサービスのアクセスコントロール

  • このエントリーをはてなブックマークに追加

こんにちは、R&D統括本部 開発推進室 セキュリティプラットフォーム技術 セキュリティスペシャリストの戸田 薫です。
今回は、ヤフーにおけるWebサービスのアクセスコントロールについてご紹介します。

ヤフーでは、会社組織やWebサービスの運営面でいろいろなアクセスコントロールを行っています。
アクセスコントロールをする目的には、いくつも理由がありますが、たとえば、以下の理由が挙げられます。

  • お客様やパートナーの情報を守らなければなりません。
  • サーバの制御を奪われ、攻撃に利用されてはいけません。
  • システムの不正な利用を予防しなければなりません。

今回は、ヤフーのWebサービスにフォーカスして説明をします。

  • インターネットからヤフーへのアクセス制御
  • ネットワーク単位のアクセス制御
  • ヤフーのサーバ間の証明書による認証
  • 社内アカウントによるアクセス制御

外部へポートを解放する

Webサービス用のサーバは、たいていヤフーのプロダクションネットワークと呼ばれるネットワークに設置されます。
サーバが設置された状態では、社内からしかアクセスができないようになっています。
インターネット側からプロダクションネットワークへのサーバへアクセスするためには、「ポート解放」と呼ばれる、ネットワーク機器の設定の変更が必要になります。

ヤフーでは、インターネット向けには基本的にhttp(80)/https(443)のポートしか解放していません。
サービスによっては、ftpやsmtp/popなどのポートが一部解放されています。
ssh などのポートは解放せず、最低限のポートしか開きません。

ルールは、不要なサービスは起動しないことやヤフーのネットワーク以外からリモートログインできない設定になっていますが、
このネットワークのアクセス制限・制御により、うっかり開いてしまっているポートが公開されたり、サーバ侵入の試み(sshd へのブルートフォース攻撃)を未然に防げます。
ネットワーク部門のサイトオペレーションがサーバにオペレーティングシステムのインストールを一括して行っていますが、デフォルトの状態では、sshdなどの必要最低限のサービスしか起動していません。さらにデフォルトの /etc/hosts.allow が設定されており、ヤフーのネットワークからしかログインできないようになっています。

外部へ公開したくない、あるいはWebベースのツールやWebAPIのサーバは、80/443といった一般的なポート以外のポートを利用するようにしています。
ヤフーとして一般的にインターネットへ公開しないポートを利用することにより、ネットワーク機器のアクセスコントロールの設定の誤り(たとえば、標準的なポートを開放する手続きで、誤ったIPアドレス(公開しないサーバ)を設定しまったケース)があった場合にも公開される可能性を減らせます。

ネットワーク単位のアクセス制御

本来、インターネット向けに公開したくないエントリーポイントは、別の社内向けサーバで提供していますが、一部の特別なエントリーポイントは、そのような分離をすることができなかったために、アクセス制限をかける必要があります。

Apache レベルのアクセス制御は、ヤフー独自の仕組みを利用しています。
Allow ディレクティブは、基本的に利用していません。
メンテナンス性、パフォーマンスを考慮して、Apache用のアクセスコントロールモジュールとヤフーのネットワークデータベースを使用しています。
このApache用モジュールは、ヤフーのApacheがインストールされているすべてのサーバで利用されています。
ネットワークデータベースでネットワーク情報が一元管理されることにより、全サービスのメンテナンスコストを下げることができ、矛盾・誤りの発生を防げます。

既存のAllow from ディレクティブを利用しない理由は以下の通りです。

  • Allow from ディレクティブは、FQDNやドメインを指定したときに、DNS look up を必要とするため、スピードが遅くなります。
    Order deny,allow
    Deny from all
    Allow from .yahoo.co.jp
    Allow from foo.yahoo.co.jp
    

    ACLをかけたエントリーポイントにアクセスが集中すると上記の理由により深刻なパフォーマンスの低下が発生します。

  • リバースDNSサーバの制御を奪われたときに、DNSリバースルックアップが安全ではなくなります。
  • サービスごとにIPアドレスを指定してアクセス制御するのは、作業の重複が発生することや、IPの再利用やネットワークの追加・削除などのさまざまな理由から煩雑でかつ複雑になるため好ましくありません。ヤフーのネットワークには、多数のネットワークがあるため、個別に管理するのは、現実的ではありません。

ネットワーク単位のアクセス制御では、簡単に以下のような単位でアクセスを制御できます。
必要に応じて、カスタムのデータベースを作成することも可能です。

  • ヤフーネットワーク
    プロダクション、および、コーポレートネットワークを意味します。
  • ヤフープロダクションネットワーク
    お客様にご利用していただくサーバ群が設置されるネットワークです。
  • ヤフーコーポレートネットワーク
    社内向けシステムのサーバが設置されるネットワークです。

ヤフーのプロダクションネットワークのみにアクセスを限定する設定ができる理由には、例として下記の理由が挙げられます。

  • プロダクション環境のお客様やコンテンツプロバイダーのデータを開発環境などの別のネットワークに持ち出せないようにする必要性があります。
  • テストされたコードがインストールされるプロダクションネットワークのサーバからはWebAPIへアクセスを許可してもよいが、開発環境で動作しているテストもされていない開発中のプログラムから本番データにアクセスするべきではありません。

ヤフーには、ほかにもいくつものネットワークが存在します。その中には、非ヤフーネットワークがあります。
非ヤフーネットワークは、目的ごとの複数のネットワークが整備されています。
ヤフーのネットワークデータベースには、この非ヤフーネットワークが定義されています。
たとえば、ヤフーと業務提携や制作の委託をしている企業とデータの受け渡しをしたりする場合に用いられます。
そのほかには、子会社ネットワークとして利用されることもあります。
この非ヤフーネットワークは、非ヤフーと定義されているため、このネットワークからプロダクションネットワークのサービスにアクセスしても、ヤフーからのアクセスとはみなされないようになっています。

ネットワークの分離

「ネットワーク単位のアクセス制御」では、広い範囲でのアクセス制御を行っていました。
場合によっては、L3 スイッチや Firewall を利用してネットワークレベルでのアクセス制限も行っています。

ヤフーでは通常、フロントエンドサーバとバックエンドサーバの間には、ネットワーク機器によるアクセス制限はかけていません。
ヤフーでは、取り扱う情報の区分を定義し、その区分に応じた対策をしています。
たとえば、扱うデータがセンシティブである場合や課金系のシステムなどでは、バックエンドサーバの設置するネットワークをネットワーク機器などによってアクセス制限をかけます。許可されたフロントエンドサーバからのみバックエンドサーバにアクセスすることが可能になります。

この対策により、ネットワークが分離されているサーバ群とは関係のないフロントエンドサーバが乗っ取られた場合のリスクを減らすことができ、社内からの不正なアクセスが可能な人間もごく一部の運用者だけに限定できます。

「ネットワーク単位のアクセス制御」でご紹介した非ヤフーネットワークは、ヤフーのプロダクションネットワークとネットワーク機器によってアクセス制限がかけられています。
ここでは、必要がある場合にのみ、最低限の通信用の設定をしています。

ヤフー証明書ベース認証

「ネットワーク単位のアクセス制御」では、主にヤフーとそれ以外という比較的単純なアクセス制御を紹介しました。
「ヤフー証明書ベース認証」では、より細かいアクセス制御について説明します。

目的

ヤフーには、社内向けや一般向け(社外向け: サービス用やYJDN公開用)のWebAPIがあります。
社内向けのWebAPIサーバは、ヤフー独自の証明書ベース認証でアクセス制御します。
細かいアクセス制御をする目的には、情報の持ち出しやシステムの不正利用を困難にすることや事故の防止などが挙げられます。

たとえば、金銭に関わるWebAPIを不正に利用することを防ぐ必要もあります。
また、個人情報をシステムから抜き出すのを困難にする必要もあります。
ヤフーの中には、広く共有できるデータもあれば、利用が限定されるセンシティブデータを蓄積しているデータベースもあります。
そういった情報をきちんと管理する必要があります。
社内におけるAPIを利用した「いたずら」や誤った利用による事故を防止する必要もあります。

「ネットワーク単位のアクセス制御」でも書きましたが、テストされたコードがインストールされるプロダクションネットワークのサーバからはアクセスを許可してもよいが、開発中のプログラムから本番データにアクセスするべきではありません。

従来のIPアドレスによる制限は、ヤフーにおいてすでに破たんしました。
というのもヤフーのサービスを構成するサーバ台数が大規模だからです。

IPアドレス単位のアクセス制限は、以下の問題がありました。

  • IPアドレスが多すぎます。
    ヤフーには、何万台もサーバがあります。
  • IPアドレスだとどこのサービスの何のサーバなのか一見分かりません。
    たくさんあるIPアドレスを1つ1つ逆引きするのは、時間の無駄です。
  • IPアドレスはいつの間にか再利用されます。
    まったく関係のないサービスのサーバが設置されているかもしれません。
  • IPアドレスの追加・削除も頻繁に起きます。
    連携するサービスの多いプラットフォームを提供している場合、あちこちのサービスから接続の依頼が来るため、負担が大きくなります。

それに、IPアドレス単位のACLのままIPv6のネットワークに移行した場合、きっと誰も運用したくなくなっているでしょう。

また、更新作業も煩雑でした。

  • 開発部門は、設定ファイルを更新して、テストを実施し、ソースコード管理システムにコミットします。
  • 開発部門は、設定ファイル用パッケージを作成し、配布サーバへインストールします。
  • 開発部門は、運用部門に設定ファイル用パッケージのインストール依頼をします。
  • 運用部門は、設定ファイル用パッケージのインストール作業を行います。

新方式では、以下の点の改善を考えました。

  • IPアドレスによる管理を廃止します。
  • 運用の負担を軽減します。
  • 複雑な設定をやめます。
  • 追加・削除のパッケージ更新作業を極力減らします。

そのためにヤフー証明書ベース認証は開発されました。

ロールの定義

「ヤフー証明書ベース認証」では、アクセスをグループ単位(ロール)で制御します。
グループは、ロールデータベースに名前空間を定義し、名前空間にロールを定義します。
ロールには、アクセスを許可するメンバーを定義します。メンバーには、ホストを指定します。

名前空間の作成やロールの編集権限は、オペレーションデータベースで設定されています。
今回は関係がないため、詳細は紹介しませんが、このロールは、パッケージをインストールするためのサーバグループとしても利用できます。

ホストを指定するときには、正規表現のような省略した表記もでき、複数のマシンを1行で定義することが可能です。
ロールは、別のロールをインクルードすることもでき、サービスごとにロールを分け、1つのロールにまとめられます。

ヤフーの認証局

ヤフーの証明局は、ヤフー独自の証明書を発行します。
証明局の発行は、WebAPIで提供されます。このAPIは、社外には公開されていません。
証明局は、クライアントに与えられているロールの情報をロールデータベースのWebAPIを利用して取得します。
証明書は、ヤフーの認証局からクライアントごとに発行されます。

WebAPIを提供するサーバ

WebAPIを提供するサーバには、ヤフー証明書ベース認証専用のApache モジュールを組み込みます。
WebAPI を提供するシステムのApacheのエントリーポイントごとにアクセスを許可するロールを定義します。
ロールのメンバーの定義は、Apache の設定ファイルなどの設定で行いません。
WebAPIサーバでアクセスを許可するロールの設定をすれば、ロールデータベースでロールを編集するだけで、アクセスできるメンバー(ホスト)を変更できます。
エンジニアは、Location の定義に独自ディレクティブでアクセス制御の設定を数行するだけです。

従来では、IPアドレスの追加・削除があるたびに、パッケージを更新していましたが、この方式では、アクセス許可のロールを設定ファイルに追加するときだけになります。
それも基本的には、ロールデータベースだけで対応できるので、運用はかなり改善されました。

モジュール内部では、複数のチェックが行われます。
たとえば、以下の項目をチェックしています。

  • 証明書のロール
  • 有効期限
  • IPアドレス
  • シグネチャ

IPアドレスのチェックでは、「ネットワーク単位のアクセス制御」に出てきたネットワークデータベースによって、クライアントのIPアドレスがヤフーのIPアドレスであるかどうかも確認が行われます。

WebAPIを利用するクライアント

ヤフー証明書ベース認証を利用するWebAPIを呼び出すクライアントは、ヤフー証明書ベース認証専用のクライアントパッケージを利用します。
クライアント用パッケージで自動的に証明書が取得・更新されます。
クライアントは、プログラムに証明書を扱うコードを追加する必要がありますが、ヤフーの証明書用のクライアント向けパッケージで提供されるライブラリを用いて、簡単に組み込めるようになっています。
ヤフー証明書ベース認証は、数行のコードを追加するだけで対応できます。

このように開発や運用に負担をかけずに、より安全なシステム構築ができるようになっています。

ヤフー社内用アカウントのアクセス制御

ヤフーの社内には、業務用やサービスの運用ツールなど、多くのWebツールがあります。
それらのツールにもアクセス制限がかかっています。

社内では、Yahoo! JAPAN ID とは異なる「社内用のアカウント」が使われます。
Yahoo! JAPAN ID ではないため、login.yahoo.co.jp とは別の認証サーバで一元管理されます。
ほとんどのツールには、社内用アカウントの認証モジュールが導入されています。
また、この社内用アカウントは、休職や退職などの理由によりアカウントが無効化されるようになっています。

このアクセス制御にも専用のApacheモジュールが用意されており、エンジニアは数行の設定を定義するだけで社内アカウント認証に対応できます。
アクセスグループを定義することができ、ツールによっては利用者を制限することも容易にできるようになっています。
アクセスグループへの権限申請のシステムを通じて、権限を付与する仕組みがあります。

まとめ

ヤフーでは、ネットワーク、オペレーティングシステム、アプリケーションレベルの複数の層でアクセスコントロールを行っています。

  • ネットワークレベルの対策
    • 必要最低限のポートをインターネットに解放します。
    • 扱う情報や機能によっては、ネットワーク機器などでネットワークを分離し、アクセス制御をかけます。
  • オペレーティングシステムレベルの対策
    • 必要なサービスしか起動しません。
    • hosts.allow でアクセス制限をかけます。
  • アプリケーションレベルの対策
    • ヤフーのネットワークデータベースによってアクセス制御を行います。
    • 独自の証明書ベース認証によってアクセス制御を行います。
    • 社内アカウント認証によるツールのアクセス制御を行います。

社内・社外の双方を意識した複数のアクセスコントロールを利用して、サービスを運営しています。
開発や運用を可能な限り妨げずに、きちんと情報を管理していく必要があると考えています。
今後も「悪いこと」ができない、そして、「悪い人」を生みださない体制を構築していきたいと思います。

Yahoo! JAPANでは情報技術を駆使して人々や社会の課題を一緒に解決していける方を募集しています。詳しくは採用情報をご覧ください。

  • このエントリーをはてなブックマークに追加