Aldryic C'boas
The Pony
Hey folks. This is a per-request follow-up to MannDude's SSH Gateway inquiry, about locking multiple VMs to only accept SSH from a single access point. As always, ALWAYS RUN NEW CODE IN A DEVELOPMENT ENVIRONMENT FOR TESTING BEFORE DEPLOYING TO PRODUCTION EQUIPMENT. Also, all VMs referenced below are assumed to be running Debian 6/7. Since we're only dealing with the sshd daemon, this makes little difference and should be cross-distro compatible. However, some distros are funny about particular syntax with /etc/ssh/sshd_config entries - use caution and man pages, in that order.
For the purpose of this guide, we'll assume that you have the following four VPSes:
STEP 1 (Gate):
For convenience sake, we'll add the three VPSes to the /etc/hosts file so that we don't have to keep remembering their IPs. Fire up vi (or nano if you must ), and add the following to your /etc/hosts file on Gate:
1.1.1.2 Anna
1.1.1.3 Boris
1.1.1.4 Vasily
We're not going to add anna.hostname.com, though if you do use domains for that purpose feel free.
Next, we're going to generate a new SSH key for Gate. (What, you use the same id_rsa for everything? Shame on you).
-13:24:12- Gate:~ :: aldryic % ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/aldryic/.ssh/id_rsa): <ENTER>
Enter passphrase (empty for no passphrase): walruscock<ENTER>
Enter same passphrase again: walruscock<ENTER>
Your identification has been saved in /home/aldryic/.ssh/id_rsa.
Your public key has been saved in /home/aldryic/.ssh/id_rsa.pub.
The key fingerprint is:
bc:88:78:1f:93:d6:42:71:d1:d5:2d:82:5e:52:26:fb aldryic@Gate
The key's randomart image is:
(no, my password is not walruscock, and you shouldn't use it either)
Nab a copy of that .pub file (or just copy/paste it to a text editor for now), we'll be using it again in a bit.
STEP 2 (Anna, Boris, Vasily):
Now to secure А́нна, Бори́с, and Васи́лий. The 'normal' /etc/ssh/sshd_config file is a bit of a mess.. so feel free to use this one if you're so inclined:
Port 8008
Protocol 2
ListenAddress 1.1.1.2
SyslogFacility AUTHPRIV
LoginGraceTime 15s
PermitRootLogin no
RSAAuthentication no
PubkeyAuthentication no
PasswordAuthentication no
UsePAM yes
PermitEmptyPasswords no
ChallengeResponseAuthentication no
GSSAPIAuthentication no
GSSAPICleanupCredentials no
AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
AcceptEnv LC_IDENTIFICATION LC_ALL
PermitUserEnvironment no
AllowTcpForwarding no
GatewayPorts no
X11Forwarding no
PrintMotd yes
PrintLastLog yes
TCPKeepAlive yes
UsePrivilegeSeparation yes
Compression delayed
ClientAliveInterval 0
ClientAliveCountMax 3
UseDNS no
Match address 1.1.1.1/32
RSAAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFiles .ssh/authorized_keys
NOTICE: You MUST change the Port, ListenAddress (to reflect the real IP), and Match address (to reflect Gate's real IP). Why do we want to bind a ListenAddress? Because when a VPS has more than one public-facing IP, why would we ever want SSH to respond except where we want it? Limit all possible breach points.
Now, take the .pub file we created earlier when running ssh-keygen and place it in your home directory. Already know what to do with the .pub file? Good for you, don't spoil it for everyone else
Now we'll run a few simple commands as root:
su aldryic
mkdir .ssh
cp ~/id_rsa.pub ~/.ssh/authorized_keys
chmod 700 ~/.ssh
chmod og-rw ~/.ssh/authorized_keys
chmod a-x ~/.ssh/authorized_keys
exit
This'll take that pubkey, and create an appropriate authorized_keys file for the sshd to use. Replace 'aldryic' with your own username (please make sure you actually create your user account first >_>).
Next, because you should never ever EVER allow root login, we'll make sure we have sudo running, and add our user to the sudo list:
apt-get update; apt-get install sudo
gpasswd -a aldryic sudo
/etc/init.d/sudo restart
Alternately, if you don't want to screw with sudo (yeah, it can be annoying sometimes), you can just use the su command and input the root password whenever you login and need to do root work.
All that's left now is to restart the sshd, and test the connection. Don't (and I can't stress this hard enough), DON'T close your current SSH session. You will just leave yourself locked out of the VM if you do this and something FUBAR'd. Open a new putty/ssh to test with.
Followup:
The major drawback to this setup is that it requires Gate to have a permanent, static IP. If Gate's IP changes, you're SOL and locked out of the VMs unless you're with a provider that offers a working serial console or VNC. The best workaround to this is to create a copy of the /etc/ssh/sshd_config we made in Step 2, and use your preferred method of distribution (rsync, httpd/wget on cron, etc) to have the file distributed to each VPS. (Remember that since we used ListenAddress, you need a distinct sshd_config for each VPS). There are honestly way too many ways to accomplish this for me to list here - that could be a guide all it's own. And if you're at the point where you're ready to use SSH lockdowns of this level, you're already well familiar with options such as rsync anyways
For the purpose of this guide, we'll assume that you have the following four VPSes:
- Gate (IP: 1.1.1.1, primary VPS or home connection w/ dedicated IP)
- Anna (IP 1.1.1.2, VPS to be SSH-locked)
- Boris (IP 1.1.1.3, VPS to be SSH-locked)
- Vasily (IP 1.1.1.4, VPS to be SSH-locked)
STEP 1 (Gate):
For convenience sake, we'll add the three VPSes to the /etc/hosts file so that we don't have to keep remembering their IPs. Fire up vi (or nano if you must ), and add the following to your /etc/hosts file on Gate:
1.1.1.2 Anna
1.1.1.3 Boris
1.1.1.4 Vasily
We're not going to add anna.hostname.com, though if you do use domains for that purpose feel free.
Next, we're going to generate a new SSH key for Gate. (What, you use the same id_rsa for everything? Shame on you).
-13:24:12- Gate:~ :: aldryic % ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/aldryic/.ssh/id_rsa): <ENTER>
Enter passphrase (empty for no passphrase): walruscock<ENTER>
Enter same passphrase again: walruscock<ENTER>
Your identification has been saved in /home/aldryic/.ssh/id_rsa.
Your public key has been saved in /home/aldryic/.ssh/id_rsa.pub.
The key fingerprint is:
bc:88:78:1f:93:d6:42:71:d1:d5:2d:82:5e:52:26:fb aldryic@Gate
The key's randomart image is:
(no, my password is not walruscock, and you shouldn't use it either)
Nab a copy of that .pub file (or just copy/paste it to a text editor for now), we'll be using it again in a bit.
STEP 2 (Anna, Boris, Vasily):
Now to secure А́нна, Бори́с, and Васи́лий. The 'normal' /etc/ssh/sshd_config file is a bit of a mess.. so feel free to use this one if you're so inclined:
Port 8008
Protocol 2
ListenAddress 1.1.1.2
SyslogFacility AUTHPRIV
LoginGraceTime 15s
PermitRootLogin no
RSAAuthentication no
PubkeyAuthentication no
PasswordAuthentication no
UsePAM yes
PermitEmptyPasswords no
ChallengeResponseAuthentication no
GSSAPIAuthentication no
GSSAPICleanupCredentials no
AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
AcceptEnv LC_IDENTIFICATION LC_ALL
PermitUserEnvironment no
AllowTcpForwarding no
GatewayPorts no
X11Forwarding no
PrintMotd yes
PrintLastLog yes
TCPKeepAlive yes
UsePrivilegeSeparation yes
Compression delayed
ClientAliveInterval 0
ClientAliveCountMax 3
UseDNS no
Match address 1.1.1.1/32
RSAAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFiles .ssh/authorized_keys
NOTICE: You MUST change the Port, ListenAddress (to reflect the real IP), and Match address (to reflect Gate's real IP). Why do we want to bind a ListenAddress? Because when a VPS has more than one public-facing IP, why would we ever want SSH to respond except where we want it? Limit all possible breach points.
Now, take the .pub file we created earlier when running ssh-keygen and place it in your home directory. Already know what to do with the .pub file? Good for you, don't spoil it for everyone else
Now we'll run a few simple commands as root:
su aldryic
mkdir .ssh
cp ~/id_rsa.pub ~/.ssh/authorized_keys
chmod 700 ~/.ssh
chmod og-rw ~/.ssh/authorized_keys
chmod a-x ~/.ssh/authorized_keys
exit
This'll take that pubkey, and create an appropriate authorized_keys file for the sshd to use. Replace 'aldryic' with your own username (please make sure you actually create your user account first >_>).
Next, because you should never ever EVER allow root login, we'll make sure we have sudo running, and add our user to the sudo list:
apt-get update; apt-get install sudo
gpasswd -a aldryic sudo
/etc/init.d/sudo restart
Alternately, if you don't want to screw with sudo (yeah, it can be annoying sometimes), you can just use the su command and input the root password whenever you login and need to do root work.
All that's left now is to restart the sshd, and test the connection. Don't (and I can't stress this hard enough), DON'T close your current SSH session. You will just leave yourself locked out of the VM if you do this and something FUBAR'd. Open a new putty/ssh to test with.
Followup:
The major drawback to this setup is that it requires Gate to have a permanent, static IP. If Gate's IP changes, you're SOL and locked out of the VMs unless you're with a provider that offers a working serial console or VNC. The best workaround to this is to create a copy of the /etc/ssh/sshd_config we made in Step 2, and use your preferred method of distribution (rsync, httpd/wget on cron, etc) to have the file distributed to each VPS. (Remember that since we used ListenAddress, you need a distinct sshd_config for each VPS). There are honestly way too many ways to accomplish this for me to list here - that could be a guide all it's own. And if you're at the point where you're ready to use SSH lockdowns of this level, you're already well familiar with options such as rsync anyways