SSH access from inside and outside a LAN using the same terminal command

Looking closer at your question, it appears you're using the same computer from both in- and outside of the LAN. I have revised my answer accordingly:

In your ~/.ssh/config, add:

Host raspi-wan
    HostName 12.34.56.78
    User john
    Port 1234

Host raspi-lan
    HostName 192.168.1.2
    User john
    Port 22

Then, you can ssh raspi-wan from outside the LAN, or ssh raspi-lan from inside the LAN without faffing about with DNS servers or editing /etc/hosts for all users, or even needing to do anything as root. If you want the name raspi to resolve differently depending upon where you are, that will probably require some shell scripting magic to detect your network and act accordingly.


This is perfectly doable with just the ssh config, without having to use separate aliases for lan and wan or creating any extra port forwards. (But you naturally need some way to detect whether you're inside your lan or not)

In ~/.ssh/config, you'll want to add something like this:

Match host raspi exec "am_i_outside_of_my_lan"
    HostName 12.345.67.89
    Port 1234

In place of am_i_outside_of_my_lan you'll want to place a command that determines whether you're inside your home network or not, and returns with 0 exit code if you're outside it, and something else otherwise.

The host condition is probably self-explanatory, but the exec condition warrants some explanation: It matches only when the given command returns with exit code 0, ie. no error.

So in other words, what this does is the host raspi part restricts this rule to when you try to connect to the host raspi, and the exec "am_i_outside_my_lan" further restricts it so that it only applies when you're connecting from outside of your home network. So inside your home network ssh user@raspi does exactly what it normally would, but outside of it the rule matches and it instead does the equivalent of ssh -p 1234 [email protected].

As for what to use in place of am_i_outside_of_my_lan, that depends entirely on your setup. I do suggest placing the commands in a separate script instead of trying to write it inline, because the quoting seems to be a bit hard to get right.

Personally, I used the following Python script to detect whether I'm inside my own network: (Since my domain name resolves to a local ip inside my own network)

#! /usr/bin/env python
import socket, sys

sys.exit(socket.gethostbyname('mydomain.com').startswith('192.168.1.'))

If you don't have a similar setup, you might have to do something else. (For example, you could look at the name of the wireless network you're connected to, or even query some what-is-my-ip service to get the external ip of the network you're connected to)


On your computer (the connect-ing one), you can set a hostname for 12.345.67.89. Open your /etc/hosts file, and set a DNS entry :

12.345.67.89    raspi

Your machine will then transform "raspi" into "12.345.67.89" as part of a local DNS resolving process. If you use several machines, the change must be made on each and every one of them. Problem is : it requires root access to edit /etc/hosts, and you might not have it everywhere.

If you want "raspi" to be recognised automatically from anywhere, then sorry : not possible. This would require the registration of "raspi" as a domain name, which cannot happen as "raspi" has no TLD, and wouldn't depend of any DNS root server. However, you can register a domain name (let's say cfbaptista.me, and point it to your WAN IP address. With some port forwarding, you will be able to access your Raspberry Pi with :

ssh (you@)(raspi.)cfbaptista.me

(still, that's spending money for almost nothing...)

Concerning the user@ part, it depends on your login name on the different machines. If you have the same name on the connecting machine and on the remote one, then no need to specify. If not, you need to specify who you are on the remote machine.