-
Notifications
You must be signed in to change notification settings - Fork 1
/
Meraki VPN Interactive Menu.rsc
288 lines (269 loc) · 8.94 KB
/
Meraki VPN Interactive Menu.rsc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
# Meraki VPN Interactive Menu
# Enable a L2TP client configured to connect to a Meraki from a Mikrotik Router
# Version 0.1.2
# Author: Dennis Cole III
# License: MIT
#
# Prerequisites:
# (Common Settings - these should always be enabled, firewall rule preference
# may need to be adjusted)
####
## Meraki profile
# /ppp profile add name=meraki use-encryption=required use-ipv6=no \
# use-mpls=no
##
## Set ipsec profile and proposal, 3des and aes128, group2 and group5
# /ip ipsec profile set [ find default=yes ] dh-group=modp1536,modp1024 \
# lifetime=8h
# /ip ipsec proposal set [ find default=yes ] \
# enc-algorithms=aes-128-cbc,3des lifetime=8h pfs-group=none
##
## Mark routing for traffic from only allowed sources
# /ip firewall mangle add action=mark-routing chain=prerouting \
# comment="Leave this enabled always" new-routing-mark=merakivpns \
# passthrough=yes src-address-list="Source VPN Addresses"
##
## Address List
## Sample of two shown below. Use as many or as few as needed.
# /ip firewall address-list add address=LOCALADDRESS1 \
# list="Source VPN Addresses"
# /ip firewall address-list add address=LOCALADDRESS2 \
# list="Source VPN Addresses"
####
# Per Client Settings (firewall rule preference may need to be adjusted):
# /interface l2tp-client add allow=pap comment=CLIENTNAME connect-to=\
# DESTINATION ipsec-secret=SECRET name=l2tp-out1 password=PASSWORD profile=\
# meraki use-ipsec=yes user="DOMAIN\\user||user@domain.com||user"
# /interface l2tp-client disable name=l2tp-out1
##
## Address List
## Sample of two shown below. Use as many or as few as needed.
# /ip firewall address-list add address=DSTADDRESS1 list=CLIENTNAME
# /ip firewall address-list add address=DSTADDRESS2 list=CLIENTNAME
##
## Firewall rule to NAT traffic for valid sources addresses to
## destination routes
# /ip firewall nat add action=masquerade chain=srcnat comment=CLIENTNAME \
# disabled=yes dst-address-list=CLIENTNAME out-interface=l2tp-out1 \
# src-address-list="Source VPN Addresses"
##
## Routes
## Sample of two shown below. Use as many or as few as needed.
# /ip route add comment=CLIENTNAME disabled=yes distance=1 dst-address=\
# DSTADDRESS1 gateway=l2tp-out1 routing-mark=merakivpns
# /ip route add comment=CLIENTNAME disabled=yes distance=1 dst-address=\
# DSTADDRESS2 gateway=l2tp-out1 routing-mark=merakivpns
####
# Function to get input
:global read do={:return}
# Funtion to enable or disable L2TP Client
:global changeClient do={
# Getting our NAT rules and routes
:local natRule [/ip firewall nat find where comment=$clientName]
:local routes [/ip route find where comment=$clientName]
# Boolean variables
:local l2tpInterfaceChangeStatus true
:local natRuleChangeStatus true
:local oneRouteChangeStatus
:local partialRouteChanges
:local allRoutesChangeStatus true
# Message and other variables
:local done "..OK!"
:local halfDone "..some failed!"
:local failed "..FAILED!"
:local lowerPrefix
:local upperPrefix
# Delay between command execution
:local delayTime 500ms
if ($change="enable") do={
:set lowerPrefix "en"
:set upperPrefix "En"
} else={
:set lowerPrefix "dis"
:set upperPrefix "Dis"
}
# L2TP Client Enable/Disable
if ($change="enable") do={
do {
/interface l2tp-client enable [find comment=$clientName]
} on-error={
:set $l2tpInterfaceChangeStatus false
}
} else={
do {
/interface l2tp-client disable [find comment=$clientName]
} on-error={
:set $l2tpInterfaceChangeStatus false
}
}
delay $delayTime
if ($l2tpInterfaceChangeStatus) do={
:put ($upperPrefix . "abling L2TP Client for $clientName." . $done)
} else={
:put ($upperPrefix . "abling L2TP Client for $clientName." . $failed)
}
# NAT Rule Change
if ($change="enable") do={
do {
/ip firewall nat enable [find comment=$clientName]
} on-error={
:set $natRuleChangeStatus false
}
} else={
do {
/ip firewall nat disable [find comment=$clientName]
} on-error={
:set $natRuleChangeStatus false
}
}
delay $delayTime
if ($natRuleChangeStatus) do={
:put ($upperPrefix . "abling NAT rule for $clientName." . $done)
} else={
:put ($upperPrefix . "abling NAT rule for $clientName." . $failed)
}
# Route Changes
delay $delayTime
:put ($upperPrefix . "abling routes for $clientName:")
delay $delayTime
foreach route in $routes do={
:set $oneRouteChangeStatus true
:local dstAddress [/ip route get value-name=dst-address \
[find where .id=$route]]
if ($change="enable") do={
do {
/ip route enable [find .id=$route]
} on-error={
:set $oneRouteChangeStatus false
}
} else={
do {
/ip route disable [find .id=$route]
} on-error={
:set $oneRouteChangeStatus false
}
}
delay $delayTime
:set $allRoutesChangeStatus ($oneRouteChangeStatus && \
$allRoutesChangeStatus)
if ($oneRouteChangeStatus) do={
:set $partialRouteChanges true
:put " - $dstAddress.$done"
} else={
:put " - $dstAddress.$done"
}
}
if ($allRoutesChangeStatus) do={:put ("Route changes" . $done)} else={
if ($partialRouteChanges) do={:put ("Route changes" . $halfDone)} else={
:put ("Routes changes" . $failed)
}
}
# Verification
if ($l2tpInterfaceChangeStatus && $natRuleChangeStatus && \
$allRoutesChangeStatus) do={
:put ("All rules for $clientName have been $lowerPrefix" . "abled" . $done)
if ($change="enable") do={
:put ("Checking status of the VPN connection...")
:local numberOfChecks 0
:local vpnIsUp
while ($numberOfChecks < 5) do={
:delay 5s
:set vpnIsUp [/interface l2tp-client get [find comment=$clientName] running]
if ($vpnIsUp) do={
:put ("VPN connection is UP!")
:set $numberOfChecks 5
} else={
:set $numberOfChecks ($numberOfChecks+1)
if ($numberOfChecks < 5) do={
:put ("VPN connection is not yet up. Try $numberOfChecks of 5 tries...")
} else={
:put ("VPN connection is not yet up. You may need to check your settings.")
}
}
}
}
} else={
if ($l2tpInterfaceChangeStatus || $natRuleChangeStatus || \
$allRoutesChangeStatus) do={
:put ("Some rules were not $lowerPrefix" . "abled.")
} else={
:put "All rule changes failed."
}
}
}
# Main routine
# Boolean variables
:local skipEnable false
# Message variables
:local goodbye "Goodbye!"
# Check for Active L2TP Clients
:local merakiL2tpActive [/interface l2tp-client find where profile="meraki" \
disabled=no]
# If there are Active L2TP Clients, we want to disable first.
foreach merakiClient in=$merakiL2tpActive do={
# Getting Info on the Active Client
:local clientName [/interface l2tp-client get \
[find where .id=$merakiClient] value-name=comment]
# Ask to disable Active Client
:local vpnIsUp [/interface l2tp-client get [find comment=$clientName] running]
if ($vpnIsUp) do={
:put "$clientName is currently enabled and the VPN connection is UP! Would you like to disable (Y/n)?"
} else={
:put "$clientName is currently enabled, however the VPN connection is down. Would you like to disable (Y/n)?"
}
:local userinput [$read]
if ( $userinput = "n" || $userinput = "N") do={
# We don't want to disable so we will end the script
:set $skipEnable true
:put $goodbye
} else={
# We will disable all rules
$changeClient clientName=$clientName change="disable"
# Do we want to enable another client?
:put "Do you want to enable another VPN (y/N)?"
:local userinput [$read]
if (!( $userinput = "y" || $userinput = "Y")) do={
:set $skipEnable true
:put $goodbye
}
}
}
# Now asking what VPN do we want to enable, that is, if we are not skipping
if (!$skipEnable) do={
:local merakiL2tpInactive [/interface l2tp-client find where \
profile="meraki" disabled=yes]
:local merakiClientsbyName [ :toarray "" ]
# Get all Meraki L2TP Clients
foreach merakiClient in=$merakiL2tpInactive do={
:local clientName [/interface l2tp-client get \
[find where .id=$merakiClient] value-name=comment]
:set merakiClientsbyName ( $merakiClientsbyName, $clientName )
}
# List Clients
:local i 1
:local numOfClients [ :len $merakiClientsbyName ]
:put "List of Meraki L2TP Clients"
foreach clientName in $merakiClientsbyName do={
if (i < 10) do={
:put " $i. $clientName"
} else={
:put " $i. $clientName"
}
:set i ($i+1)
}
:put " X. Exit"
# Decide which client to enable
:put "What client would you like to enable? (1-$numOfClients or eXit)"
:local userinput [$read]
if ([:typeof $userinput] = "num") do={
# Choice needs to be 1 less
:local choice ($userinput-1)
if ($choice >= 0 && $choice < [:len $merakiClientsbyName]) do={
$changeClient clientName=($merakiClientsbyName->$choice) change="enable"
} else={
:put $goodbye
}
} else={
:put $goodbye
}
}