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.