hosting

新卒エンジニアがGMOサイバー攻撃ネットde診断をロリポップに組み込むまで

hosting

ペパボでは、「サイクルOJT」と呼ばれる独自の研修プログラムが実施されています。 このプログラムでは、新入社員が毎月異なる事業部に所属し、幅広いスキルと知識を獲得します。

9月は@kromiii@n01e0がホスティング事業部でOJTを行いました。メンターはホスティング事業部の@litencattさんに担当していただきました。

こちらのプレスリリースにもあるように、現在ペパボホスティング事業部ではGMOサイバーセキュリティbyイエラエの提供するGMOサイバー攻撃ネットde診断(以下「ネットde診断」)の導入を進めています。

今回のOJTでは、ネットde診断をロリポップ!へ組み込む仕事を担当しました。この記事では、ネットde診断の導入に関わることで学んだことや、実際に行った作業について紹介します。

  1. ロリポップ!の開発奮闘記
    1. ネットde診断を組み込むまで
  2. 学んだこと
    1. Security by Design
    2. DNSレコードに関する知識
  3. おわりに
    1. kromiii
    2. n01e0

ロリポップ!の開発奮闘記

EUC-JP を考慮した開発環境構築

歴史の長いプロダクトにおいては、時々レトロな技術に触れることがあります。ペパボ創業当初から提供しているロリポップ!もその一つで、ソースコードの一部でUTF-8ではなくEUC-JPで書かれている箇所があります。

私は普段Neovimを使って開発しているのですが、こういった現代的なエディタとEUC-JPの組み合わせは一筋縄ではいきません。そこで私はpre-commit hookと文字コード変換ツールのnkfを駆使することで、この問題に立ち向かうことを決めました。一見原始的とも思えるこの対策ですが、以下のようなShellScriptを書くことでこの問題に対処することができました。

#!/bin/bash
git diff --name-only --staged | rg '(\.php)$' | xargs -I{} bash -c "nkf -e --in-place {} && git add {}"

こうした一時的な処理や細かな作業を円滑に遂行するためにShellScriptを書くことは、エンジニアとしてのスキルを磨く上で非常に重要だと感じました。

PHP で単体テストを書く

PHP で有名なテストフレームワークとしては PHPUnitCodeception, Behatなどがありますが、今回はすでにプロダクトに組み込まれていたPHPUnitを使ってテストを書きました。

また今回は外部APIを含むコンポーネントのテストをする必要があったので、スタブやモックをはじめとする テストダブル の概念を理解する必要がありました。

スタブやモックには PHPUnit に用意されている機能を使うこともできますが、今回はAspectMockというライブラリを使いました。

AspectMock を使うと以下のようなシンプルなコードでテストダブルを作成することができます。

// 猫であることをスタブする
test::double('Animal', ['isCat' => true]);

また引数によって返り値を変えたり、例外を返すオブジェクトについてもスタブすることができます。

// 猫しか受け付けないメソッドをスタブする
$mock = test::double('Animal', [
    'numTails' => function($name) {
        if ($name === 'cat') {
            return 1;
        } else {
            throw new Exception('This method only accepts cats.');
        }
    }
]);

今回はAPIがエラーや例外を返すケースについてもテストする必要があったので AspectMock の柔軟な記述方法には助けられました。

もちろんスタブされたメソッドの中身は実行されないので、どこをテストダブルにするかはテストの目的を考えながらケースバイケースで決める必要があります。

5月のTDD研修でも、テストダブルの概念について学んだのですが、そのときはまだ実際に使ったことがなかったので、今回のOJTを通してテストダブルについてのイメージがより具体的になりました。

ネットde診断を組み込むまで

誤検知の調査

ネットde診断は、ツールによる脆弱性の発見と網羅を行ってくれるものの、その中には一部、本来脆弱性ではない箇所に警告が出てしまう場合(以下、誤検知)も存在します。よりよいプロダクトにするために、今回のOJT期間内でイエラエ社と協力して誤検知の発見とその原因の特定を行いました。

私は検知された問題点が本当に脆弱性かどうかを確認するために、フレームワークのソースコードを紐解き、ミドルウェアの設定を検証しました。

そして、それらを通して「この構成なら誤検知を避けられるのでは?」「この挙動、実装が誤検知の原因では?」といった新たな視点を得ることができました。

htaccess の設定

上記に関連して、私はロリポップ!のデフォルトページのトリアージを行いました。

デフォルトページとはドメインにアクセスしたときに表示されるページのことで、通常シンプルなHTMLで構成されています。

基本的にはこの状態だとセキュリティ的なリスクは気にしなくて良いのですが、ネットde診断の結果を見たところ、いくつかの問題が検出されたので、それらを解決するために .htaccess の設定を変更しました。

.htaccess とは、Apache HTTP Server で使用される設定ファイルで、ロリポップではディレクトリごとに設定を変更することができます。

今回は以下のように .htaccess を書き換えることで、問題を解決することができました。

Header always append X-Frame-Options "SAMEORIGIN"
Header always set X-Content-Type-Options "nosniff"
Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval';"
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
FileETag MTime Size

今回は静的なサイトを表示しているだけなので、本来はこれらのヘッダーを設定する必要はないのですが、もしユーザーがCGIなどを使って動的なサイトを表示している場合は、これらのヘッダーを設定することでセキュリティを向上させることができます。

セキュリティに関する知識はエンジニア研修で学びましたが、こうして実践する機会があったことで、より理解が深まりました。

学んだこと

Security by Design

今回はプロジェクトの設計段階から関与することができたので、プロジェクトの初期フェーズからセキュリティについて深く考察することができました。

具体的にはThread Modelingという概念に基づき、サービス固有のセキュリティ対策を考察しました。Thread Modelingとは、潜在的な脅威やその対策を洗い出し、リスクを評価する手法です。私たちはこの手法を活用し、特有の脅威に対する具体的な対策を議論しました。

このように早い段階からセキュリティを考慮することで、手戻りを大きく減らすことができたと思います。Security by Designという考え方は今後のプロジェクトでも大いに生かしていきたいと思います。

DNSレコードに関する知識

今回はホスティング事業部でのOJTということもあり、普段あまり触れることのないDNS周りの知識を学ぶことができました。

DNSとはDomain Name Systemの略で(このOJTをやるまでDomain Name Serverの略だと思ってたのは秘密です)、ドメイン名とIPアドレスを紐づけるための仕組みです。そういう意味では私たちがインターネット上でドメイン名を使ってアクセスすることができるのはDNSのおかげだったりします。

主要なDNSレコードには以下のようなものがあります。

  • Aレコード
  • CNAMEレコード
  • MXレコード
  • TXTレコード

私はこれまで趣味でムームードメインで取得したドメインに対してDNSの設定を行ったことがあったのですが、実際のところどのレコードがどのような役割を持っているのかはあまり理解していませんでした。

しかし今回のOJTを通して、実際に dig コマンドを使ってDNSの設定を確認したり、DNSの設定を変更したときにどのような影響があるのかを確認したりすることで、DNSについての理解が深まりました。

例えば www.example.com のIPアドレスを知りたいときは以下のように指定することで取得することができます。

dig +short www.example.com A

Aレコードはドメイン名とIPアドレスを紐づけるためのレコードなので、このコマンドを実行すると www.example.com のIPアドレスが取得できます。

これまでネットワークインフラ系の技術とは無縁の生活を送ってきましたが、DNSレコードの設定が自分事になることでこれらDNSレコードの役割についてより深く理解できた気がします。

おわりに

kromiii

一カ月という短い期間でしたが、実際にロリポップのコードを触ることができてとても楽しかったです。ロリポップは10年ほど前に私が初めてペパボを知るきっかけになったサービスなので、今回その裏側をのぞくことができたのは感慨深いものがありました。

またネットde診断は今年リリースされたばかりの新しいサービスで、レンタルサーバー事業者としては先進的な取り組みになると思います。 実際のリリースはもう少し先になると思いますが、GMOインターネットグループの強みとして、イエラエのセキュリティ技術を生かしたサービスを提供してユーザーに唯一無二の価値を届けたいと思います。

n01e0

診断のハードルを下げるこのプロジェクトに関わることができたのは非常に嬉しいです。また、早い段階から関わることで、納得の行く設計にできました。

セキュリティに関わる話なのでブログには書けないこともありますが、イエラエのみなさんにも協力していただいたので、よいプロダクトとしてリリースできることを楽しみにしています。