Preliminary note
In this answer I present an alternative to the solution from my previous answer. Some insight into the problem is there, I won't repeat it here. This answer contains a standalone solution, independent from the other answer. I'm answering the question anew, so this answer addresses the situation described in the question. If you have implemented another solution, then you may need to revert to the configuration described in the question before applying this solution.
Again, to denote the remote hosts, for consistency I will use capital A and B even in code.
Solution
Remove the
RemoteCommand ssh -tt -q b
from your local SSH config.Run an SSH server (
sshd
) as your regular user on B.For this you need to:
Create a host key file for the server:
# on Bssh-keygen -f ~/.ssh/my_special_host_key -C 'Special host key for my private sshd.'
(If you cannot run
ssh-keygen
on B, generate a key pair elsewhere and move it to your~/.ssh/
on B.)Create a configuration file for the server:
# on Bcat >~/.ssh/my_special_sshd_config <<'EOF'HostKey ~/.ssh/my_special_host_keyListenAddress 127.0.0.1:17522EOF
(This creates a minimal config. Customize the config at will.)
Make sure the following command keeps running as your regular user on B:
/usr/sbin/sshd -f ~/.ssh/my_special_sshd_config
(Depending on how you run it, you may or may not want
-D
.)It may be a systemd user service, a command run in tmux on B, something your already configured connection (from A to B) that "persists the authentication status on A" runs automatically, or even the following command run locally:
# on localssh -t A 'ssh -t B "/usr/sbin/sshd -D -f ~/.ssh/my_special_sshd_config"'
Note that invoking this way from your local machine may cause B to terminate this
sshd
short after the local machine goes to sleep; or after some time; or(?) never. So after waking up the same local command may succeed or fail. I don't know enough about A and B to guide you here, I leave the implementation to you.Nowadays running
sshd
(from OpenSSH at least) as a regular user does not requireUsePrivilegeSeparation no
advised in old guides (example). Your privatesshd
on B will be able to act as your user only, it shall not allow other users to log in, even if they provide credentials otherwise valid on B. (But if you are not convinced, you can addAllowUsers yourusername
tomy_special_sshd_config
.) In my tests the right password was rejected anyway, but key-based authentication worked. By defaultsshd
uses~/.ssh/authorized_keys
(and~/.ssh/authorized_keys2
); there, register the key your localssh
uses, if not done already.Now you (or anyone on B) can reach your private
sshd
by invokingssh -p 17522 127.0.0.1
on B, but only your key(s) will be accepted. Of course logging in from B to B makes little to no sense, so let's move to A.
On A, reconfigure your already configured connection (from A to B) that "persists the authentication status on A", so it also forwards the port all the time. The right line for
~/.ssh/config
is:LocalForward 127.0.0.1:17522 127.0.0.1:17522
under
Host B
.When the forwarding works and your private
sshd
on B works, you (or anyone on A) can reach the saidsshd
by invokingssh -p 17522 127.0.0.1
on A.Now from your local computer you can reach your private
sshd
on B by jumping via A:# on localssh -J A -p 17522 127.0.0.1
To automate, put this at the beginning of your local SSH config (
~/.ssh/config
):Host B ProxyJump A Hostname 127.0.0.1 Port 17522Host *
Now local usage of ssh B
will reach B via A and every functionality (including port forwarding) should work.
Note 17522
is an arbitrary port number. Change it if it's already in use on B or on A.