Mesurer la latence totale de la session SSH

15

Existe-t-il un moyen de mesurer / signaler la latence globale dans une session SSH tunnelée?

Ma configuration particulière est:

  • Client (OS X + routeur wifi + modem ADSL)
  • Le serveur Gateway SSH exposé à Internet
  • Cible SSH interne vers laquelle je creuse un tunnel

Je suis intéressé à voir la latence entre la console sur ma machine locale et la dernière machine sur laquelle j'ai ouvert la session.

poisson-globe
la source
Pourquoi pas un tunnel SSH vers le premier serveur, puis une console SSH vers le deuxième serveur.
Bert

Réponses:

6

J'essayais de le faire moi-même et j'ai trouvé ça. Il existe probablement un moyen plus simple, mais c'est ce que j'ai trouvé.

Tout d'abord, préparez les tuyaux qui seront utilisés pour faire communiquer le programme d'analyse comparative via la connexion SSH.

$ mkfifo /tmp/up /tmp/down

Établissez ensuite une connexion en mode ControlMaster sans exécuter de commande à distance. Cela nous permet de nous authentifier de manière interactive avec l'hôte. Une fois la connexion établie, SSH se "suspend" juste ici au premier plan.

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

Dans un terminal parallèle, exécutez remote caten arrière-plan. Ce sera notre serveur d'écho dont nous mesurerons la latence. Les entrées et sorties sont connectées aux FIFO:

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

Et puis comparer un petit programme (envoyer un octet à upFIFO, recevoir un octet 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 mesure montre évidemment la latence aller-retour. Si vous devez répéter l'expérience, exécutez à nouveau les deux dernières commandes ( sshet python).

Si quelque chose semble mal se passer, utilisez l' -vindicateur SSH pour obtenir plus de sortie de débogage.

Nicht Verstehen
la source
4

J'ai sauté quelques étapes suggérées par @ 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"'

python -m timeitexécute le timeitmodule Python.

L' -s/--setupoption indique timeitquelle (s) instruction (s) exécuter avant chaque répétition.

subprocess.Popen(["ssh", "user@host", "cat"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, bufsize=0)se lance ssh- s'exécutant catsur votre hôte - en tant qu'enfant / sous-processus, redirigeant ses flux d'E / S vers des objets de type fichier Python. bufsize=0s'assure qu'aucun IO n'est mis en mémoire tampon, ce qui peut entraîner des attentes d'E / S.

Et pour chaque boucle:
p.stdin.write(b"z")écrit un seul octet à l'enfant (à son tour via ssh to cat).
p.stdout.read(1)lit un seul octet de l'enfant. L'assertion qui l'entoure teste si cet octet est le même que celui que vous lui avez écrit.

Se résume à la même chose, mais ignore la création des canaux nommés ( mkfifo). J'ai remarqué que plus vous exécutez de boucles, plus chaque boucle est rapide. Contrôlez-le en utilisant -n/--number:python -m timeit --number 50 ...

hzpc-joostk
la source
3

Voir l' sshpingutilitaire: https://github.com/spook/sshping

Exemple:

# 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
Oncle Spook
la source
0

Mon idée était d'utiliser des séquences de requêtes terminales pour cela; l'avantage est que cela peut simplement être exécuté sur le serveur, l'inconvénient est qu'il mesure la latence du terminal, non seulement la latence de la connexion (mais je suppose que, généralement, le temps de réponse de votre terminal sera négligeable par rapport aux retards du réseau) - peut-être c'est même ce que vous entendez par latence globale

#!/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)

(Cela utilise "Device Code Query", tous les terminaux auxquels j'ai essayé de répondre: xterm, alacritty, gnome-terminal. Je ne peux pas essayer moi-même sous MacOS. Donc YMMV, si celui-ci ne le fait pas, une autre des demandes qui interrogent certaines informations sur le terminal peuvent fonctionner, voir http://www.termsys.demon.co.uk/vtansi.htm )

effondrer
la source
1
Cette réponse pourrait toujours utiliser une explication pour ceux qui ne sont pas aussi familiers avec les internes tty (par exemple, pourquoi \x1b[cserait favorable)
et le
Je ne suis pas sûr que ce soit favorable, je pense que c'est une discussion valable: n'importe lequel des termes "Device Status" termsys.demon.co.uk/vtansi.htm fonctionnerait, étant donné que le terminal le prend en charge, et je n'ai aucune idée de ce qui est bien pris en charge, mais je suppose que la requête d'état de base serait (même fonctionne dans Alacritty bare-bones)
wump