page_adsence

2015年7月24日金曜日

phpファイルをテキストファイルとして返却する

Web上で差分を確認するために、phpファイルを「text/plain」として返却する必要があった。
(phpファイルとして解釈されてしまうとパラメータとか諸々展開されてしまうので、正確な差分が取れない)
ただ、差分を確認するためにいちいちテキストファイルにして比較とかはしたくなかったので、
.htaccessファイルを使って、phpファイルはテキストファイルとして解釈するようにした。
その設定がこちら。
php_flag engine off
AddType text/plain php

2015年7月23日木曜日

vagrant haltやsuspendコマンドが使えない

ansible-playbookを処理途中で「Ctrl + C」した影響か、vagrant haltやsuspendコマンドを実行すると下記の様なエラーが出るようになってしまった。
ちなみに、vagrant statusやvagrant sshは普通に使えました。

$ vagrant halt
An action 'halt' was attempted on the machine 'default',
but another process is already executing an action on the machine.
Vagrant locks each machine for access by only one process at a time.
Please wait until the other Vagrant process finishes modifying this
machine, then try again.

If you believe this message is in error, please check the process
listing for any "ruby" or "vagrant" processes and kill them. Then
try again.

原因はホストマシン側(自分の場合はWindows)で動いているrubyによるものらしい。
vagrantコマンドを実行するとホストマシン上でrubyが実行されるのですが、
コマンドの処理終了のタイミングでrubyのプロセスも切れる様になっている。
しかし、このメッセージが出ている時は、rubyのプロセスが切れずに残り続けている状態になっていた。
対応としては、該当のrubyのプロセスを切ってやればいい。
タスクマネージャーを開くと、ruby.exeというプロセスが残っているはずなので、それを右クリックしてプロセス終了をクリック。
終了したら通常通りvagrant haltやsuspendなどが使えるようになりました。

2015年7月22日水曜日

vagrantのバージョンアップしてみた

同僚の人がansible-playbookがうまくいかないとの事だったので、その人と環境を揃える為にvagrantのバージョンを1.6.5から最新の1.7.3に上げてみた。
vagrant自体のバージョンアップは簡単だけど、ちょっと面倒臭い。
旧バージョンをアンインストールして再起動、新バージョンをインストールして再起動すれば完了。
作業自体は単純ですが、Windowsの再起動が遅すぎてすごく時間が掛かった。
SSDに換装してほしい・・・。

Virtualboxのバージョンアップも行ったがこちらはインストーラーを使ってインストールするだけでバージョンアップされる。
両方のバージョンアップが終わった所で、諸々確認していく。
最終的に確認する内容としては、ansible-playbookを実行して、VM上の環境がきちんと出来上がるかどうかを確認する。

まず、1.6.5の時に作ったVMは不要になったので、一度削除して作りなおす事にした。
Cygwin上から下記のコマンドを実行。
$ vagrant destroy
Vagrant is attempting to interface with the UI in a way that requires
a TTY. Most actions in Vagrant that require a TTY have configuration
switches to disable this requirement. Please do that or run Vagrant
with TTY.

今までは普通に削除出来たのに、vagrantのバージョンを上げた途端に削除出来なくなってしまった・・・。
原因はまだ調べていないが、下記の様にオプションをつけることで削除することは可能。
$ vagrant destroy --force
==> default: Destroying VM and associated drives...

Vagrantfile自体は特に変更する必要がなかったので、vagrant upした。
$ vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Importing base box 'centos64-100g'...
==> default: Matching MAC address for NAT networking...
==> default: Setting the name of the VM: vm-test
==> default: Clearing any previously set network interfaces...
==> default: Preparing network interfaces based on configuration...
    default: Adapter 1: nat
    default: Adapter 2: hostonly
==> default: Forwarding ports...
    default: 22 => 2231 (adapter 1)
==> default: Running 'pre-boot' VM customizations...
==> default: Booting VM...
==> default: Waiting for machine to boot. This may take a few minutes...
    default: SSH address: 127.0.0.1:2231
    default: SSH username: vagrant
    default: SSH auth method: private key
    default: Warning: Connection timeout. Retrying...
    default: Warning: Remote connection disconnect. Retrying...
    default:
    default: Vagrant insecure key detected. Vagrant will automatically replace
    default: this with a newly generated keypair for better security.
    default:
    default: Inserting generated public key within guest...
    default: Removing insecure key from the guest if it's present...
    default: Key inserted! Disconnecting and reconnecting using new SSH key...
==> default: Machine booted and ready!
==> default: Checking for guest additions in VM...
==> default: Configuring and enabling network interfaces...
==> default: Mounting shared folders...
    default: /vagrant => C:/cygwin64/home/user_name/VirtualBoxMachines/vm-test

赤い文字の部分が多分バージョンアップ後に新しくデータメッセージで、
安全じゃない鍵があったから、より安全な新しい鍵ペアに置き換えるよというメッセージが出ていた。
今まで使っていた1.6系だと、1ユーザーに付き1個の鍵が生成されていて、複数のVMを作ってもその1つの鍵を使いまわして接続ができたが、1.7系にすると1台に付き1個の鍵が生成される(vagrant up時)。
設定を今まで通りの状態でPlaybookを実行すると、下記の様なエラーが出てしまう。

.ssh/configに書かれている鍵情報が古いバージョンの時の鍵のままになっている場合に出るエラー

$ ansible-playbook setup.yml

PLAY [vm-grp] *************************************************************

GATHERING FACTS ***************************************************************
fatal: [vm] => SSH Error: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).
    while connecting to 192.168.33.10:22
It is sometimes useful to re-run the command using -vvvv, which prints SSH debug output to help diagnose the issue.

TASK: [check selinux off] *****************************************************
FATAL: no hosts matched or all hosts have already failed -- aborting


PLAY RECAP ********************************************************************
           to retry, use: --limit @/home/user_name/setup.retry

vm                  : ok=0    changed=0    unreachable=1    failed=0

新しい鍵を使うために、.ssh/configを書き換える

Host vm-test
  HostName 192.168.33.10
  Port 22
  User vagrant
  #IdentityFile C:\Users\user_name\.vagrant.d\insecure_private_key <- コメントアウト
  IdentityFile /home/user_name/VirtualBoxMachine/vm1/.vagrant/machines/default/virtualbox/private_key <- 追記

ファイルのパーミッションで出るエラー

$ ansible-playbook setup.yml

PLAY [vm-grp] *************************************************************

GATHERING FACTS ***************************************************************
fatal: [vm] => SSH Error:     while connecting to 192.168.33.10:22
It is sometimes useful to re-run the command using -vvvv, which prints SSH debug output to help diagnose the issue.

TASK: [check selinux off] *****************************************************
FATAL: no hosts matched or all hosts have already failed -- aborting


PLAY RECAP ********************************************************************
           to retry, use: --limit @/home/user_name/setup.retry

vm                  : ok=0    changed=0    unreachable=1    failed=0

上記の様なパーミッションのエラーになったら確認する場所としては、下記が挙げられる。
※下記のパーミッションになっていることを確認する
~/.ssh -> 700
~/.ssh/config -> 744
.vagrant/machines/default/virtualbox/private_key -> 700

上記の対応をしたらちゃんとansible-playbookが実行できた。

2015年7月7日火曜日

久しぶりのOAuth1.0にハマった

ものすごく久々にOAuth周りを触っていたのですが、色々とハマってしまったのでメモを残す。
以前のメモはあまり役に立ちませんでした・・・。
OAuthのライブラリはGoogleのOAuth.php
http://oauth.googlecode.com/svn/code/php/OAuth.php

今回ハマった内容としてはものすごく単純でした。
既存のソースでCURLOPT_POSTFIELDSに対してリクエストパラメータの配列が配列の状態のまま渡っていたため、
BaseStringとかがすごい事になっていたのですが、そうなっている原因がすぐに分からず修正に時間がかかってしまった・・・。

例)HMAC_SHA1の形式でGETリクエストの場合

<?php
include_once 'oauth.php';

$consumerKey    = 'XXXXXXXXXXXX';
$consumerSecret = 'XXXXXXXXXXXX';
$accessToken    = null;
$method         = 'GET';
$url            = 'http://XXXX/XXX.php';
$request_params = array(
    'a' => 1,
    'b' => 2
);

$OAuthConsumer        = new OAuthConsumer($consumerKey, $consumerSecret);
$OAuthSignatureMethod = new OAuthSignatureMethod_HMAC_SHA1();

$OAuthRequest = OAuthRequest::from_consumer_and_token($OAuthConsumer, $accessToken, $method, $url, $request_params);
$OAuthRequest->sign_request($OAuthSignatureMethod , $OAuthConsumer, $accessToken);

list($buf, $OAuthAuthorization) = explode(':', $OAuthRequest->to_header(''), 2);

$OAuthAuthorizationHeader  = array(
    'Authorization:'.$OAuthAuthorization,
);

$ch   = curl_init();

curl_setopt($ch, CURLOPT_URL,            $url.'?'.http_build_query($request_params));
curl_setopt($ch, CURLOPT_HEADER,         true);
curl_setopt($ch, CURLOPT_HTTPGET,        true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HTTPHEADER,     $OAuthAuthorizationHeader);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch, CURLOPT_TIMEOUT,        30);

$res = curl_exec($ch);

例)HMAC_SHA1の形式でPOSTリクエストの場合

<?php
$consumerKey    = 'XXXXXXXXXXXX';
$consumerSecret = 'XXXXXXXXXXXX';
$accessToken    = null;
$method         = 'POST';
$url            = 'http://XXXX/XXX.php';
$request_params = array(
    'a' => 1,
    'b' => 2
);

$OAuthConsumer        = new OAuthConsumer($consumerKey, $consumerSecret);
$OAuthSignatureMethod = new OAuthSignatureMethod_HMAC_SHA1();

$OAuthRequest = OAuthRequest::from_consumer_and_token($OAuthConsumer, $accessToken, $method, $url, $request_params);
$OAuthRequest->sign_request($OAuthSignatureMethod , $OAuthConsumer, $accessToken);

list($buf, $OAuthAuthorization) = explode(':', $OAuthRequest->to_header(''), 2);

$OAuthAuthorizationHeader  = array(
    'Authorization:'.$OAuthAuthorization,
    'Content-Type: application/x-www-form-urlencoded',
);

$ch   = curl_init();

curl_setopt($ch, CURLOPT_URL,            $url);
curl_setopt($ch, CURLOPT_HEADER,         true);
curl_setopt($ch, CURLOPT_POST,           true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HTTPHEADER,     $OAuthAuthorizationHeader);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch, CURLOPT_TIMEOUT,        30);
curl_setopt($ch, CURLOPT_POSTFIELDS,     http_build_query($request_params));

$res = curl_exec($ch);

署名をチェック

<?php
include_once 'oauth.php';

$OAuthConsumerKey    = 'XXXXXXXXXXXX';
$OAuthConsumerSecret = 'XXXXXXXXXXXX';

$request              = OAuthRequest::from_request();
$OAuthSignatureMethod = new OAuthSignatureMethod_HMAC_SHA1();
$consumer             = new OAuthConsumer($OAuthConsumerKey, $OAuthConsumerSecret);

if ($OAuthSignatureMethod->check_signature($request, $consumer, null, $request->get_parameter('oauth_signature'))) {
        echo 'This signature is OK.';
} else {
        echo 'This signature is NG.';
}