--- gitea: none include_toc: true --- # SSH ## Funktionsweise ![SSH](https://gitlab.com/armindoerzbachtbz/cloud-native-bootcamp/-/raw/main/ssh/resourcen/ssh_connection_key_checks.png "SSH") ## ssh und direkt befehl ausführen ``` ssh user@host "echo 'blabla' >> test.txt" ssh user@host "cd /usr/share/bin && ls -la" ``` ## SSH als root mit fremden key ``` sudo ssh -i /home/user/.ssh/id_rsa" user@192.168.0.72 ``` über Jumphost: ``` ssh -o ProxyCommand="ssh -W %h:%p -q ubuntu@jumphost-xxx.cloud" ubuntu@10.5.2.44 ``` ## Generate public key from private key In case you only have the private key, you can generate the public key like this: ``` ssh-keygen -f ~/.ssh/id_rsa -y > ~/.ssh/id_rsa.pub ``` ## ssh agent Den Agent brauchst du in folgender Situationen: - Du hast dein Private Key mit einem Passphrase geschuetzt und moechtest die Passphrase (zum entschlüsseln des Private keys) nur einmal eingeben wenn du das Terminal oeffnest. -> Der SSH-Agent speichert deinen "ungeschuetzten" Key im RAM und kann diesen dann an ssh geben, damit du ohne Passphrase einloggen kannst. - Du hast mehrere Schlüsselpaare erzeugt mit non-Standard-Filenamen und moechtest diese brauchen ohne jedesmal ssh -i filename angeben zu muessen. -> Du kannst den Schluessel im SSH-Agent zwischenspeichern. sodass er fuer alle ssh Kommandos gebraucht wird. Der SSH-Agent ist also dafür da, dir das leben mit mehreren Keys und Passphrases zu vereinfachen. ### Private Key hinterlegen; manuell ``` eval "$(ssh-agent -s)" ssh-add ~/.ssh/id_ed25519 und dann passphrase eingeben... ``` ### Private Key hinterlegen; automatisch Wenn man den ssh-agent automatisch starten möchte, kann man folgenden Block ins `.bashrc` file schreiben: ``` if [ -z "$SSH_AUTH_SOCK" ] ; then eval "$(ssh-agent -s)" ssh-add ~/.ssh/id_ed25519 fi ``` Man muss die Passphrase nur einmal, beim Starten der Bash Shell, eingeben, und gilt für die ganze Session. ## ssh fingerprint Vor der ersten Verbindung auf einen anderen Rechner muss bestätigt werden, ob man dem Rechner anhand seines Fingerprints vertrauen soll. Der Fingerprint wird vor der Eingabe yes/no angezeigt. Wenn mit yes beantwortet wird, wird der Fingerprint lokal in der Datei .ssh/known_hosts gespeichert. ``` ubuntu@m169-18-HF-Vorkurs24-CAL:~$ ssh user2@10.10.5.5 The authenticity of host '10.10.5.5 (10.10.5.5)' can't be established. ECDSA key fingerprint is SHA256:3EDJweyx6YxKAarcfFBUhYC4+Rit/BBx7miWR1YWw2w. Are you sure you want to continue connecting (yes/no)? yes ``` Um zu prüfen, wie der Fingerprint des Hosts tatsächlich lautet, gibt es folgenden Befehl: ``` ubuntu@m169-18-HF-Vorkurs24-CAL:~$ ssh-keyscan -t ecdsa 10.10.5.5 # 10.10.5.5:22 SSH-2.0-OpenSSH_7.2p2 Ubuntu-4ubuntu2.10 10.10.5.5 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBI4gcnyHeGo3gyFKMYOq6aaPo8qu4yu3Z9YfH+4zfilgEKTPFUxG6qngVOSpbMohJ1DyIDnyTFVoB8Qthg6CJDI= ``` ## SSH unter anderem Port Dies ist z.B. nützlich, wenn man 2 WSL-Instanzen am Laufen hat, und man mit ssh verbinden möchte. Beide benutzen als Host `localhost`. Wenn WSL A per default mit Port 22 läuft, kann WSL B konfiguriert werden, damit es auf Port 2222 läuft. - `sudo vi /etc/ssh/sshd_config` - `Port` unkommentieren und `2222` angeben. - ssh neu starten `sudo systemctl restart ssh` Verbindung von WSL A nach B: `ssh user@localhost -p 2222`. Nicht vergessen, den public key in `authorized_keys` von WSL B hinterlegen. ## Local Port Forwarding Hier wird ein Port auf dem Laptop verwendet, um auf einen Dienst auf einem Remote Host B zugreifen zu können, der ansonsten nicht von aussen erreichbar wäre. Annahme: Auf dem Host B ist ein Dienst installiert, den man nur von dort aus erreichen kann. Z.B. läuft dort mysql auf Port 3306, aber Remote-Verbindungen sind nicht erlaubt (Achtung myql kann so eingerichtet sein, dass es eh nicht geht, weil über socks file... aber ist eine andere Geschichte.) Mit folgendem SSH-Befehl kann dies umgangen werden: ``` ssh -L [local_port]:[destination_address]:[destination_port] [username]@[ssh_server] ssh -L 33333:127.0.0.1:3306 rogrut@v2202306200871231373.supersrv.de ``` `33333` ist der lokale Port auf dem Laptop. Als Verbindungsparameter in mysql workbench würde man 127.0.0.1:33333 angeben. `127.0.0.1:3306` ist mysql, der auf dem Host B läuft - von dort her gesehen auf localhost, also 127.0.0.1. `rogrut@v2202306200871231373.supersrv.de` schliesslich ist Benutzername und Adresse des Hosts B. Dabei wird man auch gleich auf dem Server engeloggt. In einem zweiten Terminal vom Laptop kann man dann über den lokalen Port auf den Dienst auf Host B zugreiffen. Auf dem Laptop ist somit `127.0.0.1:33333` gleichbedeutend wie auf dem Host B mit `127.0.0.1:3306`. So können Firewalls umgangen werden, weil `v2202306200871231373.supersrv.de:3306` nicht geöffnet ist. Es wären auch Verbindungen zu mysql DBs möglich, die in Docker laufen, z.B. unter `63003`, oder sogar unter anderen IPs. ``` rogrut@v2202306200871231373:~$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 160b134da95a percona:8.0 "/docker-entrypoint.…" 5 weeks ago Up 5 weeks 33060/tcp, 127.0.0.1:63003->3306/tcp docker-percona-1 ssh -L 33333:127.0.0.1:63003 rogrut@v2202306200871231373.supersrv.de ``` ### Von Laptop auf Host C verbinden, der nur über Host B erreichbar ist es gilt immernoch: ``` ssh -L [local_port]:[destination_address]:[destination_port] [username]@[ssh_server] ``` nur verwenden wir nicht 127.0.0.1 sondern die IP von Host C. Zum Beispiel so: ``` ssh -L 8123:10.10.5.5:22 ubuntu@3.87.58.91 ``` Dann verbinden mit `ssh -p 8123 user1@localhost`. ### Port öffnen ohne Login in Shell Um zu verhindern, dass man eingeloggt wird, also nur den Port 33333 zu öffnen, müssen noch zusätzliche Parameter angegeben werden: `-LNf`, also `ssh -LNf 33333:127.0.0.1:3306 rogrut@v2202306200871231373.supersrv.de` Nicht vergessen den Port wieder zu schliessen. Zuerst PID der SSH-Verbindung suchen: (`9973`) ``` roru@saturn5:~$ ps aux | grep ssh | grep 33333 roru 9973 0.0 0.0 12284 2752 ? Ss 08:48 0:00 oder roru@saturn5:~$ lsof -i :33333 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME ssh 9973 roru 4u IPv6 253965 0t0 TCP ip6-localhost:33333 (LISTEN) ssh 9973 roru 5u IPv4 253966 0t0 TCP localhost:33333 (LISTEN) ``` und dann Prozess killen: ``` kill 9973 ``` ## Remote Port Forwarding Auch bekannt als "reverse tunneling", um von einem Host B eine sichere Verbindung auf einem lokalen Computer zu machen. Traffic wird von einem spezifischen port auf Host B an einen bestimmten Port auf dem Laptop geleitet. To initiate remote port forwarding, the user configures an SSH connection to the remote server with the -R option followed by the forwarding specifications. The syntax for setting up remote port forwarding is: ``` ssh -R [remote_port]:[destination_address]:[local_port] [username]@[ssh_server] ``` ## Dynamic Port Forwarding ### SSH Socks Proxy Man kann HTTP-Requests auf dem Host A über einen Host B, der in Deutschland steht, leiten. So denkt der Browser, er sei in Deutschland stationert. Dies verhindert z.B. Weiterleitungen von einer `.de` Domain auf die `.ch` Domain. In China könnte man so z.B. die "Chinese Firewall" überlisten. Auf Host A: ``` ssh -D 8888 rogrut@v2202306200871231373.supersrv.de ``` Im Browser kann dann als Proxy SOCKS5 angegeben werden: `127.0.0.1:8888` und schon surft man als wäre man auf dem Server `v2202306200871231373.supersrv.de`. Tipp: In Chrome die Extension ZeroOmega installieren, sodass man bequem zwischen Profilen (noproxy, proxy) hin und her switchen kann.