Lately I have been using some online/web collaborative coding tools for interviews. Which makes me wonder about how to achieve some sort of screen sharing in the terminal.
The way described here is relatively simple, and isn't particularly obscure or clever.
We will invite the guest to login with ssh, and immediately have them attached to an existing tmux session. Then we effectively have a screen share session in the terminal. Although individual cursors for each user aren't available, we trade in for simplicity. As this requires virtually no setup on the guest and just common tools on the host.
First, we will create a new user, since we don't want/need them to run any command other than attach to our session, they don't need a proper shell at all, their "shell" can just be a script that runs a single command.
useradd unprivileged --shell=/tmp/connect_to_tmux --expiredate="$(date --date='tomorrow' '+%F')" --home-dir=/tmp passwd unprivileged
Then the "shell" is just a script to attach to the tmux session. We can use the
-r flag for read-only access, remove it to allow editing. Normally we won't be able to enforce read-only access when sharing tmux session, but since we have control over what command gets run, we could lock the guest in a read-only client.
cat <<EOF >/tmp/connect_to_tmux #!/bin/sh tmux -S /tmp/tmux_session_shared_with_unprivileged attach -r EOF chmod +x /tmp/connect_to_tmux
Depending on the distribution, you might need to add the new shell to
/etc/shells for it to be recognized and used as a shell.
echo '/tmp/connect_to_tmux' >> /etc/shells
To prevent unwanted ssh access to other accounts, we can edit
/etc/ssh/sshd_config to allow only expected users to login. For example, adding/updating
AllowUsers unprivileged will prevent ssh login any user other than our new user "unprivileged". Don't forget to load/reload the config by starting/restarting the ssh server.
We can establish a TCP tunnel with ngrok to allow the guest accessing our computer with ssh.
ngrok tcp 22 # you can specify --region flag according to your location
We can start the tmux session with our own account & shell, and we will need to change the access rights of the socket file.
tmux -S /tmp/tmux_session_shared_with_unprivileged chmod 766 /tmp/tmux_session_shared_with_unprivileged
Or, if we don't want to use our own account, for example, to prevent accidentally showing something in the bash history, we can start the session with the unprivileged user instead. However, we will need to specify a normal shell instead of the
connect_to_tmux script when starting tmux.
sudo SHELL=/usr/bin/bash -u unprivileged tmux -S /tmp/tmux_session_shared_with_unprivileged
All that is left is to share the login info with your guest.
Oh did I mention there will be no fancy IDE? Time to learn VIM ;)
And after everything, even though the account will expire in a day because we added the
--expiredate flag when creating the user, we may want to clean it up.
userdel -r unprivileged
Using "custom shell" with ssh
In addition to enforcing command, you can also disable port forwarding and other stuff ssh comes with.
You can replace
screen, however there might be security concerns when sharing sessions across users.