SSH Tipps und Tricks: Difference between revisions

From Lolly's Wiki
Jump to navigationJump to search
m (Text replacement - "<source" to "<syntaxhighlight")
 
(19 intermediate revisions by the same user not shown)
Line 1: Line 1:
[[Kategorie:SSH|Tipps]]
[[Category:SSH|Tipps]]
[[Kategorie:Putty|Tipps]]
[[Category:Putty|Tipps]]
=SSH, der Weg zum Ziel=
=SSH, way to the target=
==SSH über ein oder mehrere Hops==
==SSH over one or more hops==
Um die SSH-Verbindung von Host_A zu Host_B machen zu können muß man sich über zwei Rechner dorthin tunneln (GW_1 und GW_2). Wenn man sich immer erst einloggt und dann weiter einloggt ist es manchmal sehr schwierig die Portforwardings mitzuschleifen, oder den Socks5-Proxy. Einfacher ist es, wenn man sich ProxyCommands für den Weg von Host_a zu Host_b definiert.
To make the SSH connection from host_a to host_b you have to tunnel through two hosts (jumphost_1 and jumphost_2). If you always log in first and then continue logging in, it is sometimes very difficult to loop through the port forwardings or the Socks5 proxy. It is easier to define <i>ProxyJump</i>s for the way from host_a to host_b.
Wir kommen also nur von GW_2 zu Host_b, also machen wir uns hierfür einen Eintrag in der ~/.ssh/config:
So we only get from jumphost_2 to host_b, so we make an entry in ~/.ssh/config for this:
<pre>
<pre>
Host Host_B
Host host_b
   ProxyJump GW_2
   ProxyJump jumphost_2
</pre>
</pre>
Zu GW_2 kommen wir aber nur über GW_1, also brauchen wir hierfür auch einen Eintrag:
But we can only get to jumphost_2 via jumphost_1, so we need an entry for this as well:
<pre>
<pre>
Host GW_2
Host jumphost_2
   ProxyJump GW_1
   ProxyJump jumphost_1
</pre>
</pre>


Jetzt gibt man auf Host_A einfach <i>ssh Host_B</i> ein und wird über die beiden Gateways GW_1 und GW_2 getunnelt.
Now simply type <i>ssh host_b</i> on host_a and you will be tunneled through the two gateways jumphost_1 and jumphost_2.
 
==Portforwardings for example for NFS are now easy like this==
==Portforwardings für z.B. NFS macht man jetzt einfach so==
<pre>
<pre>
root@Host_A# share -F nfs -o ro=@127.0.0.1/32 /tmp
root@host_a# share -F nfs -o ro=@127.0.0.1/32 /tmp
root@Host_A# ssh -R 22049:localhost:2049 user@Host_B
root@host_a# ssh -R 22049:localhost:2049 user@host_b
user@Host_B$ su -
user@host_b$ su -
root@Host_B# mount -oro nfs://127.0.0.1:22049/tmp /mnt
root@host_b# mount -oro nfs://127.0.0.1:22049/tmp /mnt
</pre>
</pre>
Im Hintergrund werden dann die TunnelVerbindungen aufgebaut und man macht das PortForwarding direkt von Host_A nach Host_B. Sehr schlank und elegant.


PS: Das /dev/tcp/%h/%p ist ein BASH-Builtin wobei %h und %p von der SSH durch Host (%h) und Port (%p) ausgefüllt werden
In the background the tunnel connections are established and the port forwarding is done directly from host_a to host_b. Very slim and elegant.


==Ausbruch aus dem Paradies==
==Breakout from paradise==
Problem: Die Umgebung in der man sich aufhält ist leider so unglücklich mit Firewalls verbaut, daß man nicht arbeiten kann. Man muß aber per SSH raus, um woanders kurz etwas zu schauen, oder zu holen. Nunja, es gibt immer einen Weg...
Problem: The environment you are in is unfortunately so unfortunate with firewalls that you can not work. But you have to SSH out to look somewhere else or to get something. Well, there is always a way...


Vorraussetzung ist ein lokal installiertes [http://www.meadowy.org/~gotoh/projects/connect connect], z.B. unter Ubuntu: apt-get install connect-proxy.
You need a locally installed [http://www.meadowy.org/~gotoh/projects/connect connect], e.g. under Ubuntu: apt-get install connect-proxy.
Weiterhin braucht man einen SSH-Server, wo ein sshd auf dem Port 443 lauscht, denn die meisten Proxies wollen einen nur auf known Ports durchlassen.
Furthermore you need a SSH server, where a sshd is listening on port 443, because most proxies only want to let you through on known ports.


Dann trägt man in der ~/.ssh/config ein:
Then you enter in the ~/.ssh/config:
<pre>
<pre>
Host ssh-via-proxy
Host ssh-via-proxy
   ProxyCommand connect -H proxy-server:3128 ssh-server 443
   ProxyCommand connect -H proxy-server:3128 ssh-server 443
</pre>
</pre>
Schwuppdiwupp ist man mit <i>ssh ssh-server</i> auf dem SSH-Ziel, wo man hinmöchte. Natürlich kann man auf den ssh-server wieder als ProxyCommand eintragen usw. usw.
Whoop di whoop is one with <i>ssh ssh-server</i> on the SSH target, where one would like to go. Of course you can enter another host behind this connection via <i>ProxyJump ssh-via-proxy</i> etc. etc.


==Achja... das interne Wiki...==
==Ah yes... the internal wiki...==
Auch nicht schlimm, wenn das nur vom internen Netz erreichbar ist, dann fragen wir einfach via Socks-Proxy an:
Also not bad, if this is only accessible from the internal network, then we just request via socks proxy:
<pre>
<pre>
user@Host_A$ ssh -C -N -T -f -D8080 interner-rechner
user@host_a$ ssh -C -N -T -f -D8080 internal-host
user@Host_A$ chromium-browser --proxy-server="socks5://localhost:8080" https://wiki.intern.firma.de/ &
user@host_a$ chromium-browser --proxy-server="socks5://localhost:8080" https://wiki.internal.office/ &
</pre>
</pre>
Die Optionen sind:
Options are:
<pre>
<pre>
-C      Requests compression <- das ist optional
-C      Requests compression <- das ist optional
Line 55: Line 53:
-D      Local-Remote-Socks5-Proxy Port
-D      Local-Remote-Socks5-Proxy Port
</pre>
</pre>
Oder wieder via ~/.ssh/config:
Or again via ~/.ssh/config:
<pre>
<pre>
Host wiki
Host wiki
Line 63: Line 61:
   PermitLocalCommand yes
   PermitLocalCommand yes
   LocalCommand      chromium-browser --proxy-server="socks5://localhost:8888" https://wiki.intern.firma.de/ &
   LocalCommand      chromium-browser --proxy-server="socks5://localhost:8888" https://wiki.intern.firma.de/ &
   Hostname          interner-rechner
   Hostname          internal-host
</pre>
</pre>
Und dann <i>ssh -N -f wiki</i> (Entsprechungen für -N und -f habe ich noch nicht gefunden).
And then
<SyntaxHighlight lang=bash>
$ ssh -N -f wiki
</SyntaxHighlight>


=Der Fingerabdruck=
==Do this but only if...==
If you want for example <i>ProxyJump</i> only if you are connected remote via OpenVPN but not if you are at the office:


Für die Verifikation ist es oft leichter mit kürzeren Zahlenketten. Daher ist der Fingerabdruck praktisch, um Keys einfacher zu vergleichen:
<pre>
<pre>
$ ssh-keygen -lf ~/.ssh/id_dsa.pub
Match exec "ip ro sh dev tun0 src 10.208.129.0/24 2>/dev/null" host !jumphost.office,*.office,172.16.*.*
1024 98:c5:76:...:08:fa:ba  lollypop@lollybook (DSA)
  ProxyJump jumphost.office
</pre>
</pre>


=Nutzer einschränken=
What happens here is:<br>
You will be proxied over jumphost.office if there is both of<br>
- A route on a dev tun0 where the local IP matches 10.208.129.0/24<br>
- The destination host matches !jumphost.office,*.office,172.16.*.*<br>
 
 
=rsync from remote to remote=
 
Sometimes your local host is just needed as a relay station to sync between two servers which cannot see each other. You can see both because you are in the admin network.
But you need to get files from HostA to HostB and your laptop has not enough diskspace to save it from HostA to the local disk and then copy it on HostB.
This is a possible solution:
1. Make a reverse forwarding from localhost:PortX on HostA to HostB port 22 (So all packets you send to PortX on HostA get back to your laptop and will be send to port 22, the ssh port, on HostB)
2. Execute rsync on HostA ans tell rsync to make a ssh connection to port PortX for the destination host (which is send back to your laptop and from here to HostB port 22, see 1.)
 
Here is an Example (with a random port between 50000-52999):
<SyntaxHighLight lang=bash>
$ PortX=$(( ${RANDOM} % 3000 + 50000 ))
$ HostA=10.1.0.42
$ HostB=10.2.0.43
$ ssh -AR 127.0.0.1:${PortX}:${HostB}:22 ${HostA} "rsync -e 'ssh -p ${PortX} -o StrictHostKeyChecking=no' -PWav <HostA-Path> 127.0.0.1:<HostB-Path>"
</SyntaxHighLight>
 
Some explanations:
 
$RANDOM is a bash builtin so this works only inside bash.
Use Portx=<your port choosen number> in other shells.
 
SSH Options:
<pre>
-A          Enables forwarding of connections from an authentication agent such as ssh-agent(1).  This can also be specified on a per-host basis in a configuration file.
 
            Agent forwarding should be enabled with caution.  Users with the ability to bypass file permissions on the remote host (for the agent's UNIX-domain socket) can
            access the local agent through the forwarded connection.  An attacker cannot obtain key material from the agent, however they can perform operations on the
            keys that enable them to authenticate using the identities loaded into the agent.  A safer alternative may be to use a jump host (see -J).
 
-R [bind_address:]port:host:hostport
            Specifies that connections to the given TCP port or Unix socket on the remote (server) host are to be forwarded to the local side.
 
            This works by allocating a socket to listen to either a TCP port or to a Unix socket on the remote side.  Whenever a connection is made to this port or Unix
            socket, the connection is forwarded over the secure channel, and a connection is made from the local machine to either an explicit destination specified by
            host port hostport, or local_socket, or, if no explicit destination was specified, ssh will act as a SOCKS 4/5 proxy and forward connections to the destina‐
            tions requested by the remote SOCKS client.
 
            Port forwardings can also be specified in the configuration file.  Privileged ports can be forwarded only when logging in as root on the remote machine.  IPv6
            addresses can be specified by enclosing the address in square brackets.
 
            By default, TCP listening sockets on the server will be bound to the loopback interface only.  This may be overridden by specifying a bind_address.  An empty
            bind_address, or the address ‘*’, indicates that the remote socket should listen on all interfaces.  Specifying a remote bind_address will only succeed if the
            server's GatewayPorts option is enabled (see sshd_config(5)).
 
            If the port argument is ‘0’, the listen port will be dynamically allocated on the server and reported to the client at run time.  When used together with -O
            forward the allocated port will be printed to the standard output.
 
-o StrictHostKeyChecking=no
            The StrictHostKeyChecking option can be used to control logins to machines whose host key is not known or has changed.
</pre>
 
=Fingerprint of a key=
 
For verification, it is often easier with shorter number strings. Therefore, the fingerprint is handy to compare keys more easily:
<pre>
$ ssh-keygen -lf ~/.ssh/id_rsa.pub
4096 SHA256:s1dtEFvY0EiJQcg66jTUon3BS6gfhSJT4Qegox4e7yk lollypop@lollybook (RSA)
</pre>
 
=Limit allowed users in sshd_config=
<syntaxhighlight lang=bash>
<syntaxhighlight lang=bash>
# SSH is only allowed for users in the group ssh except syslog
# SSH is only allowed for users in the group ssh except user syslog
AllowGroups ssh
AllowGroups ssh
DenyUsers syslog
DenyUsers syslog
</source>
</syntaxhighlight>


=PuTTY Portable=
=PuTTY Portable=
==pageant zusammen mit putty starten==
==Launch pageant together with putty==
In die Datei ..\PortableApps\PuTTYPortable\App\AppInfo\Launcher\PuTTYPortable.ini muß folgendes unter [Launch] stehen:
In the file ..\PortableApps\PuTTYPortable\App\AppInfo\Launcher\PuTTYPortable.ini enter the following below [Launch]:
<pre>
<pre>
[Launch]
[Launch]
Line 93: Line 159:
</pre>
</pre>


Zu PortableApps siehe auch:
For PortableApps see:
* [http://portableapps.com/manuals/PortableApps.comLauncher/ref/envsub.html Environment variable substitions]
* [http://portableapps.com/manuals/PortableApps.comLauncher/ref/envsub.html Environment variable substitions]
* [http://portableapps.com/manuals/PortableApps.comLauncher/ref/launcher.ini/launch.html#programexecutable Launch]
* [http://portableapps.com/manuals/PortableApps.comLauncher/ref/launcher.ini/launch.html#programexecutable Launch]


==ppk -> pem==
==ppk -> OpenSSH format==
<syntaxhighlight lang=bash>
<syntaxhighlight lang=bash>
$ nawk '/---- BEGIN SSH2 PUBLIC KEY ----/{printf "ssh-rsa "; getline; comment=$2; gsub(/"/,"",comment); getline line; while(line !~ /^---- END/){printf line; getline line;} printf " %s\n",comment;}' pubkey.ppk
$ nawk '/---- BEGIN SSH2 PUBLIC KEY ----/{printf "ssh-rsa "; getline; comment=$2; gsub(/"/,"",comment); getline line; while(line !~ /^---- END/){printf line; getline line;} printf " %s\n",comment;}' pubkey.ppk
</source>
</syntaxhighlight>


=Probleme mit älteren Gegenstellen=
Or simply:
<syntaxhighlight lang=bash>
$ ssh-keygen -i -f putty.pub > openssh.pub
</syntaxhighlight>
 
=Problems with older destinations=
==Unable to negotiate with <IP> port 22: no matching host key type found. Their offer: ssh-dss==
==Unable to negotiate with <IP> port 22: no matching host key type found. Their offer: ssh-dss==
<syntaxhighlight lang=bash>
<syntaxhighlight lang=bash>
$ ssh -oHostKeyAlgorithms=+ssh-dss <IP>
$ ssh -oHostKeyAlgorithms=+ssh-dss <IP>
</source>
</syntaxhighlight>
==ssh_dispatch_run_fatal: Connection to <IP> port 22: DH GEX group out of range==
==ssh_dispatch_run_fatal: Connection to <IP> port 22: DH GEX group out of range==
<syntaxhighlight lang=bash>
<syntaxhighlight lang=bash>
$ ssh -oKexAlgorithms=diffie-hellman-group-exchange-sha256,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1 <IP>
$ ssh -oKexAlgorithms=diffie-hellman-group-exchange-sha256,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1 <IP>
</source>
</syntaxhighlight>
 
==Allow outdated PubkeyAcceptedAlgorithms==
To reach hosts where you cannod use ed25519 or other more modern keys:
<syntaxhighlight lang=bash>
$ ssh -o PubkeyAcceptedKeyTypes=+ssh-rsa <old-rsa-host>
</syntaxhighlight>
 
=Problems with older clients/keys=
==Allow RSA keys again (ssh-rsa not in PubkeyAcceptedAlgorithms)==
If you try to connect to new OpenSSH daemons with an RSA key, you will find this in your log and you can not connect via ssh:
<syntaxhighlight lang=bash>
sshd[51342]: userauth_pubkey: key type ssh-rsa not in PubkeyAcceptedAlgorithms [preauth]
</syntaxhighlight>
 
The temporary workaround which is not recommended is to allow RSA keys in the sshd_config:
<syntaxhighlight lang=bash>
PubkeyAcceptedAlgorithms +ssh-rsa
</syntaxhighlight>
 
But you better should switch to ED25519 keys.


=SFTP chroot=
=SFTP chroot=
Line 116: Line 207:
<syntaxhighlight lang=bash>
<syntaxhighlight lang=bash>
# mkdir --parents --mode=0755 /sftp_chroot/etc
# mkdir --parents --mode=0755 /sftp_chroot/etc
</source>
</syntaxhighlight>


==/etc/fstab==
==/etc/fstab==
Line 123: Line 214:
/etc/passwd /sftp_chroot/etc/passwd none ro,bind 0 0
/etc/passwd /sftp_chroot/etc/passwd none ro,bind 0 0
/etc/group  /sftp_chroot/etc/group  none ro,bind 0 0
/etc/group  /sftp_chroot/etc/group  none ro,bind 0 0
</source>
</syntaxhighlight>
==/etc/ssh/sshd_config==
==/etc/ssh/sshd_config==


Line 143: Line 234:
   ChrootDirectory /sftp_chroot/
   ChrootDirectory /sftp_chroot/
   AuthorizedKeysFile /sftp_chroot/%h/.ssh/authorized_keys
   AuthorizedKeysFile /sftp_chroot/%h/.ssh/authorized_keys
</source>
</syntaxhighlight>


==Create SFTP user==
==Create SFTP user==
Line 152: Line 243:
# mkdir  --parents    --mode=0755 /home/sftp/${USER}
# mkdir  --parents    --mode=0755 /home/sftp/${USER}
# useradd --create-home --home-dir  /home/sftp/${USER}/home ${USER}
# useradd --create-home --home-dir  /home/sftp/${USER}/home ${USER}
</source>
</syntaxhighlight>


= Two factor authentication =
= Two factor authentication =
Line 163: Line 254:
<syntaxhighlight lang=bash>
<syntaxhighlight lang=bash>
$ sudo apt-get install libpam-google-authenticator
$ sudo apt-get install libpam-google-authenticator
</source>
</syntaxhighlight>


=== Add settings to the /etc/pam.d/sshd ===
=== Add settings to the /etc/pam.d/sshd ===
Line 169: Line 260:
<syntaxhighlight lang=bash>
<syntaxhighlight lang=bash>
auth [success=done new_authtok_reqd=done default=die] pam_google_authenticator.so nullok
auth [success=done new_authtok_reqd=done default=die] pam_google_authenticator.so nullok
</source>
</syntaxhighlight>


See the man page pam.d(5) or read here...
See the man page pam.d(5) or read here...
Line 186: Line 277:
ChallengeResponseAuthentication yes
ChallengeResponseAuthentication yes
AuthenticationMethods publickey,keyboard-interactive:pam
AuthenticationMethods publickey,keyboard-interactive:pam
</source>
</syntaxhighlight>


Without the setting in /etc/pam.d/sshd the "PasswordAuthentication no" will not be sufficient and still ask for a password because /etc/pam.d/sshd enables password authentication.
Without the setting in /etc/pam.d/sshd the "PasswordAuthentication no" will not be sufficient and still ask for a password because /etc/pam.d/sshd enables password authentication.
= Workarounds for CVEs =
In this section I just say: This <b>might</b> help! Absolutely no warranty for anything!<br>
If my workaround does not fix the problem look one line above this one.
== CVE-2023-48795 alias Terrapin ==
First read at [https://terrapin-attack.com/ terrapin-attack.com]
===Check if patches against this CVE are already included in OS===
On Debian/Ubuntu do:
<SyntaxHighlight lang=bash>
$ sudo apt-get changelog openssh-server | grep -i CVE-2023-48795
    - debian/patches/CVE-2023-48795.patch: implement "strict key exchange"
    - CVE-2023-48795
</SyntaxHighlight>
This means there are patches against this CVE are included.
===Check ssh and sshd if they offer problematic ciphers and macs===
sshd:
<SyntaxHighlight lang=bash>
$ sudo sshd -T | grep -iE '(chacha20-poly1305@openssh.com|-cbc|-etm@openssh.com)'
ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr
macs umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1
</SyntaxHighlight>
ssh: (Example for localhost, other hosts might get other values depending on your ~/.ssh/config or elsewhere)
<SyntaxHighlight lang=bash>
$ ssh -G localhost | grep -E '(chacha20-poly1305@openssh.com|-cbc|-etm@openssh.com)'
ciphers chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com
macs umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1
</SyntaxHighlight>
===Include workarounds===
The <i>Include</i> statement enters config in OpenSSH 7.3p1 as far as i know.
So, if you have an <i>Include</i> statement in<br>
/etc/ssh/sshd_config:
<pre>
Include /etc/ssh/sshd_config.d/*.conf
</pre>
/etc/ssh/ssh_config:
<pre>
Include /etc/ssh/ssh_config.d/*.conf
</pre>
then add the following files:<br>
/etc/ssh/sshd_config.d/000_terrapin.conf
<pre>
Ciphers -chacha20-poly1305@openssh.com,-*-cbc*
MACs    -*-etm@openssh.com
</pre>
/etc/ssh/ssh_config.d/000_terrapin.conf
<pre>
Ciphers -chacha20-poly1305@openssh.com,-*-cbc*
MACs    -*-etm@openssh.com
</pre>
After that do the checks from above. If they look good, restart sshd. If not... toss my trash.

Latest revision as of 13:02, 15 February 2024

SSH, way to the target

SSH over one or more hops

To make the SSH connection from host_a to host_b you have to tunnel through two hosts (jumphost_1 and jumphost_2). If you always log in first and then continue logging in, it is sometimes very difficult to loop through the port forwardings or the Socks5 proxy. It is easier to define ProxyJumps for the way from host_a to host_b. So we only get from jumphost_2 to host_b, so we make an entry in ~/.ssh/config for this:

Host host_b
   ProxyJump jumphost_2

But we can only get to jumphost_2 via jumphost_1, so we need an entry for this as well:

Host jumphost_2
   ProxyJump jumphost_1

Now simply type ssh host_b on host_a and you will be tunneled through the two gateways jumphost_1 and jumphost_2.

Portforwardings for example for NFS are now easy like this

root@host_a# share -F nfs -o ro=@127.0.0.1/32 /tmp
root@host_a# ssh -R 22049:localhost:2049 user@host_b
user@host_b$ su -
root@host_b# mount -oro nfs://127.0.0.1:22049/tmp /mnt

In the background the tunnel connections are established and the port forwarding is done directly from host_a to host_b. Very slim and elegant.

Breakout from paradise

Problem: The environment you are in is unfortunately so unfortunate with firewalls that you can not work. But you have to SSH out to look somewhere else or to get something. Well, there is always a way...

You need a locally installed connect, e.g. under Ubuntu: apt-get install connect-proxy. Furthermore you need a SSH server, where a sshd is listening on port 443, because most proxies only want to let you through on known ports.

Then you enter in the ~/.ssh/config:

Host ssh-via-proxy
  ProxyCommand connect -H proxy-server:3128 ssh-server 443

Whoop di whoop is one with ssh ssh-server on the SSH target, where one would like to go. Of course you can enter another host behind this connection via ProxyJump ssh-via-proxy etc. etc.

Ah yes... the internal wiki...

Also not bad, if this is only accessible from the internal network, then we just request via socks proxy:

user@host_a$ ssh -C -N -T -f -D8080 internal-host
user@host_a$ chromium-browser --proxy-server="socks5://localhost:8080" https://wiki.internal.office/ &

Options are:

-C      Requests compression <- das ist optional
-N      Do not execute a remote command.
-T      Disable pseudo-tty allocation.
-f      Requests ssh to go to background just before command execution.
-D      Local-Remote-Socks5-Proxy Port

Or again via ~/.ssh/config:

Host wiki
  Compression        yes
  DynamicForward     8888
  RequestTTY         no
  PermitLocalCommand yes
  LocalCommand       chromium-browser --proxy-server="socks5://localhost:8888" https://wiki.intern.firma.de/ &
  Hostname           internal-host

And then

$ ssh -N -f wiki

Do this but only if...

If you want for example ProxyJump only if you are connected remote via OpenVPN but not if you are at the office:

Match exec "ip ro sh dev tun0 src 10.208.129.0/24 2>/dev/null" host !jumphost.office,*.office,172.16.*.*
  ProxyJump jumphost.office

What happens here is:
You will be proxied over jumphost.office if there is both of
- A route on a dev tun0 where the local IP matches 10.208.129.0/24
- The destination host matches !jumphost.office,*.office,172.16.*.*


rsync from remote to remote

Sometimes your local host is just needed as a relay station to sync between two servers which cannot see each other. You can see both because you are in the admin network. But you need to get files from HostA to HostB and your laptop has not enough diskspace to save it from HostA to the local disk and then copy it on HostB. This is a possible solution: 1. Make a reverse forwarding from localhost:PortX on HostA to HostB port 22 (So all packets you send to PortX on HostA get back to your laptop and will be send to port 22, the ssh port, on HostB) 2. Execute rsync on HostA ans tell rsync to make a ssh connection to port PortX for the destination host (which is send back to your laptop and from here to HostB port 22, see 1.)

Here is an Example (with a random port between 50000-52999):

$ PortX=$(( ${RANDOM} % 3000 + 50000 ))
$ HostA=10.1.0.42
$ HostB=10.2.0.43
$ ssh -AR 127.0.0.1:${PortX}:${HostB}:22 ${HostA} "rsync -e 'ssh -p ${PortX} -o StrictHostKeyChecking=no' -PWav <HostA-Path> 127.0.0.1:<HostB-Path>"

Some explanations:

$RANDOM is a bash builtin so this works only inside bash. Use Portx=<your port choosen number> in other shells.

SSH Options:

-A           Enables forwarding of connections from an authentication agent such as ssh-agent(1).  This can also be specified on a per-host basis in a configuration file.

             Agent forwarding should be enabled with caution.  Users with the ability to bypass file permissions on the remote host (for the agent's UNIX-domain socket) can
             access the local agent through the forwarded connection.  An attacker cannot obtain key material from the agent, however they can perform operations on the
             keys that enable them to authenticate using the identities loaded into the agent.  A safer alternative may be to use a jump host (see -J).

-R [bind_address:]port:host:hostport
             Specifies that connections to the given TCP port or Unix socket on the remote (server) host are to be forwarded to the local side.

             This works by allocating a socket to listen to either a TCP port or to a Unix socket on the remote side.  Whenever a connection is made to this port or Unix
             socket, the connection is forwarded over the secure channel, and a connection is made from the local machine to either an explicit destination specified by
             host port hostport, or local_socket, or, if no explicit destination was specified, ssh will act as a SOCKS 4/5 proxy and forward connections to the destina‐
             tions requested by the remote SOCKS client.

             Port forwardings can also be specified in the configuration file.  Privileged ports can be forwarded only when logging in as root on the remote machine.  IPv6
             addresses can be specified by enclosing the address in square brackets.

             By default, TCP listening sockets on the server will be bound to the loopback interface only.  This may be overridden by specifying a bind_address.  An empty
             bind_address, or the address ‘*’, indicates that the remote socket should listen on all interfaces.  Specifying a remote bind_address will only succeed if the
             server's GatewayPorts option is enabled (see sshd_config(5)).

             If the port argument is ‘0’, the listen port will be dynamically allocated on the server and reported to the client at run time.  When used together with -O
             forward the allocated port will be printed to the standard output.

-o StrictHostKeyChecking=no
             The StrictHostKeyChecking option can be used to control logins to machines whose host key is not known or has changed.

Fingerprint of a key

For verification, it is often easier with shorter number strings. Therefore, the fingerprint is handy to compare keys more easily:

$ ssh-keygen -lf ~/.ssh/id_rsa.pub
4096 SHA256:s1dtEFvY0EiJQcg66jTUon3BS6gfhSJT4Qegox4e7yk lollypop@lollybook (RSA)

Limit allowed users in sshd_config

# SSH is only allowed for users in the group ssh except user syslog
AllowGroups ssh
DenyUsers syslog

PuTTY Portable

Launch pageant together with putty

In the file ..\PortableApps\PuTTYPortable\App\AppInfo\Launcher\PuTTYPortable.ini enter the following below [Launch]:

[Launch]
ProgramExecutable=putty\pageant.exe
CommandLineArguments='%PAL:DataDir%\settings\mykeys.ppk -c %PAL:AppDir%\putty\putty.exe'
DirectoryMoveOK=yes
SupportsUNC=yes

For PortableApps see:

ppk -> OpenSSH format

$ nawk '/---- BEGIN SSH2 PUBLIC KEY ----/{printf "ssh-rsa "; getline; comment=$2; gsub(/"/,"",comment); getline line; while(line !~ /^---- END/){printf line; getline line;} printf " %s\n",comment;}' pubkey.ppk

Or simply:

$ ssh-keygen -i -f putty.pub > openssh.pub

Problems with older destinations

Unable to negotiate with <IP> port 22: no matching host key type found. Their offer: ssh-dss

$ ssh -oHostKeyAlgorithms=+ssh-dss <IP>

ssh_dispatch_run_fatal: Connection to <IP> port 22: DH GEX group out of range

$ ssh -oKexAlgorithms=diffie-hellman-group-exchange-sha256,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1 <IP>

Allow outdated PubkeyAcceptedAlgorithms

To reach hosts where you cannod use ed25519 or other more modern keys:

$ ssh -o PubkeyAcceptedKeyTypes=+ssh-rsa <old-rsa-host>

Problems with older clients/keys

Allow RSA keys again (ssh-rsa not in PubkeyAcceptedAlgorithms)

If you try to connect to new OpenSSH daemons with an RSA key, you will find this in your log and you can not connect via ssh:

sshd[51342]: userauth_pubkey: key type ssh-rsa not in PubkeyAcceptedAlgorithms [preauth]

The temporary workaround which is not recommended is to allow RSA keys in the sshd_config:

PubkeyAcceptedAlgorithms +ssh-rsa

But you better should switch to ED25519 keys.

SFTP chroot

# mkdir --parents --mode=0755 /sftp_chroot/etc

/etc/fstab

...
/etc/passwd /sftp_chroot/etc/passwd none ro,bind 0 0
/etc/group  /sftp_chroot/etc/group  none ro,bind 0 0

/etc/ssh/sshd_config

...

AllowGroups ssh-user

Subsystem sftp internal-sftp
Match group sftp
  AllowGroups sftp
  X11Forwarding no
  AllowTcpForwarding no
  AllowAgentForwarding no
  PermitTunnel no
  ForceCommand internal-sftp
  PasswordAuthentication yes
  ChrootDirectory /sftp_chroot/
  AuthorizedKeysFile	/sftp_chroot/%h/.ssh/authorized_keys

Create SFTP user

Now you can put authorized keys into the files /home/sftp/.authorized_keys/username And create the sftp users like this:

# USER=myuser
# mkdir   --parents     --mode=0755 /home/sftp/${USER}
# useradd --create-home --home-dir  /home/sftp/${USER}/home ${USER}

Two factor authentication

Google Authenticator

As the Google Authenticator is a tool which is available on several SmartPhone OS I took this one for the OTP authentication.

All steps have to be done on the destination host.

Install libpam-google-authenticator

$ sudo apt-get install libpam-google-authenticator

Add settings to the /etc/pam.d/sshd

Put this line at the top of your /etc/pam.d/sshd!

auth [success=done new_authtok_reqd=done default=die] pam_google_authenticator.so nullok

See the man page pam.d(5) or read here... The meaning of the parameters:

  • success=done  : If pam_google_authenticator returns successful (code was correct) all authentication is done.
  • new_authtok_reqd=done : New authentication token is required set to done. Done is like ok, <man page>except that the stack also terminates and control is immediately returned to the application.</man page>
  • default=die  : If pam_google_authenticator failed no other authentications will be tried
  • nullok  : Allow user to access auth mechanism even if the password is empty

Add settings to the /etc/ssh/sshd_config

This lines have to be in the /etc/ssh/sshd_config:

UsePAM yes
PasswordAuthentication no
PubkeyAuthentication yes
ChallengeResponseAuthentication yes
AuthenticationMethods publickey,keyboard-interactive:pam

Without the setting in /etc/pam.d/sshd the "PasswordAuthentication no" will not be sufficient and still ask for a password because /etc/pam.d/sshd enables password authentication.


Workarounds for CVEs

In this section I just say: This might help! Absolutely no warranty for anything!
If my workaround does not fix the problem look one line above this one.

CVE-2023-48795 alias Terrapin

First read at terrapin-attack.com

Check if patches against this CVE are already included in OS

On Debian/Ubuntu do:

$ sudo apt-get changelog openssh-server | grep -i CVE-2023-48795
    - debian/patches/CVE-2023-48795.patch: implement "strict key exchange"
    - CVE-2023-48795

This means there are patches against this CVE are included.

Check ssh and sshd if they offer problematic ciphers and macs

sshd:

$ sudo sshd -T | grep -iE '(chacha20-poly1305@openssh.com|-cbc|-etm@openssh.com)'
ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr
macs umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1

ssh: (Example for localhost, other hosts might get other values depending on your ~/.ssh/config or elsewhere)

$ ssh -G localhost | grep -E '(chacha20-poly1305@openssh.com|-cbc|-etm@openssh.com)'
ciphers chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com
macs umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1

Include workarounds

The Include statement enters config in OpenSSH 7.3p1 as far as i know. So, if you have an Include statement in
/etc/ssh/sshd_config:

Include /etc/ssh/sshd_config.d/*.conf

/etc/ssh/ssh_config:

Include /etc/ssh/ssh_config.d/*.conf

then add the following files:
/etc/ssh/sshd_config.d/000_terrapin.conf

Ciphers -chacha20-poly1305@openssh.com,-*-cbc*
MACs    -*-etm@openssh.com

/etc/ssh/ssh_config.d/000_terrapin.conf

Ciphers -chacha20-poly1305@openssh.com,-*-cbc*
MACs    -*-etm@openssh.com

After that do the checks from above. If they look good, restart sshd. If not... toss my trash.