※ パクレゼルヴではWeb開発エンジニアを大募集中!詳細はこちら

Archive

Author Archive

ProxyCommandを使った踏み台サーバー経由のssh接続

2009/3/1 日曜日 2:54:29

MacやLinuxなど、sshクライアントにsshコマンドを使っている方のためのお話

夜間や休日で緊急事態のときは家からリモートメンテナンスを行うことがあるかと思います。
その際に、インターネットからサービスを行っているサーバーに直接sshでログインできるようにしておくのは不安がありますので、社内の特定のサーバーからのみ許可するようになっていることがあります。

この様な運用形態の場合、一度社内のサーバーにログインして、それから再度 sshコマンドで対象となるサーバにログインすることになり、一手間増えてしまいます。
できればワンステップでログインしたいところです。

sshコマンドにオプションをつけることで、ワンラインでログインできます。

ssh -o 'ProxyCommand ssh ユーザ名@中継サーバー nc %h %p' ユーザ名@ターゲットサーバー

これで一度にログインできるのですが、ProxyCommandと毎回入力するのは面倒なので、できれば更に短くしたいところです。

ローカルの ~/.ssh/config に以下のように記述しておくことで一度にログインできるようになります。

Host ターゲットサーバー
ProxyCommand ssh ユーザ名@中継サーバー nc %h %p

ターゲットサーバー名はワイルドカードが使えますので、*.xxxx.jpのような指定が可能です。

これで、

ssh ユーザ名@ターゲットサーバー

だけでログインできるようになります。

MacでSFTPおよびSCPクライアントを使用する場合は、Fuguを使用すると、~/.ssh/configに記述した内容を解釈し接続してくれます。
現時点ではCyberduckは中継をサポートしていませんので、Fuguを使用するとよいでしょう。

マカー Tips, ssh

存在するファイルはスルーしたい(mod_rewrite)

2009/2/7 土曜日 17:21:05

mod_rewriteのお話。
ファイルが存在する場合はそのファイルを表示し、存在しない場合はindex.phpを表示するようにしたい。
よくある例が以下のようになっているるのですが、実際にはうまく動かないことがあります。

RewriteEngine on
RewriteBase /
# ファイルが存在しない且つ、ディレクトリが存在しない場合は、index.phpを表示
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^$ /index.php [L,QSA]
RewriteRule ^(.*)$ /index.php?jb=$1 [L,QSA]

以下のように書くと期待通りに動作します。

RewriteEngine on
RewriteBase /
# ファイルが存在するか、ディレクトリが存在する場合は、そのファイルを表示する
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.* - [L]
# ファイルが存在しない且つ、ディレクトリが存在しない場合は、index.phpを表示
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^$ /index.php [L,QSA]
RewriteRule ^(.*)$ /index.php?jb=$1 [L,QSA]

これで目的は達成されるのですが、最初の例でなぜうまくいかないのか納得できないのです。
この挙動について説明できる方がおられれば、ご教授いただけると幸いです。

マカー Apache, Tips

PHPによるデーモンプロセスの作り方(その1)

2008/4/6 日曜日 15:57:02

マカーです。

2回に分けてPHPによるUNIXデーモンの作成方法について説明します。
PHPは他のLightweight Languageに比べてWeb開発言語という印象が強いですが、PHPでもデーモンを作ることもできます。

デーモンってなんだ?

メモリに常駐しバックグラウンドで様々なサービスを提供するプログラムです。

PHPで作ると何がうれしい?

C言語ではなくPHPで開発する事で、開発期間を短縮することが出来ます。

デーモンを開発する上で押さえるべきポイント

デーモンを開発する上で押さえるべきポイントは以下の通りです。
どんな言語を使う場合であっても共通です。

  1. セッションを現在のプロセスから独立させる。
    デーモンはバックグラウンドで動作する為、制御端末から切り離します。
    setsidにより行いますが、setsidは親プロセスで呼ぶと失敗するため、
    forkで子プロセス生成し、子プロセスでsetsidを呼び出します。
    再びforkして、親プロセスを終了することで、制御端末を持たなくなります。
  2. シグナルにより終了を行う。
    プロセスを終了させる方法としてシグナルを使いますので、シグナルを処理できるようにします。
    処理する必要のあるシグナルとしてSIGHUP、SIGTERM、SIGCHLDがあります。
  3. カレントディレクトリをルートディレクトリ”/”に変更する。
    デーモンのカレントディレクトリである為に、管理者がファイルシステムをアンマウントできなくなるといった事態を防ぐ為に行います。
    ルートディレクトリ以外にデーモンの処理に必要なファイルのあるディレクトリに移動する方法もあります。
  4. ファイルのアクセス権を確実に設定する為、umaskをクリアする。
    ファイルのパーミッションを制御できるようにする為に行います。パーミッションはumaskの影響を受けますが、継承したumaskがどのようになっているのか分からないためです。

サンプルコード

以下、デーモンのスケルトンコードを示します。

#!/usr/bin/php

<?php
declare(ticks = 1);

define('MAX_SIG_QUEUE_LEN', 1024);

function sig_handler($signo = NULL)
{
	static $s_signo = array();
	if (is_null($signo))
		return array_shift($s_signo);

	$s_signo[] = $signo;
	if ( count($s_signo) &gt;= MAX_SIG_QUEUE_LEN )
		array_shift($s_signo);
}

function daemonize()
{
	if ( pcntl_fork() != 0 )
		exit;
	posix_setsid();
	if ( pcntl_fork() != 0 )
		exit;

	chdir("/");
	umask(0);

	pcntl_signal(SIGTERM, "sig_handler");
	pcntl_signal(SIGHUP, "sig_handler");
	pcntl_signal(SIGCHLD, "sig_handler");
}

daemonize();
$living = TRUE;
while($living)
{
	$signo = sig_handler();

	switch ($signo)
	{
	case SIGTERM:   // 終了シグナル
		$living = FALSE; // 終了
		break;
	case SIGHUP:	// HUPシグナル
		// デーモン再起動処理
		break;
	case SIGCHLD:   // 子プロセスが終了した場合
		// 子プロセスのリソースの回収
		pcntl_waitpid(-1, $status, WNOHANG);
		break;
	case NULL:	  // シグナルがない場合
		sleep(1);   // 適当な処理
		break;
	default:
	}
}

今回は、こんな所で。
次回は一般のデーモンが行うその他の処理について補足したいと思います。

マカー Linux, PHP, その他

LinuxやMacでのシリアル接続について

2008/2/28 木曜日 23:50:40

初めまして、マカーです。
どうぞよろしくお願いいたします。

余談:Macユーザー増えてます

MacBook Airいきなり余談から始まります(笑
先日、Rails勉強会に参加しましたところ、参加者の持参ノートPCの半分以上がMacで、ちょっと感動しました。
しかも発売したばかりのMacBook Airの台数が非常に多かったことに驚きました。

MacはUNIXベースですので、LeopardにはRuby on Railsが標準でインストールされていたり、Web開発者にとっては非常に良い環境だと思います。

Web開発者以外にとってはどうなんでしょう?
そこはコメントを控えるということで(笑

また、うちの社長もMacBook Airにしちゃったようです。

そんな感じで、Macユーザー増えているなぁというのが最近感じるところです。

本題:LinuxやMacでのシリアル接続

さて、本題の方に入りますが、ルータやインテリジェントスイッチ等の機器を設定する場合に、シリアル接続でコンソールを使うことが良くあります。
Windowsの場合、OS付属のハイパーターミナルやTeraTermなどの端末エミュレータを使用します。

MacやLinuxの場合、IP接続の場合はtelnetやsshというコマンドを使用しますが、シリアル接続の場合はどうしたら良いのでしょう?

シリアル接続できる端末エミュレータとしてscreenというプログラムがあります。

使用方法は下記の通りです。

screen デバイス名

デバイス名は、OSによって多少異なります。
Linuxの場合、COM1が/dev/ttyS0というデバイスになりますので、

$ screen /dev/ttyS0

で、COM1に繋がります。

Macの場合、現在の機種は標準ではシリアルポートがありませんので、USBシリアルコンバータを使用することになりますが、デバイス名は使用しているものにより異なります。

例えば、KeyspanのUSA-49Wでポート1の場合、デバイス名が/dev/tty.USA49W1d1P1.1となっています。

デバイス名は /dev/tty. で始まりますので、

$ ls /dev/tty.*

と入力して、どんなデバイスがあるか調べてみると良いでしょう。

通信設定の変更

通信設定を変更したい場合は、sttyコマンドをあわせて使います。

9600ボー、8ビット、パリティなし、ストップビット1であれば

$ stty 9600 cs8 -parenb cstopb
$ screen /dev/tty.USA49W1d1P1.1

で行えます。

終了方法

終了したい場合は、C-a C-\で行えます。

C-aはデフォルトのエスケープキー、C-\で終了です。
エスケープキーのカスタマイズは ~/.screenrc で行えます。

いかがでしたか?
本日はこんなところで。
またお会いしましょう!

マカー Linux, Mac OS X