Pull to refresh

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

Reading time 5 min
Views 16K
Эта статья будет полезна тем, кто хочет испытать 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
Comments 10
Comments Comments 10

Articles