Программный интернет шлюз для уже не маленькой компании (Shorewall, OpenVPN, OSPF). Часть 1

от автора

Представляю две статьи (вторую пока пишу), ориентированных на «продолжающих» системных администраторов, для опытных я вряд ли открою что-то новое.В этих статьях мы рассмотрим построение интернет шлюза на linux, позволяющего связать несколько офисов компании, и обеспечить ограниченный доступ в сеть, приоритетзацию трафика (QoS) и простую балансировку нагрузки с резервированием канала между двумя провайдерами.Конкретно в этой части:

  • Простейшая настройка Shorewall
  • Ужасно сложная настройка dnsmasq
  • Не менее сложная настройка OpenVPN
  • И для многих продолжающих админов нетипичная, динамическая маршрутизация, на примере OSPF

А во второй части будут рассмотрены:

  • Более подробная настройка Shorewall
  • Страшный и не понятный QoS
  • Балансировка нагрузки и резервирование

Все описанное ниже справедливо для CentOS 7.1 (и выше, 6 серия тоже подойдет, но с небольшими особенностями)Исходим из того, что у нас:

  • Локалка первого филиала: 172.16.0.0/23
  • Подсеть OpenVPN первого филиала: 172.16.3.0/25
  • Второй филиал соответственно: 172.16.8.0/23 и 172.16.11.0/25

Вообще мой ip план подразумевал резервацию /21 сети для каждого филиала из диапазона 172.16.0.0/12. Каждый диапазон /21 нарезается на подсети для различных нужд (подробнее в следующей статье).

Простейшая настройка Shorewall

Для тех кто не слышал раньше, Shorewall это надстройка над утилитой iptables для конфигурирования NetFilter в ядре Linux. Сама по себе iptables не слишком сложная, но когда конфигурация шлюза становится большой и от этого сложной, разобраться в таком объеме команд iptables становиться не просто.На помощь в таких ситуациях приходят различные самопальные скрипты или, уже давно не самопальные, системы аналогичные Shorewall.В Shorewall все вертится вокруг понятия «зона». В зону включаются хосты (путем задания интерфейсов или непосредственно сетей или отдельный адресов).

Заглянем в файл zones

# # Shorewall -- /etc/shorewall/zones # # For information about this file, type "man shorewall-zones" # # The manpage is also online at # http://www.shorewall.net/manpages/shorewall-zones.html # ############################################################################### #ZONE	TYPE		OPTIONS		IN			OUT #					OPTIONS			OPTIONS fw	firewall red	ipv4 grn	ipv4 tun	ipv4 

Тут я определил три зоны (для протокола ipv4), помимо специальной зоны «fw», которая олицетворяет сам шлюз.

  • red — зона интернета
  • grn — зона локальной сети
  • tun — зона для наших туннелей

Пришло время поместить в эти зоны интерфейсы (отдельные хосты мы пока не будем использовать), но перед этим внесем некоторые правки в файл:

params

# # Shorewall -- /etc/shorewall/params # # Assign any variables that you need here. # # It is suggested that variable names begin with an upper case letter # to distinguish them from variables used internally within the # Shorewall programs # # Example: # #	NET_IF=eth0 #	NET_BCAST=130.252.100.255 #	NET_OPTIONS=routefilter,norfc1918 # # Example (/etc/shorewall/interfaces record): # #	net	$NET_IF		$NET_BCAST	$NET_OPTIONS # # The result will be the same as if the record had been written # #	net	eth0		130.252.100.255	routefilter,norfc1918 # ############################################################################### NET_RED1=eth0 NET_GRN=eth1 NET_TUN=tap+  #LAST LINE -- DO NOT REMOVE 

В этом файле можно задать различные переменные, которые будем потом использовать в других файлах. Сейчас у нас тут прописаны наши физические интерфейсы. Обратите внимание, tap+ говорит об использовании маски, под которую попадает любой tapX (кроме просто «tap»).Ну а теперь файл:

interfaces

# # Shorewall -- /etc/shorewall/interfaces # # For information about entries in this file, type "man shorewall-interfaces" # # The manpage is also online at # http://www.shorewall.net/manpages/shorewall-interfaces.html # ############################################################################### ?FORMAT 2 ############################################################################### #ZONE		INTERFACE		OPTIONS red		$NET_RED1		dhcp,routeback,optional grn		$NET_GRN		dhcp,routeback,optional tun		$NET_TUN		dhcp,routeback,optional 

Тут тоже ничего особенно сложного, опции говорят нам, что:

  • dhcp — на интерфейсе может работать DHCP протокол (как клиент так и сервер)
  • routeback — пригодится в будущем, заставляет возвращать ответы через тот же интерфейс, откуда пришли запросы
  • optional — говорит, что не надо паниковать, если интерфейс не активен (если Shorewall не находит обязательный интерфейс, то он не стартует целиком)

Внесем несколько изменений в файл «shorewall.conf», он довольно большой, приведу его усеченный вид (только измененные значения):

shorewall.conf

############################################################################### # #  Shorewall Version 5 -- /etc/shorewall/shorewall.conf # #  For information about the settings in this file, type "man shorewall.conf" # #  Manpage also online at http://www.shorewall.net/manpages/shorewall.conf.html ############################################################################### #		       S T A R T U P   E N A B L E D ###############################################################################  STARTUP_ENABLED=Yes  ############################################################################### #			F I R E W A L L	  O P T I O N S ###############################################################################  BLACKLIST="ALL"  CLAMPMSS=Yes  IP_FORWARDING=Yes   ################################################################################ #			P A C K E T  M A R K  L A Y O U T ################################################################################  TC_BITS=14  PROVIDER_BITS=8  PROVIDER_OFFSET=16  MASK_BITS=16  ZONE_BITS=0 

Все параметры достаточно понятны, но секция «PACKET MARK LAYOUT» будет рассмотренная в следующих частях, «BLACKLIST» задает тип блокируемых пакетов (всех) для забаненых адресов, тоже на будущее.Пришло время для создания политик по умолчанию:

policy

# # Shorewall -- /etc/shorewall/policy # # For information about entries in this file, type "man shorewall-policy" # # The manpage is also online at # http://www.shorewall.net/manpages/shorewall-policy.html # ############################################################################### #SOURCE	DEST	POLICY		LOG	LIMIT:		CONNLIMIT: #				LEVEL	BURST		MASK $FW	all	ACCEPT grn	all	ACCEPT red	all	DROP  tun	grn	ACCEPT tun	red	REJECT tun	$FW	ACCEPT 

Ключевые слова значат следующие:

  • ACCEPT — принимать (в том числе форвардить) пакеты
  • REJECT — Отбросить пакет, а отправителю сообщить, что писем мы от него не ждем
  • DROP — Отбросить пакет, и загадочно осмотревшись, никому ничего не сказать

В третий столбец можно прописать еще несколько параметров, один из которых info, задаст логирование данной политики (имеет смысл для DROP и REJECT, а то ACCEPT завалит вас логами).Заданная политика примитивна и не годится для серьезных проектов, соответствует настройке большинства домашних роутеров, но для самого старта она нам подойдет.Осталось чуть чуть, а именно настроить маскарадинг (чего в эпоху IPv6 делать будет не надо):

masq

# # Shorewall -- /etc/shorewall/masq # # For information about entries in this file, type "man shorewall-masq" # # The manpage is also online at # http://www.shorewall.net/manpages/shorewall-masq.html # ################################################################################################################################### #INTERFACE:DEST		SOURCE		ADDRESS		PROTO	PORT(S)	IPSEC	MARK	USER/	SWITCH	ORIGINAL	PROBABILITY #											GROUP		DEST $NET_RED1		172.16.0.0/23 

Очевидно, все что идет в сторону интерфейса $NET_RED1 из сети 172.16.0.0/23 нужно замаскировать.Для отслеживания и соответствующего изменения правил файрвола, в ответ на включение\отключение интерфейса, нам поможет небольшой скрипт:

/etc/NetworkManager/dispatcher.d/30-shorewall.sh

#!/bin/bash   IF=$1      # имя сетевого интерфейса, с которым связано событие STATUS=$2  # новое состояние сетевого интерфейса   case $STATUS in 	up) 		# команды выполняемые после установления соединения 		shorewall enable $IF 		shorewall6 enable $IF 	;; 	down) 		# команды выполняемые после разрыва соединения 		shorewall disable $IF 		shorewall6 disable $IF 	;; esac  

Дав команду «systemctl enable shorewall.service && systemctl restart shorewall.service», мы применим настройки нашего файрвола, и у нас ничего (ну почти), не заработает, нам не хватает самой малости: нет кэширующего DNS И DHCP серверов (не будем же мы сами все клиентские машины настраивать).

Простейшая настройка dnsmasq

Эта служба очень неплохо справляется со своей задачей, и сеть /23 для неё не является проблемой, а простота и гибкость настроек делает её очень подходящей для нашей ситуации.Так как файл настроек большой, приведу его опять в урезанном виде:

/etc/dnsmasq.conf

# Configuration file for dnsmasq. # # Format is one option per line, legal options are the same # as the long options legal on the command line. See # "/usr/sbin/dnsmasq --help" or "man 8 dnsmasq" for details.  # If you want dnsmasq to listen for DHCP and DNS requests only on # specified interfaces (and the loopback) give the name of the # interface (eg eth0) here. # Repeat the line for more than one interface. interface=eth1  # Set the domain for dnsmasq. this is optional, but if it is set, it # does the following things. # 1) Allows DHCP hosts to have fully qualified domain names, as long #     as the domain part matches this setting. # 2) Sets the "domain" DHCP option thereby potentially setting the #    domain of all systems configured by DHCP # 3) Provides the domain part for "expand-hosts" domain=domain.local  # This is an example of a DHCP range where the netmask is given. This # is needed for networks we reach the dnsmasq DHCP server via a relay # agent. If you don't know what a DHCP relay agent is, you probably # don't need to worry about this. dhcp-range=172.16.0.50,172.16.0.150,255.255.254.0,12h  # Set the DHCP server to authoritative mode. In this mode it will barge in # and take over the lease for any client which broadcasts on the network, # whether it has a record of the lease or not. This avoids long timeouts # when a machine wakes up on a new network. DO NOT enable this if there's # the slightest chance that you might end up accidentally configuring a DHCP # server for your campus/company accidentally. The ISC server uses # the same option, and this URL provides more information: # http://www.isc.org/files/auth.html dhcp-authoritative 

Думаю пояснять тут ничего особо не надо, задали интерфейс на котором обслуживать DNS и DHCP запросы, задали диапазон раздаваемых адресов, задали некоторые передаваемые в DHCP параметры и задали авторитарный режим работы.Теперь после «systemctl enable dnsmasq.service && systemctl restart dnsmasq.service» у нас заработает доступ в интернет с внутренних клиентов (как только аренду DHCP получат).

Настройка OpenVPN

Думаю это часть не составит особого труда вообще никому, но приведем эти шаги:

  1. Из epel установим пакеты: openvpn easy-rsa
  2. Скопируем из /usr/share/easy-rsa папку в /etc/openvpn и переименуем её в easy-rsa
  3. Перейдем в /etc/openvpn/easy-rsa и при необходимости отредактируем файл vars
  4. Выполним: ". ./vars && ./clean-all && ./build-dh && openvpn —genkey —secret ./keys/ta.key &&./build-ca && ./build-key-server server

Еще нам понабиться файл конфигурации сервера:

/etc/openvpn/inter-lan.conf

port 1194 proto udp topology subnet dev tap0  ca ./easy-rsa/keys/ca.crt cert ./easy-rsa/keys/server.crt key ./easy-rsa/keys/server.key dh ./easy-rsa/keys/dh1024.pem client-config-dir ./ccd/inter-lan/ client-to-client keepalive 10 120 tls-server tls-auth ./easy-rsa/keys/ta.key 0 cipher AES-256-OFB comp-lzo no auth SHA256 status /var/run/openvpn/inter-lan.status sndbuf 393216 rcvbuf 393216 push "sndbuf 393216" push "rcvbuf 393216"  mode server  push "topology subnet"  ifconfig 172.16.3.1 255.255.255.128 ifconfig-pool 172.16.3.2 172.16.3.126 255.255.255.128  ifconfig-pool-persist /var/run/openvpn/inter-lan.db 3600  verb 1 

Файл умолчательной конфигурации для клиента:

/etc/openvpn/ccd/inter-lan/DEFAULT

push "comp-lzo no" 

Файл клиентского шаблона:

/etc/openvpn/easy-rsa/templates/inter-lan.conf

client port 1194 dev tap4 proto udp remote <тут адрес вашего сервера> 1194 tls-client ns-cert-type server cipher AES-256-OFB auth SHA256 verb 1 comp-lzo no <ca> -----CERTIFICATE-CA----- </ca> <cert> -----CERTIFICATE----- </cert> <key> -----KEY----- </key> key-direction 1 <tls-auth> -----TLS----- </tls-auth> 

И вспомогательный самописный скриптик:

/etc/openvpn/easy-rsa/build-ovpn.sh

#!/bin/bash # $2 - дает команду сгенерировать новые ключи для клиента [ "$2" == "-r" ] && ./build-key $1 CWD=$(pwd) RUN=$(dirname $0) cd "$RUN" mkdir -p ../ovpn/$1 for i in $(ls -1 ./templates/); do 	TEMPLATE=$(basename $i .conf) 	sed -e '/-----CERTIFICATE-CA-----/{r /etc/openvpn/easy-rsa/keys/ca.crt' -e 'd}' ./templates/${TEMPLATE}.conf | \ 	sed -e '/-----CERTIFICATE-----/{r /etc/openvpn/easy-rsa/keys/'"$1.crt"'' -e 'd}' | \ 	sed -e '/-----KEY-----/{r /etc/openvpn/easy-rsa/keys/'"$1.key"'' -e 'd}' | \ 	sed -e '/-----TLS-----/{r /etc/openvpn/easy-rsa/keys/ta.key' -e 'd}' > ../ovpn/$1/${TEMPLATE}-$1.ovpn done cd "$CWD" 

Я использую интерфейс типа tap, потому, что tun маршрутизируется ядром OpenVPN, и конфигурируется это все директивой iroute. И печаль такова, если за одним сервером, будет еще один, к которому нам нужен маршрут, этот маршрут нам надо в явном виде прописывать в ccd, что помимо обычных маршрутов создаст лишние трудности (о каких трудностях я говорю, написано в разделе OSPF).Теперь сгенерим конфигурацию для клиента:./build-ovpn.sh <имя клиента> -rСоздадим файл ccd для клиента:

/etc/openvpn/ccd/inter-lan/<имя клиента>

# Тут могли быть параметры, если бы они нам были нужны :) 

После надо скопировать файл из каталога /etc/openvpn/ovpn/<имя клиента>/<имя клиента>.ovpn на клиентский компьютер (шлюз) и поместить его в /etc/openvpn/ с расширением ".conf"Запускаем openvpn на клиенте и сервере:systemctl enable openvpn@<имя conf файла без расширения conf>.service && systemctl start openvpn@<имя conf файла без расширения conf>.serviceА результат есть только на сервере! Клиент в непонятках. Во всем виноват shorewall, а точнее, наша политика, мы не разрешили соединения из интернета (red зона)!Внесем разрешающее правило в файл:

/etc/shorewall/rules

# # Shorewall -- /etc/shorewall/rules # # For information on the settings in this file, type "man shorewall-rules" # # The manpage is also online at # http://www.shorewall.net/manpages/shorewall-rules.html # ###################################################################################################################################################################################################### #ACTION		SOURCE		DEST		PROTO	DEST	SOURCE		ORIGINAL	RATE		USER/	MARK	CONNLIMIT	TIME		HEADERS		SWITCH		HELPER #							PORT(S)	PORT(S)		DEST		LIMIT		GROUP ?SECTION ALL ?SECTION ESTABLISHED ?SECTION RELATED ?SECTION INVALID ?SECTION UNTRACKED ?SECTION NEW #Правило ниже использует макрос из: /usr/share/shorewall/macro.OpenVPN #Макросов там достаточно, свои можно помещать в /etc/shorewall, а также переопределять там дефолтовые OpenVPN(ACCEPT)	red	$FW #Тоже самое, но без макроса было бы так: #ACCEPT		red		$FW		udp	1194 

Выполняем «shorewall restart» и видим, что клиент успешно подключился.Попробуем попинговать сеть за клиентом (172.16.8.0/23), и опять облом, ip в туннеле пингуется, а сеть нет, так как нет маршрутов, их нам предоставит OSPF.

Настройка протокола динамической маршрутизации OSPF в quagga

Тут на хабре есть серия больших статей посвященных динамической маршрутизации, тому как оно работает, и т.д., тут же я дам некоторую практическую выжимку из настройки.К использованию OSPF я пришел после того, как компания в которой я работаю, обзавелась почти десятком филиальчиков и представительств, и туннели между ними были построены не только звездой, но и были еще прямые. Когда я малость припух от числа маршрутов и мест их настройки, соорудил велосипед (скрипт, который перестраивал статические конфиги маршрутов по прописанной карте), велосипед был красивый, колеса шестиугольные, педалей десять, и для езды ты его катишь, сам идя рядом… Ну его в болото, подумал я, и по быстрому выяснил про OSPF.Нам понадобится пакет quagga, после установки, скопируем файл начальной конфигурации и запустим службу:

cp /usr/share/doc/quagga-0.99.22.4/ospfd.conf.sample /etc/quagga/ospfd.conf && chown quagga. /etc/quagga/ospfd.conf systemctl enable ospfd.service && systemctl start ospfd.service 

Теперь нам понабиться настроить ip адрес на loopback интерфейсе, который помимо прочего (смысл вы найдете в других статьях), будет выполнять роль router-id.В файл /etc/sysconfig/network-scripts/ifcfg-lo добавим строки:

IPADDR2=172.16.248.1 NETMASK2=255.255.255.255 

И повторно подымим интерфейс: ifup loТеперь подключимся к службе ospfd и проведем её настройку:

telnet localhost ospfd #пароль по умолчанию zebra ospfd# enable #Включит режим привилегированных команд ospfd# configure terminal #переход в режим конфигурирования ospfd(config)# password <пароль> #задаст пароль на консоль управления ospfd(config)# hostname <имя хоста> #задаст имя шлюза, хотя это не обязательно ospfd(config)# log syslog #пусть логи идут в системный журнал ospfd(config)# interface <в нашем случае tap0> #настроим интерфейс ospfd(config-if)# ip ospf network point-to-multipoint #Задает для tap интерфейса его тип (важно для правильного построения топологии, по умолчанию определяет не верно для наших конфигураций) ospfd(config-if)# exit #выходим из текущего режима ospfd(config)# router ospf #переход в настройку ospf ospfd(config-router)# router-id 172.16.248.1 #задаем наш идентификатор ospfd(config-router)# passive-interface <имя интерфейса> #Несколько раз выполним для всех, где у нас точно не будет взаимодействия по протоколу ospf, а именно интернет интерфейс и скорее всего смотрящий в локалку ospfd(config-router)# network 172.16.0.0/12 area 0.0.0.0 #Задаем сеть, для которой будут строится маршруты, также задает интерфейсы, по которым будет происходить взаимодействие. Сеть с маской /12 охватывает все частное пространство, в котором мы для себя нарезали подсети ospfd(config-router)# write memory #сохранит текущую настройку в файл 

Итоговый файл конфигурации:

/etc/quagga/ospfd.conf

! ! Zebra configuration saved from vty !   2016/01/05 14:20:38 ! hostname ospfd password zebra log stdout log syslog ! ! ! interface eth0 ! interface lo ! interface tap0  ip ospf network point-to-multipoint  ip ospf cost 3 ! ! router ospf  ospf router-id 172.16.248.1  passive-interface eth0  network 172.16.0.0/12 area 0.0.0.0 ! line vty ! 

Можно заметить, что файл отражает команды конфигурации что мы вводили в консоль.

Скопировав этот файл на другой шлюз (который связан с этим по OpenVPN) и внеся туда соответствующие правки, мы получим рабочую конфигурацию между двумя шлюзами.Теперь команда «ip route list» должна показать нам нечто подобное:

172.16.0.0/23 dev eth1  proto kernel  scope link  src 172.16.0.1  metric 100 172.16.3.0/25 dev tap0  proto kernel  scope link  src 172.16.3.1 172.16.3.1 dev tap0  proto zebra 172.16.8.0/23 via 172.16.3.2 dev tap0  proto zebra  metric 13 172.16.11.1 via 172.16.3.2 dev tap0  proto zebra  metric 3 172.16.12.129 via 172.16.3.2 dev tap0  proto zebra  metric 3 172.16.248.2 via 172.16.3.2 dev tap0  proto zebra  metric 13 192.168.10.0/24 dev eth0  proto kernel  scope link  src 192.168.10.37  metric 100 192.168.10.1 dev eth1  scope link  src 192.168.10.37 

Маршруты с «proto zebra» как раз добавлены с помощью OSPF.Я рекомендую всем, используйте динамическую маршрутизацию, даже если у вас всего два филиала. Когда их станет больше, вам не составит труда добавить еще один узел в сеть.И конечно, предложенная конфигурация OSPF довольна примитивна, более сложные варианты с примерами ждите в следующей статье (или читайте статьи более компетентных товарищей, по сути, OSPF я изучил еще не достаточно глубоко).

Какой VPN вы используете

Никто ещё не голосовал. Воздержавшихся нет.

Пишете ли вы правила для NetFilter, или используете надстройки

Никто ещё не голосовал. Воздержавшихся нет.

Используете ли динамическую маршрутизацию или планируете использовать

Никто ещё не голосовал. Воздержавшихся нет.

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.

ссылка на оригинал статьи http://habrahabr.ru/post/274639/


Комментарии

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

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