システム奮闘記:その39

ssh設定入門



(2005年6月18日に掲載)
はじめに

  Linuxマシンへのリモートコントロール。私がよく使うのがtelnetなのだ。
  もちろん、社内間の通信の場合、内部でデータの盗聴ができる人が
他にいないため、安心(?)して使っている。

  しかし、社外から遠隔操作を行う場合は、通信の盗聴の恐れがある。
  今まで自宅からVPN通信を使い、データを暗号化した上で、
telnetを使って、会社のサーバーに接続していた。

  だが、VPNをしなくても、sshを使った方法もある。
  そこで今回は、sshなどに関する話をする事にしました。


2005年1月14日、磯谷商店IT事業部の長尾さんからメールがやってきた。
長尾さんからのメール
 長尾です。

菅 雄一さん おひさしぶりです。


ちょっとおねがいというか、バイトの打診なのですが、
samba のサーバ立てるのをリモートでいいので手伝ってもらえないでしょうか?

  このメールを受け取った時、お手伝いできる範囲でやろうと思った。

  ただしバイトではなく、ボランティアで引き受ける事にした。
  自分の勉強にもなるので、ボランティアでも利点は充分ある。

  もちろん、お金も欲しいのは本音だが、勤務先の就業規則に抵触するからだ。
  うちの会社で兼業が許される雰囲気はない。

サラリーマンの副業は注意を払うべし!
公務員の兼業禁止の話は誰でもご存じの話なのだが、
サラリーマンも安易に兼業を行うのは危険だ!

それは就業規則に「兼業禁止」にしている会社が多いためだ。
もし、勤務先に兼業がバレると、クビが飛ぶ事だってあるし、
裁判の判例で、クビが妥当という結果が出た事もある。

だが、サラリーマンの場合、勤務先の許可が降りれば問題なく
アルバイトができる。そのため隠れてバイトをするぐらいなら、
堂々と勤務先に申請すれば良い話で、もし、隠れてやったとしても、
市民税や住民税が給与天引きの場合、バイト収入の税金分が
差異として、会社にバレてしまいますよ〜 (^^)

最近は、残業手当や昇給ができない事から、副業を認める会社も
増えていますので、就業規則を照らし合わせて、勤務先に申請するなりして
堂々とバイトをしましょう!

  もちろん、会社で勤務中にお手伝いをするわけにいかない。
  そこで、全て自宅からの操作になる。

  早速、自宅でsshが使えるのか確かめてみたら、sshがインストール
されているので、インストールする必要はなかった。

  翌日、長尾さんからメールが届いた。

長尾さんからのメール
長尾です。

お願いしたいのは、

samba サーバの設定です。iptables を設定しての運用です。

まずお願いしたいのは、
内側にあるサーバ設定で
次に、データセンター上にあるサーバです。

SSH1 ですが鍵をつけました。

ターゲットになる サーバは、XXX.YYY.ZZZ です。
添付の鍵 パスワード **** で入れるはずです。
アカウントは、suga です。

ルートのパスワードはPGPで送りたいのですが、
PGPはお使いでしょうか?

  さて、困った。

  SSHは使った事がない (^^;;

  もちろん、SSHに「SSH1」、「SSH2」の2種類あるなんて知るわけもない。

  さて、格好つけて、知ったかぶりしたいという気持ちは多少あるが、
くだらぬ格好つけのためドツボにハマり、マヌケぶりを露呈した方が、
よっぽど格好が悪い!

  知るは一時の恥、知らぬは一生の恥。

  素直に「わかりませんので教えてください」と長尾さんにメールを書いた。
  長尾さんから、お返事をいただいた。

長尾さんからのお返事
ssh -1 -l suga XXX.YYY.ZZZ
青い部分はログイン名。赤い部分は接続先のアドレス

  早速、やってみたのだが・・・

  接続できへん (TT)

  だった。

  そこで長尾さんにエラー報告を行った。

長尾さんへ送ったエラー報告の内容
  長尾さん
 
  こんばんわ。メールありがとうございます。

>  ssh -1 -l suga XXX.YYY.ZZZ
 
  これをやりましたが、ダメでした。
  ちなみにエラーの内容は以下の通りでした。
 
 ----------------------------------------------------------
 suga@jitaku[~]% ssh -1 -l suga XXX.YYY.ZZZ
 The authenticity of host 'XXX.YYY.ZZZ (xxx.yyy.zzz.aaa)' can't be
 established.
 RSA1 key fingerprint is XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.
 Are you sure you want to continue connecting (yes/no)? yes
 Warning: Permanently added 'XXX.YYY.ZZZ,xxx.yyy.zzz.aaa' (RSA1) to the
 list of known hosts.
 suga@XXX.YYY.ZZZ's password:
 Permission denied, please try again.
 -----------------------------------------------------------------
青い部分はログイン名。赤い部分は接続先のアドレス

  長尾さんからお返事が返ってきた。

長尾さんからお返事
長尾です。

わ、すみません。linux に、秘密鍵を登録していませんね。
ssh -1 -i .ssh/秘密鍵  -l XXX.YYY.ZZZ

として、秘密鍵を、.ssh の中にいれてください。

  sshって、IDとパスワード以外に、秘密鍵が必要な事を知らなかった (^^;;

パスワードとパスフレーズの違い
この奮闘記を編集していて気づいた事だが、sshでのユーザ認証のための
秘密の呪文の事をパスワードでなく、パスフレーズと呼んでいたりする。

確かに、telnetやftpでの認証のパスワードとは別物なので区別するために
パスフレーズと呼んでいたりすると思われる。(あくまでも推測)

  これで大丈夫だろうと思い、早速、挑戦するのだが、なんだか怪しい感じがする。
  下の表示を見れば、うまくいくのか不安がよぎる。

雰囲気的にあやしい (^^;;
[suga@jitaku[~]% ssh -1 -l suga XXX.YYY.ZZZ -i suga.ppk
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0644 for 'suga.ppk' are too open.
It is recommended that your private key files are NOT accessible by others.
This private key will be ignored.
bad permissions: ignore key: suga.ppk
Enter passphrase for RSA key 'suga.ppk': 

  さて、上の表示の最後のEnter passphrase for RSA key 'suga.ppk': を見て、
パスフレーズの要求だと思った私は、長尾さんから頂いたパスフレーズを入力。
  だが、入力しても、再要求してくる。

再要求の状態
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0644 for 'suga.ppk' are too open.
It is recommended that your private key files are NOT accessible by others.
This private key will be ignored.
bad permissions: ignore key: suga.ppk
Enter passphrase for RSA key 'suga.ppk': 

  再要求を見て「なんでや」と思いながら、パスフレーズを入力したのだが
再要求の画面の繰り返し。ついには・・・

  なんで、エラーが出るねん (TT)

  だった。

エラーの内容
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0644 for 'suga.ppk' are too open.
It is recommended that your private key files are NOT accessible by others.
This private key will be ignored.
bad permissions: ignore key: suga.ppk
Bad passphrase.
Connection closed by xxx.yyy.zzz.aaa

  何度も繰り返したが、同じ結果に終わった。

  その事を長尾さんに連絡すると、長尾さんも「謎ですね」とおっしゃった。
  お互い「なんでだろう?」と悩んでしまった。


  ネットを使って調べてみる事にしたが、なかなか見つからない。
  そんな時、クライアントがWindowsでもできる事を発見した。
  PuTTYというソフトを使えばできるという。

  さて、気分を変えてクライアントをWindowsにしてから、
sshでログインできるかどうか挑戦してみる事にした。
  早速、Puttyというソフトをダウンロードしてきた。

  そして、適当に設定してみる事にした。

PuTTYの設定:その1
PuTTYの設定:IPの記述
赤い部分は、接続先のホスト名(もしくはIPアドレス)を記述する。


Puttyの設定:その2
SSH1を選択する
赤い線で囲んだ部分が、SSH1を採用する部分


PuTTYの設定:その3
PuTTyの設定。秘密鍵の取り込み
赤い線で囲んだ部分が、秘密鍵を取り込む部分

  そして、接続を行う事にした。

PuTTYを使った接続
PuTTYを使った接続でログイン名を尋ねている様子
ログイン名を尋ねている様子。

PuTTYを使った接続
PuTTYを使った接続。パスフレーズを尋ねている様子。
パスフレーズを尋ねている様子。

PuTTYを使った接続
PuTTYを使った接続。ログイン成功
ログインに成功した様子

  見事、ログインに成功!

  なんとWindowsだと成功したのだった。
  しかも設定の際、多少は試行錯誤した物の、比較的簡単に設定できたのだ。

  だが、Windowsでできても、クライアントがLinuxの場合でも、
ログインできるようにしたい。なにせ、Linux上から操作した方が
慣れているのもある。


  さて、気を取り直して、クライアントがLinuxの場合でも設定できるように
SSHの勉強をしようと考えた。
  「SSHで安全なリモートアクセスを構築する」(榊原大輔:ディーアート)
を本屋で買って読んでみる事にしたのだが・・・

  全然、知りたい事が書いていない (TT)

  この時、私が欲しかったのは、クライアントがLinuxの場合で、sshを使う際の
コマンドの使い方だった。

  本来なら、腰を据えて読まないといけないのだが、何が何んでも早く解決したい
という気持ちになると、空回りを起こす。
  何度も、エラーが出ては、うんざりする。

  だが、ふとエラーの状態を眺めてみた。

要求画面に注目
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0644 for 'suga.ppk' are too open.
It is recommended that your private key files are NOT accessible by others.
This private key will be ignored.
bad permissions: ignore key: suga.ppk
Enter passphrase for RSA key 'suga.ppk': 
赤い部分に注目してみた。
もしかして、鍵のファイルのパーミッションに問題があると考えた。

確かに、青い部分を読むと「秘密鍵を他人には見えないように」という意味が
書かれている。
その下には「この秘密鍵は無視するで〜」と書いている。

  そこで、秘密鍵のパーミッションを見てみた。

秘密鍵のパーミッション
suga@jitaku[~/nagao]% ls -l
合計 12
-rw-r--r--    1 suga     users         528  1月 15日  22:30 suga.ppk
これだと他人に鍵は丸見えの状態だ。

  そこで、鍵のパーミッションを自分だけが見れるように変えてみた。

秘密鍵のパーミッションを変更
suga@jitaku[~/nagao]% ls -l
合計 12
-r--------    1 suga     users         528  1月 15日  22:30 suga.ppk
これだと自分以外の人は鍵は見えない状態だ。
もちろん、自分でも書き換え不可能な状態だ。

  これで、うまくいくかなぁと祈りながら、再度、挑戦してみた。

再度挑戦
suga@jitaku[~]% ssh -1 -l suga XXX.YYY.ZZZ -i suga.ppk
Enter passphrase for RSA key 'suga.ppk': 

  どうやら、秘密鍵のパーミッションを変更する前とは全く様子が違う。
  そして、パスフレーズを入力すると・・・

  ようやくログインに成功した (^^)V

ログイン成功の様子
suga@jitaku[~]% ssh -1 -l suga XXX.YYY.ZZZ -i suga.ppk
Enter passphrase for RSA key 'suga.ppk': 
[suga@suga]$ 

  ふぅ、長かった。
  やれやれと思った。

  SSHについて、自宅から長尾さんの所のサーバーへの接続は可能になった。
  だが、この時点では、SSHを理解したわけではなかった。
  単に、長尾さんの所のサーバーへの接続方法を知っただけだ。

  これだと理解した事に全くならず、このままでは意味はない。
  さて、長尾さんの所のお仕事の都合で、しばらくは長尾さんの所のサーバーへ
接続しない日が続いた。
  普通なら勉強する良い機会なのだが、長尾さんの所のサーバーへ接続さえ
できれば良い話で、SSHに対して必要性を感じていなかったため、
SSHを勉強する意欲は湧かなかった (^^;;


  だが、転機は訪れる。
  2005年5月12日、ふと思った。自宅から会社へSSHで接続できないかと思った。
  自宅から会社へはVPNで結んでいるのだが、VPNサーバーをLinuxから
ヤマハのルーターRTX1000に変更してからというもの、60秒間、通信がなければ、
通信が切断されるという不便な物になった。

注意
後になって、60秒経っても接続が切れない方法があるのを知った。
詳しくは「システム奮闘記:その37」(ヤマハルーターRTX1000の設定)を
ご覧ください。

  それだけでない。出張先のホテルなどからPPTPを使って社内へ接続できない
障害も発生している。NATの問題が絡んでいるらしい。
  詳しくは「システム奮闘記:その27」(LinuxでPPTPサーバー構築)をご覧ください。

  そこで、VPN(PPTP)の代わりに、SSHが使えないかと思った。
  となれば、業務上の必要になるため、堂々と会社でSSHの事を調べたり
実験を行ったりする事ができる!

  早速、SSHがどういう物かを見て行く事にした。

  まず、認証時に公開鍵暗号を使っている事だ。

認証時に公開鍵暗号技術を使っている
認証時に公開鍵暗号技術を使ってい
クライアント側は秘密鍵を持っていて、その鍵を使って暗号化する。
そして、サーバー側の公開鍵でデータの復元化を行う。
データの暗号化によってデータの安全性が保たれる。

  SSHが公開鍵暗号を使っている話は知っていたのだが、
私は以下のような誤解をしていたのだった。

私が誤解していた事
私が誤解していた事
クライアント側は公開鍵を持っていて、サーバー側に秘密鍵があると
思い込んでいた。
そのため、長尾さんとのやりとりで、私の手元で使っていた鍵が
秘密鍵である事に、違和感を感じていた。

よくよく考えると、SSHの特徴として、例え、パスフレーズがバレても
本人しか知らない鍵で暗号化して送るため、簡単にはログインする事ができず
安全性が保たれるのだが、誰でも知っている公開鍵で暗号化すると、
その特徴が台無しになる。

どうやらPGPの送り手が公開鍵で暗号化して、受け手が秘密鍵で
復元化するのと混同していたようだ (^^;;


  (注意:2007/6/1)
  実は、上の図のように秘密鍵でパスフレーズを暗号化して
  サーバー側で公開鍵で復元して認証を行うのは間違いです。
  それに関しては後述しています。


  だが、驚くなかれ。その程度の誤解は私にとっては大した事ではない。
  実は・・・

  通信データも公開鍵暗号技術で暗号化していると思っていたのらー!

私が誤解していた事
私が誤解していた事
認証が終わり、実際にデータ通信が行われる際のデータの暗号化も
公開鍵暗号が使われていると誤解していた。

よくよく考えると、暗号化と復元化に時間がかかる公開鍵暗号を
使うわけないのだが、気がつかなかった (^^;;

  公開鍵暗号が使われているのは、認証時の時のみで、データ通信時には
共通鍵暗号が使われている。
  一体、どんな共通鍵を使っているのか興味深くなる。

  ふと思った。PuTTYから見たら、すぐにわかるのでは。
  そこで、Windowsを立ち上げ、PuTTYのログを見てみる事にした。

PuTTYのログ
PuTTYのログ
ピンクで囲んだ部分が、共通鍵の暗号に関する所。
AESはSSH1では対応していないので、Blowfishという暗号を使ったと
記録されている。

  Blowfishって、聞いた事がない (^^;;

  調べてみると、Blowfishは処理が早い暗号で、SSH1の場合、
暗号強度は128ビットを使っているという。
  128ビットの暗号だと安心だ。暗号化のアルゴリズムに欠陥がない限り、
暗号破りをするのに、人間の寿命を遥かに越える時間を要するからだ。
  暗号強度に関する事は、「システム奮闘記:その27」
(LinuxでPPTPサーバー構築)をご覧ください。


  使っている暗号の種類を知ったら、一体、お互いの通信で使う暗号は、
どう決めているのか知りたくなる。
  そこで、PuTTYの設定を、よ〜く見てみる事にした。

PuTTYの設定
PuTTYの設定:暗号の種類の選択
青で囲んだ部分は、暗号の種類で、上から順番に使う際の優先度を表す。
SSH1の場合、AESは使えないので、2番目のBlowfishが使われる事を意味する。

もちろん、この順序の変更は可能で、3DESを使いたい人は、
1番目に、3DESをもってくれば良いのだ。

  クライアント側と、サーバー側で相談(?)して、使う暗号の種類を
決めている事がわかる。

  さて、クライアントがLinuxの場合、どんな設定で、どういう風に
暗号の種類を決めているのか知りたくなる。
 
  そこで、man sshで見てみる事にした。

man sshの内容(一部抜粋)
-c blowfish | 3des | des
        Selects the cipher to use for encrypting the session.  3des is
        used by default.  It is believed to be secure.  3des (triple-des)
        is an encrypt-decrypt-encrypt triple with three different keys.
        blowfish is a fast block cipher; it appears very secure and is
        much faster than 3des. des is only supported in the ssh client
        for interoperability with legacy protocol 1 implementations that
        do not support the 3des cipher.  Its use is strongly discouraged
        due to cryptographic weaknesses.
「-c」のオプションで暗号の種類(Blowfish、3DES、DES)が選べる。
青い部分は「デフォルトの場合は、3DES」という意味だ。
ピンクの部分は、安全性が高く、3DESより暗号処理が
高速のBlowfishを勧めている。

  クライアントがLinuxの場合、何もしなければ、3DESになり、
オプション「-c」を使う事で、他の暗号が選択できるという。

  ところで、SSHには、「SSH1」と「SSH2」の2種類がある。
  この違いは一体何なのか調べてみる事にした。

  主に2つの違いがあるという。
 
SSH1とSSH2の違い:その1
SSH1 認証の公開鍵暗号はRSA方式しか使えない。
SSH2 認証の公開鍵暗号はRSA方式とDSA方式の2種類が選択できる。

  2つ目の違いは、データの暗号化に使う共通鍵の受け渡しの方法だ。

SSH1ので共通鍵の受け渡し方法
SSH1ので共通鍵の受け渡し方法
通信データの暗号化のために使われる共通鍵はクライアント側で生成される。

まずは、サーバー側で秘密鍵と公開鍵を生成する。
この2つの鍵は、クライアント側で生成される共通鍵を安全に運ぶために
共通鍵を暗号化するための鍵となる。
そして、公開鍵をクライアント側に渡す。

クライアント側でデータ暗号化のための共通鍵を生成した上で、
サーバーから渡された公開鍵を使って、生成した共通鍵を暗号化して
サーバーに渡す。共通鍵を暗号化する事により、途中の経路で
盗聴されるのを防ぐ事ができる。

  安全に共通鍵の受け渡しするのがわかる。
  だが、SSH2では、もっと高度な技術が使われている。
  それは、Diffie-Hellman法と言われる方法で、お互い乱数の交換だけで
お互いにしか知らない共通鍵を生成する技術だ。

Diffie-Hellman法
Diffie-Hellman法
「離散対数的問題」と呼ばれる難しい数学を使い
お互いが生成した乱数を交換しあう事により、お互いのみ知る
数字を生成できる。これを共通鍵として利用する。

  この技術はVPN技術のIPSeC方式にも使われている。
  詳しくは「システム奮闘記:その35」をご覧ください。
 (インターネットVPN導入)


  ふと思った。さて、暗号化だが、ネットワークの階層構造の中で、
どの層で暗号化されるのか
  私はソフトを使っているから、第5層のアプリケーション層ではないかと
思った。調べてみると、予想通りアプリケーション層だった。

暗号化を行う層について他の暗号化との比較
暗号化を行う層について他の暗号化との比較
SSHはアプリケーション層で暗号化を行う。

補足 認証時の仕組み

(2007/6/1に補足追加) このシステム奮闘記を編集した時、認証時の仕組みについて 触れていませんでした。 というのも以下の方法で認証をしていると思い込んでいたのだった。
SSHでのパスフレーズ認証
SSHでのパスフレーズ認証

  編集当時は、それで問題がないと思い込んでいた。
  だが、2007年5月に、上の図のような認証を行っているというのは
間違えである事に気づいた。

  そのキッカケを作ってくださったのは、北村ごんべいさんという方で
この奮闘記をご覧になり、私の所へメールを送ってくださった事が
私の誤りを発見する出発点だった。

北村ごんべいさんからのメール(2007/5/11)
実はsshのところで疑問に思うことがありまして、メールさせて頂きました。
sshについては、サーバ側に公開鍵と秘密鍵を持たせて、
公開鍵をクライアントに送って、クライアントで共通鍵を作成し、
公開鍵で暗号化して、サーバに送って、以降共通鍵での暗号通信と
認識していたのですが、「私が誤解していた事」で、
そういうことでなさそうなようですし、
また、実際、長尾さんからのメールで
 ssh -1 -i .ssh/秘密鍵  -l XXX.YYY.ZZZ で
ログインするようにとのことですし、
PuTTYの設定でも秘密鍵の設定がありますし・・、
「秘密鍵はやはりクライアント?」 ってことなのかなと。
それで下の方を読み進めると「SSH1ので共通鍵の受け渡し方法」
ってところで、やはりこれらの鍵ペアーはサーバで
保持しとくものなのかな。って思ったりして

 この奮闘記を書いてから2年ぐらい経ち、SSHの事はすっかり忘れていた。
 SSHの事を思い出すために、自分で書いた物を見返した時、ハッと思った。

 北村さんのメールの通り、SSHではクライアント側に秘密鍵を持たせ、
サーバー側に公開鍵を持たせている。

 普通、公開鍵暗号を使った認証では、クライアントに公開鍵を持たせ
サーバー側に秘密鍵を持たせる。クライアントはパスワードを公開鍵で
暗号化して、サーバーに届くと、秘密鍵で復元化する。

公開鍵暗号を使った認証
公開鍵暗号を使った認証
誰でも知っている公開鍵でパスワードを暗号化を行い
本人しか知らない秘密鍵でパスワードを復元化を行う。

 しかし、sshの場合は、逆になっている。

  もし、クライアントの秘密鍵でパスフレーズを暗号化を行い
サーバー側にある公開鍵で復元化を行って認証をすると以下の問題が出てくる。

もし、クライアントの秘密鍵で暗号化を行うと・・・
公開鍵は盗まれる危険性がある
公開鍵は盗まれる危険性
公開鍵をサーバーに送る際、どんな方法でも良いので
ネットを経由して送信する場合が考えられる。
その場合、途中の経路で悪者によって公開鍵を盗聴される危険がある。
公開鍵が盗まれた結果
公開鍵が盗まれた結果
公開鍵が盗まれると、秘密鍵で暗号化したデータの復元化ができる。
そのため、ネットで送られる暗号化されたデータを盗聴し
公開鍵で復元化すると、パスフレーズがバレてしまう。

  上のような危険性があるので、どう考えても、クライアント側に
秘密鍵を持たせて暗号化させるとは思えない。
 さて、一体、どういう仕掛けなんだろうか。

 そこで奮闘記を見返すのだが・・・

 認証の仕組みが全く書かれてへん!!

  だった。
  編集した当時、完全に認証の部分を抜かしていた事がわかった。

 という事で、久々に次の本を読んで調べる事にした
  「SSHで安全なリモートアクセスを構築する」(榊原大輔:ディーアート)

  すると、結構、複雑な方法を使っている事がわかった。

パスフレーズの認証方法
クライアントから公開鍵を送る
認証を行う際、クライアント側からサーバーへ公開鍵を送る。
公開鍵が一致するかどうかの確認
そして、サーバー側で事前に渡された公開鍵と、認証開始時に送られた
公開鍵とを突き合わせて一致するか確かめる。
一致すれば次へ進む
サーバー側で乱数を生成する
サーバー側で乱数を発生させる。
そしてクライアントから送信された公開鍵を使って乱数を暗号化する。
それと同時に、サーバー側で乱数をハッシュ関数を使って
ハッシュデーター(不可逆暗号)を生成する。
乱数の公開鍵で暗号化してデータをクライアントへ送る
サーバーで作成された乱数の暗号データをクライアントへ送信する。
クライアントで乱数の暗号化データを復元化する
クライアントではサーバーから送られた暗号化された乱数のデータを
秘密鍵を使った復元化を行う。
この復元化の際に、パスフレーズを使う!
蘭州をハッシュ関数でハッシュデータに変換
クライアントでは秘密鍵とパスフレーズで復元化された乱数を使い
ハッシュ関数で、乱数のデータをハッシュデータに変換する。
サーバーにハッシュ変換したデータを送る
クライアントで生成したハッシュデータをサーバーへ送る。
サーバーでハッシュデータの一致の確認を行なう
サーバーへ送られたハッシュデータと、サーバーで生成した
ハッシュデータとを突き合わせて一致すれば認証終了だ。

  この方法だとパスフレーズはクライアントの内部だけで使われ
外へ送信する事がないため、安全性が高いという。

  しかも、サーバー側に登録したパスワードを入力する事もないため
パスワードが洩れる事も一切ない。

  パスフレーズという呼び方だが、サーバーのパスワードとは別物なので
区別するためパスフレーズにしたと思う。

  北村ごんべいさんのメールのお陰で、私自身、すごく勉強になった (^^)
  北村さんには感謝します。

(追加記入終わり)

SSHの設定

さて、だいたい概略がわかった所で、会社でSSHの設定実験を行う事にした。 SSH1を使った実験を行う事にした。
SSHの実験
SSHの接続実験の様子
社内にあるLinuxマシンで、クライアントとサーバーを用意する。
そして、クライアントからサーバーへSSHでログインできるようにする。

  SSHの設定で、次の本を取り出した。
  「RedHat7.3対応で作るLinux7」(サーバー構築研究会:秀和システム)

  RedHat7.3の場合、デフォルトで、sshdデーモンが立ち上がっている。
  そのため、後は、認証の際の秘密鍵と公開鍵の準備さえ行えば良いのだ。

  さて、お得意の本の丸写しで、認証に使う秘密鍵と公開鍵を生成する。
  SSH1の場合、RSAしか対応していないので、RSA方式の鍵を作る。

秘密鍵と公開鍵の生成
[suga@client]$ ssh-keygen -t rsa1
Generating public/private rsa1 key pair.
Enter file in which to save the key (/home/suga/.ssh/identity): suga
Enter passphrase (empty for no passphrase): パスフレーズを入力
Enter same passphrase again: 再度、パスフレーズを入力
Your identification has been saved in suga.
Your public key has been saved in suga.pub.
The key fingerprint is:
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX  suga@xxx.yyy.co.jp
[suga@client]$ 
赤い部分はIDの意味ではなく、秘密鍵や公開鍵の名前になる部分だ。
そして、SSHでログインする際のパスフレーズを入力する。

すると、秘密鍵「suga」と公開鍵「suga.pub」が生成される。

  さて、鍵ができたので、公開鍵をサーバー側に置く。

公開鍵をサーバー側に置く
[suga@server]$ cd .ssh
[suga@server]$ cp suga.pub authorized_keys
[suga@server]$ ls
authorized_keys  suga.pub
[suga@server]$ ls -l
合計 8
-rw-r--r--    1 suga     aaa           346  5月 13 15:40 authorized_keys
-rw-r--r--    1 suga     aaa           346  5月 13 15:38 suga.pub
[suga@server]$ 
公開鍵をログインしたいユーザーのトップディレクトリーの下の.sshに置く。
そして、公開鍵の名前はauthorized_keysにして置く。
この名前は、あくまでもデフォルトなので、SSHの設定ファイルを変更すれば
公開鍵の名前を好きなように変更できます。(後述しています)

  これで準備は完了!
  早速、SSHが使えるかどうか実験を行ってみたのだが・・・

  なんでエラーが出るねん (TT)

  意気揚々と前に進もうとしたのだが、簡単にコケてしまった。
  さて、エラーの内容を見てみる事にした。

エラーの内容
[suga@client]$ ssh -1 -l suga xxx.yyy.zzz.aaa -i suga
The authenticity of host 'xxx.yyy.zzz.aaa (xxx.yyy.zzz.aaa)' can't be established.
RSA1 key fingerprint is xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'xxx.yyy.zzz.aaa' (RSA1) to the list of known hosts.
suga@xxx.yyy.zzz.aaa's password: 
Permission denied, please try again.
suga@xxx.yyy.zzz.aaa's password: 

[suga@client]$

  ふと、勘が働く。
  もしかして秘密鍵のパーミッションに問題があるのでは・・・
  そう思った私は、秘密鍵のパーミッションを確かめる事にした。
  すると案の定、問題があった。

秘密鍵のパーミッション
[suga@client]$ ls -l
合計 4
-rw-------    1 suga     aaa          542  5月 13 18:20 suga
[suga@client]$ 
所有者のみ読み書き可能になっている。

  もしかしたら、所有者でも読み込みだけ可能にする必要があると考えた。
  そこで、パーミッションを変更した。そして再度、挑戦すると・・・

  見事、成功した (^^)V


  これで設定の面の問題は解消できた。

実験・その2
自宅から会社へSSHで接続
自宅から会社のサーバーへSSHでの接続を考えた。
接続先のSSHサーバーは、NAT越えの問題で接続できない事態を防ぐため
まずは、グローバルアドレスを持つマシンにしてみた。

  SSHの通信は、ポート22でTCPを使っている。
  会社のADSLルーターのパケットフィルターのうち、SSHサーバー宛のパケットで
ポート22のTCPを開ける事にした。
  

  自宅に帰って、早速、SSHでの接続を試みる。
  まずは、PuTTYを使っての接続だった。結果は・・・

  見事、成功した (^^)V

  そして、クライアントをLinuxにして、同じ事をやってみた。
  結果は・・・

  見事、成功した (^^)V

結果
suga@jitaku[~/test]% ssh -1 -l suga xxx.yyy.zzz.aaa -i suga
Enter passphrase for RSA key 'suga': 
Last login: Sat May 14 09:29:53 2005 from aaa.bbb.ccc.jp
[suga@kaisha]$ 

  次に、NAT越えを行ってみる事にした。
  PPTPやIPSeCのように、カプセリングのために、元々のIPヘッダーや
TCPヘッダーが見えなくなる事がないため、NAT越えは容易だと思っていたが
もしもの事を考えて、さきほどは、NAT越えをしない場合で実験を行った。
  その方が接続ができない時の原因の切り分けがしやすくなる。

  さて、NAT越えを行ってみた。結果は・・・

実験・その3
NAT越えでSSHの実験
社内LAN(プライベート側)への接続が成功したのだ。

ところで、私の自宅はプロバイダーが気前が良いのか、グローバルIPを8つ
持っている。そのため、グローバルIPを使って接続しているのだが
通常の自宅やホテルなどからのインターネット接続のように、
プライベートIPを持っているクライアントが、NAT越えを行い、
なおかつ、会社のNAT越えを行って接続ができるかについては
後述しています。

  見事、成功した (^^)V

  これでVPNの時に起こっていた、60秒以内に操作しないと接続が切れる現象に
悩まされる事がなくなった。


  ところで、だいぶ後になって気づいたのだが、クライアントがLinuxの場合、
一番最初にSSHを使った後、次のファイルが生成される。

クライアントがLinuxの場合、生成されるファイル
suga@jitaku[~/.ssh]% ls
known_hosts  suga.ppk*
suga@jitaku[~/.ssh]% 

  一体、known_hostsファイルとは何なのだろうか?

  事務員の私は、わかりませーん (^^)

  で逃げる事も可能(?)なのだが、調べてみる事にした。

  すると、予想もしない事がわかった。known_hostsファイルとは

  接続先のサーバーに置いている公開鍵

  だという。
  厳密には、公開鍵そのものではなく、公開鍵と接続先のマシンのIPが
記録されているものだ。

  SSHで接続する際、一番最初だけ、Linuxでは、次の画面が出てくる。

クライアントがLinuxの場合、一番最初だけ出る表示
suga@jitaku[~/.ssh]% ssh -1 -l suga XXX.YYY.ZZZ.AAA -i suga.ppk 
The authenticity of host 'XXX.YYY.ZZZ.AAA (XXX.YYY.ZZZ.AAA)' can't be established.
RSA1 key fingerprint is XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'XXX.YYY.ZZZ.AAA' (RSA1) to the list of known hosts.
Enter passphrase for RSA key 'suga.ppk': 
クライアントがLinuxの場合、2回目以降に出る表示
suga@jitaku[~/.ssh]% ssh -1 -l suga XXX.YYY.ZZZ.AAA -i suga.ppk
Enter passphrase for RSA key 'suga.ppk': 

  1回目の接続ためのやりとりで、サーバーから公開鍵をもらって、
known_hostsファイルに記録しているという。

公開鍵をもらう
公開鍵の受渡し
1回目の接続で、クライアントはサーバーから公開鍵を貰う。

2回目以降の接続では、クライアントが持っている公開鍵をサーバーに送り
接続元のクライアントが正しいかどうかの確認に使われる。

  クライアントがLinuxでなく、WindowsでPuTTYを使う場合も、
1回目の接続は同じような物が出る。

PuTTYで1回目の接続の時に必ず出る場面
PuTTYで1回目の接続の時に必ず出る場面

  ところで、もし、クライアントの公開鍵がサーバーが持っているものと違う物なら
どうなるのか、ちょっと実験をしてみた。

  クライアント側にあるknown_hostsファイルを改竄してみた。
  そして、サーバーへの接続を行ってみた。すると・・・

  なぜか、接続でけた (・・)

  筋書き通り、うまくいかないものだと思う。
  
  そこで、クライアントにある公開鍵を元に戻して、サーバー側の公開鍵を
別の物にしてみた。
  すると・・・

  1回目の接続と同じ画面が出た!

  恐らく、サーバーとクライアントが持っている公開鍵が合わないために
出る警告だと考えられる。推測だけど (^^;;


  だが、ちょっと恐い事を発見した。
  もし、手元にある秘密鍵が本来の秘密鍵と違った物で接続した場合、
接続拒否ではなく、違う形で接続可能になる。

これって、ちょっとやばいかも (^^;;
suga@jitaku[~/.ssh]% ssh -1 -l suga XXX.YYY.ZZZ.AAA -i mayumi.ppk
suga@XXX.YYY.ZZZ.AAA's password: 
Last login: Sat May 21 12:54:59 2005 from aaa.bbb.ccc.jp
[suga@kaisha]$ 
別の秘密鍵で接続を行おうとしたら、接続拒否ではなく、
ログインパスワードを尋ねてくる。

折角、telnetなどをパケットフィルタリングで拒否しても、
SSHのポートさえ開いていれば、telnetと同じ形でログインができる。

  ふと思った。
  本来の秘密鍵とは別物で暗号化するのだから、サーバー側で
公開鍵で開けたくても、開ける事はできない。
  もしかして、この場合、認証は暗号化されずに行われるのだろうか?

  不安が過った。
  そこで、通信パケットが暗号化されているかどうか、
Etherrealを使って、パケットキャプチャをしてみた。

パケットキャプチャをした結果
パケットキャプチャをした結果

  通信の中身は暗号化している表示が出た。

  私の推測なのだが、認証は失敗しても、お互いしか知りえない共通鍵を使い
通信を行っている感じがする。
  ソースコードを読む実力があれば、ソースを読むのだが、そんな実力は
100%ありませんので、推測しかできませーん (^^;;

  もちろん、SSH1だけでなく、SSH2でも同じ事をやってみましたが、
同じ結果が出てきました。

  今回の実験で、秘密鍵と公開鍵との一致がなくても、ログインパスワードさえ
知っていれば、簡単にログインできてしまう事から、パスワード破りがいたら
恐い話だなぁと思った。安易にSSHを信用はできない部分だ。

  さて、SSHの使い方は、だいたい理解できたと思った。

注意
 SSHには、rshと同様に、リモートシェルの働きや、ポートフォワーディング
という技が使えるぞという声があるかと思います。
 それを知ったのは、だいぶ後になってからです。

 この2つについては、後述しています。

scpの設定

さて、次にscpにの話をします。 3月に、長尾さんから次のメールがやってきた。
長尾さんからのメール
お願いしたいことは、

1.バックアップ用の samba サーバをたてる。
 というかファイルサーバですね。
2.その samba サーバを、インターネット接続して、データをデータセンタに飛ばす。
というのをやりたいのです。

  これを見た私は困った。
  どうやって、2を実現するのだろうか?
  何か特殊な方法を使って、Sambaにあるデータをデータセンターへ
飛ばす事を行うのだろうか?

  そこで長尾さんに尋ねて見る事にした。

長尾さんからのお返事
簡単です。SCPとかですね。

  scpって何やねん?

  ホントに何も知らない私なのだ。
  scpが一体何なのか調べてみる事にした。リモートコピーだという。
  データを暗号化して他のマシンへコピーする操作だという。

  rcpコマンドを暗号化した物だというのだ。

rcpコマンド
rcpコマンドの概略

  ところで、rcpコマンドの存在は知っていたものの、今まで使った事がない。
  scpを触る前に、古いrcpから触ってみる事にした。

  そして、実行できる環境を整えた。

rcpコマンドを使えるようにする設定
rcpコマンドが使えるようにするための設定

  そこで使ってみる事にしたのだが・・・

  なんで、接続エラーが出るねん (TT)

  だった。
 
  そこで調べてみると、xinetdの設定を触るのが必要な事がわかった。
  RedHat7.3の場合、xinetdの設定に関するファイルで、/etc/xinetd.d/rshの
ファイルを書き換える必要がある。

/etc/xinetd.d/rshの中身
(初期設定:RedHat7.3の場合)
# default: on
# description: The rshd server is the server for the rcmd(3) routine and, \
# consequently, for the rsh(1) program.  The server provides \
# remote execution facilities with authentication based on \
# privileged port numbers from trusted hosts.
service shell
{
socket_type = stream
wait = no
user = root
log_on_success += USERID
log_on_failure += USERID
server = /usr/sbin/in.rshd
disable = yes
}
書き換えた後
# default: on
# description: The rshd server is the server for the rcmd(3) routine and, \
# consequently, for the rsh(1) program.  The server provides \
# remote execution facilities with authentication based on \
# privileged port numbers from trusted hosts.
service shell
{
socket_type = stream
wait = no
user = root
log_on_success += USERID
log_on_failure += USERID
server = /usr/sbin/in.rshd
disable = no
}

  そして、/etc/rc.d/init.d/xinetd restart を行った。
  すると・・・

  リモートコピーができた!! (^^)V

  ついに、rcpコマンドが使えるようになったのだ。
  xinetdについては「システム奮闘記:その38」をご覧ください。
 (xinetd スーパーデーモンの設定)

  リモート操作のコマンドで、rshコマンドもある。
  これはリモート先のマシンを操作するためのコマンドだ。

rshコマンド
rshコマンドの役目

  さて、リモート先のファイル一覧を見るために、rshコマンドを使ってみた。

rshコマンドの実行結果
[suga@remote moto]$ rsh XXX.YYY.ZZZ.AAA ls
test.dat
pro
pro2
pro3
pro4
pub
赤い部分は、リモート先のIPアドレス。ホスト名での指定も可能です。

  telnetでログインしなくても、リモート先のマシンの操作ができる。

  思わず感動してしまった!

  rcp、rshコマンドのように、コマンド名の頭に「r」がつき
しかも、リモート操作を行うコマンドの事を、r系のコマンドと言う。

  だが、r系のコマンドだと通信の中身が盗聴される。
  r系統コマンドの場合、データの暗号化はされていないからだ。

  そのため、r系のコマンドは使わないのが良いと言われている。

  rcpコマンドの代わりに、大事なデータを守るために、scpコマンドがある。
  scpだとデータが暗号化されるからだ!

scpコマンドを使ってみる

早速、scpを見てみる事にした。 また、お得意の本の丸写しを行う。
scpコマンドの実行結果
suga@jitaku[~/test]% scp -i suga file suga@XXX.YYY.ZZZ.AAA:file
suga@XXX.YYY.ZZZ.AAA's password: 
Permission denied, please try again.
suga@XXX.YYY.ZZZ.AAA's password: 
Permission denied, please try again.
suga@XXX.YYY.ZZZ.AAA's password: 
Permission denied (publickey,password,keyboard-interactive).
lost connection
suga@jitaku[~/test]%
赤い部分はコピー先のIPアドレス(ホスト名でも良い)
青い部分はファイル名

  コピーできへんかった (TT)

  なぜ、コピーできないのか考えたみた。
  そこで思いついたのが、sshコマンドと同様に、SSH1を使う事を指示する
オプション「-1」が必要だと思った。

  そこで、オプション「-1」をつけてみたのだが・・・

scpコマンドの実行結果
suga@jitaku[~/test]% scp -i -1 suga file suga@XXX.YYY.ZZZ.AAA:file
Warning: Identity file -1 does not exist.
suga@XXX.YYY.ZZZ.AAA's password: 
Permission denied, please try again.

  それでもコピーできへんかった (TT)

  よく見ると、オプションをつける場所が間違えている
  「-i」の後ろに「-1」をつけて、どうするのだと思った (--;;

  そこで仕切り直しで、再度、挑戦してみた。

scpコマンドの実行結果
suga@jitaku[~/test]% scp -1 -i suga file suga@XXX.YYY.ZZZ.AAA:file
Enter passphrase for RSA key 'suga': 
file                            100%  532     0.5KB/s   00:00
suga@jitaku[~/test]% 
赤い部分は、リモート先のIPアドレス。ホスト名での指定も可能です。

  見事、成功! (^^)V

  これでデータを暗号化して、相手先とファイルの転送ができるようになった。

  だが、喜ぶのも束の間だった。
  上記のscpの実験は、クライアントがPlamoLinux4.0の場合だ。

  クライアントがRedHat7.3の場合、「-1」のオプションだとエラーが出る。

scpコマンドの実行結果(RedHat7.3の場合)
[suga@kaisha .ssh]$ scp -1 -i  suga.ppk file suga@192.168.XXX.YYY:file
scp: illegal option -- 1
usage: scp [-pqrvBC46] [-F config] [-S ssh] [-P port] [-c cipher] [-i identity]
           [-o option] f1 f2
   or: scp [options] f1 ... fn directory
[suga@kaisha .ssh]$ 

  sshのバージョンの違いだと思われるのだが、なんとも言えない。
  調べるのが面倒だからなのらー (^^;;

  RedHat7.3の場合は、manを読んだ結果、次のオプションを使う。

scpコマンドの実行結果(RedHat7.3の場合)
[suga@kaisha .ssh]$ scp -oProtocol=1 -i  suga.ppk file suga@192.168.XXX.YYY:file
Enter passphrase for RSA key 'suga.ppk': 
file                 100% |************************************************************************|    20       0
0:00    
[suga@kaisha .ssh]$ 

  バージョンの違いなどで、オプションが変わるのは、厄介な話だ (--メ


  scpも、どんな物か理解できた。だが、待てよと思った。

  scpコマンドを使う際に、パスフレーズを尋ねてくる。
もし、シェルでscpを使って自動的にデータのコピーを行う際は、
どうやってパスフレーズの入力を自動化するのだろうか?
  一体、長尾さんはどういう事を考えておられるのだろうか?

  考えれば考えるほど、謎になってくる問題だ。
  そこで、独自でシェルを考えてみた。

思いついたシェルスクリプト
echo "パスフレーズ" ;
/usr/bin/scp -oProtocol=1 -i  suga.ppk file suga@192.168.XXX.YYY:file

  早速、動かしてみたいのだが・・・

  アカンかった (TT)

  次に単純な発想で、シェルスクリプトの前後を入れ換えてみた。

思いついたシェルスクリプト
/usr/bin/scp -oProtocol=1 -i  suga.ppk file suga@192.168.XXX.YYY:file ;
echo "パスフレーズ"

  早速、動かしてみたいのだが・・・

  やっぱり、アカンかった (TT)

  echoだと、パスフレーズをscpに渡す事ができない。

  ならばと思い、google先生を活用する事にした。

  すると、scpを使った自動コピーのサイトが見つかった。
  読んでみると、ssh-agentコマンドとssh-addコマンドを使うようだ。

  ssh-agentコマンドは認証エージェントという。

  認証エージェントって何?

  調べてみると、パスフレーズを保持するプロセスのようだ。

  ssh-addコマンドは、パスフレーズを登録するものだ。

  早速、ssh-agentコマンドとssh-addコマンドを使って
試してみる事にした。

2つのコマンドを使ってみた結果
[suga@kaisha .ssh]$ ssh-agent
SSH_AUTH_SOCK=/tmp/ssh-XXdKi806/agent.22751; export SSH_AUTH_SOCK;
SSH_AGENT_PID=22752; export SSH_AGENT_PID;
echo Agent pid 22752;
[suga@kaisha .ssh]$ ssh-add
Could not open a connection to your authentication agent.

  全然、うまくいかへん (TT)

  いつもの如く、ドツボにハマる状態になってきた。

  そこで別のサイトで調べてみる事にした。

  パスフレーズを覚えさせるプロセスを動かす場合には、
単にssh-agentコマンドを叩くのではなく、eval `ssh-agent`とする
必要があると書いていた。

  仕切り直しで、もう一度、やってみる事にした。

2つのコマンドを使ってみた結果
[suga@kaisha .ssh]$ eval `ssh-agent`
Agent pid 22762
[suga@kaisha .ssh]$ ssh-add
Enter passphrase for suga@xxx.yyy.co.jp: パスフレーズ
Bad passphrase, try again:
Bad passphrase, try again:

  なんで、パスフレーズが入らへんねん (TT)

  どうもドツボにハマった感じがする。

  ふと思った。この2つのコマンドは接続元のクライアントではなく
サーバー側で設定するのではと思った。

  そこで、サーバー側で2つのコマンドを使ってみる事にしたのだが・・・

  やっぱりアカン (TT)

  よく考えると、サーバー側にパスフレーズを覚えさせるのは、おかしい。
  という事で、やはりクライアント側の設定となる。

  そこで、man ssh-addでマニュアルを読む事にした。

man ssh-addの内容(一部抜粋)
SYNOPSIS
     ssh-add [-lLdD] [file ...]
     ssh-add -s reader
     ssh-add -e reader

DESCRIPTION
     ssh-add adds RSA or DSA identities to the authentication agent, ssh-
     agent(1).  When run without arguments, it adds the files
     $HOME/.ssh/id_rsa, $HOME/.ssh/id_dsa and $HOME/.ssh/identity.  Alterna-
     tive file names can be given on the command line.  If any file requires a
     passphrase, ssh-add asks for the passphrase from the user.  The
     passphrase is read from the user's tty.  ssh-add retries the last
     passphrase if multiple identity files are 

  上の説明を見るのだが、英文なので読む気が起こらない。
  だが、推測はできる。ssh-addコマンドの後ろに秘密鍵をつければ
うまくいくのではないかと思った。

  そこで、もう一度、挑戦する事にした。

2つのコマンドを使ってみた結果
[suga@kaisha .ssh]$ eval `ssh-agent`
Agent pid 22762
[suga@kaisha .ssh]$ ssh-add ./suga.ppk
Enter passphrase for suga@xxx.yyy.co.jp: パスフレーズ
Identity added: ./suga.ppk (suga@xxx.yyy.co.jp)

  パスフレーズを覚えさせるのに成功した!

  そして、実際にパスフレーズを入力せずに、scpが実行できるかどうか
確かめる事にした。

scpコマンドを使ってみた結果
[suga@kaisha .ssh]$ scp -oProtocol=1 -i suga.ppk  test suga@XXX.YYY.ZZZ.AAA:file
file                 100% |*************************************************************************|    20       00:00  


  見事、パスフレーズなしでscpが使えた (^^)V

  ここで・・・

 パスフレーズを覚えさせるのを会得した!

 と喜びたい所だが、ふと疑問に思う。

  evalって何?

  ssh-agentに関連したsshに関する特殊なコマンドだろうと考えた。
  調べてみると、sshとは関係ないコマンドだという事がわかった。

  シェルの本を見たら、コマンドだという事がわかったのだが、
説明文を読んでも「コマンドを評価するもの」といった難解な説明で
私には全くわからなかった。そこで、実験的に触ってみる事によって
evalが何かを見ていく事にした。

  環境はRedHat7.3で初期設定で入っているbashで動かした。

evalって何か使って確かめる (環境は bashです)
evalを使わない evalを使ってみる
suga@jitaku: foo=10
suga@jitaku: x=foo
suga@jitaku: y='$'$x 
suga@jitaku: echo $y
$foo
suga@jitaku: foo=10
suga@jitaku: x=foo
suga@jitaku: eval  y='$'$x 
suga@jitaku: echo $y
10

  ちなみに上の実験は、tcshでは動きませんので。

  さて、evalが何が、まだ見えてこない。

  そこで他の使い方を見てみた。

evalの使い方
suga@jitaku:~$ eval `echo aaa=24`
suga@jitaku:~$ echo $aaa
24

  それでもevalが何が、まだ見えてこない。

  そこで他の使い方を見てみた。

evalの使い方
suga@jitaku:~$ more test.dat 
evalって何かテストするファイルやで〜
suga@jitaku:~$
suga@jitaku:~$ LLL="cat test.dat"
suga@jitaku:~$ echo $LLL
cat test.dat
suga@jitaku:~$ eval $LLL
evalって何かテストするファイルやで〜
suga@jitaku:~$

  上の結果から次の仮説を立てる事ができる。

  eval 変数とした場合、その変数の中身をチェックし
シェルとして動く事がわかれば、シェルとして動かす。

  eval `コマンド`(`はバッククォート)とした場合、
コマンドの出力結果を、シェルとして処理できるかチェックして、
できる場合は、コマンドの出力結果をシェルコマンドとして処理を行う。


  さて、仮説を立てても立証しないと意味がない。
  そこで、次のファイルを作ってみた。

kasetu.txtの中身
suga@jitaku:~$ more kasetu.txt 
ls -l
suga@jitaku:~$ 
kasetu.txtの中身は、ファイルを一覧するコマンドにしてみた。

  eval `cat kasetu.txt`とした場合、どんな結果が出るのか見てみる事にした。
  私の予想ではls -lコマンドが実行されると思った。
 
  さて結果は・・・

kasetu.txtの中身
suga@jitaku:~$ eval `cat kasetu.txt `
合計 21840
drwxr-xr-x    2 suga     suga        4096  1月 30日  11:28 c/
drwxr-xr-x    2 suga     suga        4096 11月  3日 2004年 ccc/
-rw-r--r--    1 suga     suga           6  5月 29日  12:13 kasetu.txt
drwxr-xr-x    2 suga     suga        4096  5月 12日  21:35 kyodo/
drwxr-xr-x   10 suga     suga        4096  5月  1日  11:22 linux/
(以下、省略)

  予想通りls -lコマンドが実行された!!

  つまりeval `(呪文)`を唱えると、
呪文の中身がシェルで動くかどうか確認され、動くのであれば、
次に、呪文の出力結果を見て、また、それがシェルで動くか確かめ、
シェルで動くのであれば、実行させるのだ。
  2重に実行させているとなる。なるほどと思った。

  シェルの勉強にもなった (^^)

rshとssh リモートシェルの話

さて、SSHのリモートシェルの役割について触れたいと思います。 r系のコマンドと、SSHの暗号化を使ったコマンドを比較した時 以下のイメージが頭にありました。
r系のコマンドとの比較
r系 ssh系
rlogin ssh
rcp scp

  ふと思った。
  rshのコマンドに対応する物は、ないのだろうか?

  rshの頭の「r」を「s」に返れば、sshなのに、sshには
リモートシェルではなく、rloginのような動きをするのだろうか?

  考えても、謎が深まるだけなので、調べてみる事にした。

  すると、sshコマンドにも、rshと同様にリモートシェルの役目がある事が
わかった。
  早速、試してみる事にした。

リモートシェルとしてのSSHの使い方
[suga@kaisha .ssh]$ ssh -1 -l suga 192.168.XXX.YYY -i suga.ppk ls
Enter passphrase for RSA key 'suga.ppk': 
aaa
data.c
global
nene
nenee
postfix-2.0.20.tar.gz
rlog
rlog-j
test
xinetd
xinetd-j
[suga@kaisha .ssh]$ 

  リモート先のファイルが見事に表示されている。
  しかも、rshコマンドと違って、ご丁寧に、パスフレーズをきいてくる。

  コマンドの部分の両サイドに「'」(単符号)をつけると、オプションをつけた
コマンドが使えるようになる。

リモートシェルとしてのSSHの使い方
[suga@kaisha .ssh]$ ssh -1 -l suga 192.168.XXX.YYY -i suga.ppk 'ls -l'
Enter passphrase for RSA key 'suga.ppk': 
total 1416
-rw-r--r--    1 suga     suga           111 Apr  9 11:45 aaa
-rw-r--r--    1 suga     suga           401 Mar 18 10:33 data.c
-rw-r--r--    1 suga     suga           445 Apr  4 15:18 global
-rw-r--r--    1 suga     suga          3703 May  3 17:33 nene
-rw-r--r--    1 suga     suga          3715 May  3 17:34 nenee
-rw-r--r--    1 suga     suga       1354414 Mar 17 10:31 postfix-2.0.20.tar.gz
-rw-r--r--    1 suga     suga          3780 Apr  2 17:27 rlog
-rw-r--r--    1 suga     suga          3948 Apr  2 17:28 rlog-j
-rw-r--r--    1 suga     suga            20 May 20 10:39 test
-rw-r--r--    1 suga     suga         26783 Apr  2 17:27 xinetd
-rw-r--r--    1 suga     suga         27299 Apr  2 17:28 xinetd-j
[suga@kaisha .ssh]$ 

  「ls -l」コマンドが使えている。
  リモートシェルとしての使い道は、あまりなさそうだが、
それがある事自体は、わかった。

  r系のコマンドとの比較では、次の表が正しい認識(?)事になる。

r系のコマンドとの比較
r系 ssh系
rlogin
rsh
ssh
rcp scp

ssh ポートフォワードの設定

さて、最後に、SSHのポートフォワードの話をしたいと思います。 SSHを使って自宅から会社のサーバーへ接続できる事がわかった時、 これでSSHの使い方は、だいたい習得したと思ったのだが、 調べていると、SSHを使って、会社のメールが読めるという事がわかった。 その方法がSSHの技の1つで、ポートフォワードの事だった。
SSHを使って自宅から会社のメールを読む方法
SSHを使って自宅から会社のメールを読む方法
メールの読み書きをするクライアントとSSHのクライアントを同じにして
SSHとメールのサーバーを同じにする。
SSHの暗号化を利用して、途中の経路で盗聴されないようにして
外部(私の場合は自宅)から、メールの読み書きができるという。

  具体的に、どんな技術なのか、仕組みを見てみる事にした。

SSHによるポートフォワードの仕組み
SSHによるポートフォワードの仕組み
メールの送信はポート25。受け取りは110というように、各ポート事に
通信するデータが違っていたりする。もちろんデータの暗号化はされない。

そこで、SSHの暗号化の技術を使い、クライアント側は、メールの送信の際
アクセスする所を、localhost(自分自身)にして、ポートを10025にしておく。
SSHは、ポート10025にやってくるデータを待ち受け、データが来ると
それを接続先までSSHを使った暗号化通信を行う。

接続先では、SSHがポート25宛の通信だと認識して、自分自身の
ポート25へ接続を行う。

  さて、SSHを使って、自宅から会社のメールサーバーへ接続して
メールが読めるか、実験を行う事にした。


  この設定を行う場合、サーバー側では設定ファイルsshd_configを
書き換える必要があるみたいなのだが、私の使っている環境(RedHat7.3)では
デフォルトの設定で、問題なくポートフォワーディングが可能だ。

  自宅で使っているPlamoLinux4.0では、該当の設定部分があった。

sshd_configの設定
AllowTcpForwarding yes

  一体、RedHat7.3の場合、設定ファイルにポートフォワーディングの
記述がないのか、わからない。
  あるサイトに「記述がなかったら、追加してください」というのがあったが
RedHat7.3の場合は、追加で記述しなくても、問題なくいける。
  なぜなのか、深く考えない私は、そのまま放置しまーす (^^)


  さて、クライアントの設定だが、私自身、OutlookExpressを使っているため
Windows上で動くPuTTYの説明にします。
  
PuTTYの設定部分
PuTTYのポートフォワーディングの設定
「Source port」の部分に1024以上の番号を入力。
わかりやすいように、本来のポート番号に10000を足した物を入れるのもOK

「Destination」の部分に、「localhost:25」を入れる。
この意味は、サーバー側のSSHがパケットをどこに転送するかを知らせる物で
この場合は、サーバー自身のポート25を意味している。

この設定で「localhost」がサーバー側で自分自身に接続する意味だと
理解したのは、しばらく経った後で、この設定を行った時点では、
クライアント自身の意味での「localhost」だと思っていた (^^;;

  次にOutlookExpressの設定を行う。

OutlookExpressの設定
OutlookExpressの接続サーバーの設定
OutlookExpressの設定として、みかけ上、クライアント自身に
接続する形になるので、接続先のサーバーが「localhost」になる。


OutlookExpressの設定
OutlookExpressの接続サーバーのポート番号の設定
接続先のポートは、SSHが待ち受けするために指定したポートにする。
私の場合、本来のポートに10000を足した数字にしているので
メール送信(SMTP)の場合は、25+10000=10025になり
メール受信(POP3)の場合は、110+10000=10110になる。

  これで設定が完了した。

  見事、成功!

  SSHを使って、自宅から会社のメールが読めるようになった!!


  それで、ポートフォワーディングの設定も習得したと思ったが、
ふと、次の事を思った。

自宅や外部から会社のAS/400へ接続が可能か?
自宅から会社へのAS400接続実験
自宅(外部)から会社のSSHサーバーまでの通信を暗号化して
AS/400への接続ができないかと考えた。

  どう設定して良いのか、わからない。
  だが、ネットで調べてみると、できる事がわかった。

  仕組みとしては、以下の通りだ。

SSHによるポートフォワードの仕組み:その2
SSHによるポートフォワードの仕組み
メールの送信はポート25。受け取りは110というように、各ポート事に
通信するデータが違っていたりする。もちろんデータの暗号化はされない。

そこで、SSHの暗号化の技術を使い、クライアント側は、メールの送信の際
アクセスする所を、localhost(自分自身)にして、ポートを10025にしておく。
SSHは、ポート10025にやってくるデータを待ち受け、データが来ると
それを接続先までSSHを使った暗号化通信を行う。

接続先では、SSHがポート25宛の通信だと認識して、自分自身の
ポート25へ接続を行う。

  さて、仕組みを知っても、実際に可能かどうか確かめる必要がある。
  そこで、次の実験を行ってみる事にした。

自宅や外部から会社のLinuxへ接続が可能か?
自宅から会社のlinuxマシンへの接続実験
自宅(外部)から会社のSSHサーバーまでの通信を暗号化して
他のLinuxのマシンへtelnetが可能かどうか

  まずは、PuTTYの設定を行う。

PuTTYの設定部分
PuTTYの設定:ポートと接続先
「Source port」の部分に1024以上の番号を入力。
わかりやすいように、本来のポート番号に10000を足した物を入れるのもOK

「Destination」の部分に、「192.168.XXX.YYY:23」を入れる。
この意味は、SSHで転送したい先のIPアドレス(192.168.XXX.YYY)と
telnetで使うポート23の意味だ。

  意外な事に、サーバ側の設定は不要だという。

  早速、telnetをやってみる事にした。

telnetを行ってみる
telnet localhost 10023

  結果は・・・

  見事、成功!

  これで、自宅からSSHのポートフォワードを使って、
SSHサーバー以外のLinuxマシンへtelnetできる事がわかった。

  さて、自宅からAS/400を使う場合、P-COMMで5250エミュレーターを使うため、
telnetと同じポート23を使う。

P-COMMの設定部分
P-COMMの設定部分
接続先をクライアント自身の「localhost」にした。
使うポートはtelnetの23に10000を足した10023にした。

  そして自宅からP-COMMを使って、AS/400へ接続を行った。
  結果は・・・

  見事、成功 (^^)V

自宅からAS/400へ接続できた様子
自宅からAS/400へ接続できた様子

  VPNを使って自宅から会社のAS/400への接続ができるのだが
今回の実験で、SSHという選択肢もできた。

SSHを使って外部から会社への接続実験

SSHを使って外部からの自宅からの自宅が可能になったのだが、 ホテルや外出先から社内へ接続ができるかとなると話は変わってくる。 以前、VPN(PPTP方式)で、自宅から会社へ接続は可能になった。 詳しくは「システム奮闘記:その27」をご覧ください。  (LinuxでPPTPサーバー構築) だが、ホテルなどの外出先から会社へ接続できない事がわかった。 実は、自宅では普通でない接続形態(?)をしている事にある。
自宅からの会社への接続形態
自宅からの会社への接続形態
なんと加入しているプロバイダーは気前よく8つもグローバルIPを
割り当ててくれているのだ。普通では考えられない。

 だが、一般的には以下のようなネットワーク形態になっている。

通常、考えられる会社への接続形態
通常、考えられる会社への接続形態
通常ならホテルなどではDHCPサーバーなどでIPを割り当てるが
ほとんどの場合、プライベートIPになるはずだ。

  原因は、PPTPのカプセリングによるNAT越えができないようだが、
2005年6月現在でも、推測の域をでないのだ。
  これも詳しくは「システム奮闘記:その27」をご覧ください。
 (LinuxでPPTPサーバー構築)


  そこで、SSHではNAT越えで障害が起こるのかどうか確認する必要がある。
  「できました」と喜んでいて、後で、「アカンかった」では、どうしようもない。


  だが、出張でホテルに泊まる予定もないし、友人の家に行く予定もない。

  2005年5月に、友人から連絡が入った。
  友人が「急に事務所のインターネットが使えへんようになってん。
すまんけど、いっぺん見にきてや」と言ったので、助けに行く事にした。
  そこで、事務所に行くついでに、実験も行おうと考えた。

  だが、実験はできなかった。なぜなら接続できない理由が・・・

  プロバイダー料金の滞納だからだった (--;;

  Bフレッツを入れているため、NTT西日本とプロバイダーに別々に料金を
払う必要があったのだが、そんな事は素人に、わかるわけがない。
  3月にBフレッツに加入して、NTT西日本に料金を払っていた際、
プロバイダーにも払っていると思い込んだため、2ヵ月、プロバイダー料金を
滞納した形になってしまい、接続を止められていたのだった。
  事務所の人達で、笑うしかなかった (^^;;
  すぐに料金を支払っても接続再開に2、3週間はかかるというので、実験を諦めた。


  さて、困った。自分の目で動作確認したくてもできない。
  そんなある日、急に札幌営業所へ出張予定が入った。
  パック旅行で申し込んだのだが、泊る予定のホテルがインターネット接続が
できるというので、「実験ができる」と喜んだ。

  だが、また天に見放された。なぜなら・・・

  ダイヤルアップ接続だったからだ (--;;

  モデムも無料貸出しで、インターネット接続ができる形態だった。
  自宅では、ケーブルテレビのプロバイダーなので、ダイヤルアップは
ありえない話。とことん運がない。

  だが、こんな事もあろうかと、秘策を練っていた。
  まずは、勤務先のネットワークの状態を説明します。

勤務先でのネットワークの状態
勤務先でのネットワークの状態
札幌営業所と本社との間では、インターネットVPNを使っている。
本社のインターネットVPNに使っている回線と、インターネットへの接続回線は
別の回線を使っている。

  そこで、次のような事を行えば、ホテルなどの接続環境が実現すると
札幌出張の前に考えていたのだ。

勤務先でのネットワークの状態
勤務先でのネットワークの状態
札幌で、インターネットVPNに使っている回線の設定を変更すれば、
簡単にインターネット接続ができる。
以前、ADSLルーターとして使っていたヤマハのRTA55iを使って、
札幌でインターネット接続の状態にした。
もちろん、札幌のパソコンにはプライベートIPを割り当てている。

いかにもホテルなどでの接続形態にする事ができた。

  早速、実験を行う事にした。実験の結果は・・・

  接続できへんかった (TT)

エラーの内容(PuTTY)
エラーの内容(PuTTY)
エラーの内容から見ると、パケットがサーバーに届いていないのか
それとも応答パケットがクライアントに帰って来ない事が伺える。

  PPTP同様、NAT越えの問題なのだろうか。
  だが、納得はいかない。仮に、NAT越えの問題であったとしても
PPTPのように、データリンク層でパケットをカプセリングしているわけでなく
アプリケーション層で暗号化を行っているのだ。
  NAT越えができないのは非常に考えにくい。

  本社のルーターの設定でも、キチンとSSHのパケットを通過させる設定をしている。
  でないと、自宅から接続ができないからだ。

  そこで、実際に本社のSSHサーバーにパケットが届いているのか、
サーバーからパケットを送り返しているのかを確かめるため、
tcpdump -S port 22を使って、データの採取を行った。

  だが、データの中身を札幌で原因を調べてから、やり直す時間はなかった。
  本社に戻ってからデータの中身を調べる事にした。

データの解析

さて、本社に戻り札幌で採取したデータを見てみる事にした。
tcpdump -S port 22を使って
札幌で採取したデータの中身
14:24:39.674711 AAA.BBB.CCC.ZZZ.60145 > ssh.xxx.co.jp.ssh: S 2248062641:2248062641(0) win 16384 <mss1414,nop,nop,sackOK>
14:24:39.674897 ssh.xxx.co.jp.ssh > AAA.BBB.CCC.ZZZ.60145: S 3066171333:3066171333(0) ack 2248062642 win 5840 <mss 1460,nop,nop,sackOK> (DF)
14:24:42.640422 AAA.BBB.CCC.ZZZ.60145 > ssh.xxx.co.jp.ssh: S 2248062641:2248062641(0) win 16384 <mss 1414,nop,nop,sackOK>
14:24:42.640511 ssh.xxx.co.jp.ssh > AAA.BBB.CCC.ZZZ.60145: S 3066171333:3066171333(0) ack 2248062642 win 5840 <mss 1460,nop,nop,sackOK> (DF)
14:24:43.866487 ssh.xxx.co.jp.ssh > AAA.BBB.CCC.ZZZ.60145: S 3066171333:3066171333(0) ack 2248062642 win 5840 <mss 1460,nop,nop,sackOK> (DF)
14:24:48.660800 AAA.BBB.CCC.ZZZ.60145 > ssh.xxx.co.jp.ssh: S 2248062641:2248062641(0) win 16384 <mss 1414,nop,nop,sackOK>
14:24:48.660896 ssh.xxx.co.jp.ssh > AAA.BBB.CCC.ZZZ.60145: S 3066171333:3066171333(0) ack 2248062642 win 5840 <mss 1460,nop,nop,sackOK> (DF)
14:24:49.866503 ssh.xxx.co.jp.ssh > AAA.BBB.CCC.ZZZ.60145: S 3066171333:3066171333(0) ack 2248062642 win 5840 <mss 1460,nop,nop,sackOK> (DF)
14:25:02.066501 ssh.xxx.co.jp.ssh > AAA.BBB.CCC.ZZZ.60145: S 3066171333:3066171333(0) ack 2248062642 win 5840 <mss 1460,nop,nop,sackOK> (DF)
14:25:26.066503 ssh.xxx.co.jp.ssh > AAA.BBB.CCC.ZZZ.60145: S 3066171333:3066171333(0) ack 2248062642 win 5840 <mss 1460,nop,nop,sackOK> (DF)
AAA.BBB.CCC.ZZZは札幌のVPNルーターに、1個割り当てられているグローバルIP
ssh.xxx.co.jpは本社のSSHサーバーのアドレス

ピンクの数値は、SSHサーバーが出した応答パケットのMSS値。

  この結果を見た時、SSHサーバーはパケットは受け取っているし、
その応答もキチンと返しているはずなのに、どこでパケットが消えているのか
不思議に思ったのだが、応答パケットのMSS値に注目した。

  MSS値とは、MTU値からパケットからヘッダー部分を抜いた物の値で、
データそのものの大きさを表す。
  MSS値を見ると1460になっている

  フレッツADSLの場合、MTU値は1454なので、確実、値を越えてしまう。
  しかも分割禁止のDFビットのフラグまで立っている。
  これでは、ADSL回線を応答パケットが通過する事ができない。

  これはPMTUブラックホールが起こっているはず!

  PMTUブラックホール問題。どうも私は、この問題に呪われているようだ。
  PPTPで自宅からリモートアクセスをしようとした時も、インターネットVPNを
導入した時も、この問題が発生し、頭を悩ませた事があった。

  さて、PMTUブラックホールを取り除いて、札幌での実験を再現した所だが、
まさか、このためだけに札幌へ行くわけにはいかない。

  何が良い方法がないのかと考えた所、日曜出勤する機会ができた。
  そこで考えた。本社には2回線、ADSL回線を敷いている。

本社にはADSLが2回線、敷いている
本社にはADSLが2回線、敷いている
1回線は、インターネットVPNのために使っていてる。
もう1回線は、インターネットへの接続ために使っている。

  日曜日なので拠点間通信を止めても問題はでないはず。
  そこで次のような実験を行う事を思いついた。

本社にはADSLが2回線、敷いている
本社にはADSLが2回線、敷いている
インターネットVPNに使っている回線を使って、
いかにも外部からインターネット接続をしている形にする。

そして、本社にあるインターネットへつながる回線へ接続して
NAT越えをしてSSHサーバーに接続できるか確かめる事にした。

  そして、PMTUブラックホール問題を解消するために、フレッツADSLの
MTUサイズ値(1454)を下回る1300の値を、SSHサーバーのMTUサイズにした。

  コマンドは「ifconfig eth0 mtu 1300」

  さて、実験開始。これで成功すると思いきや・・・

  なんで、つながらへんねん (TT)

  なぜ、接続できへんのか思いつかない。
  tcpdumpで採取したデータを眺めてみる事にした。

tcpdump -S port 22を使って
本社で採取したデータの中身
13:46:32.347353 XXX.YYY.ZZZ.AAA.60015 > ssh.xxx.co.jp.ssh: S 1056388070:1056388070(0) win 16384 <mss 1414,nop,nop,sackOK>
13:46:32.347467 ssh.xxx.co.jp.ssh > XXX.YYY.ZZZ.AAA.60015: S 929638769:929638769(0) ack 1056388071 win 5040 <mss 1260,nop,nop,sackOK> (DF)
13:46:32.348485 XXX.YYY.ZZZ.AAA.60015 > ssh.xxx.co.jp.ssh: R 1056388071:1056388071(0) win 0
13:46:35.322330 XXX.YYY.ZZZ.AAA.60015 > ssh.xxx.co.jp.ssh: S 1056388070:1056388070(0) win 16384 <mss 1414,nop,nop,sackOK>
13:46:35.322436 ssh.xxx.co.jp.ssh > XXX.YYY.ZZZ.AAA.60015: S 932613741:932613741(0) ack 1056388071 win 5040 <mss 1260,nop,nop,sackOK> (DF)
13:46:35.323445 XXX.YYY.ZZZ.AAA.60015 > ssh.xxx.co.jp.ssh: R 1056388071:1056388071(0) win 0
13:46:41.332984 XXX.YYY.ZZZ.AAA.60015 > ssh.xxx.co.jp.ssh: S 1056388070:1056388070(0) win 16384 <mss 1414,nop,nop,sackOK>
13:46:41.333132 ssh.xxx.co.jp.ssh > XXX.YYY.ZZZ.AAA.60015: S 938624430:938624430(0) ack 1056388071 win 5040 <mss 1260,nop,nop,sackOK> (DF)
13:46:41.334042 XXX.YYY.ZZZ.AAA.60015 > ssh.xxx.co.jp.ssh: R 1056388071:1056388071(0) win 0 
XXX.YYY.ZZZ.AAAは本社のVPNルーターに1個割り当てられているグローバルIP
ssh.xxx.co.jpは本社のSSHサーバーのアドレス

ピンクの数値は、SSHサーバーが出した応答パケットのMSS値。
これだとMTUサイズは1300になる。

  困った。そこで、無駄な抵抗として、応答パケットのDFビットを落とすため
NATのルーター側(RTX1000)に、DFビットを落とす設定を行った。

ルーターRTX1000で、パケットのDFフラグを「0」にする設定
ip fragment remove df-bit filter 100
フィルター100を通過するパケットは、DFフラグを「0」にする設定
ヤマハのルーターRTX1000の設定方法については
「システム奮闘記:その37」をご覧ください。

  だが、再度、実験に挑戦したのだが・・・

  やはり無駄な抵抗だった (TT)

  そこで、どこでパケットが詰まっているのか、考える事にした。
  ルーティングの状態を見て、辿って行くと、VPN用のルーターへ
応答パケットが行くようになっている。

パケットが進む順路
パケットが進む順路
SSHサーバーのデフォルトゲートウェイが、VPN用のルーターなので
上にあるような道筋で、パケットが進む事になる。

  そこで私は「原因は、VPN用のルーターにあるのではないか」と考えた。

  本来なら、VPN用のルーターのコンフィグを見て、原因をつぶすのが
先かもしれないのだが、何せ忍法「先送りの術」が得意な私は
まずは、応答パケットがVPNルーターへ飛ばないように、
SSHサーバーのデフォルトゲートウェイを、NATのルーターに変更した。

デフォルトゲートウェイを変更した
デフォルトゲートウェイを変更した
SSHサーバーのデフォルトゲートウェイを、NATのルータに変更し
応答パケットが上にあるような道筋で進むようにした。

  そして、もう一度、接続実験を試みると

  見事に成功した!!  (^^)V

  見事に、2重のNAT越えができている。

パケットが進む順路
パケットが進む順路
SSHサーバーのデフォルトゲートウェイを、NATのルータに変更したため
応答パケットが上の道筋で進むようになった。

  さて、成功の余韻に浸った後、パケットが詰まった原因になっていた
VPN用のルーターの設定ファイル(config:コンフィグ)を眺める事にした。
  すると納得がいく答えが見つかった

  まず、札幌での実験が失敗した理由。

本社VPNルーターの設定ファイル(config:コンフィグ)の内容
ip route AAA.BBB.CCC.ZZZ gateway pp 1
AAA.BBB.CCC.ZZZは札幌のVPNルーターに割り当てられている
グローバルIPで、記述から言えるのは、このIP宛のパケットは全て
VPNの回線へパケットを飛ばすルーティングになっている。

  つまり図に表すと下のようになる。

札幌での実験が失敗した理由
札幌での実験が失敗した理由
SSHサーバーから出た応答パケットは、VPNルーターへ行き
そこから札幌のVPNルーターへパケットを飛ばそうとした。
しかし、札幌のVPNルーターは取り外して、IPSeCの機能がないRTA55iを
ルータとして使っているため、パケットが弾かれ、消滅している形になっている。

  次に、本社での実験が失敗した理由。

本社VPNルーターの設定ファイル(config:コンフィグ)の内容
ip pp address XXX.YYY.ZZZ.AAA/32
XXX.YYY.ZZZ.AAA/32は本社のVPNルーターに割り当てられている
グローバルIPで、記述から言えるのは、このIP宛のパケットは全て
本社のVPNルーター宛になる。
しかし、IPSeC通信でも何でもないパケットなので、見事に無視され
パケットが消滅する事になる。

  つまり図に表すと下のようになる。

札幌での実験が失敗した理由
札幌での実験が失敗した理由
SSHサーバーから出た応答パケットは、VPNルーターへ行き
一見、目的地にたどり着いたと勘違い(?)を起こすが
パケットの中身がIPSeCでないため、パケットが無視され
パケットが消滅する事になる。

  これで札幌と本社での接続ができなかった謎が解けた。

  おまけに、NAT越えも問題なくできる事がわかった。

  実験は成功。めでたしめでたし (^^)V


最後に 今回は、長尾さんからの依頼がキッカケで、SSHを触る事になりましたが、 意外と便利な事に気づき、自宅から会社への接続に使うようになりました。 PPTPと違って、NAT越えの心配も考える必要がないので、 本当に、どこからでも接続できる上、ポートフォワーディングのお陰で AS/400などへの接続ができたりします。出張の時、便利です (^^) SSHを触るキッカケを作っていただいた長尾さんには感謝しています m(--)m

次章:Windowsでのパケットフィルタリングを読む
前章:xinetd スーパーデーモンの設定を読む
目次:システム奮闘記