Skip to content

Instantly share code, notes, and snippets.

@jvaubourg
Last active September 2, 2020 16:21
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save jvaubourg/db5535a55f54e3641e5a3083742d0d15 to your computer and use it in GitHub Desktop.
Save jvaubourg/db5535a55f54e3641e5a3083742d0d15 to your computer and use it in GitHub Desktop.
Share a read-only tmux session over HTTPS with password
#!/bin/bash
# SERVER:
# sudo apt-get install certbot socat tmux
# sudo ./shareterminal.sh
# Your stage: tmux new-session -As remote
# Your spectators: tmux lsc -t remote
#
# CLIENTS:
# curl -N https://tmux.example.com:1337
# or curl -N https://tmux.example.com:1337 -H 'X-Pass: foobar'
_DOMAIN=tmux.example.com
_PORT=1337 # > 1023
_PASS= # empty to disable
_LETSENCRYPT_MAIL=julien@example.com
_UNIX_USER=ju
_TMUX_WIDTH=128
_TMUX_HEIGHT=32
## SCRIPT
set -Efuo pipefail
if [ "${EUID}" -ne 0 ]; then
echo '[ERR] You must be root.' >&2
exit 1
fi
function reverse() {
trap - EXIT ERR INT
if [ ! -z "${net_device}" ]; then
iptables -D INPUT -p tcp -i "${net_device}" --dport "${_PORT}" -j ACCEPT
ip6tables -D INPUT -p tcp -i "${net_device}" --dport "${_PORT}" -j ACCEPT
iptables -D INPUT -p tcp -i "${net_device}" --dport 443 -j ACCEPT &> /dev/null || true
ip6tables -D INPUT -p tcp -i "${net_device}" --dport 443 -j ACCEPT &> /dev/null || true
fi
exit 0
}
tmux_name=remote
net_device=$(ip r g 1.2.3.4 | awk '/via/ { print $5 }')
if [ -z "${net_device}" ]; then
echo '[ERR] Unable to guess your network device.' >&2
exit 1
fi
trap reverse EXIT ERR INT
ip6tables -I INPUT -p tcp -i "${net_device}" --dport 443 -j ACCEPT
iptables -I INPUT -p tcp -i "${net_device}" --dport 443 -j ACCEPT
certbot certonly -qn --standalone --preferred-challenges tls-sni --rsa-key-size 4096 --agree-tos -m "${_LETSENCRYPT_MAIL}" -d "${_DOMAIN}"
mkdir -p "/etc/ssl/${_DOMAIN}/"
cp "/etc/letsencrypt/live/${_DOMAIN}/privkey.pem" "/etc/ssl/${_DOMAIN}/"
cp "/etc/letsencrypt/live/${_DOMAIN}/cert.pem" "/etc/ssl/${_DOMAIN}/"
cp "/etc/letsencrypt/live/${_DOMAIN}/chain.pem" "/etc/ssl/${_DOMAIN}/"
ip6tables -D INPUT -p tcp -i "${net_device}" --dport 443 -j ACCEPT
iptables -D INPUT -p tcp -i "${net_device}" --dport 443 -j ACCEPT
ip6tables -I INPUT -p tcp -i "${net_device}" --dport "${_PORT}" -j ACCEPT
iptables -I INPUT -p tcp -i "${net_device}" --dport "${_PORT}" -j ACCEPT
echo -e "SERVER (${_UNIX_USER}):\n\t tmux new-session -As ${tmux_name}"
if [ -z "${_PASS}" ]; then
echo -e "CLIENTS:\n\t curl -N https://${_DOMAIN}:${_PORT}"
else
echo -e "CLIENTS:\n\t curl -N https://${_DOMAIN}:${_PORT} -H 'X-Pass: ${_PASS}'"
fi
echo -e "\nReady... ^C to stop\n"
sudo -Eu "${_UNIX_USER}" socat\
"OPENSSL-LISTEN:${_PORT},pf=ip6,ipv6only=0,fork,reuseaddr,cert=/etc/ssl/${_DOMAIN}/cert.pem,key=/etc/ssl/${_DOMAIN}/privkey.pem,cafile=/etc/ssl/${_DOMAIN}/chain.pem,verify=0"\
"SYSTEM:\
( while [ -e /proc/\$PPID ]; do sleep 1; done; kill -TERM \$\$ ) &\
if [ ! -z \"${_PASS}\" ]; then\
while read -r i; do\
if [ \"\$i\" != \"\${i##X-Pass:}\" ]; then\
[ \"\$i\" = \"X-Pass: ${_PASS}\" ] && break;
echo Wrong password.;\
exit 0;\
fi;\
done;\
fi;\
stty cols ${_TMUX_WIDTH};\
stty rows ${_TMUX_HEIGHT};\
exec tmux attach -r -t ${tmux_name}\
",pty,stderr
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment