FreeBSD anycast DNS resolver

Пример anycast DNS resolver'а для FreeBSD.

В качестве рекурсивного DNS-сервера, как и раньше, используем unbound. А вот для установки BGP-сессии - openbgpd из проекта OpenBSD, конечно, "ортодоксам" доступна и quagga. В перспективе стоит присмотреться к exabgp.

И openbgpd и unbound есть в портах, так что с установкой проблем быть не должно. Я предпочитаю собирать из исходников, чтобы можно было самому указать необходимые опции:
cd /usr/ports/net/openbgpd && make config install clean
cd /usr/ports/dns/unbound && make config install clean


Сетевые интерфейсы:
  • bge1 - стык с маршрутизатором на "серых" адресах, исключительно для BGP.
  • lo1 - реальные адреса, на которые сервер принимает запросы от клиентов и с которого шлёт запросы в Internet. 
# cat /etc/rc.conf

cloned_interfaces="lo1"
ifconfig_bge1="inet 192.168.250.102 netmask 255.255.255.252 mtu 9000"

# resolver DNS source
ifconfig_lo1="inet 1.0.128.12 netmask 255.255.255.255"
# resolver DNS anycast
ifconfig_lo1_alias0="inet 1.0.128.10 netmask 255.255.255.255"
# resolver DNS anycast
ifconfig_lo1_alias1="inet 1.0.128.14 netmask 255.255.255.255"

# routing
defaultrouter="192.168.250.101"



# firewall
pf_enable="YES"
pflog_enable="YES"


Разрешаем запуск установленных демонов:

# cat /etc/rc.conf.local
#
# recursive DNS
unbound_enable="YES"

# for anycast DNS
openbgpd_enable="YES"


Настраиваем firewall, куда ж без него в наше время.
# cat /etc/pf.conf
ext_if="lo1"
bgp_if="bge1"

set loginterface $bgp_if
set limit { states 1000000, frags 15000, src-nodes 500000 }

table <clients> const {
    # тут нужно добавить "свои" адреса
    192.168.0.0/16
    172.16.0.0/12
    10.0.0.0/8
    100.64.0.0/10
}

set skip on lo

scrub in





# "хитрый" NAT чтобы все программы, которые "лезут" в Интернет использовали реальный адрес на lo1

nat on $bgp_if inet from ($bgp_if:0) to !($bgp_if:network) -> ($ext_if:0)

block in log
pass out

pass in on $bgp_if inet proto tcp to ($bgp_if) port { ssh }
pass in on $bgp_if inet proto tcp from <clients> to ($ext_if) port { ssh, domain }


# в случае udp принимать запрос от клиента без создания записи в таблице состояний 
pass in  quick on $bgp_if inet proto udp from <clients> to ($ext_if) port { domain } no state
pass out quick on $bgp_if inet proto udp from ($ext_if) port { domain } to <clients> no state

pass in on $bgp_if inet  proto icmp  from any to { ($bgp_if) ($ext_if) } icmp-type  { unreach, squench, echoreq, timex, paramprob }


Для openbgpd у нас предельно лаконичный конфиг:

# cat /usr/local/etc/bgpd.conf
AS 65001
router-id 192.168.250.102

fib-update no # фактически не используем bgp-маршруты, нам хватит и маршрута по умолчанию из rc.conf

log updates



# эти три маршрута мы будем анонсировать

network 1.0.128.12/32
network 1.0.128.10/32
network 1.0.128.14/32
 

group ROUTER01 {
 remote-as 65004
 announce self

 neighbor 192.168.250.101 {
  descr router4

  local-address 192.168.250.102
 }
}



Проверить, что BGP-сессия поднялась можно командой:
# bgpctl show ip bgp summary
Neighbor                   AS    MsgRcvd    MsgSent  OutQ Up/Down  State/PrfRcvd
router4                   65004      41772      40082     0 01w6d22h      1



В конфиге unbound'а указываем на каких адресах слушать,  а с какого отправлять запросы в Интернет:


# cat /usr/local/etc/unbound/unbound.conf
server:
 # specify the interfaces to answer queries from by ip-address.
        interface: 1.0.128.10
        interface: 1.0.128.14

 # specify the interfaces to send outgoing queries to authoritative
 # Specify every interface on a 'outgoing-interface:' line.
        outgoing-interface: 1.0.128.12

Комментарии

Популярные сообщения из этого блога

streaming multicast IPTV to HLS (nginx+RTMP)

using pg_partman to help partitioning postgresql for zabbix