SSH接続の帯域幅を測定する方法

SSH接続の帯域幅を測定する方法

リモートコンピュータへの特定のSSH接続の帯域幅をどのように測定しますか?たとえば、ポート転送を実行するSSHトンネルがある場合は、そのトンネルを通過するデータの量を知りたいと思います。具体的には、双方向転送速度と送信された総データ量(双方向個別)を知りたいです。どうすればいいですか?

オペレーティングシステム:Debian 11とUbuntu 20.04。

答え1

SSH接続を介して送信されたネットワークトラフィックを測定できます。

例えば:

iftop -i "$iface" -nPf "tcp and port $sport and port $dport"

$ifaceSSH接続用のパケットが送受信されるインターフェイスと送信元および$sport宛先$dportTCPポート。f送信元と宛先のIPアドレスを指定して、フィルタをさらに絞り込むことができます。

またはnethogs "$iface"、これを使用して各プロセスの詳細を取得できます。

ただし、これにはイーサネット、IP、TCP、およびSSHプロトコルの追加のオーバーヘッドが含まれるため、暗号化前にSSHトンネルを通過するデータの量は含まれません。

tsharkパケットをデコードしてTCPペイロードのサイズを知ることで、イーサネット、IP、TCPオーバーヘッドを排除できます。ただし、SSHプロトコルは暗号化されているため、これ以上分析できません。

さまざまなソースで処理する必要があるデータ量を処理するには、自分に知らせる必要がありsshますssh。あるいは、プロセスで実行されたstraceすべてのシステムコールを報告するために使用できますread()。 SSH TCPソケットの読み取り/書き込みは、暗号化とSSHプロトコルのオーバーヘッド(上記のTCPペイロードと一致する必要があります)の後に送信されたデータの量を示します。します。対話型セッションの場合は、ポートリダイレクト用のネットワークソケットなど)。write()ssh

概念証明としてPerlスクリプトを使用してこれを行うことができます。たとえば、次のようになります。

#! /usr/bin/perl
# usage: that-script <pid-of-ssh>

my $pid = shift@ARGV;
my $tunnel_fd;

# list the fds of the process on TCP sockets
open my $lsof, '-|', qw(lsof -wnPa -i tcp -Fd -p), $pid;
while (<$lsof>) {
  if (/^f(\d+)/) {
    # the first fd on a TCP socket is assumed to be that of the ssh connection
    $tunnel_fd = $1;
    last;
  }
}
close $lsof;
die "can't identify tunnel fd\n" unless defined $tunnel_fd;

my %dir;
sub pv {
  open my $fh, '|-', "sh", "-c", q(exec pv "-ctrabN$0" 2>&1 > /dev/null), $_[0];
  $fh->autoflush(1);
  return $fh;
}

open my $strace, '-|', qw(strace -q -s0 -e trace=read,write -e status=successful -a0 -o/dev/stdout -p), $pid;

$dir{"1read"}  = pv "outer  IN";
$dir{"write"}  = pv "inner  IN";
$dir{"read"}   = pv "inner OUT";
$dir{"1write"} = pv "outer OUT";

while (<$strace>) {
  if (/^(read|write)\((\d+).*= (\d+)/) {
    print { $dir{($2 eq $tunnel_fd) . $1} } "." x $3;
  }
}

pvレポートb時間、経過t時間、インスタントrフィード、a平均速度に使用されます。

次のものを提供してください。

$ sudo ./ssh-stat 26655
outer  IN:  768KiB 0:00:55 [0.00 B/s] [14.0KiB/s]
inner  IN:  718KiB 0:00:55 [0.00 B/s] [13.1KiB/s]
inner OUT: 33.0 B 0:00:55 [0.00 B/s] [ 613miB/s]
outer OUT: 1.62KiB 0:00:55 [0.00 B/s] [30.2 B/s]

たとえば、33バイトはinner OUT端末に入力されたキーに対応するいくつかの文字で送信されてouter OUTいますが、SSHプロトコルの一部として送信されたデータは次のようになります(これらの文字をカプセル化するために使用しましたが、他の方向では次のように確認します。したい)。よく) 。

各SSHチャネルに関する詳細情報を取得するには、それを拡張して各fdの個別のレポートを提供できます。各fdを記述するオプションが-yy役に立ちます。strace例えば:

$ sudo strace -yy -q -s0 -e trace=read,write -e status=successful -a0 -o /dev/stdout -p 26655
read(6</dev/pts/1<char 136:1>>, ""..., 16384) = 3
write(3<TCP:[127.0.0.1:42334->127.0.0.1:22]>, ""..., 44) = 44
read(3<TCP:[127.0.0.1:42334->127.0.0.1:22]>, ""..., 8192) = 52
write(7</dev/pts/1<char 136:1>>, ""..., 16) = 16
read(6</dev/pts/1<char 136:1>>, ""..., 16384) = 3
write(3<TCP:[127.0.0.1:42334->127.0.0.1:22]>, ""..., 44) = 44
read(3<TCP:[127.0.0.1:42334->127.0.0.1:22]>, ""..., 8192) = 60
write(7</dev/pts/1<char 136:1>>, ""..., 26) = 26
read(3<TCP:[127.0.0.1:42334->127.0.0.1:22]>, ""..., 8192) = 44
write(9<TCP:[127.0.0.1:12344->127.0.0.1:43144]>, ""..., 3) = 3
read(9<TCP:[127.0.0.1:12344->127.0.0.1:43144]>, ""..., 16384) = 11
write(3<TCP:[127.0.0.1:42334->127.0.0.1:22]>, ""..., 52) = 52

私のテストは、SSH接続(fd 3)のデータ量、tty(fds 6、7)と送受信するデータの量、ローカルポートからポート12344(fd 9)に転送されるデータの量を示しています。 。

関連情報