セキュリティ上、クラウドサービスを業務に使ってはならないとき・・・

「オンプレミスに比較して、クラウドはセキュリティが心配・・・」と言うユーザーに対して「クラウドベンダーと御社とどっちのセキュリティが上だと思ってるの?」というのは昔から良く話しとして見かける。実はクラウドサービスのセキュリティで気をつけるべき視点がひとつある。インシデント発生時に速やかな対応が可能か否かだ。

一流のクラウドベンダーならユーザー側に起因するインシデント発生時の対応も考慮されている。だが、二流三流のクラウドベンダーとなるとかなり怪しい。ユーザー側の原因でインシデントが発生した時に、影響範囲特定に必要なログ等の提供を受けられない可能性がかなり高い。例えば以下のシナリオのような状況が考えられる。

インシデントシナリオ#1
自社のWEBサービスがSQLインジェクション攻撃を受けた。この場合は影響範囲の調査にデータベースサーバの監査ログが重要な役割を果たす。もしこの時、ベンダーの提供するデータベースが他のユーザー企業とインスタンスを共有している場合、監査ログには他のユーザー企業の発行するSQL文まで含まれてしまう。ベンダー企業が監査ログをユーザー企業ごとに分割するような対策を事前に取ってない限り、迅速な対応は期待できない。

インシデントシナリオ#2
メールアカウントのユーザーIDとパスワードが漏洩して第三者が閲覧した可能性がある。この場合にはメールサーバーの認証ログを閲覧して、不自然なな時間帯や接続元からの認証、認証エラーの有無を確認したい。もしこの時、ベンダーの提供するデータベースが他のユーザー企業とインスタンスを共有している場合、そこには他のユーザー企業のログも含まれている。さらには通信事業者には通信の秘密を守る義務が課せられている。通信時間帯や接続元IPアドレスは通信の秘密に含まれるため、頑なに開示してもらえない可能性がある。こうなると被害届をだして事件化しないと、影響範囲の特定も出来なくなってしまう。

無論、きちんとしたベンダーは回答を用意している。AWS AuroraDBやSQL Azureには監査ログの機能がある。オブジェクトストレージのS3はアクセスログを提供している。GSuiteやOffice365も認証ログを提供している。

対して国内ベンダーに目を向けると、大手ベンダーでもその辺りがかなり弱い。

例えばさくらインターネットがS3互換としているオブジェクトストレージにはアクセスログの機能が無い。

あるいはNTT Communicationのメールホスティングサービスにはメールの送信ログに対する検索機能はあるが、認証ログの提供はない。法的な問題もあるので提供が難しいのは分かるが、せめて認証成功のログ程度はないとインシデント発生時に対応出来ない。

ベンダーの多くは電気通信事業者として「通信の秘密」に関する義務をおっている。何時何処と通信をおこなったかは「通信の秘密」に含まれるため、電気通信事業者としては安易にログを開示する事は出来ない。ユーザー企業に公開できるのは、ユーザー企業の管理下にあるシステムのログだけになるが、事前に準備を整えていない限り共有部分のログ提供には時間がかかる。

クラウドサービスを採用するにあたっては、セキュリティ監査に耐えるだけのログ出力機能があるか否かは確認した方が良い。もしそれらのログ出力機能が無く、インシデント発生時に相応の対応が必要なら、契約に調査対応への協力義務を盛り込む程度のことは検討しなてくはならない。

※クラウドベンダーの対応状況は2019年9月時点のもの

安価な専用サーバー・ScaleWay

参加賞で頂いたBizSparkアカウントも10月末で停止するので、そろそろ移行作業を行わないとなりません。移行先は昨年から目を付けていたScaleWayにします。

ScaleWayはちょっと変わったレンタルサーバー事業者です。ARMまたはATOMをベースとしたシンプルなワンボードコンピューターを独自開発し、この上でKVMによる仮想OSを提供しています。提供するのは仮想OSだけに限定し、様々な機能は仮想OS上でユーザーが実装すればよいと言うコンセプトです。低消費電力のCPUであるため、1Core辺りの処理能力は貧弱ですが、高速処理が必要ならスケールアウトすれば良いと言う発想です。

ScaleWayは提供する機能もCPUも貧弱ですが、その代わりめちゃくちゃ安い。ARM 4Core CPU(またはx64 2Core CPU) + RAM2GB + SSD50GBを占有して、月額2.99ユーロ(400円弱)にすぎません。この価格帯だと、他の格安サービスを探しても共有WEBサーバぐらいしか見つかりません。エンジニアにとって、サーバーまるごと占有出来るのは大きな魅力だと思います。どうしても高速処理が必要なら、ARM 64Core RAM 128GBまでスケールアップも出来ます、料金も時間単位なので必要なときだけスケールアップすると言う使い方もできます。

欠点を一つあげるなら、欧州にしかデータセンターがない事でしょうか。日本からサーバーにpingを打つと、パリもアムステルダムも280ms程度かかります。

このブログは2017年10月15日からScaleWayで動いています。ダウンロード開始までちょっともたつきますが、オールSSDな事もあって割と快適に使えているように思います。

使う上で注意点をいくつか上げておこうと思います。

アカウントを作ったら最初にSSH鍵を登録する

アカウントを作成してログインした後、WEB上からSSH公開鍵を登録します。そのために必要な公開鍵は別途作成しておかなくてはなりません。ここで登録した公開鍵が、仮想サーバを構築後、rootアカウントでログインする時のSSH鍵として設定されます。

仮想サーバーを作ったら最初にSecurity設定を

Security設定でFirewallで許可する通信ポート等を設定することが出来ます。初期状態だと何でも通すようになっています。データベース等もインターネットから接続可能な状態になってしまうので、最初に適切にポートを閉じてください。ワイルドカードで全てのポートをブロックするような設定を作れないので地味に面倒です。
デフォルトでメール送信に係わるポートが全て閉じられていることにも注意してください。メールの送信を行うには、サポートに問い合わせて、メール送信を許可して貰う必要があります。

クラウドってよくわかないんだけど・・・と言う話を聞いたので

クラウドって何か・・・クラウドって言葉の意味は使っている人ごとに違うので、そりゃ分からないです。
歴史的背景や技術的な遷移、業界事情などを把握して、クラウドなんて表現には惑わされないようになりましょう。

パソコン仮想化(2000~2004年)
クラウドの先駆けとなる技術として、仮想PC技術が広がりを見せます。VMWare WorkstationやVirtual PCなど既存のパソコン上で、パソコンのハードウェアをエミュレーションして、複数のOSを実用的に動作させる事が可能になってきました。この時点で飛びついたのは主にソフトウェア開発者などのエンジニアです。ファイルをコピーする事で他のハードウェア上に移動させたり、保存しておいたり、数時間前の状態に戻したりといった事が容易に実現できるようになりました。これ以前はテストのために何度もOSの再インストールを余儀なくされていたのです。

最初期のクラウド誕生(2003年)
2003年の終わりごろ、クリス・ピンカムとベンジャミン・ブラックはアマゾンのサーバーインフラの将来の展望についての論文を発表した。その論文では新たなサーバーインフラは完全に標準化、自動化され、ストレージやネットワークは最終的にはウェブサービスに依存することになると書かれている。またその論文の終わりでは、企業が新たなインフラ投資として仮想上のサーバーサービスが今後普及する可能性を言及されている。
2004年には極めて限定的な機能ですがAmazon Web Servicesがサービスを開始します。

サーバー仮想化(2004年~2005年)
ハードウェアレベルで仮想化をサポートするための仕組みが提供されるようになり、サーバーにも仮想化が用いられるようになります。VirtualPCを買収したMicrosoftによるVirtual Server、VMWareのVMware ESX、LinuxのXen等がでそろいます。サーバーが稼働しているときCPUは暇をしているので、仮想化を利用してサーバーを集約すればハードウェアコストを抑えられる他、サーバーの異動や再構築がファイルの複製で住むので可用性も向上し運用も楽になりました。

ですが同時に新たな問題が生まれます。規模が小さいうちはエンジニアが手作業で管理していても負荷を一様に分散させたり、負荷の低い物理サーバーを把握したり、またそれに合わせて最適化したりと言った設定を行えます。組み合わせの数は物理サーバーの台数× 物理ストレージの台数×・・・×仮想サーバーの数となるため、規模が大きくなるにつれて、人手ででの管理は到底困難な物になると考えられました。大規模システムを運用するベンダー内部で、これらの管理を自動化する方法(クラウドコンピューティング)が求められるようになります。

HaaS、PaaS、IaaSといったクラウドファームの提供開始(2006年~2010年)
「cloud computing クラウドコンピューティング」という用語の使用は、2006年のGoogleのCEOであるエリック・シュミットが使います。Google App Engine(SaaS) とか、Amazon EC2(HaaS)、Windows Azure(SaaS)と言ったクラウドサービスが出そろいます。

何でもクラウドの時代へ(2010年~2014年)
クラウドコンピューティングが成功を収めたことで、単なる仮想サーバーを提供しているサービスまでクラウド(なんちゃってクラウドと揶揄されたりする)を名乗ります。果てにはインターネットを使ったサービスであれば何にでもクラウドと付けるようになります。結果的にクラウドという用語の意味が曖昧になり、何を指しているのか分からなくなっていきます。クラウドのバズワード化です。

いまでこそ沈静化しましたが、バズワード化した影響で、人によってクラウドの意味が違ってしまっています。PaaSとかSaaS、IaaSといった用語で表現する方が、誤解無く伝わります。相手がクラウド云々言い出したら、何をさしてクラウドと言っているのかまずは確かめましょう。

開発体制を保持する(Cloud向け開発の覚書き )

クラウド向けにシステムを構築した場合、必ず自社内に開発できる体制を保持しておく。IaaSはともかく、PaaSやSaaSは仕様変更やサービス終了と無縁では居られない。仕様変更やサービス終了が告知された場合は、システムを維持するために速やかに改修する必要がある。この時に開発体制を外部に依存しているとシステムの維持に大きなリスクを負うことになる。

クラウド外にバックアップする(Cloud向け開発の覚書き )

クラウドの外にデータをバックアップする方法を検討しておく。クラウド上のデータをローカルにダウンロードしてバックアップする場合、インターネット帯域の制約を受ける。オンプレミスなら数Gbpsの帯域を使えていた物が、インターネット経由で行う場合には数十Mbps程度になってしまう。例えローカルの環境が1Gpbsでインターネットに接続していたとしても、仮想マシン側のインターネット通信帯域は数十~数百Mbps程度でしかないため、何も考えずにフルバックアップ等していては時間がかかってしかたがない。またデータ転送量も従量課金の対象となるので無駄に代金を払うことになる。
・・・ではバックアップ無しで良いかというと、そうはいかない。パブリッククラウドを使用している場合、ベンダー側の都合でサービスの使用が変更になったり、終了したり、あるいはベンダーが事業から撤退したりと言うことが常に起こる。既にHP Helion Public Cloudも撤退しているし、VMware vCloud Airは日本市場から撤退を決めている。IaaSでサービスを終了した事業者はまだそれほど多くないが、SaaSやPaaSも含めると市場から消えたサービスはさらに増える。サービスが終了したとき、他のサービスへの移行手段としてバックアップが必ず必要になる。

仮想マシンをバックアップする(Cloud向け開発の覚書き )

最低でも三重にレプリケーションされており物理障害でデータが失われる可能性は非常に少ない。とはいえ、必ずクラウドの機能を使って仮想マシンのバックアップを取得するようにしておく。
クラウドではオペレーションミスによってデータを失う可能性はむしろ高いので注意が必要になる。管理コンソールの操作ミスによって仮想マシンやストレージを削除してしまうのは勿論、仮想OSの操作ミスでSSH接続などリモートセッションの設定を破壊してしまった場合、バックアップした仮想OSを戻す事が出来なければデータ復旧は絶望的になる。
例えば私はLinuxでapt-get upgradeを実施したときに、仮想マシンのエージェントの更新がかかり、操作ミスで設定ファイルを上書きしてしまったことがある。もちろんSSHによる接続は出来ない。クラウドの管理コンソールから新しいSSHキーを設定するも動かず、バックアップされていた仮想マシンをロールバックすることで対応した。

揮発性ストレージを活用する(Cloud向け開発の覚書き)

クラウドでもオンプレミスでも、仮想OSは物理PCに比較してディスクIOのパフォーマンスが低く、この部分がボトルネックとなりやすいです。そのために頻繁なディスクIOが発生する用途ではパフォーマンスが得られにくいという欠点があります。 クラウド上の仮想マシンでのパフォーマンス改善には、仮想ディスクへのIO負荷を如何に減らすかが、最初に検討すべき重要な要素になります。
仮想PCマシン割り当てられる揮発性ストレージ(EC2では インスタンスストア)を活用できないか検討することをお勧めします。揮発性のため仮想PCが停止した場合はデータが失われますが、専用に割り当てられており、物理PCと遜色ない速度でアクセスすることが出来ます。起動後に必要なフォルダやファイルを作成したり、シャットダウン前や低周期でファイルを退避したり、一手間必要になりますが効果も大きいです。

最初からスケールアウトを考慮する(Cloud向け開発の覚書き )

オンプレミスでは当たり前に使っていたこともあり、 ついリレーショナルデータベースを使いたくなります。リレーショナルデータベースは一貫性を保つために、更新処理を排他的に実行します。頻繁なファイル更新を伴い、広大なメモリ領域を必要とするために、もともと仮想マシンとは相性が悪いのです。
Amazon RDSやAzure SQLでは仮想サーバーと相性の悪いRDBをクラウド上で利用しやすいように最適化しています。ですがスケールアウトにはすぐに限界が来ます。テーブル単位でしか分散できなかったり、無制限にスケールできるというものではないという認識が必要です。
将来的にスケールアウトを考えているなら、最初からスケールアウトに適したテクノロジを採用できないか検討する必要があります。

Traffic ServerでWORDPRESSを高速化する

最近地道にトラフィックが増えてきているので、そろそろWORDPRESSの高速化を検討してみる。世間ではNginxがはやっているようだが、ここは敢えてApatch Traffic Serverを使ってみたい。

OSはUbuntu 15.xを使用しています。

Apatche Traffic Serverの初期設定

apt-getを使用して標準のレポジトリからApatche Traffic Serverをインストールします。

sudo apt-get install trafficserver

Reverse-Proxeの接続先を設定します。

sudo nano remap.config
map http://www.example.net:8080/ http://127.0.0.1/
reverse_map http://127.0.0.1/ http://www.example.net:8080/

サービスを起動してポート8080に接続してみますが、動作しません。

sudo service trafficserver start

ログファイルを閲覧すると、以下のようなエラーが発生しています。

less /var/log/trafficserver/traffic.out
traffic_server: using root directory '/usr'
FATAL: Trafficserver has not been designed to serve pages while
        running as root. There are known race conditions that
        will allow any local user to read any file on the system.
        If you still desire to serve pages as root then
        add -DBIG_SECURITY_HOLE to the CFLAGS env variable
        and then rebuild the server.
        It is strongly suggested that you instead modify the
        proxy.config.admin.user_id directive in your
        records.config file to list a non-root user.

どうやら標準のままだとrootアカウントで起動されてしまうけど、trafficserverはrootアカウントで起動できないため権限周りでエラーとなっているようです。/etc/trafficserver/records.configを編集してproxy.config.admin.user_idの設定を追加するように指示されているので追加します。trafficserverアカウントは既に作られているので、追加の必要は無いようです。

sudo nano /etc/trafficserver/records.config
CONFIG proxy.config.admin.user_id STRING trafficserver

サービスを再起動してポート8080に接続してみると、今度は動作しました。

sudo service trafficserver restart

サービスの移行

正常に動作するようなので、本番に移行します。
Windows Azureを使っているので、エンドポイントの設定を変更してポート80への接続を、ポート8080に振り分けるようにします。こういう所、手抜きできるからクラウド好きです。

remap.configの設定を本番用に変更します。先ほどはポート8080の記載がありましたが、それを削除します。

sudo nano remap.config
map http://www.example.net/ http://127.0.0.1/
reverse_map http://127.0.0.1/ http://www.example.net/

このままだとWORDPRESSが正常に動作しないので、以下の設定をwp-config.phpに追記します。

sudo nano /var/www/wordpress/wp-config.php
$_SERVER['HTTP_HOST'] = $_SERVER['HTTP_X_FORWARDED_HOST'];
$_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_X_FORWARDED_FOR'];

apatch2とtrafficserverを再起動します。

sudo nano /var/www/wordpress/wp-config.php
$_SERVER['HTTP_HOST'] = $_SERVER['HTTP_X_FORWARDED_HOST'];
$_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_X_FORWARDED_FOR'];

ポート80に繋いでみますが、正常に動作しているようです。

ローカルストレージへのキャッシュ移動

標準設定のままだと/var/cash/trafficserverにキャッシュデータを保存します。クラウド上の仮想サーバーは一般的にIO速度が遅いため、あまり速度が改善しません。その代わりにWindows Azureでは高速な揮発性のローカルストレージも提供されています。揮発性のストレージは仮想サーバをシャットダウンすると失われますが、キャッシュデータなら失われても問題ないのでこちらに移動します。
ローカルストレージはスワップファイル用に/mntにマウントされているので、/mnt/trafficserverと言うフォルダを新たに用意してこちらを使います。

新たにフォルダを作成します
sudo mkdir /mnt/trafficserver
sudo chown trafficserver /mnt/trafficserver

storage.configを編集して、キャッシュの保存先を変更します。
sudo nano /etc/trafficserver/storage.config
/mnt/trafficserver 256M

trafficserverを再起動します。
sudo service trafficserver restart

どの程度改善されたか

トップページの表示完了まで5,000msかかっていたのが700ms程度に。トップページのhtmlだけなら2,500ms程度かかっていたのが、20ms程度にまで高速化されました。応答速度が125倍改善して、体感的にも7倍くらい速くなっている計算。

参考

WordPressをリバースプロクシ対応にする3つのポイント
How to Set Up Apache Traffic Server as a Reverse-Proxy on Ubuntu 14.04

Google Blogger API v3.0を使ってエントリを書き込む

先日、C#からGoogle Blogger API v3.0を使用した。
検索してもサンプルが見当たらなかったので、ブログを書き込むサンプルをメモとして公開しておく。

準備

Google Blogger API v3.0はNuGetからインストールします。

コード

using Google.Apis.Auth.OAuth2;
using Google.Apis.Services;
using Google.Apis.Util.Store;
using Google.Apis.Blogger;
using Google.Apis.Blogger.v3;
using Google.Apis.Blogger.v3.Data;
//...
    static void Main(string[] args)
    {
       // OAuth 認証を行う
        UserCredential credential;
        using (var stream = new FileStream("client_id.json", FileMode.Open, FileAccess.Read))
        {
            credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
                    GoogleClientSecrets.Load(stream).Secrets,
                    new[] { BloggerService.Scope.Blogger },
                    "user", CancellationToken.None);
        }

       // Bloggerのインスタンスを取得
        BloggerService service = new BloggerService(new BaseClientService.Initializer()
        { HttpClientInitializer = credential, ApplicationName = "Blogger Convert" });

       // Blogの一覧を取得
       var blogList = service.Blogs.ListByUser("self").Execute();

      // Blogに新しいエントリを作成する
       var newPost = new Post();
       newPost.Title = "blog title";
       newPost.Content = "blog body text
"; newPost.Published = DateTime.Prase("2016-01-01 12:00"); var updPost = service.Posts.Insert(newPost, blogList.Items[0].Id).Execute(); //...

ちなみにバグがあってブログのラベルを設定することは出来ない。もう随分長いこと放置されているので、修正の見込はないと思っておこう。
画像データをアップロードする機能は見当たらない。おそらくはPicasaと連携しろって事なのだとも思うけど・・・Picasaって2016年5月にサービス終了するんだよな。