@usex/mikrotik-mcp 4.7.0 → 4.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -28
- package/dist/cli.js +1 -1
- package/dist/index.js +1 -1
- package/dist/shared/{cli-38m6waxx.js → cli-s2s6hryh.js} +4689 -3226
- package/dist/shared/{cli-jd7xqp2f.js → cli-xfa5x65h.js} +1 -1
- package/dist/shared/{library-31wz8hdh.js → library-6zh75zhp.js} +1 -1
- package/dist/shared/{library-fs4nps73.js → library-wm3vc8kq.js} +4689 -3226
- package/package.json +1 -1
- package/prompts/security-hardening-sweep.md +132 -0
- package/prompts/setup-eoip-tunnel-between-sites.md +119 -0
- package/prompts/setup-gre-tunnel-between-sites.md +163 -0
- package/prompts/setup-ipip-tunnel-between-sites.md +110 -0
- package/prompts/setup-openvpn-tunnel-between-sites.md +136 -0
- package/prompts/setup-sstp-tunnel-between-sites.md +136 -0
- package/prompts/setup-tunnel-between-sites.md +55 -8
- package/prompts/setup-vxlan-tunnel-between-sites.md +129 -0
- package/prompts/setup-wireguard-tunnel-between-sites.md +183 -0
- package/schemas/README.md +1 -1
- package/schemas/tool-catalog.json +658 -2
- package/schemas/tools/add_firewall_default_deny.json +25 -0
- package/schemas/tools/apply_security_hardening_fixes.json +25 -0
- package/schemas/tools/audit_account_hygiene.json +7 -0
- package/schemas/tools/audit_address_list_enforcement.json +7 -0
- package/schemas/tools/audit_certificate_hygiene.json +7 -0
- package/schemas/tools/audit_connection_tracking_helpers.json +7 -0
- package/schemas/tools/audit_dns_resolver_exposure.json +7 -0
- package/schemas/tools/audit_firewall_default_deny.json +7 -0
- package/schemas/tools/audit_ip_service_exposure.json +7 -0
- package/schemas/tools/audit_ipv6_firewall_baseline.json +7 -0
- package/schemas/tools/audit_kernel_ip_hardening.json +7 -0
- package/schemas/tools/audit_management_plane_exposure.json +7 -0
- package/schemas/tools/audit_network_segmentation.json +7 -0
- package/schemas/tools/audit_ssh_hardening.json +7 -0
- package/schemas/tools/bootstrap_ipv6_firewall_baseline.json +25 -0
- package/schemas/tools/enforce_address_list_blocking.json +25 -0
- package/schemas/tools/fix_certificate_crl_policy.json +25 -0
- package/schemas/tools/fix_password_policy.json +25 -0
- package/schemas/tools/harden_connection_tracking_helpers.json +25 -0
- package/schemas/tools/harden_dns_resolver_exposure.json +25 -0
- package/schemas/tools/harden_ip_service_exposure.json +25 -0
- package/schemas/tools/harden_kernel_ip_settings.json +25 -0
- package/schemas/tools/harden_management_plane_exposure.json +25 -0
- package/schemas/tools/harden_ssh_service.json +25 -0
- package/schemas/tools/run_security_hardening_audit.json +29 -0
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: setup-wireguard-tunnel-between-sites
|
|
3
|
+
title: Build a WireGuard tunnel between two MikroTik devices
|
|
4
|
+
description: Configure BOTH routers of a WireGuard site-to-site tunnel from one conversation — keys, peers, addressing, routes, firewall, MTU/MSS — then verify end to end. Includes DPI-resistant / censorship-bypass transport options.
|
|
5
|
+
arguments:
|
|
6
|
+
- name: device_a
|
|
7
|
+
description: First configured device (config key or label from list_mikrotik_devices), e.g. site-a.
|
|
8
|
+
required: false
|
|
9
|
+
- name: device_b
|
|
10
|
+
description: Second configured device, e.g. site-b.
|
|
11
|
+
required: false
|
|
12
|
+
- name: tunnel_subnet
|
|
13
|
+
description: Small transit subnet for the tunnel link itself in CIDR, e.g. 10.255.255.0/30 (A=.1, B=.2). Omit to let you pick one that doesn't collide with either LAN.
|
|
14
|
+
required: false
|
|
15
|
+
- name: listen_port
|
|
16
|
+
description: UDP port WireGuard listens on. Default 13231. Consider 443/53/500 to survive restrictive networks (see the bypass section).
|
|
17
|
+
required: false
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
You are building a **WireGuard site-to-site tunnel between two MikroTik routers**
|
|
21
|
+
this server can both reach. WireGuard is the right default for MikroTik↔MikroTik:
|
|
22
|
+
modern crypto (Curve25519 / ChaCha20-Poly1305), stateless, tiny, and roams across
|
|
23
|
+
IP changes. You will drive **both** routers in one flow via the `device` argument.
|
|
24
|
+
Precision matters — a single mismatched key, allowed-address, or MTU silently
|
|
25
|
+
breaks the tunnel. Confirm the plan before any change; never write without approval.
|
|
26
|
+
|
|
27
|
+
Device A: {{device_a}}
|
|
28
|
+
Device B: {{device_b}}
|
|
29
|
+
Transit subnet: {{tunnel_subnet}}
|
|
30
|
+
Listen port: {{listen_port}}
|
|
31
|
+
|
|
32
|
+
## 0. Discover and confirm both endpoints (do this FIRST)
|
|
33
|
+
|
|
34
|
+
- Call `list_mikrotik_devices` to enumerate the configured routers (key, label,
|
|
35
|
+
transport target, default).
|
|
36
|
+
- Resolve `{{device_a}}` / `{{device_b}}` against that inventory. If either is
|
|
37
|
+
missing or ambiguous, STOP and show the list — never substitute a similar name
|
|
38
|
+
(these are different physical routers). If either was omitted, ask the user which
|
|
39
|
+
two devices to connect.
|
|
40
|
+
- Only one of the two ends needs a reachable public endpoint. Determine which side
|
|
41
|
+
is publicly reachable (static WAN IP or DDNS) — that side is the **responder**;
|
|
42
|
+
the other becomes the **initiator** and uses `persistent-keepalive` to hold the
|
|
43
|
+
path open through NAT. If **both** are behind NAT with no port-forward, say so:
|
|
44
|
+
a plain WireGuard tunnel can't form — you'd need a relay/VPS or a reachable side.
|
|
45
|
+
|
|
46
|
+
## 1. Gather the facts (read-only, per device)
|
|
47
|
+
|
|
48
|
+
For each of {{device_a}} and {{device_b}}, with `device=<name>`:
|
|
49
|
+
`get_system_identity`, `list_interfaces`, `list_ip_addresses`, `get_routing_table`,
|
|
50
|
+
and `get_ip_cloud` (for a DDNS name if there's no static WAN). Record each side's:
|
|
51
|
+
public/WAN address (or DDNS), the WAN interface and its MTU, and the **LAN
|
|
52
|
+
subnet(s)** to route. Verify the two LANs do **not overlap** — if they do, WireGuard
|
|
53
|
+
allowed-address routing is ambiguous and you must NAT one side or renumber; flag it.
|
|
54
|
+
|
|
55
|
+
## 2. Pick non-colliding addressing
|
|
56
|
+
|
|
57
|
+
- Transit subnet: `{{tunnel_subnet}}` or a /30 that collides with neither LAN
|
|
58
|
+
(e.g. `10.255.255.0/30`). A=`.1`, B=`.2`.
|
|
59
|
+
- Confirm the plan back to the user: interface names (`wg-<peer>`), listen ports,
|
|
60
|
+
transit IPs, and which LAN each side will advertise.
|
|
61
|
+
|
|
62
|
+
## 3. Create the WireGuard interfaces and exchange keys
|
|
63
|
+
|
|
64
|
+
- On EACH side: `create_wireguard_interface` (`device=<name>`, name e.g.
|
|
65
|
+
`wg-{{device_b}}` on A and `wg-{{device_a}}` on B, `listen_port`={{listen_port}}
|
|
66
|
+
or 13231). RouterOS auto-generates the private key and derives the public key.
|
|
67
|
+
- Read each side's **public key** with `get_wireguard_interface` (`device=<name>`).
|
|
68
|
+
You will cross-feed these: A's peer uses **B's** public key and vice-versa. Never
|
|
69
|
+
transmit or log the private keys — they never leave their router.
|
|
70
|
+
- `add_ip_address` the transit IP on each wg interface (A: `10.255.255.1/30` on
|
|
71
|
+
`wg-...`; B: `10.255.255.2/30`).
|
|
72
|
+
|
|
73
|
+
## 4. Add the peers (the exact, symmetric part)
|
|
74
|
+
|
|
75
|
+
On **A** (`device={{device_a}}`): `add_wireguard_peer`
|
|
76
|
+
|
|
77
|
+
- `interface` = A's wg interface
|
|
78
|
+
- `public_key` = **B's** public key
|
|
79
|
+
- `allowed_address` = the transit peer + **B's LAN(s)**, e.g.
|
|
80
|
+
`10.255.255.2/32,192.168.20.0/24` (comma-separated; this is WireGuard's crypto-
|
|
81
|
+
routing table — it must list every subnet you expect to reach through B)
|
|
82
|
+
- `endpoint_address` = B's public IP/DDNS, `endpoint_port` = B's listen port
|
|
83
|
+
(set these on whichever side is the initiator; the responder can omit them)
|
|
84
|
+
- `persistent_keepalive` = `25` on the side behind NAT (the initiator) so the
|
|
85
|
+
mapping stays open
|
|
86
|
+
- optional `preshared_key` = the SAME 32-byte PSK on both peers for an extra
|
|
87
|
+
symmetric layer (post-quantum-ish defense-in-depth; must match exactly).
|
|
88
|
+
|
|
89
|
+
On **B** (`device={{device_b}}`): mirror it — `public_key` = **A's**,
|
|
90
|
+
`allowed_address` = `10.255.255.1/32,<A's LAN>`, endpoint pointing at A **only if**
|
|
91
|
+
A is the reachable side.
|
|
92
|
+
|
|
93
|
+
## 5. Route each far LAN over the tunnel
|
|
94
|
+
|
|
95
|
+
`allowed-address` governs what WireGuard will _cryptographically_ accept, but you
|
|
96
|
+
still need an IP route so RouterOS _sends_ far-LAN traffic into the interface:
|
|
97
|
+
|
|
98
|
+
- On A: `add_route` (`device={{device_a}}`) `dst-address=<B's LAN>`,
|
|
99
|
+
`gateway=<A's wg interface>`.
|
|
100
|
+
- On B: mirror with A's LAN.
|
|
101
|
+
(The transit /30 already has a connected route from step 3.)
|
|
102
|
+
|
|
103
|
+
## 6. Firewall — safely, per device
|
|
104
|
+
|
|
105
|
+
Per side, under Safe Mode (`enable_safe_mode` `device=<name>` → edits → verify →
|
|
106
|
+
`commit_safe_mode`; Safe Mode is per-device so each commits independently):
|
|
107
|
+
|
|
108
|
+
- `input` chain: accept `protocol=udp dst-port=<listen_port>` from the far side's
|
|
109
|
+
WAN (or from any, if the endpoint is dynamic) — place it **above** any default
|
|
110
|
+
drop.
|
|
111
|
+
- `forward` chain: accept traffic between the two LANs in both directions; if there
|
|
112
|
+
is a default-deny, add explicit accepts for `src`/`dst` of each LAN over the wg
|
|
113
|
+
interface.
|
|
114
|
+
- Do NOT masquerade the tunnel subnet unless you deliberately want NAT (it breaks
|
|
115
|
+
return routing for site-to-site).
|
|
116
|
+
|
|
117
|
+
## 7. MTU / MSS (the silent-failure trap)
|
|
118
|
+
|
|
119
|
+
WireGuard adds ~60 bytes of overhead. Small pings work but large flows (TLS, file
|
|
120
|
+
transfer) stall if MTU is wrong:
|
|
121
|
+
|
|
122
|
+
- Set the wg interface MTU to **1420** (1412 if the WAN is PPPoE) via
|
|
123
|
+
`update_wireguard_interface`.
|
|
124
|
+
- Clamp TCP MSS on the `forward` chain (`create_filter_rule` mangle
|
|
125
|
+
`action=change-mss new-mss=clamp-to-pmtu tcp-flags=syn`) or set it per the
|
|
126
|
+
interface MTU, so TCP sessions negotiate a size that fits.
|
|
127
|
+
|
|
128
|
+
## 8. Verify end to end
|
|
129
|
+
|
|
130
|
+
- From A (`ping` `device={{device_a}}`): ping B's transit IP (`10.255.255.2`), then
|
|
131
|
+
a host in B's LAN with `src_address` = A's LAN IP. Repeat from B.
|
|
132
|
+
- `list_wireguard_peers` / `get_wireguard_status` on each side: confirm a recent
|
|
133
|
+
**last-handshake** and rx/tx counters climbing. No handshake ⇒ firewall/endpoint/
|
|
134
|
+
key/allowed-address mismatch — check in that order.
|
|
135
|
+
- Large-payload test: ping with size 1400 and `do-not-fragment`; if it fails,
|
|
136
|
+
revisit MTU/MSS (step 7).
|
|
137
|
+
|
|
138
|
+
## Bypassing country / DPI restrictions (legitimate censorship circumvention)
|
|
139
|
+
|
|
140
|
+
Some networks block or throttle VPNs. The following are for lawful privacy /
|
|
141
|
+
accessibility on links you're authorized to use — comply with local law and any
|
|
142
|
+
service terms. From least to most evasive:
|
|
143
|
+
|
|
144
|
+
1. **Port camouflage.** Move `listen_port` to a port that's rarely filtered:
|
|
145
|
+
`443` (HTTPS/QUIC), `53` (DNS), `123` (NTP), or `500`. UDP/443 often survives
|
|
146
|
+
because it looks like QUIC. Cheapest change; update the peer `endpoint_port` on
|
|
147
|
+
the other side to match. _Caveat: this hides the port, not the handshake._
|
|
148
|
+
2. **DPI fingerprinting reality.** WireGuard's first handshake message has a fixed,
|
|
149
|
+
recognizable shape, so deep-packet-inspection can block it regardless of port.
|
|
150
|
+
RouterOS has **no native WireGuard obfuscation** (no obfs4/wstunnel/Shadowsocks/
|
|
151
|
+
XRay). To defeat DPI you must wrap the tunnel in something that looks benign:
|
|
152
|
+
3. **Wrap WireGuard inside a TLS-looking tunnel.** Bring up an **SSTP** tunnel
|
|
153
|
+
(PPP-over-TLS on **TCP 443** — indistinguishable from HTTPS to most DPI) between
|
|
154
|
+
the sites with `create_sstp_client`/the SSTP server tools, then either route the
|
|
155
|
+
far LANs directly over SSTP, or run the WireGuard endpoint _across_ the SSTP link
|
|
156
|
+
so the WG handshake never touches the open internet. **OpenVPN in TCP/443 mode**
|
|
157
|
+
(`create_ovpn_client`, `tls`) is an equivalent camouflage. This trades throughput
|
|
158
|
+
(TCP-in-TCP) for reachability.
|
|
159
|
+
4. **IPsec IKEv2 as an alternative fingerprint.** If WireGuard specifically is
|
|
160
|
+
blocked, an IKEv2 tunnel over **UDP 4500 (NAT-T)** presents a different signature
|
|
161
|
+
and is often allowed; use the `setup-ipsec-site-to-site` flow. GRE-over-IPsec
|
|
162
|
+
(`ipsec_secret`) rides ESP and is another option.
|
|
163
|
+
5. **Advanced obfuscation via a RouterOS container.** For hostile DPI (active
|
|
164
|
+
probing, protocol allow-lists), the strong tools — **XRay/VLESS+Reality,
|
|
165
|
+
sing-box, Shadowsocks, obfs4** — aren't native. Run one in a RouterOS
|
|
166
|
+
**`/container`** (or on a VPS you control) and route the site tunnel through it;
|
|
167
|
+
WireGuard then rides an already-obfuscated transport. Call this out as the
|
|
168
|
+
heavier, most robust option and confirm the device has container support and
|
|
169
|
+
spare resources before proposing it.
|
|
170
|
+
6. **Keepalive + MTU hygiene under hostile networks.** Keep `persistent-keepalive`
|
|
171
|
+
low (15–25 s) so aggressive NATs don't reap the mapping, and set MTU
|
|
172
|
+
conservatively (fragmentation-sensitive DPI drops oversized handshakes).
|
|
173
|
+
|
|
174
|
+
Recommend the lightest option that works for the user's threat model (start at #1,
|
|
175
|
+
escalate to #3, reserve #5 for active blocking), explain the throughput/complexity
|
|
176
|
+
trade-off, and never present obfuscation as a guarantee — it is an arms race.
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
Report, per side: interface name, public key (never the private key), listen port,
|
|
181
|
+
transit IP, peer allowed-address, routes and firewall rules added, the MTU/MSS
|
|
182
|
+
settings, and the verification results (handshake time, ping). State plainly which
|
|
183
|
+
device each change ran on. Never apply changes the user hasn't approved.
|
package/schemas/README.md
CHANGED
|
@@ -7,7 +7,7 @@ edit by hand — regenerate instead.
|
|
|
7
7
|
| File | Contents |
|
|
8
8
|
|------|----------|
|
|
9
9
|
| `config.schema.json` | The runtime configuration object (env vars / CLI flags). |
|
|
10
|
-
| `tool-catalog.json` | Every one of the
|
|
10
|
+
| `tool-catalog.json` | Every one of the 819 tools: `name`, `risk`, `title`, `description`, and input JSON Schema. |
|
|
11
11
|
| `tools/<name>.json` | The input JSON Schema for a single tool. |
|
|
12
12
|
|
|
13
13
|
`risk` is derived from the MCP tool annotations:
|