2007/09/05

ssh and firewall

firewall の内側の Debian マシンから, 外側にある Debian マシンへの ssh
の接続を試みているのですが, ちょっとつまづいております.

http://hp.vector.co.jp/authors/VA000770/docs/NikkeiLinux00-12/config.ja.html
を参考にしてやったことは以下の通りです.


Kernel 2.4.6 Microsoft Proxy Server 2.0
+----------------+ STDIN +------------+ +-----------+
| |------->| |-------| |
| ssh 2.5.2p2-3 | | proxy-klab | | web proxy |
| |<-------| command |<------| |
+----------------+ STDOUT +------------+ https +-----------+
Client Machine ^ |
https | | https
< inside > | |
----------Firewall--------------------------------+---+-----
< outside > kernel-2.2.19 | |
+-----------------+ | |
| |-----+ |
| ssh 2.5.2p2-3 | |
| port 443 |<--------+
+-----------------+
Server Machine


Firewall の内側にある, Microsoft Proxy Server 2.0 がうけつけているポー
トは, 80 番 (http) と, 21 番 (ftp) と, 443 番 (https) にあてたものだけ
です. やろうとしているのは, Firewall の外側にある Server Machine の
sshd サーバを, port 443 (https) で走らせ, FIrewall の内側の Client
Machine の ssh クライアントから, proxy-klab という perl script を介し
て, web proxy 経由で, Server Machine の https の 443 番ポートにアクセ
スし, ssh コネクションをはるということです.

そのために, まず, Firewall の外側にある Server Machine の
/etc/ssh/sshd_config において, 「Port 22」という記述を,「Port 443」に
書き変えて, 「/etc/init.d/ssh restart」とし, port 443 番 (https) で sshd を立ち上げ直しました.

次に, Firewall の内側にある Client Machine の ~/.ssh/config で,

Compression yes
Host ip.address.of.Server.Machine
Port 443
ForwardAgent yes
ForwardX11 yes
ProxyCommand /path/to/proxy-klab %h %p

としました. そして, 本メール末尾に添える proxy-klab という perl script
を用意し, 以下のようにすると,

# ssh -v -l UID ip.address.of.Server.Machine
OpenSSH_2.5.2p2, SSH protocols 1.5/2.0, OpenSSL 0x0090601f
debug1: Seeding random number generator
debug1: Rhosts Authentication disabled, originating port will not be trusted.
debug1: ssh_connect: getuid 1000 geteuid 1000 anon 1
debug1: Executing proxy command: /path/to/proxy-klab ip.address.of.Server.Machine 443
debug1: unknown identity file /home/UID/.ssh/identity
debug1: identity file /home/UID/.ssh/identity type -1
debug1: unknown identity file /home/UID/.ssh/id_rsa
debug1: identity file /home/UID/.ssh/id_rsa type -1
debug1: unknown identity file /home/UID/.ssh/id_dsa
debug1: identity file /home/UID/.ssh/id_dsa type -1

と, ここでネゴシエーションが止まってしまいます. この時, サーバ側には,

Jul 18 23:03:33 phys5 sshd[2222]: Did not receive identification string from ipp.address.of.client.Machine

というログが残っていました.

同様の環境で, proxy server が 「Microsoft Proxy Server 2.0」ではなく,
「squid-1.1.20」に変えたものだと, この方法で ssh で上手く外に出られる
ことは確認できています. したがって, 怪しいのは, この方法と MS の proxy
server との相性 (もしくは設定の違い) ということになるのですが, どなた
か同様の状況に遭遇された方はいらっしゃいますでしょうか. MS Proxy が返
すメッセージについてもう少し調べてみようと思いますが, 何でもよいので情
報を頂けたら有難いです. よろしくお願いします.

# Microsoft Proxy Server 2.0 の web proxy は ftp URL もうけつけるので
# すが, 愛用の ncftp だと外に出ることができません. Netscape では,
# ftp://UID:passward@ip.address.of.Server.Machine とアドレスを指定する
# と, うまくログインでき, ファイルのダウンロードはできるのですが, ファ
# イルのアップロードはできません. ncftp の作者は,
# FIREWALL-PROXY-README で「Note that NcFTP does _not_ work with HTTP
# proxies that accept FTP URLs. Why? Because they accept HTTP
# requests, silly, not FTP, which this program does.」とちょっとお怒り
# の様子です. ssh で上手く接続できれば ftp はいらないのですが,
# HTTP proxy を経由で, ftp で接続することができるクライアントがもしあ
# れば, 教えて下さい.

---
wada


# dpkg -l ssh
ii ssh 2.5.2p2-3 Secure rlogin/rsh/rcp replacement (OpenSSH)

# cat proxy-klab
#! /usr/bin/perl
$PROXY_KLAB = "ip.address.of.proxy.server";
$PROXY_KLAB_PORT = 80;
$Verbose = 0;

while ($_ = shift) {
last if ! /^-(.*)/;
if ($1 =~ /^v+$/) { $Verbose += length($&); next; }
print <<EOF;
Usage: proxy [option...]
Options:
-v Verbose mode
EOF
}
$HOST = $_;
if ($_ = shift) {
$PORT = $_;
} else {
$PORT = 23;
}
print "Verbose Level: $Verbose\n" if $Verbose;
use Socket;
($name, $aliases, $proto) = getprotobyname('tcp');
($name, $aliases, $type, $len, $thataddr) = gethostbyname($PROXY_KLAB);
$that = sockaddr_in($PROXY_KLAB_PORT, $thataddr);
socket(S, PF_INET, SOCK_STREAM, $proto) || die "socket: $!";
connect(S, $that) || die "connect: $!";
if ($Verbose > 1) {
$Rin = &fhbits('STDIN S');
} else {
$Rin = &fhbits('S');
}
&login;
&connect;
exit 0;
# login 処理
sub login {
&receive(0.1);
&send("CONNECT $HOST:$PORT HTTP/1.0\r\n\r\n");
do { &receive(0.1); } until (/HTTP\/[\d\.]+ 200.*\n\n/);
$Raw =~ m/HTTP\/[\d\.]+ 200.*[\r\n]+/;
$Raw = $';
}
# connect
sub connect {
local($rout);
print "CONNECT\n" if $Verbose;
$Rin = &fhbits('STDIN S');
syswrite(STDOUT,$Raw,length($Raw));
while ((select($rout=$Rin,undef,undef,undef))[0]) {
if (vec($rout,fileno(S),1)) {
return if sysread(S,$_,1024) <= 0; # EOF
syswrite(STDOUT,$_,length);
}
if (vec($rout,fileno(STDIN),1)) {
return if sysread(STDIN,$_,1024) <= 0; # EOF
syswrite(S,$_,length);
}
}
}
# send(str);
# str を送る
sub send {
undef $Buffer;
undef $Raw;
while( $_ = shift ) {
print if $Verbose > 2;
syswrite(S,$_,length);
}
}
# receive(s);
# s 秒入力が途絶えるまで待つ
sub receive {
local($timeout) = shift;
local($rout);
while ((select($rout=$Rin,undef,undef,$timeout))[0]) {
if (vec($rout,fileno(S),1)) {
&abort if sysread(S,$_,1024) <= 0; # EOF
$Raw .= $_;
tr/\r\000\012\021\023\032/\n/d;
$Buffer .= $_;
print if $Verbose > 1;
}
if (vec($rout,fileno(STDIN),1)) {
&abort if sysread(STDIN,$_,1024) <= 0; # EOF
s/\n/\r/g;
syswrite(S,$_,length);
}
}
$_ = $Buffer;
}
sub fhbits {
local(@fhlist) = split(' ',$_[0]);
local($bits);
for (@fhlist) {
vec($bits,fileno($_),1) = 1;
}
$bits;
}
sub abort {
exit(1);
}


ssh を使った Firewall 越えの問題が解決したので報告致します.

From: wada@mail2.off.ne.jp
Subject: [debian-users:29218] ssh を使った Firewall 越え
Date: Thu, 19 Jul 2001 17:01:42 +0900

> firewall の内側の Debian マシンから, 外側にある Debian マシンへの ssh
> の接続を試みているのですが, ちょっとつまづいております.

> 次に, Firewall の内側にある Client Machine の ~/.ssh/config で,
>
> ProxyCommand /path/to/proxy-klab %h %p
>
> としました. そして, 本メール末尾に添える proxy-klab という perl script
> を用意し, 以下のようにすると,

Web proxy サーバの MS proxy 2.0 に telnet をかけてみたら, squid の時と
異なる反応を返してくるので, 用意した proxy-klab という perl script と
の相性が悪かったと思い, こいつを改造することを考えて ssh のプロトコル
を色々調べているうちに, 以下のソースに辿りつきました.

http://www.imasy.or.jp/~gotoh/connect.c

この connect.c をコンパイルし (gcc -o connect connect.c),
/etc/ssh/ssh_config もしくは ~/.ssh/config で,

Host Name
HostName Ip.Address.Of.Server.Machine
Port 443
#ProxyCommand /home/wada/bin/proxy-klab %h %p
ProxyCommand /home/wada/bin/connect -H Ip.Address.Of.Proxy.Server %h %p

としたらあっさり上手くいきました. お騒がせしましたがお蔭様で幸せになれ
ました.

No comments: