Pull to refresh

Mikrotik 6to4 автоматизация при динамическом IPv4

Reading time5 min
Views17K
Эта статья будет полезна тем, кто хочет испытать IPv6 по протоколу инкапсуляции 6to4, но имеющего динамический IPv4.

Mikrotik IPv6


Первым делом, проверим, есть ли у вас возможность использовать публичный 6to4 шлюз, пингуем его по адресу: 192.88.99.1. Если пинг идет, читаем дальше.

Итак, для начала, нужно установить модуль поддержки IPv6 (скачиваем Extra packages для вашего устройства с сайта). Из архива вытаскиваем ipv6-*.npk и заливаем его на роутер, затем перезапускаем его.

Теперь у вас есть поддержка IPv6, учтите, что правила firewall для неё нужно делать отдельно.

Настройка 6to4


Далее, создаем специальный интерфейс «6to4 Tunnel», в Remote Adress ставим адрес публичного шлюза, в Local Adress наш текущий публичный IPv4 адрес (или «ошибаемся» в адресе, что-бы скрипт настроил все сам).

В маршрутизации нужно настроить интерфейс туннеля как шлюз по умолчанию (до адреса ::/0).
Теперь можем проверить, есть ли пинг до чего-нибудь из IPv6 (к примеру ipv6.google.com)
Если пинги есть, то идем далее:

Скрипт автонастройки


##############Script Settings##################

:local "IF-TUN" "6to4tun"
:local "IF-LOC" "local"
:local "POOL-6TO4" "pool_v6-local"
:local "force-update" false
############ use then static ip #######################
:local "lease-address" [/ip address get [find interface=$"interface"] address]
:local "interface" "ext"
:local bound 1

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

:global MAC2EUI64 do={
	:local EUI64 ""
	:local MAC $1
	:local HEX2DEC "0123456789ABCDEF"
	:for i from=0 to=5 step=1 do={
		:if ( $i = 0 ) do={
			:set EUI64 [:pick $MAC 0]
			:set EUI64 ($EUI64.[:tostr [:pick $"HEX2DEC" ([:find $"HEX2DEC" [:pick $MAC 1]] ^ 2)]])
		}
		:if ( $i = 1 || $i = 3) do={
			:set EUI64 ($EUI64.":")
		}
		:if ( $i = 2 ) do={
			:set EUI64 ($EUI64."FF:FE")
		}
		:if ( [:find $MAC ":"] = 2 ) do={
			:set MAC [:pick $MAC 3  [:len $MAC]]
			:set EUI64 ($EUI64.[:pick $MAC 0 2])
		}
	}
	:return ($EUI64)
}

:global dec2hex do={
	:local hex ""
	:local dec [:tonum $1]
	:for i from=0 to=4 step=4 do={
		:set hex ([:pick "0123456789ABCDEF" (($dec>>$i)&0xf) ((($dec>>$i)&0xf)+1)].$hex)
	}
	:return ([:tostr $hex])
}

:local 6to4prefix do={
	:global dec2hex
	:local ipv4 $1
	:local ipv6 "2002:"
	:for i from=0 to=2 step=1 do={		
		:if ( $i = 2) do={
			:set ipv6 ($ipv6.":")
		}
		:local fp [:find $ipv4 "."]
		:if ( $fp > 0 ) do={
			:set ipv6 ($ipv6.[$dec2hex [:pick $ipv4 0 $fp]])
			:set ipv4 [:pick $ipv4 ($fp + 1 ) [:len $ipv4]]
		}
	}
	:return ($ipv6.[$dec2hex $ipv4])
}
:local "str_replace" do={
	:local "str-pos" [:find $1 $2]
	:local "str-len" [:len $2]
	:local str ""
	:local rest $1
	:while ($"str-pos" >= 0) do={
		:local t [:pick $rest 0 $"str-pos"]
		:if ( $4 > 0 ) do={
			:for i from=1 to=($4 - [:len $t]) step=1 do={
				:set str ($str.$5)
			}
		}
		:set str ($str.$t.$3)
		:set rest [:pick $rest ($"str-pos"+$"str-len") [:len $rest]]
		:set "str-pos" [:find $rest $2]
	}
	:return ($str.$rest)
}

:if ($bound=1) do={
    :local t [:find $"lease-address" "/"]

    :if ( $t >= 0 ) do={
        :set "lease-address" [:pick $"lease-address" 0 $t]
    }

    :if ( [/interface 6to4 print count-only where name=$"IF-TUN"] = 0) do={
        /interface 6to4 add !keepalive local-address=$"lease-address" mtu=1280 name=$"IF-TUN" remote-address=192.88.99.1
        :set "force-update" true
    }

    :local "IPv4-TUN" [/interface 6to4 get [find name=$"IF-TUN"] local-address];

    :if ( $"lease-address" != $"IPv4-TUN" || $"force-update" = true) do={
        /interface 6to4 set [find name=$"IF-TUN"] local-address=$"lease-address"
        /ipv6 address remove [find interface=$"IF-TUN"]
        /ipv6 address remove [find interface=$"IF-LOC"]
        /ipv6 route remove [find gateway ~ $"IF-TUN" and dst-address="::/0"]
        :local "pool-prefix" [$6to4prefix $"lease-address"]
        :if ( [/ipv6 pool print count-only where name=$"POOL-6TO4"] = 0) do={	
            /ipv6 pool add name=$"POOL-6TO4" prefix=($"pool-prefix".":1::/64")  prefix-length=64
        } else={
            /ipv6 pool set [/ipv6 pool find where name=$"POOL-6TO4"] prefix=($"pool-prefix".":1::/64")
        }
        /ipv6 address add address=($"pool-prefix"."::".[$MAC2EUI64 [/interface get [find name=$"interface"] mac-address]]."/3") interface=$"IF-TUN" advertise=no
        /ipv6 address add eui-64=yes from-pool=$"POOL-6TO4" interface=$"IF-LOC" advertise=yes
        /ipv6 route add dst-address=::/0 gateway=("::192.88.99.1%".$"IF-TUN")
        :local t [/ipv6 address get [find interface=$"IF-LOC"] address]
        :set t [:pick $t 0 [:find $t "/"]]
        :if ( [/ipv6 dhcp-server option print count-only where name=DNS] = 0) do={
            /ipv6 dhcp-server option add code=23 name=DNS value=("0x".[$"str_replace" $t ":" "" 4 "0"])
        } else={
            /ipv6 dhcp-server option set [/ipv6 dhcp-server option find where name=DNS] value=("0x".[$"str_replace" $t ":" "" 4 "0"])
        }
        :if ( [/ipv6 dhcp-server print count-only where interface=$"IF-LOC"] = 0) do={
            /ipv6 dhcp-server add address-pool=$"POOL-6TO4" dhcp-option=DNS interface=$"IF-LOC" lease-time=1d name=$"IF-LOC"
        }
        :if ( [ipv6 nd print count-only where interface=$"IF-LOC"] = 0) do={
            /ipv6 nd add advertise-dns=no interface=$"IF-LOC" other-configuration=yes
        }
    }
}

В скрипте нужно установить переменные, отвечающие за интерфейсы, которые мы настраиваем:

  • interface — внешний интерфейс
  • IF-TUN — туннельный интерфейс
  • IF-LOC — локальный интерфейс
  • POOL-6TO4 — название пула адресов в локальной сети
  • force-update — Если установлено true, то считается что ip менялся
  • lease-address — Задаем статический адрес

Скрипт адаптирован для работы в DHCP-CLIENT, так что секцию статических параметров надо закомментировать, если вы будете использовать DHCP.
Запустив скрипт, мы получим сконфигурированный туннель и локальный интерфейс с префиксом /64.

Теперь добавим этот скрипт в планировщик (я запускаю каждые 5 минут), и при смене внешнего IPv4, с небольшой задержкой 6to4 будет перенастроен.

Какие сложности вас ждут?


Клиенты получают IPv6 с помощью SLAAC, и нет возможности задать DNS и шлюз (Win клиенты получают только шлюз через RA). В Mikrotik есть DHCPv6, но толку от него ещё мало (не доделан он в полной мере).

Для поддержки DNS в самом Mikrotik выставляем известные публичные сервера (к примеру 2620:0:ccc::2 и 2620:0:ccd::2), у клиентов можно настроить link local адрес Mikrotik.
Tags:
Hubs:
+15
Comments10

Articles