Medir la latencia total de la sesión SSH

15

¿Hay alguna manera de medir / informar la latencia general en una sesión de SSH tunelizada?

Mi configuración particular es:

  • Cliente (OS X + enrutador wifi + módem ADSL)
  • Servidor Gateway SSH expuesto a Internet
  • Objetivo SSH interno al que estoy haciendo un túnel

Estoy interesado en ver la latencia entre la consola en mi máquina local y la máquina final en la que tengo abierta la sesión.

pez globo
fuente
¿Por qué no hacer un túnel SSH al primer servidor y luego la consola SSH al segundo servidor?
Bert

Respuestas:

6

Estaba tratando de hacer esto yo mismo y se me ocurrió esto. Probablemente hay una manera más simple, pero esto es lo que se me ocurrió.

Primero, prepare las tuberías que se utilizarán para que el programa de evaluación comparativa se comunique a través de la conexión SSH.

$ mkfifo /tmp/up /tmp/down

Luego establezca una conexión en modo ControlMaster sin ejecutar ningún comando remoto. Esto nos permite autenticarnos con el host de forma interactiva. Una vez establecida la conexión, SSH simplemente se "colgará" aquí en primer plano.

$ ssh $HOST -N -M -S /tmp/control

En una terminal paralela, ejecute remoto caten segundo plano. Será nuestro servidor de eco cuya latencia mediremos. Las entradas y salidas están conectadas a FIFOs:

$ ssh $HOST -S /tmp/control cat </tmp/up >/tmp/down &

Y luego compara un pequeño programa (envía un byte a upFIFO, recibe un byte de downFIFO):

$ python -m timeit -s 'import os' \
    'os.write(3, "z"); z=os.read(4, 1); assert z=="z", "got %s" % z' \
    3>/tmp/up 4</tmp/down
10 loops, best of 3: 24.6 msec per loop

La medida obviamente muestra la latencia de ida y vuelta. Si necesita repetir el experimento, ejecute los dos últimos comandos ( sshy python) nuevamente.

Si algo parece salir mal, use el -vindicador SSH para obtener más resultados de depuración.

Nicht Verstehen
fuente
4

Me salté algunos pasos sugeridos por @ nicht-verstehen:

python -m timeit --setup 'import subprocess; p = subprocess.Popen(["ssh", "user@host", "cat"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, bufsize=0)' 'p.stdin.write(b"z"); assert p.stdout.read(1) == b"z"'

Dónde

python -m timeitEjecuta el timeitmódulo Python.

La -s/--setupopción le dice timeitqué declaración (s) ejecutar antes de cada repetición.

subprocess.Popen(["ssh", "user@host", "cat"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, bufsize=0)se inicia ssh, ejecutándose caten su host, como un hijo / subproceso, redirigiendo sus secuencias de E / S a objetos similares a archivos de Python. bufsize=0se asegura de que no se almacenen IO, lo que puede provocar que IO espere.

Y para cada ciclo:
p.stdin.write(b"z")escribe un solo byte en el hijo (a su vez a través de ssh cat).
p.stdout.read(1)lee un solo byte del niño. La afirmación a su alrededor prueba si ese byte es el mismo que le escribió.

Se reduce a lo mismo, pero omite la creación de las canalizaciones con nombre ( mkfifo). Noté que cuantos más bucles ejecutes, más rápido será cada bucle. Controlarlo usando -n/--number:python -m timeit --number 50 ...

hzpc-joostk
fuente
3

Vea la sshpingutilidad: https://github.com/spook/sshping

Ejemplo:

# sshping 172.16.47.143
--- Login: 1725 msec
--- Minimum Latency: 4046 nsec
---  Median Latency: 11026 nsec  +/- 0 std dev
--- Average Latency: 178105 nsec
--- Maximum Latency: 8584886 nsec
---      Echo count: 1000 Bytes
---  Transfer Speed: 11694919 Bytes/second

# sshping --help
Usage: sshping [options] [user@]addr[:port]

  SSH-based ping that measures interactive character echo latency
  and file transfer throughput.  Pronounced "shipping".

Options:
  -c  --count NCHARS   Number of characters to echo, default 1000
  -e  --echocmd CMD    Use CMD for echo command; default: cat > /dev/null
  -h  --help           Print usage and exit
  -i  --identity FILE  Identity file, ie ssh private keyfile
  -p  --password PWD   Use password PWD (can be seen, use with care)
  -r  --runtime SECS   Run for SECS seconds, instead of count limit
  -t  --tests e|s      Run tests e=echo s=speed; default es=both
  -v  --verbose        Show more output, use twice for more: -vv
Tio spook
fuente
0

Mi idea era usar secuencias de consulta de terminal para esto; la ventaja es que esto simplemente se puede ejecutar en el servidor, la desventaja es que mide la latencia del terminal, no solo la latencia de la conexión (sino que supongo que, por lo general, el tiempo de respuesta de su terminal será insignificante en comparación con los retrasos de la red), tal vez esto es incluso lo que quieres decir con latencia general

#!/usr/bin/env python3
# Measure terminal latency (round-trip time) using "Query device code" command
from sys import stdin, stdout
import tty, termios, time

oldtty = termios.tcgetattr(stdin)
try:
    tty.setcbreak(stdout)

    runs = 10
    results = []
    for _ in range(runs):
        stdout.write("\x1b[c")
        stdout.flush()
        t1 = time.time()
        ch = stdin.read(1)
        assert(ch == '\x1b')
        t2 = time.time()
        while stdin.read(1) != 'c': # swallow rest of report
            continue
        latency = (t2 - t1) * 1000
        print('%.1fms' % (latency))
        results.append(latency)

    print()
    print('avg: %.1fms min: %.1fms max: %.1fms' % (
        sum(results) / runs,
        min(results),
        max(results)))
finally:
    termios.tcsetattr(stdin, termios.TCSADRAIN, oldtty)

(Esto usa "Device Code Query", todos los terminales que he intentado responden a esto: xterm, alacritty, gnome-terminal. No puedo probar esto en MacOS. Entonces YMMV, si este no lo hace, otra de las solicitudes para consultar información sobre el terminal que podría funcionar, consulte http://www.termsys.demon.co.uk/vtansi.htm )

wump
fuente
1
Esta respuesta aún podría usar alguna explicación para aquellos que no están tan familiarizados con los elementos internos (por ejemplo, por qué \x1b[csería favorable)
ans
No seguro de que es favorable, creo que es una discusión válida: cualquier desde el "Estado del dispositivo" termsys.demon.co.uk/vtansi.htm quiere trabajar, dada la terminal lo soporta, y no tengo ni idea de lo que está bien soportado, pero Supongo que la consulta básica de estado sería (incluso funciona en Alacritty)
wump