Google Secure Data Connectorを利用してFW内のデータをAppsと連携する
Google Secure Data Connector(以下SDC)は、Google Appsとイントラネットのデータを安全に連携するために提供されているGoogle Appsの一機能です。
SDCを利用して、連携できるAppsのサービスには
- Google AppEngine(ドメイン制限をかける)
- Google Apps Script
- Google Sites
- Google SpreadSheet
があります。
Appsとイントラネットの連携は、SDCエージェントをイントラネットにインストールしてSSLトンネリングで通信します。
接続はSDC Agent(図中のSecure Data Connector)からTunnel Serversに対して行われるので、デフォルトではアウトバウンドの443ポートのみ空けてあれば基本的な通信は可能です。環境によってはFWの設定なしでも利用できてしまいます。
今回は、SDCをイントラネットと連携する手順を一通り試してみました。
- Appsの設定
- SDCエージェントのインストール
- AppEngineアプリケーションの作成
アプリケーションは、infoScoopのSaaSであるinfoScoop for Google Appsとの連携をターゲットとしているのでSites用のガジェットではなくAppEngineを選択しています。
今回はEC2インスタンスのローカルに立てたApacheをイントラネットのサービスに見立ててテストプログラムを作成しました。
つまりは、本来DMZに置かれるSDC Agentと同じく、サービスも同一セグメントのDMZに配置されている環境と言えます。
試した環境の構成は以下ようになります。
EC2インスタンスのセキュリティグループの設定は以下の通り。インバウンドで空けているのはssh(22ポート)のみです。
以下、http://code.google.com/intl/ja/securedataconnector/docs/1.3/config.htmlにしたがって、SDCのインストールとAppsの設定を行い、その後、作成したAppEngineのアプリケーションのサンプルについて解説していきます。
Java 1.6のインストール
SDCはJavaのプログラムですので前提条件としてJava1.6以上がインストールされている必要があります。
EC2のAmazon Linuxは1.6のOpenJDKがインストールされているので、とりあえずそれを使います。
$java -version java version "1.6.0_20" OpenJDK Runtime Environment (IcedTea6 1.9.1) (amazon-44.1.9.1.21.amzn1-x86_64) OpenJDK 64-Bit Server VM (build 19.0-b06, mixed mode)
SDCのダウンロードとインストール
SDCをダウンロードして解凍します。2011/4/22現在の最新版は1.3-rc2です。
$ wget http://google-secure-data-connector.googlecode.com/files/google-secure-data-connector-1.3-rc2-all.zip $ unzip google-secure-data-connector-1.3-rc2-all.zip
ダウンロードサイトはこちら: http://code.google.com/p/google-secure-data-connector/downloads/list
Apps管理画面でSDCを有効にする
Appsの管理画面の[高度なツール]タブの[Secure Data Connector]を表示します。
[Secure Data Connector有効にして設定]リンクをクリックします。
[有効化]にチェックして、[SDC Agent パスワード]を設定して[変更を保存]します。
次にsecure-data-connector-userの画像認証をアンロックします。
しかし、google accountsのアカウントとAppsアカウントが統合された後に変更されたのが原因なのか分かりませんが、開発ドキュメントにあるURL「https://www.google.com/a/<ドメイン名>/UnlockCaptcha」では「ユーザ名とパスワードが一致しません」とエラーになってしまいました。
とりあえず、Google Accountsの以下のURLで画像認証を外しました。
https://www.google.com/accounts/UnlockCaptcha
(後述しますが、最初に起動した際は認証エラーでSDCサーバーへ接続できませんでした、画像認証のアンロックができていないのが原因かと思い上記の手順で無理やりアンロックしましたが、その後もmypasswordファイルの設定に気づかず認証エラーになってしまっていたので、画像認証のアンロックが実際に有効だったのかどうかは不明です)
Google Appsへの接続を設定する
設定はconfig/localConfig.xmlに記述します。
$ cd data-connector-agent/config $ vi localConfig.xml
apps-secure-data-connector.google.com 443 co-meeting.com secure-data-connector-user xxxyyyzzz agent1_co-meeting-com 1080
設定するのは赤字の箇所のみでが、一通り解説。
- sdcServerHost: Google側のSDCサーバーのホスト名なので設定はそのまま。
- sdcServerPort: Google側のSDCサーバーの通信ポートなので設定はそのまま。
- domain: Google Appsのドメインを指定します。
- user: 管理画面で確認した固定のSDC Agentユーザ名「secure-data-connector-user」を指定するので、そのままです。
- password: 管理画面で設定したSDC Agentパスワードを指定します。注意: 1.3-rc2では、起動シェルstart.shから呼び出されるrunagent.shをそのまま使う場合この設定は無視されます。
- agentId: SDC AgentのIDを指定します。例の通り「agent1_<ドメイン名>」などを設定してください。英数字と_-のみが利用可能です。
- socksServerPort: 1080を他のサービスで利用していない場合はそのまま。
- healthCheckGadgetUsers: ヘルスチェックガジェットにアクセスするユーザを指定しますが、とりあえず今回は使わないので空のまま。
config/mypasswordにパスワードを設定する。
前述の通り、起動シェルをそのまま使う場合、SDCサーバに接続するパスワードはlocalConfig.xmlのpassword要素の値ではなくconfig/mypasswordに記述した値が使用されます。
シェルを編集しない場合は、mypasswordにパスワードを設定してください。
$ vi config/mypassword
xxxyyyzzz
ちなみに、com.google.dataconnector.client.Clientのソースを見ると以下の様に記述されているので、mypasswordファイルを消すか、runagent.shを適当に編集すればlocalConfig.xmlの値が使われます。
if (localConf.getPasswordFile() != null) { String password = new FileUtil().readFile(localConf.getPasswordFile()); localConf.setPassword(password); }
リソースルールを設定する
リソースルールはローカルドメインにアクセス可能なユーザを指定します。
$ vi resourceRules.xml
デフォルト設定は親切にたくさん書いてありますが、今回はAppEngineからのアクセスに関する設定のみしてみます。
1 agent1_co-meeting-com adimn@co-meeting.com AppEngine hello-sdc http://localhost/news.feed URLEXACT
イントラネットのホストへアクセスするためのURLは各rule要素に指定します。
- ruleNum: SDCの処理が実行される順番を整数で指定します。
- agetnId: localConfig.xmlに指定したagentIdを指定します。allはドキュメントには将来対応すると書いてありますが、現在のバージョンで動作するかは未確認です。
- viewerEmail: URLで指定されるリソースにアクセス可能なユーザのEmailアドレスを指定します。これはこの組織の人に公開とかするには面倒くさいのか?
- apps: 連携するサービスの設定を含みます。
- service: 「AppEngine」、「Apps Script」、「Gadgets」、「Spreadsheets」のいづれかを指定
- appId: service要素に「AppEngine」を指定した場合はアプリケーションID(http://<ここ>.appspot.com)、「Gadgets」の場合はガジェットのURLを指定します。
- allowAnyAppId: service要素に「Spreadsheets」を指定した場合は、値trueを指定します。
- url: アクセスするリソースのURLを指定します。
- urlMatch: url要素に指定したURLの適用方法について指定します。
- HOSTPORT: 指定したホスト名とポート名が合って入れば任意のパスに対してアクセスできます。
- URLEXACT: 指定したURLのパスにのみアクセスを許可します。クエリーパラメータは任意です。
SDC Agentの起動
起動はroot権限のあるユーザで実行します。
$ sudo ./bin/start.sh
起動の確認
log/agent.logに以下の様なログが出力されればSDCサーバーへ接続成功です。
$ vi log/agent.log
******************************************************************* Date: 2011年 4月 25日 月曜日 07:15:43 UTC Config directory: Runtime directory: /home/ec2-user/data-connector-agent PID file: /home/ec2-user/data-connector-agent/agent.pid args = Password file = /home/ec2-user/data-connector-agent/config/mypassword Run: /usr/bin/java -Djava.net.preferIPv4Stack=true -jar /home/ec2-user/data-connector-agent/lib/sdc-agent.jar -localConfigFile "/home/ec2-user/data-connector-agent/config/localConfig.xml" -rulesFile "/home/ec2-user/data-connector-agent/config/resourceRules.xml" -log4jPropertiesFile "/home/ec2-user/data-connector-agent/config/log4j.properties" -passwordFile "/home/ec2-user/data-connector-agent/config/mypassword" log4j:ERROR Could not find value for key log4j.appender.A.layout 25 4 2011 07:15:45,904 [main] INFO com.google.dataconnector.client.SdcConnection - Connecting to SDC server 25 4 2011 07:15:45,908 [main] INFO com.google.dataconnector.util.SSLSocketFactoryInit - Using SSL for client connections. Setting iddle timeout to 60000 ms. Setting accept timeout to 60000 ms. Setting udp timeout to 600000 ms. 25 4 2011 07:15:45,918 [com.google.dataconnector.client.JsocksStarter] INFO com.google.dataconnector.client.JsocksStarter - Starting JSOCKS listener thread on port 1080 25 4 2011 07:15:45,923 [com.google.dataconnector.client.JsocksStarter] INFO net.sourceforge.jsocks.socks.ProxyServer - Starting SOCKS Proxy on:127.0.0.1:1080 25 4 2011 07:15:47,056 [main] INFO com.google.dataconnector.client.SdcConnection - Sending initial handshake msg 25 4 2011 07:15:47,056 [main] INFO com.google.dataconnector.client.SdcConnection - Attemping login 25 4 2011 07:15:47,839 [main] INFO com.google.dataconnector.client.SdcConnection - Successful login 25 4 2011 07:15:47,849 [main] INFO com.google.dataconnector.registration.v4.Registration - Sending resources info agentId: "agent1_co-meeting-com" socksServerPort: 1080 healthCheckPort: 65535 resourceKey { ip: "localhost" port: 80 key: 270530414318891608 } resourcesXml: "<resourceRules>\n <rule repeatable=\"true\">\n <ruleNum>1</ruleNum>\n <agentId>agent1_co-meeting-com</agentId>\n <viewerEmail repeatable=\"true\">adimn@co-meeting.com</viewerEmail>\n <apps repeatable=\"true\">\n <service>AppEngine</service>\n <appId>hello-sdc</appId>\n </apps>\n <url>http://localhost/news.feed</url>\n <urlMatch>URLEXACT</urlMatch>\n </rule>\n</resourceRules>\n" 25 4 2011 07:15:47,854 [main] INFO com.google.dataconnector.util.SdcKeysManager - Adding rule for Pair[localhost, 80] 25 4 2011 07:15:47,858 [main] INFO com.google.dataconnector.client.SdcConnection - Starting hearbeat/ health check thread. 25 4 2011 07:15:47,863 [main] INFO com.google.dataconnector.client.SdcConnection - starting a thread to watch resources file 25 4 2011 07:15:47,864 [com.google.dataconnector.client.HealthCheckHandler] INFO com.google.dataconnector.client.HealthCheckHandler - healthcheck config is not yet received from the SDC server. will check again in 5 sec 25 4 2011 07:15:48,329 [main] INFO com.google.dataconnector.registration.v4.Registration - registration successful. Received config info from the SDC server ...
SDCと連携するAppEngineアプリケーションの作成
AppEngineから外部リソースの取得はURLFetchServiceを利用しますが、SDCの通信を通したリソースの取得も同様にURLFetchServiceを利用します。これまでの設定が終わっていれば、以下の様に通常の呼び出しにSDC通信用のヘッダーを指定するだけです。
from google.appengine.api import urlfetch result = urlfetch.fetch(url="http://www.corp.example.com/sales.csv", headers={'use_intranet': 'yes'}) if result.status_code == 200: parseCSV(result.content)
上記は、Pythonのコードです。以下に載せているシンプルなアプリケーションもPythonで記述しています。
Java版はSDCの開発ガイドに完全なサンプルの解説がありますのでそちらを参考にしてください。http://code.google.com/intl/ja/securedataconnector/docs/1.0/tutorials/appengine.html
また、Python版のAppEngine SDKの環境構築については以下を参考にしてください:
- スタートガイド: Python: http://code.google.com/intl/ja/appengine/docs/python/gettingstarted/
- Google App Engine for Pythonの開発環境をUbuntu 10.04に構築する: http://d.hatena.ne.jp/hrendoh/20101210/1291950506
アプリケーションの登録
まず、AppEngineの管理画面(https://appengine.google.com/)から新規にアプリケーションを登録します。
SDCと連携するアプリケーションは、自社ドメインにのみ公開することがほとんどかと思います。
この場合、[Open to all Google Accounts users (default)]の[Edit]をクリックして[Restricted to the following Google Apps domain:]を選択、ドメインを指定します。
次にAppsにAppEngineのアプリケーションを登録します。
https://appengine.google.com/から登録したアプリケーションを選択します。
[Application Settings]を開き[Domain Setup]の[Add Domain...]をクリックします。
アプリケーションを利用するドメインを入力して[Add Domain...]をクリックします。
指定したドメインのAppsのログイン画面が表示されるのでログインします。
Google App Engineの利用規約に[同意]にチェックし[このサービスを有効にする]をクリックします。
以上で、ドメインでAppEngineのアプリケーションが利用可能になります。
hello-sdc.py
Google Tunnel Servers - SDC Agentを介してhttp://localhost/news.feedからRSSを取得して表示する簡単なサンプルは以下の通りです。
from google.appengine.api import users from google.appengine.ext import webapp from google.appengine.ext.webapp.util import run_wsgi_app from google.appengine.api import urlfetch from xml.etree.ElementTree import * user = users.get_current_user() class MainPage(webapp.RequestHandler): def get(self): user = users.get_current_user() if user: #url = 'http://www.infoscoop.org/index.php/ja/news.feed' url = 'http://localhost/news.feed' result = urlfetch.fetch(url, headers={'use_intranet': 'yes'}) self.response.headers['Content-Type'] = 'text/html; charset=utf-8' if result.status_code == 200: rss = fromstring(result.content) for item in rss.getiterator('item'): title = item.find('title') link = item.find('link') self.response.out.write(''+ title.text + '
') else: self.redirect(users.create_login_url(self.request.uri)) application = webapp.WSGIApplication( [('/', MainPage)], debug=True) def main(): run_wsgi_app(application) if __name__ == "__main__": main()
返すHTMLはかなり適当です。
XMLの処理は、標準ライブラリに含まれるxml.etree.ElementTreeを利用しました。
http://docs.python.org/library/xml.etree.elementtree.html#
app.yml
application: hello-sdc version: 1 runtime: python api_version: 1 handlers: - url: /.* script: hello-sdc.py
サンプルは以上2ファイルです。
AppEngineへのデプロイします。
テスト用のRSSフィードを用意
ローカルにApacheをインストールしてルートにRSSを置きます。
$ sudo yum install httpd $ cd /var/www/html/ $ sudo wget http://www.infoscoop.org/index.php/ja/news.feed $ sudo /etc/init.d/httpd start
動作の確認
「http://hello-sdc.appspot.com/」にアクセスすると、Appsドメインのログイン画面が表示されます。
ログインすると以下の様にRSSのアイテムが表示されました。(RSSはinfoScoopのニュースを拝借しています)