In this situation it is not possible to connect to remote hosts (e.g. github.com) for managing repos over ssh. A tunnel through a remote host (tunnel.myhost.com) can remedy this. An ssh configuration file can be added to the ~/.ssh/config
directory to specify a specific command for connecting github.com.
See also How to setup SSH Tunneling
Setup
- create a tunnel host that accepts incomming connections:
tunnel.myhost.com
- install nc
apt install nc
- create a tunnel user on remote host:
- create an ssh key and add public remote keys on
tunnel.myhost.com
[tunnel]$ ssh-keygen
- add appropriate public keys to tunnel user
~/.ssh/authorized_hosts
- on local host add the following configuration to ~/.ssh/config
Host github.com
ProxyCommand ssh -q -p 5223 [email protected] nc %h %p
- use git as normal
git [email protected]:bar/foo.git
The network prevents opening an SSH connection to another device on the same physical network. Local Device A (LA) cannot connect to Local Device B (LB). The solution is to use an intermediary Remote Host C (RC) that supports SSH tunnels. From LA, create a remote tunnel into RC; from LB SSH to RC and then connect back to LA through the LA<==>RC tunnel.
The solution to this problem is to create a long-standing auto-renewing SSH tunnel using autossh. Autossh will monitor the ssh connection and reestblish it as needed from a system daemon.
Local Device A (LA)
This device will be accessible via SSH. I use this for headless Raspberry Pis that are deployed in environments that do not allow direct local connections.
- Generate ssh keypairs if they do not alreay exist
ssh-keygen
- Install autossh on LA
- Test autossh by making an outgoing connection to RC
autossh -M 5112 -N -R 50505:localhost:22 [email protected] -p 22
-M xxxx
Sets the monitoring port; autossh monitors the status of the tunnel on this port. Choose any port outside of the reserved range (>1024)-N
Do not execute a remote command; this is for setting up port forwards-R yyyyy:localhost:zz
setup the remote port forward; yyyyy (anything outside of the reserved range) is the outgoing port and zz (typically 22 for SSH) is the incoming port on RC.[email protected]
standard ssh user@host-p zzzz
incoming port to use on remote host; this is only necessary if RC does not accept SSH connections on port 22.
- Connect to RC and add public key to the
authorized_hosts
file- This is necessary for daemon connections to be restablished automatically
- See this link for instructions
- Configure the autosshd daemon using a unit file in
/etc/systemd/system/autossh-tunnel.service
(see below)- Update the
ExecStart
portion to match your configuration
- Update the
- Enable the daemon with
sudo systemctl enable autossh-tunnel.service
- Reload the daemon units with
sudo systemctl daemon-reload
, then (re)start the daemon withsudo systemctl restart autossh-tunnel.service
autossh-tunnel.service unit file
[Unit]
Description=AutoSSH tunnel service to remote.foo on port 443 (remote 50505)
Wants=network-online.target
After=network-online.target
[Service]
Environment="AUTOSSH_GATETIME=0"
ExecStart=/usr/bin/autossh -M 5122 -o "ServerAliveInterval 30" -o "ServerAliveCountMax 3" -N -R 50505:localhost:22 [email protected] -p 443
User=your_local_user
Group=your_local_user
Restart=always
[Install]
WantedBy=multi-user.target
Remote Host C (RC)
- Ensure that SSH is setup and configured
Local Device B (LB)
This is typically the device you are using (e.g. a Laptop) that will establish the ssh connection to LA via RC.
- Connect to RC using ssh
- Establish a connection to LA through the SSH tunnel
ssh LA_user@localhost -p 50505
- the ssh connection will be sent over localhost tunnel on port 50505. This match the port settings in the Local Device A setup.
- Work on remote machine as expected
Tips
- View all active tunnels:
sudo ss -ltp |grep sshd