CentOS 6 as an SSH bastion using redir and an introduction to daemonize and monit
Recently I got myself in a situation where I was working on an OpenStack cluster where my tenant had only a single floating IP available.
I viewed this as a good opportunity to play with bastions and proxies. In this post I'll only deal with the bastion part.
All hosts had internal IPs but only one had a public IP.
I recreated this scenario on Atlantic.net - here's how I did it.
Environment:
You only need 2 instances to try this - one I'm going to call the " bastion", the other one " private1" as it will be cut off from the internet and only accessible through SSH from the bastion.
Part 1 - Set private IPs and test redir:
On private1 test your network settings first (we'll make them permanent later)
ifconfig eth1 10.42.226.2 netmask 255.255.255.0
try pinging your private ip to make sure it works:
[root@private1 ~]# ping 10.42.226.2 -c1
PING 10.42.226.2 (10.42.226.2) 56(84) bytes of data.
64 bytes from 10.42.226.2: icmp_seq=1 ttl=64 time=0.019 ms
--- 10.42.226.2 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.019/0.019/0.019/0.000 ms
now make those permanent by editing /etc/sysconfig/network-scripts/ifcfg-eth1
(second interface)
add the lines:
IPADDR=10.42.226.2
NETMASK=255.255.255.0
The file should now look like this:
# Virtio Network Device Private Interface
DEVICE=eth1
BOOTPROTO=static
HWADDR=00:00:0a:3a:26:e3
ONBOOT=yes
IPADDR=10.42.226.2
NETMASK=255.255.255.0
reboot your instance to make sure everything worked.
now on the bastion do the same:
ifconfig eth1 10.42.226.1 netmask 255.255.255.0
and add the following lines to the file /etc/sysconfig/network-scripts/ifcfg-eth1
IPADDR=10.42.226.1
NETMASK=255.255.255.0
and ping private1
ping 10.42.226.2
PING 10.42.226.2 (10.42.226.2) 56(84) bytes of data.
64 bytes from 10.42.226.2: icmp_seq=1 ttl=64 time=1.57 ms
^C
--- 10.42.226.2 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 605ms
rtt min/avg/max/mdev = 1.577/1.577/1.577/0.000 ms
excellent.
Now on private1, kill all public networking by bringing down interface eth0:
ifdown eth0
also to make sure it's not coming back up edit the file /etc/sysconfig/network-scripts/ifcfg-eth0
and change the line:
ONBOOT=yes
to:
ONBOOT=no
You'll notice that networking died! perfect!!!!
Now let's use redir on bastion to redirect connections to private1
yum install epel-release -y
yum install redir -y
With redir now in place let's create a forwarder:
redir --lport 2201 --cport=22 --caddr=10.42.226.2 --debug
Confirm that redir created listening port 2201 by running netstat -ntlp | grep redir
, you should get something like:
tcp 0 0 0.0.0.0:2201 0.0.0.0:* LISTEN 1123/redir
Sweet! Now you should be able to connect to port 2201 over SSH and that will take you to private1.
ssh 69.87.216.89 -p 2201
Part 2 - Daemonize redir...using daemonize
and create a control script:
First install the daemonize package:
yum install daemonize -y
Now test daemonize using the redir command above:
daemonize -a -e /var/log/redir-ssh-2201 -o /var/log/redir-ssh-2201 -p /var/run/redir-ssh-2201.pid -l /var/lock/subsys/redir-ssh-2201 /usr/sbin/redir --lport 2201 --cport=22 --caddr=10.42.226.2
Explanation of the above options (stolen from daemonize's help)
-a Append to, instead of overwriting, output files. Ignored
unless -e and/or -o are specified.
-e <stderr> Send daemon's stderr to file <stderr>, instead of /dev/null.
-o <stdout> Send daemon's stdout to file <stdout>, instead of /dev/null.
-p <pidfile> Save PID to <pidfile>.
-l <lockfile> Single-instance checking using lockfile <lockfile>.now that we have confirmed that this worked, let's set up monit to make sure our process keeps on running:
Let's add a start/stop script for our redir script: /usr/local/bin/redir-ssh-2201
#!/bin/bash
daemonize=/usr/sbin/daemonize
redir=/usr/sbin/redir
local_port=2201
lockfile=/var/lock/subsys/redir-ssh-$local_port.lock
logfile=/var/log/redir-ssh-$local_port.log
pid=/var/run/redir-ssh-$local_port.pid
forward_port=22
forward_ip=10.42.226.2
start() {
echo -n "Starting redir for local port $local_port, forward port $forward_port and forward_ip $forward_ip "
daemonize -a -e $logfile -o $logfile -p $pid -l $lockfile $redir --lport=$local_port --cport=$forward_port --caddr=$forward_ip
if [ $? -eq 0 ]; then
echo -e '\t\t\t[ OK ]'
fi
}
echo -n "Stopping redir for local port $local_port, forward port $forward_port and forward_ip $forward_ip "
kill `cat $pid`
if [ $? -eq 0 ]; then
echo -e '\t\t\t[ OK ]'
fi
}
# See how we were called.
case "$1" in
start)
start
;;
;;
start
;;
*)
exit 2
esac
Part 3 - Install and setup Monit to monitor the daemonized redir
Install Monit in the usual way:
yum install monit -y
Make sure it's set to start along with the host:
chkconfig monit on
Add the following Monit configuration in /etc/monit.d/redir-2201
# Check redir-ssh-2201
check process redir-ssh-2201 pidfile /var/run/redir-ssh-2201.pid
start program = "/usr/local/bin/redir-ssh-2201 start"
stop program = "/usr/local/bin/redir-ssh-2201 stop"
Now start Monit with:
/etc/init.d/monit start
Done!