Network equipment manufacturers are slowly moving towards a universal API for setting and collecting indicators: there is NETCONF , OpenConfig , there is software for importing MIBs, the same setting using SNMP has existed for a long time. But I will not touch on these high matters, but will simply share a way to automate the configuration of network equipment - in case of mass opening of branches, for example,
For illustration, I use D-Link DFL-800 in an imaginary central office and MikroTik RB951UI-2HnD on the periphery. In particular, let's set up an IPsec tunnel between them, since we are talking about a scenario with a new branch office.
The easiest way to configure MikroTik is using a configuration file, which is a script with a set of console commands. The described configuration principle is also suitable for other routers with a similar parameter setting mechanism.
First of all, we will get the configuration file of the already configured and working MikroTik, using the / export command. The file will be almost identical to backup, but it will not contain user names and MAC addresses.
To apply the configuration file on another router, some parameters need to be changed to unique ones. For this, the possibilities of a scripting language built into the firmware will be suitable - in particular, the removal of individual settings into variables. Here is an example script with a default gateway assignment:
local Gate "10.1.3.1" /ip route :if ([:len [/ip route find distance=1]] = 0) do={add distance=1 gateway=$Gate; } else={set [find distance=1] gateway=$Gate}
Initially, the idea was to create a universal script that can be used without resetting the configuration. Therefore, the code checks for the presence of a default route, after which it is created from scratch or changes. But this idea had to be abandoned, because in the latest firmware changes are constantly added to the default configuration. It is impossible to foresee everything, but with constant updating of the script, the sense of automation is lost.
It is more convenient to set the individual parameters of the router not in a text file, but in the GUI - then even people unfamiliar with the specifics of the device will manage to configure the router. What you need for a remote office, which can serve employees of different qualifications.
I draw the GUI in an AutoIT script. In this script, I also added the function of recalculating network masks (255.255.255.0 = / 24) and line by line filling in the configuration file. The development tool itself for solving the problem is not critical - you can use something more familiar to you personally.
The resulting configuration interface
Let us examine in more detail the function that forms the window.
All the features of the future configurator will require the following libraries, mainly from the AutoIT bundle:
RandomString to generate an IPsec key (not included, by Altlans );
GuiIPAddress for the IP input form;
GUIConstantsEx for running GUI;
The principles of working with the graphical interface in AutoIT can be found in the official documentation , but I will immediately turn to the result:
$hgui = GUICreate("" , 300, 600) GUICtrlCreateLabel(" ",2,2) $iploc1 = _GUICtrlIpAddress_Create($hgui, 10, 20) GUICtrlCreateLabel(" ",2,55) $iplocnet1 = _GUICtrlIpAddress_Create($hgui, 10, 75) GUICtrlCreateLabel(" ",2,115) $ipext1 = _GUICtrlIpAddress_Create($hgui, 10, 135) GUICtrlCreateLabel(" ",2,170) $ipextnet1 = _GUICtrlIpAddress_Create($hgui, 10, 190) GUICtrlCreateLabel(" ",2,225) $ipgate1 = _GUICtrlIpAddress_Create($hgui, 10, 245) GUICtrlCreateLabel(" 1",2,280) $DNS11 = _GUICtrlIpAddress_Create($hgui, 10, 300) GUICtrlCreateLabel(" 2",2,335) $DNS21 = _GUICtrlIpAddress_Create($hgui, 10, 355) GUICtrlCreateLabel(" ",2,390) $secret1 = GUICtrlCreateInput("",10, 410) GUICtrlCreateLabel(" ",2,445) $ports1 = GUICtrlCreateInput("5000,8000",10, 480) GUICtrlCreateLabel(" :",2,515) $mac1 = GUICtrlCreateInput("00:00:00:00:00:00",10, 535) $OK_Btn = GUICtrlCreateButton("", 75, 570, 70, 25) _GUICtrlIpAddress_Set($iploc1, $iploc8) _GUICtrlIpAddress_Set($ipext1, $ipext8) _GUICtrlIpAddress_Set($iplocnet1, "255.255.255.0") _GUICtrlIpAddress_Set($ipextnet1, "255.255.255.252") if $secret8 = "" Then GUICtrlSetData($secret1,_Crypto_GetRandomString(12,7)) Else GUICtrlSetData($secret1,$secret8) EndIf GUISetState(@SW_SHOW) While 1 $msg = GUIGetMsg() Select Case $msg = $GUI_EVENT_CLOSE Exit Case $msg = $OK_Btn ; "" $iploc=_GUICtrlIpAddress_Get($iploc1) $iplocnet=_GUICtrlIpAddress_Get($iplocnet1) $DNS1=_GUICtrlIpAddress_Get($DNS11) $DNS2=_GUICtrlIpAddress_Get($DNS21) $ipext=_GUICtrlIpAddress_Get($ipext1) $ipextnet=_GUICtrlIpAddress_Get($ipextnet1) $ipgate=_GUICtrlIpAddress_Get($ipgate1) $secret=GUICtrlRead($secret1) $ports=GUICtrlRead($ports1) $mac=GUICtrlRead($mac1) $iploc2=_GUICtrlIpAddress_GetArray($iploc1) ; $ipterm1 = $iploc2[0] & "." &$iploc2[1] & "." &$iploc2[2] & ".210" $ipterm2 = $iploc2[0] & "." &$iploc2[1] & "." &$iploc2[2] & ".220" if $iploc = 0 or $iplocnet=0 or $DNS1=0 or $DNS2=0 or $ipext=0 or $ipextnet=0 or $ipgate=0 or StringLen($secret)=0 then MsgBox(4160, "Information", " ") else GUIDelete() ExitLoop EndIf EndSelect WEnd
Then the logic of the program is as follows: the new text file is line by line filled with the obtained values ​​using FileWriteLine. The resulting script-config can be transferred to MikroTik.
#include <RandomString.au3> #include <GuiIPAddress.au3> #include <GUIConstantsEx.au3> #include <File.au3> _mikrot() func _mikrot ($iploc8="", $secret8="", $ipext8="") local $file = @TempDir &"\script.txt" $hgui = GUICreate("" , 300, 600) GUICtrlCreateLabel(" ",2,2) $iploc1 = _GUICtrlIpAddress_Create($hgui, 10, 20) GUICtrlCreateLabel(" ",2,55) $iplocnet1 = _GUICtrlIpAddress_Create($hgui, 10, 75) GUICtrlCreateLabel(" ",2,115) $ipext1 = _GUICtrlIpAddress_Create($hgui, 10, 135) GUICtrlCreateLabel(" ",2,170) $ipextnet1 = _GUICtrlIpAddress_Create($hgui, 10, 190) GUICtrlCreateLabel(" ",2,225) $ipgate1 = _GUICtrlIpAddress_Create($hgui, 10, 245) GUICtrlCreateLabel(" 1",2,280) $DNS11 = _GUICtrlIpAddress_Create($hgui, 10, 300) GUICtrlCreateLabel(" 2",2,335) $DNS21 = _GUICtrlIpAddress_Create($hgui, 10, 355) GUICtrlCreateLabel(" ",2,390) $secret1 = GUICtrlCreateInput("",10, 410) GUICtrlCreateLabel(" ",2,445) $ports1 = GUICtrlCreateInput("5000,8000",10, 480) GUICtrlCreateLabel(" :",2,515) $mac1 = GUICtrlCreateInput("00:00:00:00:00:00",10, 535) $OK_Btn = GUICtrlCreateButton("", 75, 570, 70, 25) _GUICtrlIpAddress_Set($iploc1, $iploc8) _GUICtrlIpAddress_Set($ipext1, $ipext8) _GUICtrlIpAddress_Set($iplocnet1, "255.255.255.0") _GUICtrlIpAddress_Set($ipextnet1, "255.255.255.252") if $secret8 = "" Then GUICtrlSetData($secret1,_Crypto_GetRandomString(12,7)) Else GUICtrlSetData($secret1,$secret8) EndIf GUISetState(@SW_SHOW) While 1 $msg = GUIGetMsg() Select Case $msg = $GUI_EVENT_CLOSE Exit Case $msg = $OK_Btn $iploc=_GUICtrlIpAddress_Get($iploc1) $iplocnet=_GUICtrlIpAddress_Get($iplocnet1) $DNS1=_GUICtrlIpAddress_Get($DNS11) $DNS2=_GUICtrlIpAddress_Get($DNS21) $ipext=_GUICtrlIpAddress_Get($ipext1) $ipextnet=_GUICtrlIpAddress_Get($ipextnet1) $ipgate=_GUICtrlIpAddress_Get($ipgate1) $secret=GUICtrlRead($secret1) $ports=GUICtrlRead($ports1) $mac=GUICtrlRead($mac1) $iploc2=_GUICtrlIpAddress_GetArray($iploc1) ; $ipterm1 = $iploc2[0] & "." &$iploc2[1] & "." &$iploc2[2] & ".210" $ipterm2 = $iploc2[0] & "." &$iploc2[1] & "." &$iploc2[2] & ".220" if $iploc = 0 or $iplocnet=0 or $DNS1=0 or $DNS2=0 or $ipext=0 or $ipextnet=0 or $ipgate=0 or StringLen($secret)=0 then MsgBox(4160, "Information", " ") else GUIDelete() ExitLoop EndIf EndSelect WEnd $temp1=_Subnet($iploc, $iplocnet) $iplocnet=$temp1[1]&"/"&$temp1[6] $temp1=_Subnet($ipext, $ipextnet) $ipext=$ipext&"/"&$temp1[6] If Not _FileCreate($file) Then MsgBox(4096, "Error", " :" & @error) EndIf FileOpen ( $file, 2) FileWriteLine ( $file, "local locIP """&$iploc&""";") FileWriteLine ( $file, "local Net """&$iplocnet&""";") FileWriteLine ( $file, "local DNS1 """& $DNS1 & """;") FileWriteLine ( $file, "local DNS2 """&$DNS2&""";") FileWriteLine ( $file, "local IP """&$ipext&"""") FileWriteLine ( $file, "local Gate """&$ipgate&"""") FileWriteLine ( $file, "local MAC """&$mac&"""") FileWriteLine ( $file, "local secret """&$secret&"""") FileWriteLine ( $file, "local BankPorts """&$ports&""" ") FileWriteLine ( $file, "local term1 """&$ipterm1&"""") FileWriteLine ( $file, "local term2 """&$ipterm2&""" ") FileWriteLine ( $file, '/interface set ether1 name=ether1-gateway;') FileWriteLine ( $file, '/interface set ether2 name=ether2-master-local;') FileWriteLine ( $file, '/interface set ether3 name=ether3-slave-local;') FileWriteLine ( $file, '/interface set ether4 name=ether4-slave-local;') FileWriteLine ( $file, '/interface set ether5 name=ether5-slave-local;') FileWriteLine ( $file, '/interface ethernet set ether3-slave-local master-port=ether2-master-local;') FileWriteLine ( $file, '/interface ethernet set ether4-slave-local master-port=ether2-master-local;') FileWriteLine ( $file, '/interface ethernet set ether5-slave-local master-port=ether2-master-local;') FileWriteLine ( $file, '/interface bridge add name=bridge-local disabled=no auto-mac=no protocol-mode=rstp;') FileWriteLine ( $file, ':local bMACIsSet 0;') FileWriteLine ( $file, ':foreach k in=[/interface find] do={:local tmpPort [/interface get $k name];') FileWriteLine ( $file, ':if ($bMACIsSet = 0) do={:if ([/interface get $k type] = "ether") do={/interface bridge set "bridge-local" admin-mac=[/interface ethernet get $tmpPort mac-address];') FileWriteLine ( $file, ':set bMACIsSet 1;}}') FileWriteLine ( $file, ':if (!($tmpPort~"bridge" || $tmpPort~"ether1" || $tmpPort~"slave")) do={') FileWriteLine ( $file, '/interface bridge port add bridge=bridge-local interface=$tmpPort;}} ') FileWriteLine ( $file, '/interface wireless set [ find name=wlan1 ] band=2ghz-b/g/n channel-width=20/40mhz-Ce country=japan disabled=no distance=indoors mode=ap-bridge ssid=MikroTik wireless-protocol=802.11;') FileWriteLine ( $file, '/interface wireless security-profiles') FileWriteLine ( $file, 'set [ find default=yes ] authentication-types=wpa-psk group-ciphers=tkip \') FileWriteLine ( $file, ' mode=dynamic-keys unicast-ciphers=tkip wpa-pre-shared-key=\') FileWriteLine ( $file, ' MegaWiFiKey wpa2-pre-shared-key=MegaWiFiKey') FileWriteLine ( $file, '/ip ipsec proposal set [ find default=yes ] auth-algorithms=md5 lifetime=1h') FileWriteLine ( $file, '/ip pool') FileWriteLine ( $file, 'add name=default-dhcp ranges=("$locIP". "1". "-". "$locIP". "00");') FileWriteLine ( $file, '/ip dhcp-server add address-pool=default-dhcp disabled=no interface=bridge-local name=default') FileWriteLine ( $file, '/ip dhcp-server network add address=$Net comment="default configuration" dns-server="$locIP,8.8.8.8" gateway=$locIP netmask=24') FileWriteLine ( $file, '/ip dns') FileWriteLine ( $file, 'set allow-remote-requests=yes servers=("$DNS1". ",". "$DNS2")') FileWriteLine ( $file, '/ip firewall address-list') FileWriteLine ( $file, ':if ([:len [/ip firewall address-list find list=local]] = 0) do={add address=$Net list=local;') FileWriteLine ( $file, '} else={set [find list=local] address=$Net;}') FileWriteLine ( $file, ':if ([:len [/ip firewall address-list find list=office]] = 0) do={add address=10.0.0.0/24 list=office;}') ; FileWriteLine ( $file, ':if ([:len [/ip firewall address-list find list=remote]] = 0) do={add address=1.2.3.4 list=remote comment=office1.domain.ru;') FileWriteLine ( $file, 'add address=1.2.3.5 list=remote comment=office2.domain.ru;') FileWriteLine ( $file, 'add address=10.0.0.0/24 list=remote;}') FileWriteLine ( $file, '/ip address') FileWriteLine ( $file, 'add address="$locIP/24" interface=bridge-local') FileWriteLine ( $file, ':if ([:len [/ip address find interface=ether1-gateway]] = 0) do={add address=$IP interface=ether1-gateway;') FileWriteLine ( $file, '} else={set [find interface=ether1-gateway] address=$IP;}') FileWriteLine ( $file, '/ip route') FileWriteLine ( $file, ':if ([:len [/ip route find distance=1]] = 0) do={add distance=1 gateway=$Gate;') FileWriteLine ( $file, '} else={set [find distance=1] gateway=$Gate}') FileWriteLine ( $file, ':delay 1000ms;') FileWriteLine ( $file, '/ip ipsec peer') FileWriteLine ( $file, '/ip ipsec proposal set default auth-algorithms=md5 enc-algorithms=3des') FileWriteLine ( $file, ':if ([:len [/ip ipsec peer find lifetime=8h]] = 0) do={add address=1.2.3.4/32 lifetime=8h nat-traversal=yes secret=$secret enc-algorithm=3des hash-algorithm=md5 comment=office;') FileWriteLine ( $file, '} else={set [/ip ipsec peer find lifetime=8h] address=1.2.3.5/32 nat-traversal=yes secret=$secret enc-algorithm=3des hash-algorithm=md5 comment=office;}') FileWriteLine ( $file, '/ip ipsec policy') FileWriteLine ( $file, '/ip ipsec proposal set default auth-algorithms=md5 enc-algorithms=3des') FileWriteLine ( $file, ':if ([:len [/ip ipsec policy find dst-address=10.0.0.0/24]] = 0) do={add dst-address=10.0.0.0/24 sa-dst-address=188.93.243.170 sa-src-address=[/ip route get [find gateway=ether1-gateway] pref-src] src-address=$Net tunnel=yes comment=office proposal=default;') FileWriteLine ( $file, '} else={set [find dst-address=10.0.0.0/24] sa-dst-address=1.2.3.4 sa-src-address =[/ip route get [find gateway=ether1-gateway] pref-src] src-address=$Net tunnel=yes comment=office;} ') FileWriteLine ( $file, '/ip service') FileWriteLine ( $file, 'set telnet disabled=yes') FileWriteLine ( $file, 'set ftp disabled=yes') FileWriteLine ( $file, 'set www port=80') FileWriteLine ( $file, 'set api disabled=yes') FileWriteLine ( $file, 'set api-ssl disabled=yes') FileWriteLine ( $file, 'set www-ssl disabled=yes') FileWriteLine ( $file, '/system clock manual') FileWriteLine ( $file, 'set time-zone=+03:00') FileWriteLine ( $file, '/system leds') FileWriteLine ( $file, 'set 0 interface=wlan1') FileWriteLine ( $file, '/system ntp client') FileWriteLine ( $file, 'set enabled=yes primary-ntp=61.67.210.241 secondary-ntp=205.171.76.135') FileWriteLine ( $file, '/system script') FileWriteLine ( $file, ':if ([:len [/system script find name=ipsec]] != 0) do={') FileWriteLine ( $file, 'remove ipsec') FileWriteLine ( $file, '}') ; IPsec . ; keepalive ; FileWriteLine ( $file, 'add name=ipsec policy=reboot,read,write,policy,test,password,sniff,sensitive \') FileWriteLine ( $file, ' source=":local RemoteGw \" DFL\";\r\') FileWriteLine ( $file, ' \n:local LocalGw [/ip route get [find gateway=\"bridge-local\"] pref-src];\') FileWriteLine ( $file, ' \r\') FileWriteLine ( $file, ' \n:local currentIP [/ip route get [find gateway=\"ether1-gateway\"] pref-s\') FileWriteLine ( $file, ' rc];\r\') FileWriteLine ( $file, ' \n:local Ip1 [:resolve office1.domain.ru];\r\') FileWriteLine ( $file, ' \n:local Ip2 [:resolve office2.domain.ru];\r\') FileWriteLine ( $file, ' \n### Check office IPs ###\r\') FileWriteLine ( $file, ' \n:local Ip [/ip firewall address-list get [find comment=office1.dom\') FileWriteLine ( $file, ' ain.ru] address];\r\') FileWriteLine ( $file, ' \n:if (\$Ip!=\$Ip2) do={\r\') FileWriteLine ( $file, ' \n/ip firewall address-list set [find comment=office1.domain.ru] addr\') FileWriteLine ( $file, ' ess=\$Ip2;\r\') FileWriteLine ( $file, ' \n}\r\') FileWriteLine ( $file, ' \n:set Ip [/ip firewall address-list get [find comment=office2.domain\') FileWriteLine ( $file, ' .ru] address];\r\') FileWriteLine ( $file, ' \n:if (\$Ip!=\$Ip1) do={\r\') FileWriteLine ( $file, ' \n/ip firewall address-list set [find comment=office2.domain.ru] addr\') FileWriteLine ( $file, ' ess=\$Ip1;\r\') FileWriteLine ( $file, ' \n}\r\') FileWriteLine ( $file, ' \n### Check ipsec status ###\r\') FileWriteLine ( $file, ' \n:local Status [/ping \$RemoteGw count=1 src-address=\$LocalGw];\r\') FileWriteLine ( $file, ' \n### ipsec is down ###\r\') FileWriteLine ( $file, ' \n:if (\$Status=0) do={\r\') FileWriteLine ( $file, ' \n### ping Ip2 and Ip1 ###\r\') FileWriteLine ( $file, ' \n:local StatusIp1 [/ping \$Ip1 count=2 src-address=\$currentIP];\r\') FileWriteLine ( $file, ' \n:local StatusIp2 [/ping \$Ip2 count=2 src-address=\$currentIP];\r\') FileWriteLine ( $file, ' \n:if (\$StatusIp1>0 or \$StatusIp2>0) do={\r\') FileWriteLine ( $file, ' \n:if (\$StatusIp1>0) do={\r\') FileWriteLine ( $file, ' \n### Ping Ip1 ok ###\r\') FileWriteLine ( $file, ' \n/ip ipsec policy set [find sa-dst-address=\$Ip2] sa-dst-address \$Ip1;\r\') FileWriteLine ( $file, ' \n/ip ipsec peer set [find address=\"\$Ip2/32\"] address \"\$Ip1/32\";\r\') FileWriteLine ( $file, ' \n:log info (\"Reset tunnel: Status IP Office1: \$StatusIp1\");\r\') FileWriteLine ( $file, ' \n} else={\r\') FileWriteLine ( $file, ' \n### Ping Ip1 NOT ok ###\r\') FileWriteLine ( $file, ' \n/ip ipsec policy set [find sa-dst-address=\$Ip1] sa-dst-address \$Ip2;\r\') FileWriteLine ( $file, ' \n/ip ipsec peer set [find address=\"\$Ip1/32\"] address \"\$Ip2/32\";\r\') FileWriteLine ( $file, ' \n:log info (\"Reset tunnel: Status IP Office2: \$StatusIp2\");\r\') FileWriteLine ( $file, ' \n}\r\') FileWriteLine ( $file, ' \n/ip ipsec installed-sa flush;\r\') FileWriteLine ( $file, ' \n/ip ipsec remote-peers kill-connections;\r\') FileWriteLine ( $file, ' \n:local Status [/ping \$RemoteGw count=2 src-address=\$LocalGw];\r\') FileWriteLine ( $file, ' \n:if (\$Status=0) do={\r\') FileWriteLine ( $file, ' \n:log info (\"check for misconfiguration\");\r\') FileWriteLine ( $file, ' \n### Check local IP ###\r\') FileWriteLine ( $file, ' \n:set Ip [/ip ipsec policy get [find comment=office] sa-src-address];\r\') FileWriteLine ( $file, ' \n:if (\$Ip!=\$currentIP) do={\r\') FileWriteLine ( $file, ' \n/ip ipsec policy set [find comment=office] sa-src-address=\$currentIP;\r\') FileWriteLine ( $file, ' \n:log info (\"misconfiguration: policy, local address\");\r\') FileWriteLine ( $file, ' \n}\r\') FileWriteLine ( $file, ' \n### Check remote IP ###\r\') FileWriteLine ( $file, ' \n:set Ip [/ip ipsec policy get [find comment=office] sa-dst-address];\r\') FileWriteLine ( $file, ' \n:if (\$Ip!=\$Ip1 and \$Ip!=\$Ip2) do={\r\') FileWriteLine ( $file, ' \n:if (\$StatusIp1>0) do={\r\') FileWriteLine ( $file, ' \n/ip ipsec policy set [find comment=office] sa-dst-address=\$Ip1;\r\') FileWriteLine ( $file, ' \n} else={/ip ipsec policy set [find comment=office] sa-dst-address=\$Ip2;\') FileWriteLine ( $file, ' }\r\') FileWriteLine ( $file, ' \n:log info (\"misconfiguration: policy, remote address\");\r\') FileWriteLine ( $file, ' \n}\r\') FileWriteLine ( $file, ' \n:set Ip [/ip ipsec peer get [find comment=office] address];\r\') FileWriteLine ( $file, ' \n:if (\$Ip!=\$Ip1.\"/32\" and \$Ip!=\$Ip2.\"/32\") do={\r\') FileWriteLine ( $file, ' \n:if (\$StatusIp1>0) do={\r\') FileWriteLine ( $file, ' \n/ip ipsec peer set [find comment=office] address=\$Ip1;\r\') FileWriteLine ( $file, ' \n} else={/ip ipsec peer set [find comment=office] address=\"\$Ip1/32\";}\r\') FileWriteLine ( $file, ' \n:log info (\"misconfiguration: peer\");\r\') FileWriteLine ( $file, ' \n}\r\') FileWriteLine ( $file, ' \n} else={:log info (\"Ipsec tunnel status: OK\");}\r\') FileWriteLine ( $file, ' \n} else={:log info (\"Ipsec tunnel status: Office is DOWN!\");}\r\') FileWriteLine ( $file, ' \n} else={:log info (\"Ipsec tunnel status: OK\");}"') ; ntp, FileWriteLine ( $file, ':if ([:len [/system script find name=ntp]] != 0) do={') FileWriteLine ( $file, 'remove ntp') FileWriteLine ( $file, '}') FileWriteLine ( $file, 'add name=ntp policy=\') FileWriteLine ( $file, 'ftp,reboot,read,write,policy,test,password,sniff,sensitive source=":local \') FileWriteLine ( $file, 'ntp1 [:resolve pool.ntp.org];\r\') FileWriteLine ( $file, '\n:local ntp2 [:resolve time.windows.com];\r\') FileWriteLine ( $file, '\n:local Ip [/system ntp client get primary-ntp];\r\') FileWriteLine ( $file, '\n:if (\$Ip!=\$ntp1) do={\r\') FileWriteLine ( $file, '\n/system ntp client set primary-ntp=\$ntp1;\r\') FileWriteLine ( $file, '\n}\r\') FileWriteLine ( $file, '\n:set Ip [/system ntp client get secondary-ntp];\r\') FileWriteLine ( $file, '\n:if (\$Ip!=\$ntp2) do={\r\') FileWriteLine ( $file, '\n/system ntp client set secondary-ntp=\$ntp2;\r\') FileWriteLine ( $file, '\n}"') FileWriteLine ( $file, '/system scheduler') FileWriteLine ( $file, ':if ([:len [/system scheduler find name=ipsec-test]] = 0) do={') FileWriteLine ( $file, 'add interval=3m name=ipsec-test on-event="/system script run ipsec" policy=\') FileWriteLine ( $file, ' reboot,read,write,policy,test,password,sniff,sensitive') FileWriteLine ( $file, ' }') FileWriteLine ( $file, ':if ([:len [/system scheduler find name=ntp]] = 0) do={') FileWriteLine ( $file, 'add interval=1d name=ntp on-event="/system script run ntp" policy=\') FileWriteLine ( $file, ' reboot,read,write,policy,test,password,sniff,sensitive') FileWriteLine ( $file, ' }') FileWriteLine ( $file, '/ip firewall nat') FileWriteLine ( $file, 'add chain=srcnat comment=ipsec dst-address-list=office out-interface=\') FileWriteLine ( $file, ' ether1-gateway src-address-list=local') FileWriteLine ( $file, 'add action=masquerade chain=srcnat comment=bank1 src-address=$term1 dst-port=$BankPorts out-interface=ether1-gateway protocol=tcp disable=yes') FileWriteLine ( $file, 'add action=masquerade chain=srcnat comment=bank2 src-address=$term2 dst-port=$BankPorts out-interface=ether1-gateway protocol=tcp disable=yes') FileWriteLine ( $file, 'add action=masquerade chain=srcnat comment="outbound icmp" out-interface=\') FileWriteLine ( $file, ' ether1-gateway protocol=icmp') FileWriteLine ( $file, 'add action=masquerade chain=srcnat comment="default configuration" disabled=\') FileWriteLine ( $file, ' yes out-interface=ether1-gateway') FileWriteLine ( $file, '/ip firewall filter') FileWriteLine ( $file, 'add chain=input comment="remote admin" dst-port=80,22,8291 src-address-list=remote in-interface=\') FileWriteLine ( $file, ' ether1-gateway protocol=tcp') FileWriteLine ( $file, 'add chain=input comment=icmp protocol=icmp') FileWriteLine ( $file, 'add chain=input comment="established, related" connection-state=established') FileWriteLine ( $file, 'add chain=input connection-state=related') FileWriteLine ( $file, 'add action=drop chain=input comment="drop other" in-interface=ether1-gateway') FileWriteLine ( $file, 'add chain=forward comment="established, related" connection-state=established') FileWriteLine ( $file, 'add chain=forward connection-state=related') FileWriteLine ( $file, 'add action=drop chain=forward comment="drop other" connection-state=invalid') FileWriteLine ( $file, '/ip dhcp-server lease') FileWriteLine ( $file, ':if ([:len [/ip dhcp-server lease find address=("$locIP". "1")]]>0) do={') FileWriteLine ( $file, 'set [/ip dhcp-server lease find address=("$locIP". "1")] address=("$locIP". "1") mac-address=$MAC;}') FileWriteLine ( $file, ':if ([:len [/ip dhcp-server lease find address=("$locIP". "1")]] = 0) do={add address=("$locIP". "1") mac-address=$MAC;}') FileWriteLine ( $file, '/user') FileWriteLine ( $file, 'set [find name=admin] password=MegaPassW0rd') fileclose($file) run("notepad "&$file) EndFunc ; . Func _Subnet($sIp, $sNetmask) Dim $netmaskbinary Dim $subnetaddarray[5] Dim $invmaskarray[5] Dim $broadcastaddarray[5] Dim $sSubnetinfo[7] Dim $subnetadd Dim $invmask Dim $broadcastadd ; Reads IP and Netmask to an array $iparray = StringSplit($sIp, ".") $netmaskarray = StringSplit($sNetmask, ".") ; Validates IP address For $i = 1 To 4 If Number($iparray[$i]) < 0 Or Number($iparray[$i]) > 255 Then SetError(1) Return (-1) EndIf Next ; Converts netmask into a decimal $netmaskdec = ($netmaskarray[1] * 16777216) + ($netmaskarray[2] * 65536) + ($netmaskarray[3] * 256) + $netmaskarray[4] ; Converts decimal netmask into binary (ex. 11111111111111111100000000000000) While $netmaskdec <> 0 $binmod = Mod($netmaskdec, 2) $netmaskbinary = $binmod & $netmaskbinary $netmaskdec = Int($netmaskdec / 2) WEnd ; Determines the "slash" value of the netmask $maskslash = StringInStr($netmaskbinary, "0", 1) - 1 ; Validates the "slash" value and netmask value If StringInStr(StringRight($netmaskbinary, 32 - $maskslash), "1") Then If $netmaskarray[4] = "255" Then $maskslash = 32 Else SetError(1) Return (-1) EndIf EndIf ; Creates arrays conatining subnet address, wilcard, and broadcast addresses For $i = 1 To $iparray[0] $subnetaddarray[$i] = BitAND($iparray[$i], $netmaskarray[$i]) $invmaskarray[$i] = BitNOT($netmaskarray[$i] - 256) $broadcastaddarray[$i] = BitOR($subnetaddarray[$i], $invmaskarray[$i]) Next ; Creates strings conatining subnet address, wilcard, and broadcast addresses $subnetadd = $subnetaddarray[1] & "." & $subnetaddarray[2] & "." & $subnetaddarray[3] & "." &$subnetaddarray[4] $invmask = $invmaskarray[1] & "." & $invmaskarray[2] & "." & $invmaskarray[3] & "." & $invmaskarray[4] $broadcastadd = $broadcastaddarray[1] & "." & $broadcastaddarray[2] & "." & $broadcastaddarray[3] & "." & $broadcastaddarray[4] If $maskslash = 32 Then $iprange = $iparray[1] & "." & $iparray[2] & "." & $iparray[3] & "." & $iparray[4] $hosts = 1 Else ; Determines the IP range for this subnet $iprange = $subnetaddarray[1] & "." & $subnetaddarray[2] & "." & $subnetaddarray[3] & "." & $subnetaddarray[4] + 1 & _ "-" & $broadcastaddarray[1] & "." & $broadcastaddarray[2] & "." & $broadcastaddarray[3] & "." & $broadcastaddarray[4] - 1 ; Calculates number of available hosts on this subnet $hosts = ($invmaskarray[4] + 1) * ($invmaskarray[3] + 1) * ($invmaskarray[2] + 1) * ($invmaskarray[1] + 1) - 2 EndIf $sSubnetinfo[1] = $subnetadd $sSubnetinfo[2] = $broadcastadd $sSubnetinfo[3] = $invmask $sSubnetinfo[4] = $iprange $sSubnetinfo[5] = $hosts $sSubnetinfo[6] = $maskslash Return ($sSubnetinfo) EndFunc Func _SameSub($sIp, $sSubadd, $sBroadadd) Dim $iparray[5] Dim $subaddarray[5] Dim $broadaddarray[5] $iparray = StringSplit($sIp, ".") $subaddarray = StringSplit($sSubadd, ".") $broadaddarray = StringSplit($sBroadadd, ".") For $i = 1 To 4 If Number($iparray[$i]) < 0 Or Number($iparray[$i]) > 255 Then SetError(1) Return (-1) EndIf If Number($subaddarray[$i]) < 0 Or Number($subaddarray[$i]) > 255 Then SetError(1) Return (-2) EndIf If Number($broadaddarray[$i]) < 0 Or Number($broadaddarray[$i]) > 255 Then SetError(1) Return (-3) EndIf Next $ipint = ($iparray[1] * 16777216) + ($iparray[2] * 65536) + ($iparray[3] * 256) + $iparray[4] $subaddint = ($subaddarray[1] * 16777216) + ($subaddarray[2] * 65536) + ($subaddarray[3] * 256) + $subaddarray[4] $broadaddint = ($broadaddarray[1] * 16777216) + ($broadaddarray[2] * 65536) + ($broadaddarray[3] * 256) + $broadaddarray[4] If $ipint > $subaddint And $ipint < $broadaddint Then Return (1) Else Return (0) EndIf EndFunc
It remains to execute the resulting script on MikroTik after the configuration has been reset, in any convenient way: via the / system script, use the saved file and reset the configuration as shown in the picture:
Now, to set up a new MikroTik, it is enough to launch the program, specify individual settings in the GUI, get the setup script and transfer it to the router. It remains to bring to mind the configuration of the router in the proposed central office.
Setting up the DFL is more convenient through the console. This type of setting is also amenable to automation, for example using the Plink tool from the creator of Putty .
The concept of transferring commands to an open console cannot be called ideal, but in the case of D-Link DFL, you can use its own “scripts”. As an example, consider the function that is used in conjunction with the previously described. If MikroTik needs to be configured from scratch, then on the DFL it is enough to create an IPsec tunnel and include it in the interface group in order to apply the built-in firewall rules.
The settings window is much simpler, because in our case DFL does not need to be configured from scratch.
To access the router via SSH, you will need Plink , as well as Pscp to transfer files — you just need to set the path to the executable files in the script.
local $_plink_loc = "\\server\share\plink.exe" local $scploc="\\server\share\pscp.exe"
When Plink and Pscp are working, there is a feature: if password authentication is used, then when you first connect or replace equipment, you will be asked to make a print in the registry. You can bypass the request by passing "Y" to the console window.
$_plinkhandle = Run(@comspec & " /c " & $_plink_loc & " -ssh admin@" & $_plinkserver &" -pw MegaPass","",@SW_HIDE,7) sleep (500) StdinWrite($_plinkhandle, "y"& @CR)
DFL works with objects at the group level. Since it is impossible to add an object to a group without listing all its members, I generate a script on the DFL, create a script, take it as a file and change it. :
script -create InterfaceGroup VPNs -name=vpns.sgs
SCP. script.sgs , D-Link SCP .
script -execute -name=script.sgs
script -remove -name=script.sgs
func _dfl($lanip8="",$PSK8="",$ipext8="") local $file = @TempDir &"\script.sgs" local $file1 = @TempDir &"\script1.sgs" if FileExists($file) then FileDelete($file) EndIf if FileExists($file1) then FileDelete($file1) EndIf ; . local $_plink_loc = "\\server\share\plink.exe" local $scploc="\\server\share\pscp.exe" Local $_plinkserver = " DFL" local $magazname local $magaznumber local $lanip local $ipext local $PSK $hgui = GUICreate(" DFL" , 300, 270) GUICtrlCreateLabel(" ",2,2) $lanip1 = _GUICtrlIpAddress_Create($hgui, 10, 20) GUICtrlCreateLabel(" ",2,45) $ipext1 = _GUICtrlIpAddress_Create($hgui, 10, 65) GUICtrlCreateLabel(" ",2,90) $secret1 = GUICtrlCreateInput("",10, 110) GUICtrlCreateLabel(" ",2,130) $name1=GUICtrlCreateInput("",10, 150) GUICtrlCreateLabel(" (77 NN88)",2,170) $number1=GUICtrlCreateInput("",10, 190) $OK_Btn = GUICtrlCreateButton("", 75,230 , 70, 25) if $PSK8 = "" Then GUICtrlSetData($secret1,_Crypto_GetRandomString(12,7)) Else GUICtrlSetData($secret1,$PSK8) EndIf _GUICtrlIpAddress_Set($ipext1, $ipext8) _GUICtrlIpAddress_Set($lanip1, $lanip8) GUISetState(@SW_SHOW) While 1 $msg = GUIGetMsg() Select Case $msg = $GUI_EVENT_CLOSE Exit Case $msg = $OK_Btn $lanip=_GUICtrlIpAddress_Get($lanip1) $ipext=_GUICtrlIpAddress_Get($ipext1) $PSK=GUICtrlRead($secret1) $magazname=GUICtrlRead($name1) $magaznumber=GUICtrlRead($number1) $lanip2=_GUICtrlIpAddress_GetArray($lanip1) ; if $lanip = 0 or $ipext=0 or StringLen($PSK)=0 then MsgBox(4160, "Information", " ") else if StringRegExp($magazname,"[0-9a-zA-Z_]") =0 then MsgBox(4160, "Information", " !") Else if $lanip2[3]<>1 Then MsgBox(4160, "Information", " .1 !") Else GUIDelete() ExitLoop EndIf EndIf EndIf EndSelect WEnd $_plinkhandle = Run(@comspec & " /c " & $_plink_loc & " -ssh admin@" & $_plinkserver &" -pw MegaPass","",@SW_HIDE,7) sleep (500) ;DFL . . ; , ... StdinWrite($_plinkhandle, "y"& @CR) sleep (500) StdinWrite($_plinkhandle, "script -remove -name=vpns.sgs "& @CR) sleep (500) StdinWrite($_plinkhandle, "script -remove -name=script.sgs "& @CR) sleep (500) ; - . StdinWrite($_plinkhandle, "script -create InterfaceGroup VPNs -name=vpns.sgs "& @CR) sleep (500) StdinWrite($_plinkhandle, "Exit " & @CR) sleep (250) ProcessClose("plink.exe") RunWait(@comspec & " /c " & $scploc & " -pw MegaPass admin@"&$_plinkserver&":script/vpns.sgs " & $file,"",@SW_HIDE,7) $line = FileReadLine($file,1) local $lannet=StringMid($lanip,1,StringLen($lanip)-1)&"0/24" FileOpen ( $file, 2) FileWriteLine ( $file, "cc AddressFolder VpnAdresses") FileWriteLine ( $file, "add IP4Address Pool"&$magaznumber&"_"&$magazname&" Address="&$lannet&" -silent") FileWriteLine ( $file, "add IP4Address Ip"&$magaznumber&"_"&$magazname&" Address="&$ipext&" -silent") FileWriteLine ( $file, "add IP4Address Router"&$magaznumber&"_"&$magazname&" Address="&$lanip&" -silent") FileWriteLine ( $file, "cc ..") FileWriteLine ( $file, "add PSK Key_"&$magaznumber&"_"&$magazname&" Type=ASCII PSKAscii="&$PSK&" Comments="&$PSK&" -silent") ; DFL FileWriteLine ( $file, "add IPsecTunnel Magaz_"&$magazname&" LocalNetwork=InterfaceAddresses/lannet RemoteNetwork=VpnAdresses/Pool"&$magaznumber&"_"&$magazname&" RemoteEndpoint=VpnAdresses/Ip"&$magaznumber&"_"&$magazname&" IKEAlgorithms=High IPsecAlgorithms=High AuthMethod=PSK PSK=Key_"&$magaznumber&"_"&$magazname&" PFS=PFS KeepAlive=Manual KeepAliveSourceIP=VpnAdresses/Router_Main KeepAliveDestinationIP=VpnAdresses/Router"&$magaznumber&"_"&$magazname&" index=57 -silent") $line=StringReplace ( $line, "add", "set" ,1,1 ) $line=StringReplace ( $line, " -silent", "" ,1,1 ) $line=StringReplace ( $line, " -force", "" ,1,1 ) $line=_StringInsert($line, ", "& "Magaz_"&$magazname, -1) FileWriteLine ( $file, $line) FileCLose($file) FileCopy($file,$file1) RunWait(@comspec & " /c " & $scploc & " -pw MegaPass " & $file1 & " admin@"&$_plinkserver&":script/script.sgs","",@SW_HIDE,7) $_plinkhandle = Run(@comspec & " /c " & $_plink_loc & " -ssh admin@" & $_plinkserver &" -pw QfJatp123","",@SW_HIDE,7) sleep (500) StdinWrite($_plinkhandle, "script -execute -name=script.sgs "& @CR) sleep (250) StdinWrite($_plinkhandle, "activate "& @CR) sleep (10000) StdinWrite($_plinkhandle, "commit "& @CR) sleep (250) StdinWrite($_plinkhandle, "exit "& @CR) sleep (250) ProcessClose("plink.exe") EndFunc
, .
DFL : full.bak config.bak. , . SCP . – .
#include <Date.au3> #Include <File.au3> Local $_plinkserver = " dfl" local $scploc="\\server\share\pscp.exe" local $path=@ScriptDir&"\" $date1=@YEAR&@MON&@MDAY local $file = $path &"config-"&$date1&".bak" $handle=Run(@comspec & " /c " & $scploc & " -pw MegaPass admin@"&$_plinkserver&":config.bak " & $file,"",@SW_HIDE,7) sleep (500) StdinWrite($_plinkhandle, "y"& @CR) sleep (500) $file = $path &"full-"&$date1&".bak" RunWait(@comspec & " /c " & $scploc & " -pw MegaPass admin@"&$_plinkserver&":full.bak " & $file,"",@SW_HIDE,7) ; ; , if FileExists($path &"full-"&$date1&".bak") and FileExists($file = $path &"config-"&$date1&".bak") Then $files = _FileListToArray($path, "*.bak", 1,True) $date=@YEAR&"/"&@MON&"/"&@MDAY $newdate=_DateAdd("D",-14,$date) $formatdate=StringSplit($newdate,"/") $newdate=$formatdate[1]&$formatdate[2]&$formatdate[3]&@HOUR&@MIN&@SEC If IsArray($files) Then For $i = 1 To UBound($files) - 1 $aTime = FileGetTime( $files[$i], 0, 1) If $aTime < $newdate Then FileDelete($files[$i]) EndIf Next EndIf EndIf
DFL.
, , - . SNMP API . Mikrotik . , .
– !
Source: https://habr.com/ru/post/321028/
All Articles