Skip to content

Instantly share code, notes, and snippets.

@wiktorbgu
Last active March 3, 2026 12:14
Show Gist options
  • Select an option

  • Save wiktorbgu/1f2dfe99837d8f2803483be95814d2e5 to your computer and use it in GitHub Desktop.

Select an option

Save wiktorbgu/1f2dfe99837d8f2803483be95814d2e5 to your computer and use it in GitHub Desktop.
Mikrotik WireGuard anti DPI

Чуть подправил скрипт , чтобы лишний раз не бегал по клиентским пирам, которые подключаются к этому роутеру, а только где роутер как клиент.
Работает убойно! Proton и Warp пробивает)

Upd.: увеличил время в фильтре до 2м30с как защита от ложных срабатываний у медленных подключений.
Считаю выполнение скрипта раз в 2 минуты средним нормальным значением.
Так же добавил в скрипт закомментированную строку с возможность исключения какого-либо wg интерфейса из проверки.

Если при выполнении скрипта на этапе генерации трафика выходит ошибка в лог, то:
выполнить команду /system/device-mode/print
если получаем mode: advanced и при этом в выводе нету traffic-gen: yes,
выполняем команду
/system/device-mode/update traffic-gen=yes и следуем инструкциям в консоли.
Официальная справка по device-mode.

Скрипт добавляется по пути в меню System - Scheduler


Новый скрипт + справка там же от Medium1992

версия v2

:local Jc   4
:local Jmin 40
:local Jmax 70
:local TTL 64

:local i1 "c3000000010870ac9c05f49d2bff0341d26000421578ace2b50e80d3a3e8b2c2e2e5f50aebf6f7364c9fbed6be8c14606445db7e5c0f75b825ffc3d872b3c463422f0c6334b45a1d1297ee2abda6150110864de45ade52b8a2e33a7c4db399678ccb0501ce14696ae1de40c350293d31db073976e3eae493500358df59b6e16867d4c39ff670168bf0ab50e43aa0fc0814c0762227ff93f334522d9562142dcdef7241b554bfe2c27a3ab066d516f4d31a47526318c644e15d90e98899e25c0ce8a67e14df149769c3d14833d27a25e25fde8afd68f587cc573e8c88e502793b50626f4c5267a5786b2903172a0ef4eea2fa282a02e3d3385d598baa9cacb9395d6c43c5ccbbdce9845a39ded847779f00c44cf5df34f3ad2a22e63504316b748eabacb3b03a1cc3df9c8d6ab60a0255b7f8d433d6d0a671b5cf30a0af2c04a7138cc1b264382e164ebbbcc290176ac9d6672e57cac55effa9df991a0ec1b4ed63910432ff03b187c3a22206c6a4914e16d59e36f011a08f03f3ac7baed06a884f9fa3ee84ab2d097d4863f84edc87b624ca9aeafcec920339d3addc7b5fae21e59cc47c58147b244300ad857e71b8cb9772c4fed8a7a775744f0d8448c70a491e3a7fa5a98c0997be9319a32495011cafb4c2f9b3ade1ef1a5efbc00dd7374e5ea0226d62934a2847c55c0d524337d4073557e96b9ff177414ef03945503fb7c6149db4c3f4a449e70363fe259360de0df0d194f43a44dd364acadb6683262927e1b3dbcbb8e8a610ab0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
:local i2 ""
:local i3 ""
:local i4 ""
:local i5 ""

:local tohex do={
  :local n $1
  :local h ""
  :while ($n>0) do={
    :local r ($n % 16)
    :set h ([:pick "0123456789abcdef" $r ($r+1)] . $h)
    :set n ($n / 16)
  }
  :return $h
}

:local mac2hex do={
    :local m $1
    :set m ([:pick $m 0 2].[:pick $m 3 5].[:pick $m 6 8].[:pick $m 9 11].[:pick $m 12 14].[:pick $m 15 17])
    :return [:convert transform=lc $m]
}

:local hex16 do={
    :local n [:tonum $1]
    :local hi ($n >> 8)
    :local lo ($n & 255)

    :local digits "0123456789abcdef"

    :local h1 [:pick $digits ($hi >> 4) (($hi >> 4) + 1)]
    :local h2 [:pick $digits ($hi & 15) (($hi & 15) + 1)]
    :local h3 [:pick $digits ($lo >> 4) (($lo >> 4) + 1)]
    :local h4 [:pick $digits ($lo & 15) (($lo & 15) + 1)]

    :return ($h1 . $h2 . $h3 . $h4)
}

:local hex8 do={
    :local n [:tonum $1]
    :local digits "0123456789abcdef"

    :local h1 [:pick $digits ($n >> 4) (($n >> 4) + 1)]
    :local h2 [:pick $digits ($n & 15) (($n & 15) + 1)]

    :return ($h1 . $h2)
}

:local ip2hex do={

    :local ip [:tostr $1]
    :local out ""
    :local digits "0123456789abcdef"

    :foreach octet in=[:toarray $ip delimiter="."] do={

        :local n [:tonum $octet]

        :local h1 [:pick $digits ($n >> 4) (($n >> 4) + 1)]
        :local h2 [:pick $digits ($n & 15) (($n & 15) + 1)]

        :set out ($out . $h1 . $h2)
    }

    :return $out
}

:local ipchecksum do={
    :local header $1
    :local sum 0

    :for j from=0 to=9 do={
        :local offset ($j * 4)
        :local word [:pick $header $offset ($offset + 4)]
        :local val [:tonum ("0x" . $word)]
        :set sum ($sum + $val)
    }

    :while ($sum > 65535) do={
        :set sum (($sum & 65535) + ($sum >> 16))
    }

    :local checksum (65535 - $sum)

    :local hi ($checksum >> 8)
    :local lo ($checksum & 255)

    :local digits "0123456789abcdef"

    :local h1 [:pick $digits ($hi >> 4) (($hi >> 4) + 1)]
    :local h2 [:pick $digits ($hi & 15) (($hi & 15) + 1)]
    :local h3 [:pick $digits ($lo >> 4) (($lo >> 4) + 1)]
    :local h4 [:pick $digits ($lo & 15) (($lo & 15) + 1)]

    :return ($h1 . $h2 . $h3 . $h4)
}

:local udpchecksum do={
    :local srcHex $1
    :local dstHex $2
    :local udpLenNum $3 
    :local udpTmp $4
    :local pay $5

    :local pseudo ($srcHex . $dstHex . "0000" . "11" . [$hex16 $udpLenNum])

    :local checkdata ($pseudo . $udpTmp . $pay)

    :if (([:len $checkdata] % 4) != 0) do={
        :set checkdata ($checkdata . "00")
    }

    :local sum 0
    :local wordCount ([:len $checkdata] / 4)
    :for j from=0 to=($wordCount - 1) do={
        :local offset ($j * 4)
        :local word [:pick $checkdata $offset ($offset + 4)]
        :local val [:tonum ("0x" . $word)]
        :set sum ($sum + $val)
    }

    :while ($sum > 65535) do={
        :set sum (($sum & 65535) + ($sum >> 16))
    }

    :local checksum (65535 - $sum)
    :if ($checksum = 0) do={ :set checksum 0 }

    :local hi ($checksum >> 8)
    :local lo ($checksum & 255)
    :local digits "0123456789abcdef"
    :local h1 [:pick $digits ($hi >> 4) (($hi >> 4) + 1)]
    :local h2 [:pick $digits ($hi & 15) (($hi & 15) + 1)]
    :local h3 [:pick $digits ($lo >> 4) (($lo >> 4) + 1)]
    :local h4 [:pick $digits ($lo & 15) (($lo & 15) + 1)]

    :return ($h1 . $h2 . $h3 . $h4)
}

:local randhex do={

    :local bytes $1
    :local out ""
    :local digits "0123456789abcdef"

    :for i from=1 to=$bytes do={

        :local r [:rndnum from=0 to=255]

        :local h1 [:pick $digits ($r >> 4) (($r >> 4) + 1)]
        :local h2 [:pick $digits ($r & 15) (($r & 15) + 1)]

        :set out ($out . $h1 . $h2)
    }

    :return $out
}

:local parts ($i1 . "," . $i2 . "," . $i3 . "," . $i4 . "," . $i5)

:for j from=1 to=$Jc do={
    :local size [:rndnum from=$Jmin to=$Jmax]
    :local junk [$randhex $size]
    :set parts ($parts . "," . $junk)
}
:global Tx
:global Rx
/interface/wireguard/peers

# при частых ребутах роутера или других ошибках отключается пир wg, т.к. внезапно прерывается выполнение скрипта
# решение просто раскомментировать следующую строку и внести имя интерфейса чей пир нужно включить в любом случае, если выключен.
#:foreach y in=[find where disabled=yes and responder!=yes and interface="wireguard-warp"] do={set $y disabled=no}
# либо использовать включение по комменту к пиру auto_on
:foreach y in=[find where disabled=yes and responder!=yes and comment="auto_on"] do={set $y disabled=no}

# Далее идут варианты строки :foreach i in=, которые взаимоисключающие т.е. сейчас активна строка, можете её закомментировать и раскомментировать другую по необходимости.
# Исключить подключение wireguard-client по имени интерфейса чтобы скрипт его никогда не трогал
#:foreach i in=[find where disabled=no and responder!=yes and interface!="wireguard-client"] do={
:foreach i in=[find where disabled=no and responder!=yes] do={
:local LocalTx [get $i tx]
    :local LocalRx [get $i rx]
    :local LastHandshake [get $i last-handshake]
    :local isDisabled [get $i disabled]
    :if (([:tostr $LastHandshake] = "") or ($LastHandshake > [:totime "2m30s"]) or ($isDisabled = yes)) do={
        :local PeerName [get $i name]
        #Disable peer
        :log warning ("Disable peer: $PeerName")
        set $i disabled=yes
        :local Interface [get $i interface]
        :local EndpointAddress [get $i endpoint-address]
        :local EndpointIP ""

        :local dotCount 0
        :local isIP true
        :local pos 0
        :while ($pos < [:len $EndpointAddress]) do={
            :local ch [:pick $EndpointAddress $pos ($pos + 1)]
            :if ($ch = ".") do={
                :set dotCount ($dotCount + 1)
            } else={
                :if ([:find "0123456789" $ch] = []) do={
                    :set isIP false
                }
            }
            :set pos ($pos + 1)
        }

        :if ($isIP and $dotCount = 3) do={
            :set EndpointIP $EndpointAddress
        } else={
            :set EndpointIP [:resolve $EndpointAddress]
        }

        :local DstPort [get $i current-endpoint-port]
        :local rndport [:rndnum from=10000 to=59999]
        /interface wireguard set $Interface listen-port=$rndport
        :local SrcPort [/interface wireguard get $Interface listen-port]

        /tool ping address=$EndpointIP count=1 interval=200ms
        :delay 1s        
        :local conn [/ip firewall connection find where dst-address="$EndpointIP" and protocol=icmp]
        :if ([:len $conn]=0) do={
            :log error "No WG conntrack entry for $EndpointIP:$DstPort"
            :return
        }
        :local cid [:pick $conn 0]
        :local srcip [/ip firewall connection get $cid reply-dst-address]

        :local route [/ip route check dst-ip=$EndpointIP once as-value]
        :local outIf ($route->"interface")
        :local ifType [/interface get $outIf type]

        :if ([:len $route]=0) do={
            :log error "Route check failed"
            :return
        }

        :local eth ""
        :local gw ""
        :if ($ifType = "ether" or $ifType = "bridge") do={  
            :set gw ($route->"nexthop")
            :local srcmacRaw [/interface get $outIf mac-address]
            :local srcmac [$mac2hex $srcmacRaw]
            :local dstmacRaw [/ip arp get [find where address=$gw and interface=$outIf] mac-address]
            :local dstmac [$mac2hex $dstmacRaw]
            :set eth ($dstmac.$srcmac."0800")
        }

        :if ($ifType = "vlan") do={  
            :set gw ($route->"nexthop")
            :local srcmacRaw [/interface get $outIf mac-address]
            :local srcmac [$mac2hex $srcmacRaw]
            :local dstmacRaw [/ip arp get [find where address=$gw and interface=$outIf] mac-address]
            :local dstmac [$mac2hex $dstmacRaw]
            :local vlanId [/interface/vlan/get $outIf vlan-id]
            :local vlanIdHex [$hex16 $vlanId]
            :set outIf [/interface/vlan/get $outIf interface]
            :set eth ($dstmac.$srcmac."8100".$vlanIdHex."0800")
        }

        :local srcipHex [$ip2hex $srcip]
        :local dstipHex [$ip2hex $EndpointIP]
        :local ttlHex [$hex8 $TTL]

        :local ipid [:rndnum from=0 to=65535]
        :local ipidHex [$hex16 $ipid]

        :local srcPortHex [$hex16 $SrcPort]
        :local dstPortHex [$hex16 $DstPort]

        #Log peer info
        :log warning ("Peer: $PeerName, Interface: $Interface")
        :log warning ("Endpoint Address: $EndpointAddress, Endpoint IP: $EndpointIP")
        :log warning ("Src Port: $SrcPort, Dst Port: $DstPort, Last Handshake: $LastHandshake")
        :log warning ("Last Rx: " . $Rx->[:tostr $i] . ", Current Rx: $LocalRx")
        :log warning ("Last Tx: " . $Tx->[:tostr $i] . ", Current Tx: $LocalTx")
        
        :delay 100ms
        
        #Generating spam
        :log warning ("Generating spam")
        :delay 1

        :log warning ("gateway: $gw")
        :log warning ("eth: $eth")
        :log warning ("srcip: $srcip")
        :log warning ("srcipHex: $srcipHex")
        :log warning ("dstip: $EndpointIP")
        :log warning ("dstipHex: $dstipHex")
        :log warning ("outInterface: $outIf")

        :foreach part in=[:toarray $parts] do={

            :if ([:len $part] = 0) do={ :continue }
            :local partLen ([:len $part] / 2)
            :local udpLen ($partLen + 8)
            :local ipLen ($udpLen + 20)
            :local udpHeaderTmp ($srcPortHex.$dstPortHex.[$hex16 $udpLen]."0000")
            :local udpCsum [$udpchecksum $srcipHex $dstipHex $udpLen $udpHeaderTmp $part]
            :local udpHeader ($srcPortHex.$dstPortHex.[$hex16 $udpLen].$udpCsum)
            :local ipHeaderTmp ("45"."00".[$hex16 $ipLen].$ipidHex."0000".$ttlHex."11"."0000".$srcipHex.$dstipHex)
            :local ipCsum [$ipchecksum $ipHeaderTmp]
            :local ipHeader ("45"."00".[$hex16 $ipLen].$ipidHex."0000".$ttlHex."11".$ipCsum.$srcipHex.$dstipHex)
            :local l34 ($ipHeader.$udpHeader)
            :local fullpacket ($eth.$l34.$part)

            :log warning ("fullpacket: $fullpacket")
            /tool/traffic-generator/inject $outIf data=$fullpacket

            :delay 5ms
        }
        
        #Enable peer
        :log warning ("Enable peer: $PeerName")
        set $i disabled=no
    }
    :set ($Tx->[:tostr $i]) $LocalTx
    :set ($Rx->[:tostr $i]) $LocalRx
}

Старая версия

:global Tx
:global Rx
/interface/wireguard/peers

# при частых ребутах роутера или других ошибках отключается пир wg, т.к. внезапно прерывается выполнение скрипта
# решение просто раскомментировать следующую строку и внести имя интерфейса чей пир нужно включить в любом случае, если выключен.
#:foreach y in=[find where disabled=yes and responder!=yes and interface="wireguard-warp"] do={set $y disabled=no}
# либо использовать включение по комменту к пиру auto_on
:foreach y in=[find where disabled=yes and responder!=yes and comment="auto_on"] do={set $y disabled=no}

# Далее идут варианты строки :foreach i in=, которые взаимоисключающие т.е. сейчас активна строка, можете её закомментировать и раскомментировать другую по необходимости.
# Исключить подключение wireguard-client по имени интерфейса чтобы скрипт его никогда не трогал
#:foreach i in=[find where disabled=no and responder!=yes and interface!="wireguard-client"] do={
:foreach i in=[find where disabled=no and responder!=yes] do={
  :local LocalTx [get $i tx]
  :local LocalRx [get $i rx]
  :local LastHandshake [get $i last-handshake]
  :if (([:tostr $LastHandshake] = "") or (($LastHandshake > [:totime "2m30s"]) and ($Rx->[:tostr $i] = $LocalRx))) do={
    :local rawHeader [:rndstr length=4 from=123456789abcdef]
    :local EndpointAddress [get $i endpoint-address]
    :local EndpointAddressIP $EndpointAddress
    :local EndpointAddressIP [get $i current-endpoint-address]
    :local name [get $i name]
    :local wgDstPort [get $i current-endpoint-port]
    :local interface [get $i interface]
    
    # Сбрасываем исходящий порт на уровне интерфейса
    /interface wireguard set $interface listen-port=0
    :local srcport [/interface/wireguard/get $interface listen-port];

    :log info ("WG name is $name, EndpointAddress $EndpointAddress , LastHandshake $LastHandshake, LastTx " . $Tx->[:tostr $i] . ", CurrentTx $LocalTx, LastRx " . $Rx->[:tostr $i] . ", CurrentRx $LocalRx")
    :log info ("WG Currentinterface $interface, srcport $srcport, EndpointAddressIP $EndpointAddressIP, DstPort $wgDstPort")
    :log info ("Generating spam for RKN")
    set $i disabled=yes
    /tool traffic-generator stream remove [find]
    /tool traffic-generator packet-template remove [find]
    :delay 1
    /tool/traffic-generator/packet-template/add header-stack=mac,ip,udp,raw ip-dst=$EndpointAddressIP name=packet-template-wg raw-header=$rawHeader special-footer=no udp-dst-port=$wgDstPort udp-src-port=$srcport
    :delay 1
    /tool traffic-generator stream add disabled=no mbps=1 name=stream1 id=3 packet-size=1450 pps=0 tx-template=packet-template-wg
    :delay 1
    /tool traffic-generator quick duration=4
    :delay 1

    :log info ("Starting WG $EndpointAddress")
    set $i endpoint-address=$EndpointAddress
    set $i disabled=no
  }
  :set ($Tx->[:tostr $i]) $LocalTx
  :set ($Rx->[:tostr $i]) $LocalRx
}

Настройки задания в планировщике

/system script add dont-require-permissions=yes name=PushWG policy=read,write,policy,test,sniff,sensitive source=":local Jc 4\r\
\n:local Jmin 40\r\
\n:local Jmax 70\r\
\n:local TTL 64\r\
\n\r\
\n:local i1 \"c3000000010870ac9c05f49d2bff0341d26000421578ace2b50e80d3a3e8b2c2e2e5f50aebf6f7364c9fbed6be8c14606445db7e5c0f75b825ffc3d872b3c463422f0c6334b45a1d1297ee2abda6150110864de45ade52b8a2e33a7c4db399678ccb0501ce14696ae1de40c350293d31db073976e3eae493500358df59b6e16867d4c39ff670168bf0ab50e43aa0fc0814c0762227ff93f334522d9562142dcdef7241b554bfe2c27a3ab066d516f4d31a47526318c644e15d90e98899e25c0ce8a67e14df149769c3d14833d27a25e25fde8afd68f587cc573e8c88e502793b50626f4c5267a5786b2903172a0ef4eea2fa282a02e3d3385d598baa9cacb9395d6c43c5ccbbdce9845a39ded847779f00c44cf5df34f3ad2a22e63504316b748eabacb3b03a1cc3df9c8d6ab60a0255b7f8d433d6d0a671b5cf30a0af2c04a7138cc1b264382e164ebbbcc290176ac9d6672e57cac55effa9df991a0ec1b4ed63910432ff03b187c3a22206c6a4914e16d59e36f011a08f03f3ac7baed06a884f9fa3ee84ab2d097d4863f84edc87b624ca9aeafcec920339d3addc7b5fae21e59cc47c58147b244300ad857e71b8cb9772c4fed8a7a775744f0d8448c70a491e3a7fa5a98c0997be9319a32495011cafb4c2f9b3ade1ef1a5efbc00dd7374e5ea0226d62934a2847c55c0d524337d4073557e96b9ff177414ef03945503fb7c6149db4c3f4a449e70363fe259360de0df0d194f43a44dd364acadb6683262927e1b3dbcbb8e8a610ab0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"\r\
\n:local i2 \"\"\r\
\n:local i3 \"\"\r\
\n:local i4 \"\"\r\
\n:local i5 \"\"\r\
\n\r\
\n:local tohex do={\r\
\n :local n \$1\r\
\n :local h \"\"\r\
\n :while (\$n>0) do={\r\
\n :local r (\$n % 16)\r\
\n :set h ([:pick \"0123456789abcdef\" \$r (\$r+1)] . \$h)\r\
\n :set n (\$n / 16)\r\
\n }\r\
\n :return \$h\r\
\n}\r\
\n\r\
\n:local mac2hex do={\r\
\n :local m \$1\r\
\n :set m ([:pick \$m 0 2].[:pick \$m 3 5].[:pick \$m 6 8].[:pick \$m 9 11].[:pick \$m 12 14].[:pick \$m 15 17])\r\
\n :return [:convert transform=lc \$m]\r\
\n}\r\
\n\r\
\n:local hex16 do={\r\
\n :local n [:tonum \$1]\r\
\n :local hi (\$n >> 8)\r\
\n :local lo (\$n & 255)\r\
\n\r\
\n :local digits \"0123456789abcdef\"\r\
\n\r\
\n :local h1 [:pick \$digits (\$hi >> 4) ((\$hi >> 4) + 1)]\r\
\n :local h2 [:pick \$digits (\$hi & 15) ((\$hi & 15) + 1)]\r\
\n :local h3 [:pick \$digits (\$lo >> 4) ((\$lo >> 4) + 1)]\r\
\n :local h4 [:pick \$digits (\$lo & 15) ((\$lo & 15) + 1)]\r\
\n\r\
\n :return (\$h1 . \$h2 . \$h3 . \$h4)\r\
\n}\r\
\n\r\
\n:local hex8 do={\r\
\n :local n [:tonum \$1]\r\
\n :local digits \"0123456789abcdef\"\r\
\n\r\
\n :local h1 [:pick \$digits (\$n >> 4) ((\$n >> 4) + 1)]\r\
\n :local h2 [:pick \$digits (\$n & 15) ((\$n & 15) + 1)]\r\
\n\r\
\n :return (\$h1 . \$h2)\r\
\n}\r\
\n\r\
\n:local ip2hex do={\r\
\n\r\
\n :local ip [:tostr \$1]\r\
\n :local out \"\"\r\
\n :local digits \"0123456789abcdef\"\r\
\n\r\
\n :foreach octet in=[:toarray \$ip delimiter=\".\"] do={\r\
\n\r\
\n :local n [:tonum \$octet]\r\
\n\r\
\n :local h1 [:pick \$digits (\$n >> 4) ((\$n >> 4) + 1)]\r\
\n :local h2 [:pick \$digits (\$n & 15) ((\$n & 15) + 1)]\r\
\n\r\
\n :set out (\$out . \$h1 . \$h2)\r\
\n }\r\
\n\r\
\n :return \$out\r\
\n}\r\
\n\r\
\n:local ipchecksum do={\r\
\n :local header \$1\r\
\n :local sum 0\r\
\n\r\
\n :for j from=0 to=9 do={\r\
\n :local offset (\$j * 4)\r\
\n :local word [:pick \$header \$offset (\$offset + 4)]\r\
\n :local val [:tonum (\"0x\" . \$word)]\r\
\n :set sum (\$sum + \$val)\r\
\n }\r\
\n\r\
\n :while (\$sum > 65535) do={\r\
\n :set sum ((\$sum & 65535) + (\$sum >> 16))\r\
\n }\r\
\n\r\
\n :local checksum (65535 - \$sum)\r\
\n\r\
\n :local hi (\$checksum >> 8)\r\
\n :local lo (\$checksum & 255)\r\
\n\r\
\n :local digits \"0123456789abcdef\"\r\
\n\r\
\n :local h1 [:pick \$digits (\$hi >> 4) ((\$hi >> 4) + 1)]\r\
\n :local h2 [:pick \$digits (\$hi & 15) ((\$hi & 15) + 1)]\r\
\n :local h3 [:pick \$digits (\$lo >> 4) ((\$lo >> 4) + 1)]\r\
\n :local h4 [:pick \$digits (\$lo & 15) ((\$lo & 15) + 1)]\r\
\n\r\
\n :return (\$h1 . \$h2 . \$h3 . \$h4)\r\
\n}\r\
\n\r\
\n:local udpchecksum do={\r\
\n :local srcHex \$1\r\
\n :local dstHex \$2\r\
\n :local udpLenNum \$3 \r\
\n :local udpTmp \$4\r\
\n :local pay \$5\r\
\n\r\
\n :local pseudo (\$srcHex . \$dstHex . \"0000\" . \"11\" . [\$hex16 \$udpLenNum])\r\
\n\r\
\n :local checkdata (\$pseudo . \$udpTmp . \$pay)\r\
\n\r\
\n :if (([:len \$checkdata] % 4) != 0) do={\r\
\n :set checkdata (\$checkdata . \"00\")\r\
\n }\r\
\n\r\
\n :local sum 0\r\
\n :local wordCount ([:len \$checkdata] / 4)\r\
\n :for j from=0 to=(\$wordCount - 1) do={\r\
\n :local offset (\$j * 4)\r\
\n :local word [:pick \$checkdata \$offset (\$offset + 4)]\r\
\n :local val [:tonum (\"0x\" . \$word)]\r\
\n :set sum (\$sum + \$val)\r\
\n }\r\
\n\r\
\n :while (\$sum > 65535) do={\r\
\n :set sum ((\$sum & 65535) + (\$sum >> 16))\r\
\n }\r\
\n\r\
\n :local checksum (65535 - \$sum)\r\
\n :if (\$checksum = 0) do={ :set checksum 0 }\r\
\n\r\
\n :local hi (\$checksum >> 8)\r\
\n :local lo (\$checksum & 255)\r\
\n :local digits \"0123456789abcdef\"\r\
\n :local h1 [:pick \$digits (\$hi >> 4) ((\$hi >> 4) + 1)]\r\
\n :local h2 [:pick \$digits (\$hi & 15) ((\$hi & 15) + 1)]\r\
\n :local h3 [:pick \$digits (\$lo >> 4) ((\$lo >> 4) + 1)]\r\
\n :local h4 [:pick \$digits (\$lo & 15) ((\$lo & 15) + 1)]\r\
\n\r\
\n :return (\$h1 . \$h2 . \$h3 . \$h4)\r\
\n}\r\
\n\r\
\n:local randhex do={\r\
\n\r\
\n :local bytes \$1\r\
\n :local out \"\"\r\
\n :local digits \"0123456789abcdef\"\r\
\n\r\
\n :for i from=1 to=\$bytes do={\r\
\n\r\
\n :local r [:rndnum from=0 to=255]\r\
\n\r\
\n :local h1 [:pick \$digits (\$r >> 4) ((\$r >> 4) + 1)]\r\
\n :local h2 [:pick \$digits (\$r & 15) ((\$r & 15) + 1)]\r\
\n\r\
\n :set out (\$out . \$h1 . \$h2)\r\
\n }\r\
\n\r\
\n :return \$out\r\
\n}\r\
\n\r\
\n:local parts (\$i1 . \",\" . \$i2 . \",\" . \$i3 . \",\" . \$i4 . \",\" . \$i5)\r\
\n\r\
\n:for j from=1 to=\$Jc do={\r\
\n :local size [:rndnum from=\$Jmin to=\$Jmax]\r\
\n :local junk [\$randhex \$size]\r\
\n :set parts (\$parts . \",\" . \$junk)\r\
\n}\r\
\n:global Tx\r\
\n:global Rx\r\
\n/interface/wireguard/peers\r\
\n\r\
\n# \EF\F0\E8 \F7\E0\F1\F2\FB\F5 \F0\E5\E1\F3\F2\E0\F5 \F0\EE\F3\F2\E5\F0\E0 \E8\EB\E8 \E4\F0\F3\E3\E8\F5 \EE\F8\E8\E1\EA\E0\F5 \EE\F2\EA\EB\FE\F7\E0\E5\F2\F1\FF \EF\E8\F0 wg, \F2.\EA. \E2\ED\E5\E7\E0\EF\ED\EE \EF\F0\E5\F0\FB\E2\E0\E5\F2\F1\FF \E2\FB\EF\EE\EB\ED\E5\ED\E8\E5 \F1\EA\F0\E8\EF\F2\E0\r\
\n# \F0\E5\F8\E5\ED\E8\E5 \EF\F0\EE\F1\F2\EE \F0\E0\F1\EA\EE\EC\EC\E5\ED\F2\E8\F0\EE\E2\E0\F2\FC \F1\EB\E5\E4\F3\FE\F9\F3\FE \F1\F2\F0\EE\EA\F3 \E8 \E2\ED\E5\F1\F2\E8 \E8\EC\FF \E8\ED\F2\E5\F0\F4\E5\E9\F1\E0 \F7\E5\E9 \EF\E8\F0 \ED\F3\E6\ED\EE \E2\EA\EB\FE\F7\E8\F2\FC \E2 \EB\FE\E1\EE\EC \F1\EB\F3\F7\E0\E5, \E5\F1\EB\E8 \E2\FB\EA\EB\FE\F7\E5\ED.\r\
\n#:foreach y in=[find where disabled=yes and responder!=yes and interface=\"wireguard-warp\"] do={set \$y disabled=no}\r\
\n# \EB\E8\E1\EE \E8\F1\EF\EE\EB\FC\E7\EE\E2\E0\F2\FC \E2\EA\EB\FE\F7\E5\ED\E8\E5 \EF\EE \EA\EE\EC\EC\E5\ED\F2\F3 \EA \EF\E8\F0\F3 auto_on\r\
\n:foreach y in=[find where disabled=yes and responder!=yes and comment=\"auto_on\"] do={set \$y disabled=no}\r\
\n\r\
\n# \C4\E0\EB\E5\E5 \E8\E4\F3\F2 \E2\E0\F0\E8\E0\ED\F2\FB \F1\F2\F0\EE\EA\E8 :foreach i in=, \EA\EE\F2\EE\F0\FB\E5 \E2\E7\E0\E8\EC\EE\E8\F1\EA\EB\FE\F7\E0\FE\F9\E8\E5 \F2.\E5. \F1\E5\E9\F7\E0\F1 \E0\EA\F2\E8\E2\ED\E0 \F1\F2\F0\EE\EA\E0, \EC\EE\E6\E5\F2\E5 \E5\B8 \E7\E0\EA\EE\EC\EC\E5\ED\F2\E8\F0\EE\E2\E0\F2\FC \E8 \F0\E0\F1\EA\EE\EC\EC\E5\ED\F2\E8\F0\EE\E2\E0\F2\FC \E4\F0\F3\E3\F3\FE \EF\EE \ED\E5\EE\E1\F5\EE\E4\E8\EC\EE\F1\F2\E8.\r\
\n# \C8\F1\EA\EB\FE\F7\E8\F2\FC \EF\EE\E4\EA\EB\FE\F7\E5\ED\E8\E5 wireguard-client \EF\EE \E8\EC\E5\ED\E8 \E8\ED\F2\E5\F0\F4\E5\E9\F1\E0 \F7\F2\EE\E1\FB \F1\EA\F0\E8\EF\F2 \E5\E3\EE \ED\E8\EA\EE\E3\E4\E0 \ED\E5 \F2\F0\EE\E3\E0\EB\r\
\n#:foreach i in=[find where disabled=no and responder!=yes and interface!=\"wireguard-client\"] do={\r\
\n:foreach i in=[find where disabled=no and responder!=yes] do={\r\
\n:local LocalTx [get \$i tx]\r\
\n :local LocalRx [get \$i rx]\r\
\n :local LastHandshake [get \$i last-handshake]\r\
\n :local isDisabled [get \$i disabled]\r\
\n :if (([:tostr \$LastHandshake] = \"\") or (\$LastHandshake > [:totime \"2m30s\"]) or (\$isDisabled = yes)) do={\r\
\n :local PeerName [get \$i name]\r\
\n #Disable peer\r\
\n :log warning (\"Disable peer: \$PeerName\")\r\
\n set \$i disabled=yes\r\
\n :local Interface [get \$i interface]\r\
\n :local EndpointAddress [get \$i endpoint-address]\r\
\n :local EndpointIP \"\"\r\
\n\r\
\n :local dotCount 0\r\
\n :local isIP true\r\
\n :local pos 0\r\
\n :while (\$pos < [:len \$EndpointAddress]) do={\r\
\n :local ch [:pick \$EndpointAddress \$pos (\$pos + 1)]\r\
\n :if (\$ch = \".\") do={\r\
\n :set dotCount (\$dotCount + 1)\r\
\n } else={\r\
\n :if ([:find \"0123456789\" \$ch] = []) do={\r\
\n :set isIP false\r\
\n }\r\
\n }\r\
\n :set pos (\$pos + 1)\r\
\n }\r\
\n\r\
\n :if (\$isIP and \$dotCount = 3) do={\r\
\n :set EndpointIP \$EndpointAddress\r\
\n } else={\r\
\n :set EndpointIP [:resolve \$EndpointAddress]\r\
\n }\r\
\n\r\
\n :local DstPort [get \$i current-endpoint-port]\r\
\n :local rndport [:rndnum from=10000 to=59999]\r\
\n /interface wireguard set \$Interface listen-port=\$rndport\r\
\n :local SrcPort [/interface wireguard get \$Interface listen-port]\r\
\n\r\
\n /tool ping address=\$EndpointIP count=1 interval=200ms\r\
\n :delay 1s \r\
\n :local conn [/ip firewall connection find where dst-address=\"\$EndpointIP\" and protocol=icmp]\r\
\n :if ([:len \$conn]=0) do={\r\
\n :log error \"No WG conntrack entry for \$EndpointIP:\$DstPort\"\r\
\n :return\r\
\n }\r\
\n :local cid [:pick \$conn 0]\r\
\n :local srcip [/ip firewall connection get \$cid reply-dst-address]\r\
\n\r\
\n :local route [/ip route check dst-ip=\$EndpointIP once as-value]\r\
\n :local outIf (\$route->\"interface\")\r\
\n :local ifType [/interface get \$outIf type]\r\
\n\r\
\n :if ([:len \$route]=0) do={\r\
\n :log error \"Route check failed\"\r\
\n :return\r\
\n }\r\
\n\r\
\n :local eth \"\"\r\
\n :local gw \"\"\r\
\n :if (\$ifType = \"ether\" or \$ifType = \"bridge\") do={ \r\
\n :set gw (\$route->\"nexthop\")\r\
\n :local srcmacRaw [/interface get \$outIf mac-address]\r\
\n :local srcmac [\$mac2hex \$srcmacRaw]\r\
\n :local dstmacRaw [/ip arp get [find where address=\$gw and interface=\$outIf] mac-address]\r\
\n :local dstmac [\$mac2hex \$dstmacRaw]\r\
\n :set eth (\$dstmac.\$srcmac.\"0800\")\r\
\n }\r\
\n\r\
\n :if (\$ifType = \"vlan\") do={ \r\
\n :set gw (\$route->\"nexthop\")\r\
\n :local srcmacRaw [/interface get \$outIf mac-address]\r\
\n :local srcmac [\$mac2hex \$srcmacRaw]\r\
\n :local dstmacRaw [/ip arp get [find where address=\$gw and interface=\$outIf] mac-address]\r\
\n :local dstmac [\$mac2hex \$dstmacRaw]\r\
\n :local vlanId [/interface/vlan/get \$outIf vlan-id]\r\
\n :local vlanIdHex [\$hex16 \$vlanId]\r\
\n :set outIf [/interface/vlan/get \$outIf interface]\r\
\n :set eth (\$dstmac.\$srcmac.\"8100\".\$vlanIdHex.\"0800\")\r\
\n }\r\
\n\r\
\n :local srcipHex [\$ip2hex \$srcip]\r\
\n :local dstipHex [\$ip2hex \$EndpointIP]\r\
\n :local ttlHex [\$hex8 \$TTL]\r\
\n\r\
\n :local ipid [:rndnum from=0 to=65535]\r\
\n :local ipidHex [\$hex16 \$ipid]\r\
\n\r\
\n :local srcPortHex [\$hex16 \$SrcPort]\r\
\n :local dstPortHex [\$hex16 \$DstPort]\r\
\n\r\
\n #Log peer info\r\
\n :log warning (\"Peer: \$PeerName, Interface: \$Interface\")\r\
\n :log warning (\"Endpoint Address: \$EndpointAddress, Endpoint IP: \$EndpointIP\")\r\
\n :log warning (\"Src Port: \$SrcPort, Dst Port: \$DstPort, Last Handshake: \$LastHandshake\")\r\
\n :log warning (\"Last Rx: \" . \$Rx->[:tostr \$i] . \", Current Rx: \$LocalRx\")\r\
\n :log warning (\"Last Tx: \" . \$Tx->[:tostr \$i] . \", Current Tx: \$LocalTx\")\r\
\n \r\
\n :delay 100ms\r\
\n \r\
\n #Generating spam\r\
\n :log warning (\"Generating spam\")\r\
\n :delay 1\r\
\n\r\
\n :log warning (\"gateway: \$gw\")\r\
\n :log warning (\"eth: \$eth\")\r\
\n :log warning (\"srcip: \$srcip\")\r\
\n :log warning (\"srcipHex: \$srcipHex\")\r\
\n :log warning (\"dstip: \$EndpointIP\")\r\
\n :log warning (\"dstipHex: \$dstipHex\")\r\
\n :log warning (\"outInterface: \$outIf\")\r\
\n\r\
\n :foreach part in=[:toarray \$parts] do={\r\
\n\r\
\n :if ([:len \$part] = 0) do={ :continue }\r\
\n :local partLen ([:len \$part] / 2)\r\
\n :local udpLen (\$partLen + 8)\r\
\n :local ipLen (\$udpLen + 20)\r\
\n :local udpHeaderTmp (\$srcPortHex.\$dstPortHex.[\$hex16 \$udpLen].\"0000\")\r\
\n :local udpCsum [\$udpchecksum \$srcipHex \$dstipHex \$udpLen \$udpHeaderTmp \$part]\r\
\n :local udpHeader (\$srcPortHex.\$dstPortHex.[\$hex16 \$udpLen].\$udpCsum)\r\
\n :local ipHeaderTmp (\"45\".\"00\".[\$hex16 \$ipLen].\$ipidHex.\"0000\".\$ttlHex.\"11\".\"0000\".\$srcipHex.\$dstipHex)\r\
\n :local ipCsum [\$ipchecksum \$ipHeaderTmp]\r\
\n :local ipHeader (\"45\".\"00\".[\$hex16 \$ipLen].\$ipidHex.\"0000\".\$ttlHex.\"11\".\$ipCsum.\$srcipHex.\$dstipHex)\r\
\n :local l34 (\$ipHeader.\$udpHeader)\r\
\n :local fullpacket (\$eth.\$l34.\$part)\r\
\n\r\
\n :log warning (\"fullpacket: \$fullpacket\")\r\
\n /tool/traffic-generator/inject \$outIf data=\$fullpacket\r\
\n\r\
\n :delay 5ms\r\
\n }\r\
\n \r\
\n #Enable peer\r\
\n :log warning (\"Enable peer: \$PeerName\")\r\
\n set \$i disabled=no\r\
\n }\r\
\n :set (\$Tx->[:tostr \$i]) \$LocalTx\r\
\n :set (\$Rx->[:tostr \$i]) \$LocalRx\r\
\n}\r\
\n"
/system scheduler
add interval=2m name=PushWG on-event="/system/script/ run PushWG" policy=read,write,policy,test,sniff,sensitive start-time=startup
/system script
add dont-require-permissions=yes name=PushWG policy=read,write,policy,test,sniff,sensitive source=":global Tx\r\
\n:global Rx\r\
\n/interface/wireguard/peers\r\
\n\r\
\n# \EF\F0\E8 \F7\E0\F1\F2\FB\F5 \F0\E5\E1\F3\F2\E0\F5 \EE\F2\EA\EB\FE\F7\E0\E5\F2\F1\FF \EF\E8\F0 wg\r\
\n# \F0\E5\F8\E5\ED\E8\E5 \EF\F0\EE\F1\F2\EE \F0\E0\F1\EA\EE\EC\EC\E5\ED\F2\E8\F0\EE\E2\E0\F2\FC \F1\EB\E5\E4\F3\FE\F9\F3\FE \F1\F2\F0\EE\EA\F3 \E8 \E2\ED\E5\
\F1\F2\E8 \E8\EC\FF \E8\ED\F2\E5\F0\F4\E5\E9\F1\E0 \F7\E5\E9 \EF\E8\F0 \ED\F3\E6\ED\EE \E2\EA\EB\FE\F7\E8\F2\FC \E2 \EB\FE\E1\EE\EC \F1\EB\F3\F7\E0\E5, \E5\
\F1\EB\E8 \E2\FB\EA\EB\FE\F7\E5\ED.\r\
\n#:foreach y in=[find where disabled=yes and responder!=yes and interface=\"wireguard-warp\"] do={set \$y disabled=no}\r\
\n\r\
\n# \C4\E0\EB\E5\E5 \E8\E4\F3\F2 \E2\E0\F0\E8\E0\ED\F2\FB \F1\F2\F0\EE\EA\E8, \EA\EE\F2\EE\F0\FB\E5 \E2\E7\E0\E8\EC\EE\E8\F1\EA\EB\FE\F7\E0\FE\F9\E8\E5 \F2.\
\E5. \F1\E5\E9\F7\E0\F1 \E0\EA\F2\E8\E2\ED\E0 \F2\F0\E5\F2\FC\FF \F1\F2\F0\EE\EA\E0, \EC\EE\E6\E5\F2\E5 \E5\B8 \E7\E0\EA\EE\EC\EC\E5\ED\F2\E8\F0\EE\E2\E0\F2\
\FC \E8 \F0\E0\F1\EA\EE\EC\EC\E5\ED\F2\E8\F0\EE\E2\E0\F2\FC \EE\E4\ED\F3 \E8\E7 \EF\E5\F0\E2\FB\F5 \E4\E2\F3\F5 \E2\E0\F0\E0\E8\ED\F2\EE\E2 \EF\EE \ED\E5\EE\
\E1\F5\EE\E4\E8\EC\EE\F1\F2\E8. \CA \E4\EE\EF\EE\EB\ED\E8\F2\E5\EB\FC\ED\FB\EC \E2\E0\F0\E8\E0\ED\F2\E0\EC \E4\E0\ED\FB \EA\EE\EC\EC\E5\ED\F2\E0\F0\E8\E8 \E4\
\EB\FF \F7\E5\E3\EE \EE\ED\E8 \ED\F3\E6\ED\FB.\r\
\n# \C4\EB\FF \E2\E5\F0\F1\E8\E9 ROS < 7.17\r\
\n#:foreach i in=[find where disabled=no and is-responder!=yes] do={\r\
\n# \C8\F1\EA\EB\FE\F7\E8\F2\FC \EF\EE\E4\EA\EB\FE\F7\E5\ED\E8\E5 wireguard-client \EF\EE \E8\EC\E5\ED\E8 \E8\ED\F2\E5\F0\F4\E5\E9\F1\E0 \F7\F2\EE\E1\FB \F1\
\EA\F0\E8\EF\F2 \E5\E3\EE \ED\E8\EA\EE\E3\E4\E0 \ED\E5 \F2\F0\EE\E3\E0\EB\r\
\n#:foreach i in=[find where disabled=no and responder!=yes and interface!=\"wireguard-client\"] do={\r\
\n:foreach i in=[find where disabled=no and responder!=yes] do={\r\
\n :local LocalTx [get \$i tx]\r\
\n :local LocalRx [get \$i rx]\r\
\n :local LastHandshake [get \$i last-handshake]\r\
\n :if (([:tostr \$LastHandshake] = \"\") or ((\$LastHandshake > [:totime \"2m30s\"]) and (\$Rx->[:tostr \$i] = \$LocalRx))) do={\r\
\n :local rawHeader [:rndstr length=4 from=123456789abcdef]\r\
\n :local EndpointAddress [get \$i endpoint-address]\r\
\n :local EndpointAddressIP \$EndpointAddress\r\
\n :local EndpointAddressIP [get \$i current-endpoint-address]\r\
\n :local name [get \$i name]\r\
\n :local wgDstPort [get \$i current-endpoint-port]\r\
\n :local interface [get \$i interface]\r\
\n \r\
\n # \D1\E1\F0\E0\F1\FB\E2\E0\E5\EC \E8\F1\F5\EE\E4\FF\F9\E8\E9 \EF\EE\F0\F2 \ED\E0 \F3\F0\EE\E2\ED\E5 \E8\ED\F2\E5\F0\F4\E5\E9\F1\E0\r\
\n /interface wireguard set \$interface listen-port=0\r\
\n :local srcport [/interface/wireguard/get \$interface listen-port];\r\
\n\r\
\n :log info (\"WG name is \$name, EndpointAddress \$EndpointAddress , LastHandshake \$LastHandshake, LastTx \" . \$Tx->[:tostr \$i] . \", CurrentTx \$Loc\
alTx, LastRx \" . \$Rx->[:tostr \$i] . \", CurrentRx \$LocalRx\")\r\
\n :log info (\"WG Currentinterface \$interface, srcport \$srcport, EndpointAddressIP \$EndpointAddressIP, DstPort \$wgDstPort\")\r\
\n :log info (\"Generating spam for RKN\")\r\
\n set \$i disabled=yes\r\
\n /tool traffic-generator stream remove [find]\r\
\n /tool traffic-generator packet-template remove [find]\r\
\n :delay 1\r\
\n /tool/traffic-generator/packet-template/add header-stack=mac,ip,udp,raw ip-dst=\$EndpointAddressIP name=packet-template-wg raw-header=\$rawHeader speci\
al-footer=no udp-dst-port=\$wgDstPort udp-src-port=\$srcport\r\
\n :delay 1\r\
\n /tool traffic-generator stream add disabled=no mbps=1 name=stream1 id=3 packet-size=1450 pps=0 tx-template=packet-template-wg\r\
\n :delay 1\r\
\n /tool traffic-generator quick duration=4\r\
\n :delay 1\r\
\n\r\
\n :log info (\"Starting WG \$EndpointAddress\")\r\
\n set \$i endpoint-address=\$EndpointAddress\r\
\n set \$i disabled=no\r\
\n }\r\
\n :set (\$Tx->[:tostr \$i]) \$LocalTx\r\
\n :set (\$Rx->[:tostr \$i]) \$LocalRx\r\
\n}"
/system scheduler
add interval=2m name=PushWG on-event="/system/script/ run PushWG" policy=read,write,policy,test,sniff,sensitive start-time=startup
@Cykooz
Copy link

Cykooz commented Nov 12, 2024

:local LastHandshake [get $i last-handshake]

У меня это не работает как ожидается, т.к. хендшейки не проходят, скорее всего из-за блокировки. Из-за этого last-handshake в роутере у меня всегда 00:00:00. При этом сам WG-тунель работает нормально.

Может тут лучше использовать более явную проверку на то, что тунель работает или нет. Например посылать через него запрос куда-то в интернет.

PS: На сервере у меня самый обычный WG, без доп. функций для обхода блокировок, может поэтому хендшейки от него не доходят до роутера. Сам сервер видит хендшейки от роутера.

@wiktorbgu
Copy link
Author

Не встречал такого, даже с заворачиванием хендшейков в другой туннель счетчики ходят.
Версия ROS последняя?
А пробовали открыть порт входящий в брандмауэре для интерфейса WG?

@Cykooz
Copy link

Cykooz commented Nov 12, 2024

Прошивка 7.16.1.
До блокировки WG хендшейки нормально "бегали". Я даже ориентировался по ним, что что-то не так с тунелем.
Сейчас у меня ещё есть тунель внутри России, который не блокируется - там всё нормально с хендшейками, даже не смотря на то что один из peer-ов сидит за провайдерским NAT-ом с серым IP. Ничего специального, вроде открытия портов, я не делал для этого.
К тому же, как понима, порт в роутере нет смысла открывать, он автоматом должен быть открыт иначе как же WG будет работать. Но для проверки я разрешил в фаерволе input на порт, который слушает WG интерфейс. Трафик в нём идёт, но хендшейки не фиксируются.

@Cykooz
Copy link

Cykooz commented Nov 12, 2024

При этом параметры Rx и Tx в статистике пира тоже по нулям.

@wiktorbgu
Copy link
Author

У меня ощущение, что он даже и не работает, если даже трафик не считает) можем попробовать разобраться, в телегу закиньте скринов

@Cykooz
Copy link

Cykooz commented Nov 12, 2024

Трафик идёт, но его видно только в статистике WG интерфейса, а в пире аналогичная статистика по нулям. Специально traceroute-ом проверял, что запросы идут через WG, а не напрямую в интернет.

@q000p
Copy link

q000p commented Dec 7, 2024

изображение

@q000p
Copy link

q000p commented Dec 7, 2024

На двух нижних работает статистика, на двух верхних - нет.

@skylevels
Copy link

skylevels commented Jan 22, 2025

Приветствую! Вышла ROS 7.17, на ней скрипт не отрабатывает, в логах просто: executing script from scheduler failed, please check it manually
выскакивает сразу после: traffic generator stream added by scheduler:wg-rkn (*1 = /tool traffic-generator stream add disabled=no id=3 mbps=1 name=stream1 packet-size=1450 pps=0 tx-template=packet-template-wg)

@Cykooz
Copy link

Cykooz commented Jan 22, 2025

@skylevels Полагаю что следует почитать про device-mode. В нем как раз по дефолту отключен трафик-генератор. Надо как-то его отдельно включать.

@skylevels
Copy link

skylevels commented Jan 22, 2025

@Cykooz Дело не в этом. Генератор трафика включен 100%. Поднимаю туннель на один и тотже ip адрес из разных городов. РКН блочит трафик, причем только от некоторых (иначе было бы подозрение на кривые руки). То-есть условие проверки скрипта благоприятные. Но вот на 3х микротах, где наблюдается эффект ТСПУ скрипт выкидывает ошибку. Везде версия 7.17 стабильная. Подозрение что в ROS что-то наковыряли, либо в скрипте ошибка =(

@wiktorbgu
Copy link
Author

ROS тут ни при чем....

@Cykooz
Copy link

Cykooz commented Jan 22, 2025

@skylevels тогда попробуйте запустить скрипт из терминала, так он хотя бы какие-то детали по ошибке покажет

@GentleFly
Copy link

GentleFly commented May 7, 2025

Спасибо!
RouterOS 7.18.2. У меня заработал.

До апокалипсиса в Моск. области, как то работала. Почему, мне было не понятно, так как с телефонов, через wifi этого же роутера не работало, с тем же удаленным сервером. Во время "апокалипсиса" роутер выпал из сети на пару дней ..
Я к тому, что вы выставили в "System - Scheduler" каждые пять минут. Есть подозрение, что в некоторых случаях будет достаточно раз в сутки. У себя выставил запуск каждые 24 часа. Посмотрим.

UPD00:
У меня за работоспособностью WireGuard сети наблюдает Netwatch:

/tool netwatch
add comment=wireguard.example.org disabled=no down-script="/tool e-mail send\
    \_to=example@example.ru subject=\"WireGuard\" body=\"WireGuard router\
    \_not respond\"" host=172.30.0.1 test-script="" type=simple up-script="/to\
    ol e-mail send to=example@example.ru subject=\"WireGuard\" body=\"Wir\
    eGuard router is online\""

UPD01:
Может, когда удаленный хост (в моем случае 172.30.0.1) в сети WireGuard не доступен, тогда и запускать скрипт.

UPD02:
Отвалился недели через 2-3. Видимо раз в сутки мало. Поставил на запуск каждый час. Посмотрим.

UPD03:
Отваливаться стал чаще. Сократил до 5 минут.

@whiteo
Copy link

whiteo commented May 10, 2025

:local name [get $i name] тоже нет в ROS < 7.17

@AlexDerkachev
Copy link

Спасибо! RouterOS 7.18.2. У меня заработал.

До апокалипсиса в Моск. области, как то работала. Почему, мне было не понятно, так как с телефонов, через wifi этого же роутера не работало, с тем же удаленным сервером. Во время "апокалипсиса" роутер выпал из сети на пару дней .. Я к тому, что вы выставили в "System - Scheduler" каждые пять минут. Есть подозрение, что в некоторых случаях будет достаточно раз в сутки. У себя выставил запуск каждые 24 часа. Посмотрим.

UPD00: У меня за работоспособностью WireGuard сети наблюдает Netwatch:

/tool netwatch
add comment=wireguard.example.org disabled=no down-script="/tool e-mail send\
    \_to=example@example.ru subject=\"WireGuard\" body=\"WireGuard router\
    \_not respond\"" host=172.30.0.1 test-script="" type=simple up-script="/to\
    ol e-mail send to=example@example.ru subject=\"WireGuard\" body=\"Wir\
    eGuard router is online\""

UPD01: Может, когда удаленный хост (в моем случае 172.30.0.1) в сети WireGuard не доступен, тогда и запускать скрипт.

UPD02: Отвалился недели через 2-3. Видимо раз в сутки мало. Поставил на запуск каждый час. Посмотрим.

Вот бы ещё скриптик без этих кривых переносов, может быть rsc экспорт сюда выложите?

@xdenb43
Copy link

xdenb43 commented Jun 20, 2025

Вот бы ещё скриптик без этих кривых переносов, может быть rsc экспорт сюда выложите?

Так все ж выложено в Вашей же цитате)))

Поделюсь своим.
У меня скрипт сам прописывается в планировщик, работает на разных микротиках на версиях RoS 7.18+
Есть форк скрипта Виктора

Также есть нетфоч, который мониторит состояние ВПН и кидает ошибку в лог.
Экспорт

/tool netwatch
add disabled=no down-script="" host=10.2.0.1 http-codes="" name="vpn proton" test-script="" type=simple up-script=""

Далее отдельный скрипт мониторит лог, и если видит ключевые слова - кидает уведомление в телеграм

@9vvk
Copy link

9vvk commented Feb 1, 2026

Пора модернизировать скрипт
https://github.com/bol-van/zapret2/blob/master/init.d/custom.d.examples.linux/50-wg4all

update
Не.
Такое не сделать скриптом, надо через NFQWS прогонять

@Medium1992
Copy link

Пора модернизировать скрипт https://github.com/bol-van/zapret2/blob/master/init.d/custom.d.examples.linux/50-wg4all

update Не. Такое не сделать скриптом, надо через NFQWS прогонять

https://gist.github.com/Medium1992/b6aab2ff51153185b1c5793fa73713d0

@Medium1992
Copy link

https://github.com/bol-van/zapret2/blob/master/init.d/custom.d.examples.linux/50-wg4all

Предложенная тут стратегия не пробивает всё равно, в итоге запретом просто придется сделать аналог поведения амнезии 1.5, стратегия получится не малых размеров) Но запрет да, будет перед каждым хендшейком делать мусор, вообще я уже сделал это в своем контейнере
https://github.com/Medium1992/mihomo-proxy-ros

ENVs

ZAPRET2_WG_CMD - стратегия так сказать мусора перед WG хендшейком, по умолчанию стратегия такая `--blob=quic_vk:@/zapret-fakebin/quic_initial_vk_com.bin --payload wireguard_initiation --lua-desync=fake:blob=quic_vk:repeats=6`

ZAPRET2_WG_DST - заполняются IP:PORT,IP:PORT,IP:PORT WG серверов, трафик udp на эти ip:port пойдет через очередь запрета и будет обработан стратегией ZAPRET2_WG_CMD, также он в исключении NAT и не попадает в михомо, поэтому ответные пакеты поступят непосредственно на интерфейс микрота минуя контейнер

Например у вас в WG пире указан
Endpoint: 162.159.192.1
Endpoint port: 4500
чтобы пропустить трафик через контейнер только пакетов инициализации нужно добавить правило mangle с отправкой хендшейка в таблицу маршрутизации с контейнером

/ip firewall mangle
add action=mark-routing chain=output dst-address=162.159.192.1 dst-port=4500 new-routing-mark=MihomoProxyRoS packet-size=176 passthrough=no protocol=udp

А ENV

/container envs
add key=ZAPRET2_WG_DST list=MihomoProxyRoS value=162.159.192.1:4500

Ну и если просто скриптом, то выше привел скрипт для ipv4 аналог AWG 1.5

@flow-contr0l
Copy link

Если микротик в роли wg сервера скрипт работать не будет?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment