динамический проброс портов by Андрей Гриценко

Может кому-то пригодиться.
Столкнулся с такой ситуевиной есть два веб-сервака с разными каналами в мир. По сути это один сервак и для него сучествуют две записи в днс:
@ in a ip1
@ in a ip2
так вот при падении одного из них приходиться одну запись дропать. Но она то остаеться в половины клиентов в хеше их ДНС сервера… И они ломяться на лежащий сервак(или канал).
Так вот для нормальной работы и что бы не было гемора с этим всем дерьмом я взял сервак на колоколе с двумя айпишнегами и написал след скрипт(его приведу позже).

Сейчас схема:

channel1 channel2
| |
————- ————
| web-srv1| |web-srv2|
————- ————-

это было, а стало:

————-
| spreader |
————-
/
ssh tunnel1 ssh tennel2
/
channel1 channel2
| |
————- ————
| web-srv1| |web-srv2|
————- ————-

этот скрипт висит себе в вечном цикле и чекает серваки на доступность если один из них не доступен переводит оба ссш тунеля на второй. Если лежат оба то подымает локальный веб сервак который уведомляет юзеров что пиздец….
написал я все это на перле )

для начала надо сгенерить ключи для ссш коннектов.

на серваке
#ssh-keygen -t dsa
#scp /root/.ssh/id_dsa.pub root@SERVER1:/root/.ssh/authorized_keys
#scp /root/.ssh/id_dsa.pub root@SERVER2:/root/.ssh/authorized_keys

только лучше вместо scp делать таГ:
cat /root/.ssh/id_dsa.pub | ssh root@SERVER2 «cat — >> /root/.ssh/authorized_keys»
в таком случае если в файле authorized_keys есть уже какие-то хосты то они не затруться ))
[root@ip scripts]# cat monitoring
#! /usr/bin/perl
#
# Written by Grytsenko Andrii 2008(c)
#

use Net::Telnet();
use Sys::Syslog;

#This function send all debug msg’s to syslog(to enable it change $debut to 1 and tune local0.info in your syslog.conf )
sub put_in_log {
syslog («info|local0″,»$_[0]»);
}

#This function clear all old ssh tunnels(needed to change)
sub clear_ssh_tunnels {
#system(«ps uax | grep ssh | grep L |awk ‘{print «/bin/kill -9 » $2}’| bash «);
system(«killall ssh»);
}
#This function create ssh tunnels
sub create_ssh_tunnel {
put_in_log «$_[0]n» if $debug;
$web_svr1=»SERVER1″;
$ssh_svr1=»SERVER1″;
$web_svr2=»SERVER2″;
$ssh_svr2=»SERVER2″;
$local_ip1=»LOCAL_IP1″;
$local_ip2=»LOCAL_IP2″;
$port1=»443″;
$port2=»80″;

if ( «$_[0]» == «normal» ) {
clear_ssh_tunnels();
system(«ssh root@$ssh_svr1 -N -t -T -L $local_ip1:$port1:$web_svr1:$port1 -L $local_ip1:$port2:$web_svr1:$port2 &»);
system(«ssh root@$ssh_svr2 -N -t -T -L $local_ip2:$port1:$web_svr2:$port1 -L $local_ip2:$port2:$web_svr2:$port2 &»);
put_in_log(«change to normal») if $debug;
}
elsif ( «$_[0]» == «SERVER1» ) {
clear_ssh_tunnels();
system(«ssh root@$ssh_svr2 -N -t -T -L $local_ip2:$port1:$web_svr2:$port1 -L $local_ip2:$port2:$web_svr2:$port2 -L $local_ip1:$port1:$web_svr2:$port1 -L $local_ip1:$port2:$web_svr2:$port2 &>/dev/null &»);
put_in_log(«change ip 212.82.216.43») if $debug;
}
elsif ( «$_[0]» == «SERVER2» ) {
clear_ssh_tunnels();
system(«ssh root@$ssh_svr1 -N -t -T -L $local_ip1:$port1:$web_svr1:$port1 -L $local_ip1:$port2:$web_svr1:$port2 -L $local_ip2:$port1:$web_svr1:$port1 -L $local_ip2:$port2:$web_svr1:$port2 &>/dev/null &»);
put_in_log(«change ip 92.240.97.198») if $debug;
}
else {
put_in_log(«Wrong argument») if $debug;
}
}
#This function check avaible port
sub check_port {
$tel = new Net::Telnet (Timeout => 10,
Port => ‘443’);
eval { $tel->open(«$_[0]») ; } ;
if ($@){
return 0;
}
else {
return 1;
}
}

# create log file
#determinate hosts
@hosts_array=(«SERVER1″,»SERVER2»);
$array_count=0;
@old_status=(«1″,»1»);
$debug=0;
#create initial tunnels
create_ssh_tunnel(«normal»);
while (1){
#create_ssh_tunnel(«web_srv1»);
foreach $host (@hosts_array) {
$status=check_port(«$host»);
put_in_log(«status = $statusnhost = $host») if $debug;
if ($status != 1) {
if ($status != $old_status[$array_count]) {
create_ssh_tunnel($host);
$old_status[$array_count]=$status;
put_in_log(«status = $statusn iold_status = $old_status[$array_count]») if $debug;
}
}
elsif ($status == 1) {
if ($status != $old_status[$array_count]) {
create_ssh_tunnel(«normal»);
$old_status[$array_count]=$status;
put_in_log(«status = $statusn iold_status = $old_status[$array_count]») if $debug;
}
}
$array_count++;
put_in_log(«array_count=$array_count») if $debug;
}
sleep 30;
$array_count=0;
}

Share