IP oder Hostname des Ursprungscomputers finden (ssh)

10

Ich verbinde mich ständig mit einer Reihe von Maschinen, von verschiedenen physischen Standorten (und damit von verschiedenen physischen Maschinen). Das meiste wird über ssh gemacht, manchmal sind ein oder zwei Gateway-Rechner erforderlich (die ich über ProxyCommandin aufrufe ~/.ssh/config). Ich möchte wissen, ob es eine Methode gibt, um die IP-Adresse oder den Hostnamen des Computers zu identifizieren, der die ursprüngliche Verbindung (dh den Computer, an dem ich arbeite) am Remote-Ende aufruft.

  • Ich möchte keine Umgebungsvariablen senden, da auf einigen Computern kein Root festgelegt werden muss PermitUserEnvironment.
  • Die $SSH_CLIENTUmgebungsvariable ist nützlich für direkte Verbindungen, listet jedoch nur das aktuellste Gateway auf.

Meine aktuelle Idee für eine Lösung ist $SSH_CLIENTes, den $SSH_CLIENTWert dieser Maschine zu ermitteln und zu wiederholen, bis er nicht mehr existiert. Nehmen Sie dann den Hostnamen und ziehen Sie ihn irgendwie zurück.

Scheint allerdings ein bisschen wie ein Hack-Job zu sein; Hat jemand eine bessere Methode?

Ich arbeite hauptsächlich in einer Bash-Shell, freue mich aber auch über Vorschläge, die diese nicht verwenden.

Geodätisch
quelle
Ein Zweck von ProxyCommand ist natürlich, den Ursprungshost zu verbergen (oder zu vergessen) (der beispielsweise ohnehin nicht vom endgültigen Host routbar ist)
Hagen von Eitzen
Können Sie ein Beispiel geben, wo oder warum Sie diese Informationen benötigen? Es könnte andere nicht offensichtliche Lösungen geben.
Manwe
@Manwe Ich möchte letztendlich länderspezifische Abschnitte in Dingen wie meiner .bashrc einrichten. Im Moment möchte ich nur eines von drei Tastaturlayouts automatisch in vim einstellen, je nachdem, auf welchem ​​Computer ich arbeite.
Geodätisch

Antworten:

3

Ich habe es noch nie versucht, aber mir fällt etwas ein, das funktionieren könnte: Sie lassen SSH Ihre Login-Shell nicht starten, sondern nehmen die Angelegenheit selbst in die Hand. Sie können SSH anweisen, beliebige Befehle auszuführen. Anstatt von

ssh remote_host

Sie würden etwas in der Art von laufen

ssh remote_host -t "
    . /etc/profile; 
    . /etc/bash.bashrc; 
    DAT_ORIGIN_HOST=$(ifconfig eth0|grep -Po 't addr:\K[\d.]+') /bin/bash -l -i"

Dies gibt SSH etwas anderes zu tun, anstatt eine Login-Shell zu starten. Das ist eine Zeichenfolge, die remote als Befehl ausgeführt wird. Wir verwenden dies, um eine Shell auf eine ganz besondere Art und Weise zu starten: Wir geben ihr eine Umgebungsvariable DAT_ORIGIN_HOST, die unsere IP auf eth0 enthält (möglicherweise müssen Sie dies ändern).

Der Trick, den wir ausführen, besteht darin, dass wir den Befehl zur Remote-Ausführung in doppelte Qouten setzen ". Die doppelten Anführungszeichen (zumindest in Bash) bedeuten, dass unsere Shell, bevor der String an SSH übergeben wird, ihn scannt und gegebenenfalls Erweiterungen / Ersetzungen durchführt. Dies bedeutet, dass unsere Shell den Teil `$ (ifconfig ...) an unsere aktuelle IP-Adresse auswertet und ssh eine Zeichenfolge übergibt, die die Definition für eine Umgebungsvariable mit unserer lokalen IP-Adresse enthält.

Sobald Sie am Remote-Computer angemeldet sind, echo $DAT_ORIGIN_HOSTsollten Sie Ihre IP-Adresse drucken.

Um diesen Aufruf an SSH zu entwickeln, habe ich von hier aus schamlos die IP-Adresse extrahiert und hier das -t und wie man etwas Interaktives startet

Haftungsausschluss: Ich bin mir nicht sicher über die -lund -iOption zu /bin/bash. Vielleicht müssen Sie sie weglassen.

user1129682
quelle
Sie könnten hier auf etwas sein! Ich werde ein bisschen damit herumspielen und mich bei Ihnen melden.
Geodätisch
Ich markiere diese Antwort, da sowohl Pseudo-tty- als auch Remote-Befehle funktionieren. Ich habe meinen speziellen Fall letztendlich mit ^ E-Rückrufen gelöst, basierend auf dem Vorschlag für einen Fernbefehl - es wird ein bisschen sauberer und allgemeiner. Vielen Dank!
Geodätische
2

Ich habe richtig verstanden, dass Sie mit proxycommandHopfen direkt von der Ursprungsmaschine zum Ziel verbunden sind . Und so sind hier drei Hacks für Sie (dritter nach Kommentar zum Nutzungsszenario hinzugefügt). Erstens) Verwenden Sie die Remote-Port-Weiterleitung, damit Sie mit zu Ihrem Ursprungscomputer zurückkehren können-R remotemachineport:dstonlocalnet:dstportonlocalnet

ssh -R 2222:localhost:22 user@target
# on "target" you can now do this to get back to origin host
ssh user2@localhost -p 2222 

Zweitens) Missbrauch AcceptEnv LC_*am Ziel. Es ist nicht schön, aber es ist durchaus üblich, LOCALE-Variablen zuzulassen, selbst wenn AcceptUserEnviconment nicht verfügbar ist. Jetzt können Sie also Folgendes tun:

export LC_SOURCEHOST=my.ip.addr.or:something
ssh user@target
# on tathet:
echo $LC_SOURCEHOST

Drittens) Verwenden Sie ssh remote forward, um den Host oder den Hosttyp zu identifizieren.

# Here is an example what you can use on target machine. 
# This will modify your PS1 variable (prompt) based on source host (port forwarding)
# Add this to .bash_profile

function checkHost {
  RET=""
  ## loop over test port numbers 17891-17895 in my example
  for x in $(seq 1 5); do 
    # if netstat is not available test port some other way like with nc or something
    ## && RET= will set RET = 1-5
    /bin/netstat -lnt|/bin/grep -q 127.0.0.1:1789$x && RET=$x;
  done
  # return RET
  # please note that if you have multiple open connections with different port numbers
  # this method cannot not distinguish between them 
  echo $RET
}

# get 1-5 number from function above
VAL=$(checkHost)
# do something like set PS1 var or map vim file or something
export PS1='\[\033k\033\\\]\u@\h: \w\$ '$VAL

Verbinden Sie sich jetzt mit der Portweiterleitung:

### this will still enable ssh forwarding back. Change 22 to something else like 
### 24 to disable it (if nothing is listening on your source machines 24 port)
ssh -R 17891:localhost:22 user@target
Manwe
quelle
Vielen Dank für die Vorschläge, aber noch nicht zu meiner vollsten Zufriedenheit. Die Weiterleitung des Remote-Ports ist keine schlechte Idee, aber eine notwendige Annahme ist, dass Sie auf allen Hosts denselben Benutzernamen haben. Das ist hier weder der Fall noch etwas, das ich ändern kann. Zweitens: Ich konnte das nicht zum Laufen bringen. Wollen Sie damit sagen , dass AcceptEnv LC_*ist im Allgemeinen erlaubt, aber kein Standard, standardmäßig Einstellung?
Geodätische
Nun, der LC_ ist ein Hit und Miss. Ich kann nicht kommentieren, wie häufig das ist, aber es könnte funktionieren. (Denken Sie daran, LC_SOURCEHOST vor der SSH-Verbindung zu exportieren.)
Manwe
LC_ * getestet und es funktioniert. Es kann sich um eine beliebige Variable handeln, die in der AcceptEnvDirektive in aufgeführt ist /etc/ssh/sshd_config. Denken Sie daran, neu zu starten, sshdwenn diese Datei geändert wird.
david.perez
1

Sie können who -mauf der Remote-Seite eingeben, um Informationen zum aktuell angemeldeten Benutzer (einschließlich des Hostnamens) abzurufen. whogibt Ihnen Informationen zu angemeldeten Benutzern und der -mSchalter zeigt Ihnen "nur Hostname und Benutzer, die mit stdin verknüpft sind".

Paulo Almeida
quelle
Dies ist jedoch nur nützlich, wenn ich nicht durch einen Gateway-Computer tunnele.
Geodätisch
0

Hast du folgendes versucht?

 netstat -an | grep " 22 "

quelle
Diese Methode ist nur für One-Hop-Verbindungen nützlich, daher ist sie für mich nicht nützlich.
Geodätische