GateOneをAPI認証機能有効化してアプリケーションに組み込む
GateOneには、認証機能が備わっています。
Googleの認証と連携したり、PAM認証と連携するなどができるようです。
(GateOneについては前回記事GateOneで複数のSSH接続をブラウザで統合管理 - ike-daiの日記を参照して下さい。)
今回は、GateOneを別のアプリケーションに組み込んで使う場合のAPI認証を有効化する方法を試してみます。
手順は公式マニュアルをもとに実施しています。
server.confの変更
GateOneのserver.confの設定でauth = 'api'に設定します。(デフォルトはnone)
$ vim /opt/gateone/server.conf ・・・略 auth = 'api' ・・・略
APIキーの発行
gateone.pyスクリプトを使ってAPIキーを発行します。
$ /opt/gateone/gateone.py --new_api_key [I 130322 09:35:19 gateone:2880] A new API key has been generated: MDg0MGFmY2I0YTBiNGU0OTg5NGRjMzcwNmM2NjBkNDEyA [I 130322 09:35:19 gateone:2881] This key can now be used to embed Gate One into other applications.
発行されたAPIキーの情報はserver.confのapi_keysに登録されています。
api_keys = "MDg0MGFmY2I0YTBiNGU0OTg5NGRjMzcwNmM2NjBkNDEyA:ODg0MmRhYjJkYzU0NDg2M2E4NjQ5MTk3NzY0YjkzOWQwM"
APIキー:シークレットキーのセットで書きこまれているのがわかります。
アプリケーション側の設定
次に、GateOneを組み込みたいアプリケーション側の設定です。
まず、API認証を有効にしない場合にはこのような感じでGateOneを組み込むことができます。
https://hostnameでGateOneが稼働している場合の例です。
<html> <head> <script src="https://hostname/static/gateone.js"></script> </head> <body> <div style="width: 60em; height: 30em;"> <div id="gateone"></div> </div> <span onclick="GateOne.init({url:'https://hostname/'});">Start GateOne</span> </body> </html>
gateone.jsを読み込み、GateOne.initを実行すると、
のエリアにGateOneのコンソールを表示できます。認証設定がない場合、GateOneはANONYMOUSユーザでアクセスした状態になります。
この状態では、ブックマークの情報や鍵情報が他の誰からも利用できるため、セキュリティ的にもよくありません。
そこで、このファイルを変更し、API認証を実現してみます。
API認証を実施するには、GateOne.initの実行時に認証オブジェクト({auth: auth_obj})を渡す必要があります。
認証オブジェクトは次のようなユーザ名やAPIキー等を持ったオブジェクトです。
authobj = { 'api_key': 'MjkwYzc3MDI2MjhhNGZkNDg1MjJkODgyYjBmN2MyMTM4M', 'upn': 'joe@company.com', 'timestamp': '1323391717238', 'signature': "f6c6c82281f8d56797599aeee01a5e3efab05a63", 'signature_method': 'HMAC-SHA1', 'api_version': '1.0' }
※GateOne公式マニュアルより引用
今回は試しにJavaScriptで認証オブジェクトを生成して許可するようにします。
このようになります。
<html> <head> <script src="https://localhost/static/gateone.js"></script> <script src='http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/hmac-sha1.js'></script> <script> function ConnectGateOne(){ var api_key = 'MDg0MGFmY2I0YTBiNGU0OTg5NGRjMzcwNmM2NjBkNDEyA'; var upn = 'ikeda@example.com'; var now = new Date(); var timestamp = now.getTime(); var signature_method = 'HMAC-SHA1'; var api_version = '1.0'; var secret = 'ODg0MmRhYjJkYzU0NDg2M2E4NjQ5MTk3NzY0YjkzOWQwM'; var hash = CryptoJS.HmacSHA1(api_key + upn + timestamp, secret); var signature = hash.toString(CryptoJS.enc.Hex); var authobj = { 'api_key':api_key, 'upn':upn, 'timestamp':timestamp.toString(), 'signature':signature, 'signature_method':signature_method, 'api_version':api_version } console.log(authobj); GateOne.init({auth: authobj, url:'https://hostname/'}); } </script> </head> <body> <div style="width: 60em; height: 30em;"> <div id="gateone"></div> </div> <span onclick="ConnectGateOne();">Start GateOne</span> </body> </html>
注意点としては、timestampの値を文字列型で持たせる必要がある点です。
timestampをそのまま数値型で持たせていると、GateOne内で処理する際に、signature生成処理中にエラーが発生します。
[E 130322 10:51:48 websocket:261] Uncaught exception in /ws Traceback (most recent call last): File "/usr/lib/pymodules/python2.7/tornado/websocket.py", line 258, in wrapper return callback(*args, **kwargs) File "/opt/gateone/gateone.py", line 1102, in on_message self.commands[key](value) File "/opt/gateone/gateone.py", line 1245, in authenticate secret, api_key, upn, timestamp) File "/usr/lib/pymodules/python2.7/tornado/web.py", line 2068, in _create_signature hash.update(utf8(part)) File "/usr/lib/pymodules/python2.7/tornado/escape.py", line 168, in utf8 assert isinstance(value, unicode) AssertionError
このようにすることで、GateOneへのログインユーザがikeda@example.comになります。
ログインした状態でブックマークの追加や鍵の追加を行うと、他のユーザ(ANONYMOUS等)からはこの情報は見れなくなります。
ブックマーク設定や鍵については、「/opt/gateone/users/ユーザ名」ディレクトリの配下に保存されるようになります。
今回は簡単に動作確認するためにJavaScriptでAPI認証を行う処理を記述しましたが、実際には、組み込むアプリケーション内で上記の処理を行うようにします。
PHP、Ruby、Pythonでの記述方法についてはGateOneの公式サイトに書かれているので参考にして下さい。
公式マニュアル