こんにちは。RedHat9を使用しています。
SSHクライアントに就いての質問です。
$ rpm -qa | grep ssh
openssh-clients-3.5p1-11
openssh-askpass-gnome-3.5p1-11
openssh-server-3.5p1-11
openssh-3.5p1-11
openssh-askpass-3.5p1-11
# grep -v ^# /etc/ssh/ssh_config
Host *
ForwardX11 yes
Host 192.168.1.105
HostbasedAuthentication yes
としています。他ホストのSSHサーバにアクセスする時には送信元ポートはダイナミックポートがランダムに選択されているようですが
これはどうしてランダムに選択されるのでしょうか?
(セキュリティの為なんでしょうか)
所でこれを制限する
(例えば、65500〜65535をSSHクライアントとして使用させる)
方法を知りたいのですがどうすれば制限できるのでしょうか?
> としています。他ホストのSSHサーバにアクセスする時には送信元ポートはダイナミックポートがランダムに選択されているようですが
> これはどうしてランダムに選択されるのでしょうか?
> (セキュリティの為なんでしょうか)
>
> 所でこれを制限する
> (例えば、65500〜65535をSSHクライアントとして使用させる)
> 方法を知りたいのですがどうすれば制限できるのでしょうか?
クライアント側がどのポートを使ってアクセスするかは、クライアントの作りに依存するので制御はできません。一般的には、SSHだけでなくクライアント側からセッションを設定する場合、OSに任せており、OSが管理しているポートでその時点で空いているポートがアサインされるのでコントロールできません。
仮にコントロールできたとしても、今度はクライアントのネットワーク環境で問題がでます。クライアントがグローバルアドレスを持っているなら問題にはなりませんが、NATルータ(今回のようなケースでは、少し正確にNAPTルータといったほうがいいかもしれません)経由で繋がっている場合、仮にクライアントが65500でアクセスしてもルータが勝手に書き換えてしまう(これで、複数の端末が1つのグローバルアドレスで同時通信できるようにしている)ので、意味がありません。
セキュリティ対策なら秘密鍵方式なり、アドレス制限なりいろいろあると思いますが。
ご丁寧なご説明に恐縮致します。
> クライアント側がどのポートを使ってアクセスするかは、クライアントの作りに依
> 存するので制御はできません。
例えば、hogeというクライアントは「50000〜60000で空いているポートでなるべく若いポート番号を使用する」
みたいな感じですかね…
> 一般的には、SSHだけでなくクライアント側からセッ
> ションを設定する場合、OSに任せており、OSが管理しているポートでその時点で空い
> ているポートがアサインされるのでコントロールできません。
一般的に空いているポートでなるべく若い番号のポートを使用させるのですよね。
> 仮にコントロールできたとしても、今度はクライアントのネットワーク環境で問題
> がでます。クライアントがグローバルアドレスを持っているなら問題にはなりません
> が、NATルータ(今回のようなケースでは、少し正確にNAPTルータといったほうがいい
> かもしれません)経由で繋がっている場合、仮にクライアントが65500でアクセスして
> もルータが勝手に書き換えてしまう(これで、複数の端末が1つのグローバルアドレ
> スで同時通信できるようにしている)ので、意味がありません。
つまり、ルータにA、Bというクライアントマシン(双方とも同ネットワークアドレス)が繋がっている場合、
もし、Aでのユーザがsshクライアントポートとして50000を指定してルータ経由でWAN側とアクセスを開始すると
そのルータからもWAN側に送信元ポート番号として50000というパケットが送り出される。
この後にBでもユーザがsshクライアントポートとして同じく50000を指定した場合にルータは同様に50000を送信元ポート番号として
パケットが送出される。しかし、ルータは戻ってきた応答パケットをAのsshクライアント、Bのsshクライアントのどちらに届ければいいのか判別不能に陥ってしまうということですか?
そうしますと、BのOSはsshクライアントが使用するポートを決定する際に先ず、ルータに50000番ポートを使用可能か問い合わせして
使用可能ならそのポートをsshクライアントに割当てる。もし、既にAのsshクライアントが使用中ならBは50000以外のポートの使用を検討する。
という具合なのでしょうか(つまり、OSはsshクライアントの使用ポートを決定する場合、localhostとゲートウェイに相談して決定するのですか)?
参考にお伺いしたいのですがもし、ネットワークツールを自作して60000は常にそのツールが使用可能にしておきたい場合には
/etc/serviceに予約しておけばいいのですね?
あっ、もしこういう事が可能ならsshクライアントポートを55000〜60000に制限したい場合には
49152〜54999を/etc/serviceに記述して予約しておけばいいのでは?
(OSが自由に使用できるポートが55000〜60000の5000ポートというのは少なすぎますかね)
> セキュリティ対策なら秘密鍵方式なり、アドレス制限なりいろいろあると思います
> が。
そのようですね。
こんばんは。
少し酔ってますが、大丈夫でしょう。
> > クライアント側がどのポートを使ってアクセスするかは、クライアントの作りに依
> > 存するので制御はできません。
> 例えば、hogeというクライアントは「50000〜60000で空いているポートでなるべく若いポート番号を使用する」
> みたいな感じですかね…
少しニュアンスが違いますね。各クライアントのポートの管理はOSが行っており、クライアントでソフトが動作する時にどのポートを使うかは、各ソフトのつくりによります。ソフトがOSに明示的に使用するポートを指定してアサインしてもらうものと、何でもいいからアサインしてと要求するものの二種類があります。ここで、OSがアサインするのが1024〜65535まででその時点で空いているポートをアサインします。明示的にオポートを指定して要求したとき、他のソフトでそれがふさがっていれば、その旨OSはソフトに返すので、ソフト側は改めてポートを変更して要求します。
> > 一般的には、SSHだけでなくクライアント側からセッ
> > ションを設定する場合、OSに任せており、OSが管理しているポートでその時点で空い
> > ているポートがアサインされるのでコントロールできません。
> 一般的に空いているポートでなるべく若い番号のポートを使用させるのですよね。
このあたりはよくわかりません。順番にあがっていっているようにも見えます。
> > 仮にコントロールできたとしても、今度はクライアントのネットワーク環境で問題
> > がでます。クライアントがグローバルアドレスを持っているなら問題にはなりません
> > が、NATルータ(今回のようなケースでは、少し正確にNAPTルータといったほうがいい
> > かもしれません)経由で繋がっている場合、仮にクライアントが65500でアクセスして
> > もルータが勝手に書き換えてしまう(これで、複数の端末が1つのグローバルアドレ
> > スで同時通信できるようにしている)ので、意味がありません。
> つまり、ルータにA、Bというクライアントマシン(双方とも同ネットワークアドレス)が繋がっている場合、
> もし、Aでのユーザがsshクライアントポートとして50000を指定してルータ経由でWAN側とアクセスを開始すると
> そのルータからもWAN側に送信元ポート番号として50000というパケットが送り出される。
> この後にBでもユーザがsshクライアントポートとして同じく50000を指定した場合にルータは同様に50000を送信元ポート番号として
> パケットが送出される。しかし、ルータは戻ってきた応答パケットをAのsshクライアント、Bのsshクライアントのどちらに届ければいいのか判別不能に陥ってしまうということですか?
これが、NATです。つまりプライベートアドレスをグーロバルアドレスに変換するだけなので、一対一にしか対応できず、この対応をスタティックにルータに設定して使用します。これを解消する技術がBBRに実装されているNAPT(IPマスカレードといったり、ルータによってはNATといっています。)で、NATがアドレスの変換しかしないのに対して、ポート番号も変換します。上記でいうなら、Aが50000のポートでインターネットアクセスすると、アドレスをルータのWAN側のグローバルアドレスに変換し、ポートを例えば10000に変換して送り出します。同時に、Bが50000でアクセスしてくると、アドレスを同様にWAN側グローバルに変換し、ポートを今度は10001に変換して送り出します。この変換表をルータは覚えておき、帰りのパケットが10000宛にもどってくればそれは、Aにいくようアドレスを変換し、ポートも元の50000に変換して返します。同様に10001ならBの50000に返します。これにより、ひとつのグローバルアドレスで家庭内の複数の端末が同時通信できるわけです。
> そうしますと、BのOSはsshクライアントが使用するポートを決定する際に先ず、ルータに50000番ポートを使用可能か問い合わせして
> 使用可能ならそのポートをsshクライアントに割当てる。もし、既にAのsshクライアントが使用中ならBは50000以外のポートの使用を検討する。
>
> という具合なのでしょうか(つまり、OSはsshクライアントの使用ポートを決定する場合、localhostとゲートウェイに相談して決定するのですか)?
上記のとおりです、クライアントで独立して使用ポートが決定され、ルータがダイナミックにWAN側で使うポートにマッピングします。
> 参考にお伺いしたいのですがもし、ネットワークツールを自作して60000は常にそのツールが使用可能にしておきたい場合には
> /etc/serviceに予約しておけばいいのですね?
> あっ、もしこういう事が可能ならsshクライアントポートを55000〜60000に制限したい場合には
> 49152〜54999を/etc/serviceに記述して予約しておけばいいのでは?
> (OSが自由に使用できるポートが55000〜60000の5000ポートというのは少なすぎますかね)
上記のとおりで、クライアントソフトが決めるものです。servicesに書いてあるのは、クラサバのサーバ側で使用するポート(即ち、サーバがクライアントからの接続を待ち受けているポート)です。送信元のポートと宛先のポートが存在していることを忘れないでください。
>>> クライアント側がどのポートを使ってアクセスするかは、クライアントの作り
> に依
>>> 存するので制御はできません。
>> 例えば、hogeというクライアントは「50000〜60000で空いているポートでなるべく
> 若いポート番号を使用する」
>> みたいな感じですかね…
> 少しニュアンスが違いますね。各クライアントのポートの管理はOSが行っており、
> クライアントでソフトが動作する時にどのポートを使うかは、各ソフトのつくりによ
> ります。ソフトがOSに明示的に使用するポートを指定してアサインしてもらうもの
> と、何でもいいからアサインしてと要求するものの二種類があります。ここで、OSが
> アサインするのが1024〜65535まででその時点で空いているポートをアサインしま
> す。明示的にオポートを指定して要求したとき、他のソフトでそれがふさがっていれ
> ば、その旨OSはソフトに返すので、ソフト側は改めてポートを変更して要求します。
なるほど。
> して送り出します。この変換表をルータは覚えておき、帰りのパケットが10000宛に
この変換表はRedHat9では何というファイルにになるのですかね?
> 上記のとおりで、クライアントソフトが決めるものです。servicesに書いてあるの
> は、クラサバのサーバ側で使用するポート(即ち、サーバがクライアントからの接続
> を待ち受けているポート)です。
> 送信元のポートと宛先のポートが存在していること
> を忘れないでください。
つまり、サーバ待ち受けポートとして予約してあるからいざクライアントが送信元ポートとしてそのポートを避けてくれるという訳ではないのですね。
これは知りませんでした。
クライアントの/etc/serviceに予め49152〜54999を記述しておけば、クライアントは49152〜54999以外のポート番号でOSにアサインを要求しにいってくれるのでは思いましたが甘かったですね。
たとえ、そのように記述しておいたとしてもクライアントが送信元ポートして49152〜54999の使用も可能な訳ですね。
(49152〜54999がサーバ待ち受けポートになっていようがクライアントには知ったこっちゃない!?)
MKaoriさん、おやじさんこんばんは。
この話題、興味があったので2.4.18のカーネルソースをざっと見て調べて見ました。
というわけで、あくまでカーネル2.4.18の実装の話です。
あるマシンで管理されているポートは、送信元と待ち受けの差はありません。
一元的に管理されているポートの内、あるポートを「使って」待ち受けたり、あるポートを「使って」
送信したりするだけです。
apacheは、80番ポートを「使って」待ち受けます。
そのマシンでtelnetクライアントを動かすと、例えば自動割当された50000番ポートを「使って」
宛先マシンの23番に接続します。
結局そのマシンでは、80番と50000番ポートが利用中になります。
ただし、当然ながら利用中ポートの管理とは別に通信の管理があって、そこでは自分のIP:自分のポート、
相手のIP:相手のポートというセットの管理をしています。
では、上のtelnetクライアントの50000番ポートがどのように選択されるかですが、一般的なクライアント
プログラムは、OSに空いているポートを自動的に割り当ててもらいます。
この自動割当ポートの範囲は搭載メモリ量によって決まり、cat /proc/sys/net/ipv4/ip_local_port_range
で確認することができます。
私の手持ちのマシンでは、
256MB搭載 32768-61000
64MB搭載 1024-4999
となっています。
この範囲の中から現在未使用のポートが選択されますが、ロジックは以下の通りです。
1)初めての自動割当の時は、自動割当範囲の最小値から順に調べ、未使用ポートを割り当てる。
2)2回目以降は、前回割り当てたポートから1増やしながら調べて未使用ポートを割り当てる。
3)自動割当範囲の最大値まで来たら、最小値に戻る。
例えば、telnetクライアントにポート32768番が割り当てられたとします。
そのtelnetクライアントを終了すれば32768番は空くのですが、次にtelnetクライアントを立ち上げると
1増やした32769番が割り当てられます。
> つまり、サーバ待ち受けポートとして予約してあるからいざクライアントが送信元ポートとしてその
> ポートを避けてくれるという訳ではないのですね。
> クライアントの/etc/serviceに予め49152〜54999を記述しておけば、クライアントは49152〜54999以外
> のポート番号でOSにアサインを要求しにいってくれるのでは思いましたが甘かったですね。
> たとえ、そのように記述しておいたとしてもクライアントが送信元ポートして49152〜54999の使用も
> 可能な訳ですね。
> (49152〜54999がサーバ待ち受けポートになっていようがクライアントには知ったこっちゃない!?)
/etc/servicesに記述しても無理です。49152-54999を使っているプログラム(サーバでもクライアントでも)
が動作していることが必要です。
>> して送り出します。この変換表をルータは覚えておき、帰りのパケットが10000宛に
> この変換表はRedHat9では何というファイルにになるのですかね?
これは勘違いしています。
変換表を覚えているのは「ルータ」ですので、RedHat9には全く関係ありません。
ただしRedHat9がルータ(iptablesを動かしていて、かつIPマスカレードを行っている)なら、
cat /proc/net/ip_conntrack
で変換表を見ることができます。
かつさん、こんばんは。
今年もよろしくお願いします。
> この話題、興味があったので2.4.18のカーネルソースをざっと見て調べて見ました。
> というわけで、あくまでカーネル2.4.18の実装の話です。
元気ですね。基本的に、おやじの認識はあっていたことを確認させていただきました。
ただ、メモリ量でポートレンジが変わるということは知りませんでした。総ポート数が変わるのは物理的なリソースから当然としても、スタートポイントが変わるというのは、何故なんですかね。
> かつさん、こんばんは。
> 今年もよろしくお願いします。
こちらこそ、宜しくお願いします。
> > この話題、興味があったので2.4.18のカーネルソースをざっと見て調べて見ました。
> > というわけで、あくまでカーネル2.4.18の実装の話です。
>
> 元気ですね。基本的に、おやじの認識はあっていたことを確認させていただきました。
実は、おやじさんの方こそ元気だと常々思ってます。
私は、自分が興味が出たところだけ調べてるので、大したことないです。
> ただ、メモリ量でポートレンジが変わるということは知りませんでした。
> 総ポート数が変わるのは物理的なリソースから当然としても、スタートポイントが変わるというのは、
> 何故なんですかね。
自動割当範囲が1024-4099ということは、well-known-portも合わせると1-4099を管理すべくメモリを
確保しています。
自動割当範囲が49152-54999の場合は、1-54999までを管理しているみたいです。
という訳で、スタートポイントもずらしているんだと思います。