SSH 연결의 대역폭을 측정하는 방법

SSH 연결의 대역폭을 측정하는 방법

원격 컴퓨터에 대한 특정 SSH 연결의 대역폭을 어떻게 측정합니까? 예를 들어 포트 전달을 수행하는 SSH 터널이 있는 경우 해당 터널을 통과하는 데이터의 양을 알고 싶습니다. 특히, 양방향 전송 속도와 전송된 총 데이터 양(양방향 개별)을 알고 싶습니다. 어떻게 해야 하나요?

운영 체제: Debian 11 및 Ubuntu 20.04.

답변1

SSH 연결을 통해 전송된 네트워크 트래픽을 측정할 수 있습니다.

예를 들어:

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

$ifaceSSH 연결을 위한 패킷이 전송/수신되는 인터페이스 와 $sport소스 $dport및 대상 TCP 포트입니다. f소스 및 대상 IP 주소를 지정하여 필터를 더욱 구체화 할 수 있습니다 .

또는 nethogs "$iface"이를 사용하면 각 프로세스에 대한 세부 정보를 얻을 수 있습니다.

그러나 여기에는 이더넷, IP, TCP 및 SSH 프로토콜의 추가 오버헤드가 포함되므로 암호화 전에 SSH 터널을 통과하는 데이터의 양은 포함되지 않습니다.

tshark패킷을 디코딩하고 TCP 페이로드의 크기를 알려줌으로써 이더넷, IP, TCP 오버헤드를 제거할 수 있습니다. 그러나 SSH 프로토콜은 암호화되어 있으므로 더 이상 분석할 수 없습니다.

다양한 소스에서 처리해야 하는 데이터의 양을 처리하려면 스스로에게 알려야 ssh합니다 ssh. 또는 프로세스에서 수행된 strace모든 시스템 호출을 보고하는 데 이를 사용할 수 있습니다 read(). SSH TCP 소켓에 대한 읽기/쓰기는 암호화 및 SSH 프로토콜 오버헤드(위의 TCP 페이로드와 일치해야 함) 후에 전송된 데이터의 양을 알려주며, 나머지 대부분은 다른 채널(예: tty)에서 읽고 쓰는 내용이어야 합니다. 대화형 세션의 경우 포트 리디렉션을 위한 네트워크 소켓 등).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)로 전달되는 데이터의 양을 보여줍니다. .

관련 정보