1

I have set up a local ssh server, which I like to access with this neat alias from my local network:

~/.ssh/config:

Host myserver-local
HostName 192.168.2.8
User iago-lito
Port 22

In order to access it remotely, I have set up a no-ip account to access it via a dyndns IP resolution, which I like to access with this neat alias from any other network:

~/.ssh/config:

Host myserver
HostName myserver.ddns.net
User iago-lito
Port 22

Unfortunately, because my router do not allow NAT loopbacks, I need to use:

ssh myserver

when I'm away and:

ssh myserver-local

when I'm at home.. which makes scripting quite annoying when it comes to automately scp, git push etc.

How could I make the same alias work in both cases?

1

With a reasonably modern OpenSSH, you can run a shell command to select a Match block in ~/.ssh/config. Assuming you have a script am-on-home-network that returns 0 when executed on your home network and 1 when executed outside:

Match Host myserver exec "am-on-home-network"
HostName myserver
User iago-lito
Port 22

Host myserver
HostName myserver.ddns.net
User iago-lito
Port 22

For am-on-home-network, you can use arp to explore the local network. Look for your home router's MAC address. (Looking for IP addresses is unreliable because many private networks use the same ranges of private IP addresses.)

#!/bin/sh
timeout 0.2 arping -f -q -I eth0 12:34:56:78:9a:bc

Adjust the MAC address to the MAC address of your router that your computer sees when it's at home. Adjust eth0 to the network interface on your computer that is used to connect to your home router.


The pure SSH approach has the advantage that it can be done in userland, but it only works for SSH, and it increases the connection establishment delay noticeably. A better solution is to run a DNS server at the system level, and configure it to serve the local IP address the global name myserver.ddns.net when on the local network. Dnsmasq is a small, simple DNS cache and server, suitable for running on an endpoint machine or a small network. If you aren't already running a DNS cache on your machine, it will make general Internet usage a bit faster. Ubuntu runs dnsmasq by default.

In dnsmasq, create a file /etc/dnsmasq.d/home-server containing

host-record=myserver.ddns.net,192.168.2.1

Add the following script to your network startup scripts (whatever they are on your distribution):

#!/bin/sh
comment=\#
if timeout 0.2 arping -f -q -I eth0 12:34:56:78:9a:bc; then
  comment=
fi
sed -i "\$s/^#*/$comment/" /etc/dnsmasq.d/home-server
service dnsmasq restart

If your system sets up Dnsmasq through D-Bus, editing the configuration file isn't the best option, and I don't even know if it'll work. You would need to call dbus-send to add or remove the host record based on the output of arping. Or, if you're using NetworkManager, configure it to set the host entry on the connection corresponding to your home network.

  • This is neater and more complete, thanks ! :) – iago-lito Feb 20 '17 at 7:09
2

You could write a script that pings your server's local address, and based on the result, swap in one or another .ssh/config file. For example:

ping -c1 -W1 192.168.x.x

Those options are Count, i.e. one ping, and Wait, 1 second. Use the return value of ping - 0 found, not 0, not found.

You could set this script to run when you connect to a network.

Sorry about being brief, I'm writing from my phone.

  • This works fine enough. It is true that it should not take more than 1 second to ping the server in local. Cheers :) – iago-lito Feb 19 '17 at 14:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.