- A great YouTube video on overview on SSH
- SSH Essentials: Working with SSH Servers, Clients, and Keys
- https://smallstep.com/blog/ssh-agent-explained/
- https://gist.github.com/ryuheechul/494f4e6f08eaca34ef00ab8b238eca2a#ssh-server
RemoteCommand tmux a # as something other than default shell
RequestTTY force # as our (remote) command require TTY
# equivalent to `ssh [host] -t 'tmux a'also see Eleven SSH Tricks
Compression yesAgent forwarding is kind of a must so that the end client's pubkey is used
ForwardAgent yesAlso make sure to run ssh-add -k # or ssh-add [keyname] to add keys to agent or check with ssh-add -l to see if it's listed.
Otherwise it will not be picked up. And you might see an error meesage below.
**sign_and_send_pubkey: signing failed: agent refused operation** # (it might print your key name here too)An additional config stanza like below could add automatically.
AddKeysToAgent yesBut I experienced that some system don't (like Blink Shell at the moment) so make sure to verify keys added by seeing the key at the result of ssh-add -l.
Sometimes a server has its own local agent running and connect it via a config like below
host *
IdentityAgent some/socket/fileBut this will ignore $SSH_AUTH_SOCK and (this is so not obvious as ssh-add -l will still show the one from $SSH_AUTH_SOCK but that's what it is...).
There is a workaround to this though by only setting IdentityAgent when it's a direct connect (achieved by looking at the presence of $SSH_TTY).
Match host * exec "test -z $SSH_TTY"
IdentityAgent some/socket/fileNow $SSH_AUTH_SOCK will be honored with the config above.
There is a thread on this information - https://1password.community/discussion/comment/662319/#Comment_662319.
- https://github.com/maxgoedjen/secretive/blob/main/FAQ.md#how-do-i-tell-ssh-to-use-a-specific-key
- maxgoedjen/secretive#127 (comment)
- maxgoedjen/secretive#92 (comment)
- maxgoedjen/secretive#156 (comment)
- maxgoedjen/secretive#117 (comment)
Enter Keychain, https://www.funtoo.org/OpenSSH_Key_Management,_Part_2
https://esc.sh/blog/ssh-agent-windows10-wsl2/ or
# maybe in your .bashrc or .zshrc
eval $(keychain [--quiet] --eval --agents ssh [id_rsa])assuming
pbcopy&pbpasteis what is used for clipboard on both systems
ssh remote-host pbpaste | pbcopy
pbpaste | ssh remote-host pbcopy
not strictly related to above, but I enjoyed reading this article, https://andrewbrookins.com/technology/synchronizing-the-ios-clipboard-with-a-remote-server-using-command-line-tools/ and hopefully iPad gets to have macOS one day, lol.
Even beyond simply accessing it, sharing clipboard is also possible via something called X11 forwaring.
A nice explanation is at https://askubuntu.com/a/305681.
# client side at ./ssh/config
Host [host]
ForwardX11 yes # make sure this is on# server side at /etc/ssh/sshd_config
X11Forwarding yes # make sure this is on - this might be blocked by default on macOS host
# When an error occur like this
# ```
# Remote: No xauth program; cannot forward
# X11 forwarding request failed on channel 0
# ```
# and the host is macOS and xquartz is installed, this should help with error above
XAuthLocation /opt/X11/bin/xauth # or the path what `which xauth` returnsRestart the sshd on macOS after editing
# applying edited /etc/ssh/sshd_config requires restarting sshd
sudo launchctl stop com.openssh.sshd && sudo launchctl start com.openssh.sshdserving SSH via tailscale seems to have an issue with X11Forwarding, tailscale/tailscale#5160
[an update on above] I discovered an workaround! - tailscale/tailscale#5160 (comment)
On macOS, there is no X11 server by default but it can be installed
I would install it by one of these ways:
nix-env -iA nixpkgs.xquartzbrew install --cask xquartz
Another important thing is that we need to know how to use clipboard on linux and that information can be found at https://ostechnix.com/access-clipboard-contents-using-xclip-and-xsel-in-linux/.
I prefer to use xsel over xclip.
And having xsel is enough to make these two plugins work:
I also would make an alias to help my muscle memory used to macOS.
# bring `pbcopy` and `pbpaste` to linux
alias pbcopy='xsel -i -b'
alias pbpaste='xsel -o -b'Now things copied inside ssh and vice versa!
If you are in a "abnormal" situation that simple ForwardX11 yes doesn't work (i. e. WSL with WSLg), the solution below might work.
# below is equivalent to `ssh -R 6020:/tmp/.X11-unix/X0 [host]` if it was used as CLI
Host [host]
RemoteForward 6020 /tmp/.X11-unix/X0 # basically can be used in place of `ForwardX11 yes`
# ^ ^
# | |
# | |
# as a TCP port on remote host |
# (6020) |
# as a Unix Domain Socket on the SSH client host
# (/tmp/.X11-unix/X0)
# which your xorg server (possibly WSLg) is lisetning to
# and the remote host side would need to `export DISPLAY=':20'`
# so that X11 client will use `localhost:6020` for X11 channel
# where is +6000 coming from?
# > `man 1 xorg | grep 6000`
# what exactly the values like these `:0` or `:20` mean?
# > `man 7 X` and search `DISPLAY NAMES`
# > to see how these resolves to which protocols (i.e. TCP or Unix Domain Socket)
# also read links below to understand more about why it works and why it might not work for some situations- TIL - X11 FORWARDING IN WSLG
- X11 Forwarding using an SSH Reverse Tunnel
- How do X clients know that they will need to connect to TCP port 6000+?
But this can fail with the message below (depends on your SSH client side setup):
# from remote side
$ printenv DISPLAY
:20
$ xsel -o -b
Authorization required, but no authorization protocol specified
xsel: Can't open display: (null)
: Socket is not connected# from ssh client (NixOS + Gnome + XWayland)
$ printenv XAUTHORITY # does this have anything to do with it?
/run/user/1000/.mutter-Xwaylandauth.ABCXYZ
# yes it's probably due to a mismatch between $DISPLAY and $XAUTHORITY
# run `xauth list` to debugBut... nested X would make it work althrough how useful would that be is up to you
Let's say a host is macOS and guest is a Linux VM running via UTM (and there is an agent syncing clipboard).
And with whatever reason, on the host side, there is no X server (XQuartz) are running or just ForwardX11 doesn't work.
In this case, the SSH client connection (from the host) can "pretend" that it is running directly from the guest GUI by setting $XAUTHORITY.
Get the value by running printenv DISPLAY XAUTHORITY from the terminal within the guest directly.
And export DISPLAY and XAUTHORITY within the client connection.
# an example (that values from the above step)
export DISPLAY=:0
export XAUTHORITY=/run/user/1000/.mutter-Xwaylandauth.XYZABCActually there is a better way to get these value less manually via
systemctl systemctl --user show-environment. e.g. https://github.com/ryuheechul/dotfiles/commit/1f4329b603646e24048a232aeedf43e026a614bc
With this particular "workaround", unlike the usual usage, we are using the X server is at the remote host (VM guest in this case) not at the SSH client (Host macOS machine)
- application (e.g. poetry, pip) that excpect the keyring auth will prompt in the original virtual console which is hard to know unless you are looking the original virtual console via for example UTM window.
- possibly you can get hint on this by running a command with verbose log option like
-v, -vv, -vvvif command supports it
- possibly you can get hint on this by running a command with verbose log option like
Few readings regarding above:
- https://goteleport.com/blog/x11-forwarding/
- https://forums.opensuse.org/t/authorization-required-but-no-authorization-protocol-specified/167149/15
Using after initial installation may require reboot (let me know if not)
xeyes command to see if it's working (and it should run the app if it wasn't)
A timing could be little tricky that when it actually start working.
Check to see if xsel (or xclip if you prefer) is installed on the host system.
But bascially, when you run printenv DISPLAY, you should see something like below.
# on the client side - in this case, macOS
$ printenv DISPLAY
/private/tmp/com.apple.launchd.xYzAbCde/org.xquartz:0
# on the ssh host side - in this case, linux
$ printenv DISPLAY
localhost:10.0The selection should be CLIPBOARD not PRIMARY nor SECONDARY.
These should work
xclip [-i] [-o] -s clipboardxclip [-i] [-o] -s cxsel [-i] [-o] --clipboardxsel [-i] [-o] -b
but not these:
xclip [-i] [-o]xsel [-i] [-o]
via X11 forwarding, xeyes works but not xsel -ib from the remote machine? (xse -ob works when it's copied from the client)
# `xsel -ib` could fail silently, which happens with `xsel -ob`, too.
# let's see the verbose messages
$ xsel -obvvv
xsel: Window id: 0xc00001 (unmapped)
xsel: Timestamp: 30457450
xsel: Maximum request size: 4000 bytes
xsel: Conversion refused
xsel: Conversion refused
# conversion refused... why?
$ echo 'please copy me' | xsel -ibvvv
xsel: Window id: 0x1c00001 (unmapped)
xsel: Timestamp: 30561631
xsel: Maximum request size: 4000 bytes
xsel: opened logfile /home/[user]/.cache/xsel.log
# ok let's follow the log file and then try `xsel -ib`
$ tail -f ~/.cache/xsel.log
xsel: BadAccess (attempt to access private resource denied): Resource temporarily unavailableTurns out adding one more option like below worked
# ~/.ssh/config
Host [host]
ForwardX11 yes # not just this one but the line below
ForwardX11Trusted yes # but it doesn't seem to be always necessary (depends on your client machine, I guess)
# for example, I didn't need `ForwardX11Trusted yes` on macOS + XQuartz but with NixOS + XWayland
# I don't know why exactly yet, but I assume the X server configuration on (my) NixOS configuration has a tighter control.pbcopy and pbpaste seems not work out of the box to forwarded X11 on the host side. (when it is on the client side it works)
xsel [-i] [-o] -bstill works though
Even after running XQaurtz on the host side and make sure it syncs clipboards. My speculation is that it's because even if it syncs, it syncs with the host X11 not the client's which makes sense to me.
I'm looking for an way to mitigate this as this could be annoying that plugins that I use automatically select pbcopy|paste when they exist.
I invented a workaround that uses these wrapper scripts:
- https://github.com/ryuheechul/dotfiles/blob/master/bin/local/pbcopy
- https://github.com/ryuheechul/dotfiles/blob/master/bin/local/pbpaste
They worked as I hoped for my use cases!
And now these plugins works on macOS host.
Just make sure those scripts are exported to $PATH.
But this might break the sync between macOS clipboard and xsel -b. I'm looking into it. I'm fine with the workaround for now.
TODO: add information about reverse sshfs: