ubuntu server 11.04 + 2 провайдера + OpenVPN + бридж

Задача №1: Раздавать инет в локальную сеть предприятия.

Задача№2: резервирование подключения к интернету. Автоматическое переключение на резервный канал интернета при пропадании пингов на основном канале

Задача№3: OpenVPN + мост с локальной сетью предприятия

1) sudo nano /etc/network/interfaces

auto lo
iface lo inet loopback
#WAN - Websream
auto eth0
iface eth0 inet static
address 192.168.1.61
netmask 255.255.255.0
network 192.168.1.0
broadcast 192.168.1.255

#WAN - T-service
auto eth1
iface eth1 inet static
address 192.168.123.123
netmask 255.255.255.252
network 192.168.123.0
broadcast 192.168.123.255

# lokalka
auto eth2
iface eth2 inet static
address 192.168.2.61
netmask 255.255.255.0
network 192.168.2.0
broadcast 192.168.2.255

Пишем наши DNS сервера в порядке значимости - сначала основного канала

sudo mc resolf.conf

search vashdomain.local
nameserver 192.168.1.1
nameserver 81.1.241.1

Делаем из машины роутер путем добавления в /etc/sysctl.conf строчки:

net.ipv4.ip_forward=1

Чтобы не перезагружаться сообщаем ядру о включении форвардинга:

echo 1 > /proc/sys/net/ipv4/conf/all/forwarding

Ставим dnsmasq ipmasq для трансляции dns-запросов Источник

sudo apt-get install dnsmasq

2) sudo /etc/init.d/networking restart

Проверяем: ping ya.ru

3) Ставим OpenVPN

(замечение: вместо повторений sudo можно единожды написать sudo su)

sudo apt-get update
sudo apt-get upgrade
sudo apt-get install openvpn
cd /usr/share/doc/openvpn/examples/easy-rsa/2.0/
nano vars

export EASY_RSA="pwd"
export OPENSSL="openssl"
export PKCS11TOOL="pkcs11-tool"
export GREP="grep"
export KEY_CONFIG=$EASY_RSA/whichopensslcnf $EASY_RSA
export KEY_DIR="$EASY_RSA/keys"
echo NOTE: If you run ./clean-all, I will be doing a rm -rf on $KEY_DIR
export PKCS11_MODULE_PATH="dummy"
export PKCS11_PIN="dummy"
export KEY_SIZE=2048
export CA_EXPIRE=3650
export KEY_EXPIRE=3650
export KEY_COUNTRY="RU"
export KEY_PROVINCE="Mos"
export KEY_CITY="Mos"
export KEY_ORG="ORG"
export KEY_EMAIL="admin@site.ru"

Инициализируем переменные и очищаем от старых сертификатов и ключей папку keys и создаем серийный и индексные файлы для новых ключей:

source ./vars
./clean-all #содержание папки keys затрется!

В директории /usr/share/doc/openvpn/examples/easy-rsa/2.0/keys/ появляются серийный и индексный файлы.

Создаем ключи, отвечая на предлагаемые вопросы (можно не отвечать, а жать enter):

./build-ca # Создаем Certificate Authority для сервера
./build-key-server server # Создаем сертификат X.509 для сервера
./build-dh # Создаем ключ Диффи Хелмана

В папке ./keys появляется созданные ключи, нужные ключи нужно скопировать в директорию /etc/openvpn/:

cp ./keys/ca.crt /etc/openvpn
cp ./keys/server.crt /etc/openvpn
cp ./keys/server.key /etc/openvpn
cp ./keys/dh2048.pem /etc/openvpn

Создаем ключи для клиентов (имена не должны совпадать):

./build-key client1
./build-key client2

PS: чтобы впоследствии добавить дополнительные сертификаты надо предварительно выполнить source ./vars

Настраиваем сервер OpenVPN

sudo nano /etc/openvpn/server.conf

port 1194  #Стандартный порт OpenVPN, можно было бы и не писать
proto udp  #Работать будем по протоколу UDP, тк быстрее
dev tap0
comp-lzo
tun-mtu 1500
server-bridge 192.168.2.61 255.255.255.0 192.168.2.201 192.168.2.254  #Характерно для соедининения в режиме бриджа. IPсервера - маска - начальный IP клиентов - конечный ИП клиентов
persist-key
persist-tun
dh dh2048.pem
ca ca.crt
cert server.crt
key server.key
log \vars\log\openvpn.log
verb  3

Стартуем OpenVPN сервер:

/etc/init.d/openvpn start

Источник

4) Ставим бридж

Нам понадобятся 2 скрипта. Создаем их в \etc\openvpn\

openvpn-add-br0

#!/bin/bash

# Set up Ethernet bridge on Linux

# Requires: bridge-utils

#################################

# Define Bridge Interface

br="br0"

# Define list of TAP interfaces to be bridged,

# for example tap="tap0 tap1 tap2".

tap="tap0"

# Define physical ethernet interface to be bridged

# with TAP interface(s) above.

eth="eth2"                    #

eth_ip="192.168.2.61"          #

eth_netmask="255.255.255.0"   #Не забываем поменять эти параметры,

eth_broadcast="192.168.2.255" #если они у вас не соответсвуют!

for t in $tap; do

openvpn --mktun --dev $t

done

brctl addbr $br

brctl addif $br $eth

for t in $tap; do

brctl addif $br $t

done

for t in $tap; do

ifconfig $t 0.0.0.0 promisc up

done

ifconfig $eth 0.0.0.0 promisc up

ifconfig $br $eth_ip netmask $eth_netmask broadcast $eth_broadcast

openvpn-del-br0

#!/bin/bash####################################

# Tear Down Ethernet bridge on Linux

####################################

# Define Bridge Interface

br="br0"

# Define list of TAP interfaces to be bridged together

tap="tap0"

ifconfig $br down

brctl delbr $br

for t in $tap; do

openvpn --rmtun --dev $t

done

Источник

5) Настраиваем NAT - iptables

Создаем скрипт запуска правил ip-tables (не забываем сделать исполняемым)

sudo touch /etc/nat-up
sudo nano /etc/nat-up

#!/bin/sh

# очищаем все настройки
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

# Разрешаем шлюзу передавать транзитный трафик
#echo 1 > /proc/sys/net/ipv4/ip_forward
# Всегда принимаем трафик на loopback-интерфейсе
iptables -A INPUT -i lo -j ACCEPT

#Разрешаем все входящие на порт 1194 для OpenVPN (для всех -p all)
iptables -A INPUT -p udp --dport 1194 -j ACCEPT

#Разрешаем доступ из LAN-сети к внешним сетям
iptables -A FORWARD -i br0 -j ACCEPT
#Разрешаем ответ на установленные соединения из локалки
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT

#Разрешаем соединения, которые инициированы внутри (br0)
iptables -A INPUT -m state --state NEW -i br0 -j ACCEPT
#Разрешаем пакеты по уже установленным соединениям
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
#препятствуем спуфингу
iptables -I INPUT -m state --state NEW,INVALID -p tcp --tcp-flags SYN,ACK SYN,ACK -j REJECT --reject-with tcp-reset
# Masquerade.
iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
# Запрещаем форвардинг из внешнего мира во внутреннюю сеть
iptables -A FORWARD -i eth0 -j DROP
iptables -A FORWARD -i eth1 -j DROP

Восстановление правил после перезагрузки:

sudo nano /etc/rc.local

/etc/nat-up

exit 0

exit 0

источник

6) Добавляем все на исполнение при загрузке

sudo nano /etc/network/interfaces

Добавляем строки

#Шлюз по умолчанию (постоянно слитает)
post-up /sbin/route add default gateway 192.168.1.1
#Стартуем бридж OpenVPN-lokalka
post-up /etc/openvpn/openvpn-add-br0

Проверяем

sudo /etc/init.d/networking restart
/sbin/route -n

Таблица маршутизации ядра протокола IP
Destination Gateway Genmask Flags Metric Ref Use Iface
192.168.123.123 0.0.0.0         255.255.255.252 U     0      0        0 eth1
192.168.1.0   0.0.0.0         255.255.255.0   U     0      0        0 eth0
192.168.2.0   0.0.0.0         255.255.255.0   U     0      0        0 br0
0.0.0.0         192.168.1.1   0.0.0.0         UG    0      0        0 eth0

7) Резервирование каналов провайдера (2 провайдера)

Есть 2 провайдера с директ-IP адресами и с выходом в интернет.
Первый провайдер основной и через него идет весь трафик, второй просто подключен и шлюз в сетевых параметрах не указан.

Каждую минуту мы пингуем произвольный адрес в сети Интернет (например www.ru) и в том случае, когда потери пакетов до этого адреса превышают заданный нами порог, назначаем шлюзом по умолчанию - шлюз резервного провайдера. Это событие записываем в лог файл и отправляем емейл админу (ну или emailTOsms)
При этом продолжаем проверять, не восстановился ли канал на основном провайдере и если он снова стабилен, возвращаем исходный адрес шлюза по умолчанию на главного провайдера.

Сохраняем скрипт например в /etc/reserv.sh и назначаем его на автозапуск через крон на каждую минуту

sudo touch /etc/rezervnyy-kanal.sh
sudo nano /etc/rezervnyy-kanal.sh

#!/bin/bash

CheckHost="sibnet.ru" # Контрольный адрес через основного провайдера, который должен быть доступен при его нормальной работе.

GW1="192.168.1.1"         # Основной шлюз, основного провайдера
NC1="eth0"            # Имя сетевого адаптера основного провайдера

GW2="192.168.123.205"        # Основной шлюз, резервного провайдера
NC2="eth1"            # Имя сетевого адаптера резервного провайдера

# Наибольший процент потерь до контрольного адреса через шлюз основного провайдера
MaxLoss="80"
#Начало рабочего дня
datanrd="9"
#Конец рабочего дня
datakrd="20"
#Емейл с которого отправляем
emailfrom="error@site.ru"
#Емейл на который отправляем - можно и через смс шлюз
emailto="7913XXXXXXX@sms.mtslife.ru"

# Путь к log-файлу
log="/var/log/rezervnyykanal.log"

datah="date +"%H""
#echo date +"%d.%m.%Y %T %:z". "PID"$$" - Запуск проверки доступности каналов" >> ${log}

####################################### Контроль и переключение #############################################################

# Запоминаем текущий адаптер на котором прописан маршрут по умолчанию
EthDo=/sbin/route -n | /usr/bin/awk '{print $(NF-5) " " $(NF-0)}' | /bin/grep 0.0.0.0 | /usr/bin/awk '{print $(NF-0)}'

# Добавляем временный точный маршрут до контрольного адреса через основного провайдера
/sbin/route add ${CheckHost}/32 gateway ${GW1} ${NC1}

# Проверяме контрольный адрес и запоминаем процент потерь
pgw=/bin/ping -I ${NC1} -c20 -l1 -q -W2 ${CheckHost} | /bin/grep loss | /usr/bin/awk '{print $(NF-4)}' | /usr/bin/cut -d"%" -f1

# Пишем в лог, если потери больше нуля
if [ 0 = "${pgw}" ]
then
:
else
if [ "${pgw}" ]
then
:
else
pgw="100"
fi
echo date +"%d.%m.%Y %T %:z". "PID"$$" - Потери пакетов до контрольного адреса ${CheckHost} составили ${pgw}%" >> ${log}
fi

# Удаляем временный маршрут
/sbin/route del ${CheckHost}/32 gateway ${GW1} ${NC1}

# Проверяем, что процент потерь и если он больше допустимого значения, переключаем шлюз по умолчанию на резервный интерфейс
if [ "${MaxLoss}" -le "${pgw}" ]
then
if [ "${EthDo}" = "${NC1}" ]
then
echo date +"%d.%m.%Y %T %:z". "PID"$$" - Переход на резервный канал - шлюз ${GW2}, интерфейс ${NC2}. Причина - потери пакетов на интерфесе ${NC1} до контрольного хоста ${CheckHost} составили ${pgw}% при пороге не более ${MaxLoss}%" >> ${log}

/sbin/route del default $NC1
/sbin/route add default gateway $GW2 $NC2
iptables -t nat -A POSTROUTING -o $NC2 -j MASQUERADE

#отправляем письмо админу
if [ $datah -ge $datanrd -a $datah -le $datakrd ]
then
( cat < Content-Type: text/plain; charset=\"utf-8\"
From: GW Ubuntu Server <$emailfrom>
To: admin <$emailto>
Subject: ERROR: Активирован провайдер Т-Сервис
Переход на резервный канал - шлюз ${GW2}, интерфейс ${NC2}. Причина - потери пакетов на интерфесе ${NC1} контрольного хоста ${CheckHost} составили ${pgw}% при пороге не более ${MaxLoss}%
EOF
) | msmtp -t
fi
#закончили отправлять письмо админу

fi
fi

# Проверяем не востановилась ли связь по основному интерфейсу и если да возвращаемся на него
if [ "${EthDo}" = "${NC2}" ]
then
if [ "${pgw}" -le "${MaxLoss}" ]
then
echo date +"%d.%m.%Y %T %:z". "PID"$$" - Переход на основной канал - шлюз ${GW1}, интерфейс ${NC1}." >> ${log}

/sbin/route del default $NC2
/sbin/route add default gateway $GW1 $NC1
iptables -t nat -A POSTROUTING -o $NC1 -j MASQUERADE
#отправляем письмо админу
if [ $datah -ge $datanrd -a $datah -le $datakrd ]
then
(
cat < Content-Type: text/plain; charset=\"utf-8\"
From: GW Ubuntu Server <$emailfrom>
To: admin <$emailto>
Subject: ERROR: Активирован провайдер Webstream
Переход на основной канал - шлюз ${GW1}, интерфейс ${NC1}.
EOF
) | msmtp -t
fi
#закончили отправлять письмо админу

fi
fi

Добавляем задание для крон - Запуск каждую минуту с проверкой не запущен ли уже скрипт

sudo crontab -e

LANG=ru_RU.UTF-8
*/1 * * * * flock -n /tmp/rezervnyykanal.sh-lock /etc/rezervnyykanal.sh

Источник

8 ) Ставим msmtp для отправки писем админу (если не стоит smtp-сервер). Я использую " почта для домена " от яндекса.

sudo apt-get install msmtp

sudo touch /etc/msmtprc
sudo nano /etc/msmtprc

account default
host smtp.yandex.ru
auth login
port 587
from error@site.ru
user error@site.ru
password PA$$$$$$$
tls off
tls_certcheck off
logfile /var/log/msmtp.log

 

9) Ну и конечно же клиенты! Обычно это винда. Поэтому идем на http://ovpnp.sourceforge.net/ http://openvpn.se/ или на http://openvpn.net/index.php/open-source/downloads.html

В моем случае клиенты подключают не постоянно, поэтому будем юзать портабельную версию, которая передается на флешке из рук в руки.

качаем http://sourceforge.net/projects/ovpnp/files/OpenVPN%20Portable/. На момент написания это ovpnp_1.6.6

идем в OpenVPNPortable\data\config

Кладем сюда сертификаты (clietn.key client.crt ca.crt) и создаем файлик client.ovpn. Правим его:

client
proto udp
remote 123.123.123.123
port 1194
dev tap0
nobind
tun-mtu 1500
ping 10
persist-key
persist-tun
ca ca.crt
cert client.crt
key clietn.key
comp-lzo

Вот впрочем и все... Интересный был денек...

 

      

6 thoughts on “ubuntu server 11.04 + 2 провайдера + OpenVPN + бридж

  1. Спасибо. Неплохая статья. Скрипт пригодился, добавил только перезапуск сервиса Опенвпн после поднятия основного канала(он для меня приоритетный)

  2. Спасибо за статью. Только нет описания того, как переключиться на IP адрес резервного провайдера, если он прописан в DNS и на IP адрес назначен домен.

    1. Дополнение: Получается, что нужно прописать два IP на одно доменное имя, если основной провайдер отвалился, то пользователи, которые заходят на сервер по имени, чтобы не заметили того, что основной провайдер отвалился.
      Раньше было так, что на одно доменное имя было назначено два IP, но при этом странички на сервере открывались очень долго, так как при запросе каждой странички, компьютер подключался то через резервного прова, то через основного. Как это решить, установить у себя DNS сервер и прописать в Name Servers у прова (хостинга) и настроить Round Robin на DNS, чтобы он проверял, доступен ли хост по такому-то адресу или нет и только тогда выдавал бы IP

  3. в сообщении встречаются неверные символы: » ″, а также при запуске скрипта выдаёт сообщение:
    root@ntsk:~# /home/toxi/rezerv.sh
    /home/toxi/rezerv.sh: line 31: NF-0: command not found
    awk: ‘{print
    awk: ^ invalid char ‘▒’ in expression
    /home/toxi/rezerv.sh: line 31: NF-5: command not found
    /home/toxi/rezerv.sh: line 31: NF-0: command not found
    awk: ‘{print
    awk: ^ invalid char ‘▒’ in expression
    SIOCADDRT: No such device
    /home/toxi/rezerv.sh: line 37: NF-4: command not found
    awk: ‘{print
    awk: ^ invalid char ‘▒’ in expression
    SIOCDELRT: No such device
    /home/toxi/rezerv.sh: line 71: syntax error near unexpected token newline'
    /home/toxi/rezerv.sh: line 71:
    From: GW Ubuntu Server ‘

    Вывод: Скрипт нужно полностью править ручками после того, как скачали. Не имею ввиду IP адреса и адреса e-mail.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *