@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
package/package.json
CHANGED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: security-hardening-sweep
|
|
3
|
+
title: Security hardening sweep (pick device → audit → fix by finding)
|
|
4
|
+
description: Discover the configured MikroTik devices, let the user choose which one to harden, then run the granular Security Hardening suite — per-category, evidence-based findings with a stable finding_id — and remediate only the findings the user approves, safely (snapshot + Safe Mode).
|
|
5
|
+
arguments:
|
|
6
|
+
- name: device
|
|
7
|
+
description: Which configured device to harden (its config key or friendly label from list_mikrotik_devices). Omit to discover the devices and let the user choose.
|
|
8
|
+
required: false
|
|
9
|
+
- name: categories
|
|
10
|
+
description: Comma-separated category slugs to scope the sweep (e.g. "firewall_default_deny,dns_resolver_exposure"). Omit to let the user pick a hardening goal (All / DDoS / port-scanning / remote-management / …), which you translate into these slugs.
|
|
11
|
+
required: false
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
You are running a **granular, evidence-based security hardening sweep** on a
|
|
15
|
+
MikroTik RouterOS device managed by this MCP server. This server may manage
|
|
16
|
+
**several routers**, so you MUST establish which one to harden before touching
|
|
17
|
+
anything. Unlike a scored compliance grade, this suite finds each specific
|
|
18
|
+
misconfiguration, gives it a stable `finding_id`, and lets you remediate
|
|
19
|
+
**exactly the findings the user approves — one at a time, by ID.** Work safely:
|
|
20
|
+
pick the device, audit, present findings, and never write without explicit approval.
|
|
21
|
+
|
|
22
|
+
Requested device: {{device}}
|
|
23
|
+
Categories to scope: {{categories}}
|
|
24
|
+
|
|
25
|
+
Follow this workflow:
|
|
26
|
+
|
|
27
|
+
0. **Discover devices and confirm the target (do this FIRST, always).**
|
|
28
|
+
- Call `list_mikrotik_devices` to enumerate every configured router — its
|
|
29
|
+
config key, friendly label, transport target (host/MAC), and which is the
|
|
30
|
+
default.
|
|
31
|
+
- **If `{{device}}` was provided**, resolve it against that inventory. If it
|
|
32
|
+
doesn't match a known key or label, STOP and show the user the available
|
|
33
|
+
devices so they can correct it — never guess or substitute a similar name
|
|
34
|
+
(these are different physical routers).
|
|
35
|
+
- **If `{{device}}` was NOT provided**, present the inventory as a short list
|
|
36
|
+
and **ask the user which device they want to harden.** Do not proceed to the
|
|
37
|
+
audit until they choose. If exactly one device is configured, name it and
|
|
38
|
+
confirm before continuing.
|
|
39
|
+
- Once chosen, pass that device on **every** subsequent tool call via the
|
|
40
|
+
`device` argument (audit, apply, snapshot, and verify calls all target the
|
|
41
|
+
same router). State plainly which device you are operating on.
|
|
42
|
+
|
|
43
|
+
0.5 **Choose WHAT to harden (do this before the audit).**
|
|
44
|
+
|
|
45
|
+
- **If `{{categories}}` was provided**, use those slugs directly and skip the menu.
|
|
46
|
+
- **Otherwise, offer the user a plain-language goal menu** and let them pick one
|
|
47
|
+
or more. Then translate their choice into the category slugs below and pass
|
|
48
|
+
them as the `categories` argument to the audit. Suggested menu:
|
|
49
|
+
|
|
50
|
+
| Goal (what to say to the user) | Category slugs to audit |
|
|
51
|
+
| -------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
|
|
52
|
+
| **Everything** (full hardening pass) | _(omit `categories` — runs all 12)_ |
|
|
53
|
+
| **DDoS protection** (enforce populated DDoS lists, SYN-cookies, close open resolver) | `address_list_enforcement`, `firewall_default_deny`, `kernel_ip_hardening`, `dns_resolver_exposure` |
|
|
54
|
+
| **Prevent port scanning** (nmap etc. — enforce scanner detection lists, close the perimeter) | `address_list_enforcement`, `firewall_default_deny` |
|
|
55
|
+
| **Lock down remote management** (brute-force ladders, exposed services, the Winbox trap) | `firewall_default_deny`, `ip_service_exposure`, `ssh_hardening`, `management_plane_exposure` |
|
|
56
|
+
| **Close open/unused services** (telnet, reverse-proxy, unused conntrack helpers) | `ip_service_exposure`, `connection_tracking_helpers`, `management_plane_exposure` |
|
|
57
|
+
| **Anti-spoofing / kernel hardening** (rp-filter, source-route, redirects) | `kernel_ip_hardening` |
|
|
58
|
+
| **IPv6 safety** (forwarding with no filter) | `ipv6_firewall_baseline`, `kernel_ip_hardening` |
|
|
59
|
+
| **DNS resolver safety** (open-resolver / amplification) | `dns_resolver_exposure` |
|
|
60
|
+
| **Account & credential hygiene** (password policy, stray accounts) | `account_hygiene` |
|
|
61
|
+
| **Certificate hygiene** (CRL checking) | `certificate_hygiene` |
|
|
62
|
+
| **Network segmentation review** (flat L2, servers + clients share a domain) | `network_segmentation` |
|
|
63
|
+
|
|
64
|
+
- Present these as a short numbered list (goal + one-line "what it covers"), ask
|
|
65
|
+
the user to choose, and confirm the resulting slug set before auditing. The
|
|
66
|
+
user may combine goals — union the slugs.
|
|
67
|
+
- **Scope caveat — enforcement vs. detection.** This suite _enforces_ protections
|
|
68
|
+
the config already implies (e.g. it turns an existing-but-unblocked
|
|
69
|
+
`port scanners` / `ddoser` address-list into an active drop, and closes an open
|
|
70
|
+
resolver). It does NOT create brand-new detection rules. If the user wants to
|
|
71
|
+
_add_ fresh DDoS rate-limiting or port-scan (`psd`) detection where none exists,
|
|
72
|
+
point them to `harden_firewall` (Security Shield: `ddos_conn_limit`, `syn_flood`,
|
|
73
|
+
`port_scan` presets) and run this sweep afterwards to confirm the new lists are enforced.
|
|
74
|
+
|
|
75
|
+
1. **Audit (read-only).** Call `run_security_hardening_audit` with
|
|
76
|
+
`device=<chosen device>` and `categories=<the slugs from step 0.5>` (omit
|
|
77
|
+
`categories` for a full pass). It covers firewall default-deny, address-list
|
|
78
|
+
enforcement, kernel IP hardening, IPv6 baseline, SSH, IP service exposure,
|
|
79
|
+
connection-tracking helpers, management-plane exposure, account hygiene,
|
|
80
|
+
certificate CRL policy, network segmentation, and DNS resolver exposure, and
|
|
81
|
+
returns one severity-ranked report. This is pure read: no confirmation needed.
|
|
82
|
+
|
|
83
|
+
2. **Present the findings.** Organize by severity (critical → low). For each
|
|
84
|
+
finding, show:
|
|
85
|
+
- the `finding_id`, category, and severity;
|
|
86
|
+
- the **confidence**: `proven` (settled by static config) vs
|
|
87
|
+
`needs_live_verification` (latent, or dependent on runtime chain/NAT
|
|
88
|
+
interaction). Call these out separately — never present a speculative finding
|
|
89
|
+
with the same certainty as a proven one.
|
|
90
|
+
- the exact target (`.id`/rule signature), the current value, and the proposed
|
|
91
|
+
action;
|
|
92
|
+
- whether it has an automated fix or is **manual-review only** (e.g. suspicious
|
|
93
|
+
accounts, group policy, and network segmentation are never auto-applied).
|
|
94
|
+
|
|
95
|
+
3. **Note the two special cases.**
|
|
96
|
+
- **IPv6 baseline (4.4)** surfaces as two _mutually-exclusive_ options with
|
|
97
|
+
distinct finding_ids — bootstrap a safe IPv6 filter, or disable IPv6
|
|
98
|
+
forwarding. Help the user pick exactly one; do not apply both.
|
|
99
|
+
- **Disabled-enforcement drop (the Winbox trap)** — re-enabling a deliberately
|
|
100
|
+
disabled drop is a separate finding_id from inserting a new default-deny.
|
|
101
|
+
Confirm the admin didn't disable it on purpose before re-enabling.
|
|
102
|
+
|
|
103
|
+
4. **Plan the remediation (with user approval).** Once the user chooses which
|
|
104
|
+
findings to fix, preview first. Call `apply_security_hardening_fixes` with
|
|
105
|
+
`device=<chosen device>`, the chosen `finding_ids`, and `confirm` omitted/false
|
|
106
|
+
— this returns a **dry run** of the exact commands in safe apply order
|
|
107
|
+
(default-deny and address-list enforcement before service exposure before
|
|
108
|
+
helpers/hygiene). Per-category tools (`add_firewall_default_deny`,
|
|
109
|
+
`enforce_address_list_blocking`, `harden_kernel_ip_settings`,
|
|
110
|
+
`harden_ssh_service`, `harden_dns_resolver_exposure`, `fix_password_policy`, …)
|
|
111
|
+
offer the same dry-run preview for a single category — pass `device=` on those too.
|
|
112
|
+
|
|
113
|
+
5. **Apply (only with explicit approval).** Re-issue the call with `device=<chosen
|
|
114
|
+
device>` and `confirm=true`. The tool captures a pre-change **snapshot** (returns
|
|
115
|
+
a `snapshot_id`), wraps any lockout-risky change in **Safe Mode** (auto-reverts
|
|
116
|
+
if your session drops), applies each finding's fix, and commits. Report the
|
|
117
|
+
per-finding results, the `snapshot_id`, and the device it ran on.
|
|
118
|
+
|
|
119
|
+
6. **Verify.** Re-run `run_security_hardening_audit` on the same `device=` to
|
|
120
|
+
confirm the applied findings no longer appear (the suite is idempotent — a
|
|
121
|
+
re-run of a fixed finding is a no-op). If anything looks wrong, roll back with
|
|
122
|
+
`diff_config_snapshots device=<chosen device> from=<snapshot_id> to=live` and the
|
|
123
|
+
snapshot tools.
|
|
124
|
+
|
|
125
|
+
Finish with a short prioritized checklist (Critical / Recommended / Optional /
|
|
126
|
+
Manual-review) and the exact `finding_id`s and tool calls for each tier — each
|
|
127
|
+
call carrying the `device` argument. Never pass a blanket "fix everything" request
|
|
128
|
+
— always remediate explicit finding_ids the user approved on the chosen device.
|
|
129
|
+
If the user wants to harden **more than one** router, repeat this whole workflow
|
|
130
|
+
per device (each has its own findings, snapshot, and Safe-Mode session); do not
|
|
131
|
+
mix finding_ids across devices. For a scored A+–F posture grade instead, use
|
|
132
|
+
`run_compliance_audit`; for shadowed/broad/dead-rule analysis, use `firewall_audit`.
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: setup-eoip-tunnel-between-sites
|
|
3
|
+
title: Build an EoIP (Layer-2) tunnel between two MikroTik devices
|
|
4
|
+
description: Configure BOTH routers of an EoIP site-to-site tunnel — a bridgeable Ethernet-over-IP link that puts two sites on the SAME L2 broadcast domain — with matching tunnel-id, bridging, MTU/MSS, and (recommended) IPsec encryption, then verify. Includes DPI/censorship-bypass notes.
|
|
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_id
|
|
13
|
+
description: EoIP tunnel ID (0–65535). MUST be identical on both peers and unique per EoIP tunnel. Omit to let you pick one.
|
|
14
|
+
required: false
|
|
15
|
+
- name: encrypt
|
|
16
|
+
description: Secure EoIP with IPsec (shared secret). Recommended — EoIP is cleartext. "yes" (default) or "no".
|
|
17
|
+
required: false
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
You are building an **EoIP (Ethernet-over-IP) tunnel between two MikroTik routers**
|
|
21
|
+
this server can both reach. EoIP is unique among these tunnels: it is **Layer 2** —
|
|
22
|
+
it transports Ethernet frames, so bridging the EoIP interface at both sites places
|
|
23
|
+
them on **one broadcast domain** (same subnet spans both sites; ARP, DHCP, and
|
|
24
|
+
broadcast cross the tunnel). That is powerful and dangerous: a broadcast storm or a
|
|
25
|
+
loop now spans both sites. Use it only when you genuinely need shared L2; for routed
|
|
26
|
+
L3 connectivity prefer GRE/IPIP/WireGuard. **EoIP is unencrypted** — secure with
|
|
27
|
+
IPsec (default here). Drive **both** routers via the `device` argument. Confirm
|
|
28
|
+
before any change.
|
|
29
|
+
|
|
30
|
+
Device A: {{device_a}}
|
|
31
|
+
Device B: {{device_b}}
|
|
32
|
+
Tunnel ID: {{tunnel_id}}
|
|
33
|
+
Encrypt with IPsec: {{encrypt}}
|
|
34
|
+
|
|
35
|
+
## 0. Discover and confirm (FIRST)
|
|
36
|
+
|
|
37
|
+
- `list_mikrotik_devices`; resolve {{device_a}}/{{device_b}} — never substitute a
|
|
38
|
+
similar name; ask which two if omitted.
|
|
39
|
+
- Both ends need to reach the other's public IP (EoIP uses protocol 47, like GRE).
|
|
40
|
+
Behind NAT ⇒ prefer IPsec-encrypted EoIP (ESP/4500) and flag it.
|
|
41
|
+
- **L2 safety check:** confirm the user really wants a single stretched subnet. If a
|
|
42
|
+
DHCP server runs at both sites, decide which one serves the stretched VLAN (two
|
|
43
|
+
servers on one L2 = conflict). Warn about loop/STP risk before bridging.
|
|
44
|
+
|
|
45
|
+
## 1. Facts (read-only, per device)
|
|
46
|
+
|
|
47
|
+
Per side (`device=<name>`): `get_system_identity`, `list_interfaces`,
|
|
48
|
+
`list_bridges` (or `list_interfaces`), `list_ip_addresses`, `get_routing_table`,
|
|
49
|
+
`get_ip_cloud`. Record public/WAN address, WAN MTU, the LAN bridge each site uses,
|
|
50
|
+
and the subnet to stretch.
|
|
51
|
+
|
|
52
|
+
## 2. Plan
|
|
53
|
+
|
|
54
|
+
Pick `tunnel_id` = `{{tunnel_id}}` (identical both sides, unique per EoIP). Decide
|
|
55
|
+
the target bridge on each side. Confirm interface names (`eoip-<peer>`), tunnel-id,
|
|
56
|
+
and the stretched subnet/VLAN with the user. If encrypting, generate a strong shared
|
|
57
|
+
secret for `ipsec_secret` on both sides.
|
|
58
|
+
|
|
59
|
+
## 3. Create the EoIP interfaces (symmetric)
|
|
60
|
+
|
|
61
|
+
- On **A** (`device={{device_a}}`): `create_eoip_tunnel` — `name`=`eoip-{{device_b}}`,
|
|
62
|
+
`remote_address`=**B's** public IP, `local_address`=A's public IP,
|
|
63
|
+
`tunnel_id`={{tunnel_id}} (MUST match), `keepalive`=`10s,3`, `clamp_tcp_mss`=true,
|
|
64
|
+
`ipsec_secret`=<secret> if encrypting, `mtu` per step 6.
|
|
65
|
+
- On **B**: mirror — `remote_address`=A's IP, `local_address`=B's IP, **same
|
|
66
|
+
`tunnel_id`**, identical `ipsec_secret`. (A mismatched tunnel_id silently fails.)
|
|
67
|
+
|
|
68
|
+
## 4. Bridge the tunnel (the L2 step)
|
|
69
|
+
|
|
70
|
+
On each side add the EoIP interface as a **bridge port** on the LAN bridge that owns
|
|
71
|
+
the stretched subnet (bridge/port tools). Now the two LANs are one L2 domain.
|
|
72
|
+
|
|
73
|
+
- **Strongly recommend enabling STP/RSTP** on both bridges so an accidental parallel
|
|
74
|
+
path can't create a bridging loop across the WAN.
|
|
75
|
+
- Do NOT put an IP on the EoIP interface itself — it's a bridge member, not a routed
|
|
76
|
+
link (that's the difference from GRE/IPIP).
|
|
77
|
+
|
|
78
|
+
## 5. Firewall — safely, per device
|
|
79
|
+
|
|
80
|
+
Per side under Safe Mode (`enable_safe_mode`→edits→verify→`commit_safe_mode`; per-device):
|
|
81
|
+
|
|
82
|
+
- Unencrypted: `input` accept `protocol=gre` from far WAN (EoIP rides GRE; cleartext).
|
|
83
|
+
- IPsec-encrypted: `input` accept `udp dst-port=500,4500` + `protocol=ipsec-esp`.
|
|
84
|
+
- Bridged L2 traffic is `forward`-chain; if `use-ip-firewall` is on, allow it.
|
|
85
|
+
|
|
86
|
+
## 6. MTU / MSS (critical for L2)
|
|
87
|
+
|
|
88
|
+
EoIP has GRE-like overhead AND carries full Ethernet frames, so MTU mismatch bites
|
|
89
|
+
hard. Set the EoIP `mtu`/`l2mtu` high enough (the WAN path must carry the encapsulated
|
|
90
|
+
frame — often needs the WAN to support ~1500+; otherwise lower the guests' effective
|
|
91
|
+
MTU), keep `clamp_tcp_mss=true`, and clamp MSS on `forward`. Test large frames
|
|
92
|
+
explicitly.
|
|
93
|
+
|
|
94
|
+
## 7. Verify
|
|
95
|
+
|
|
96
|
+
- `get_eoip_tunnel` each side: running=yes; tunnel-ids match. If encrypted,
|
|
97
|
+
`get_ipsec_active_peers` shows an established SA (no SA + it works ⇒ CLEAR, stop).
|
|
98
|
+
- L2 proof: a host at site A should ARP-resolve and `ping` a host at site B **in the
|
|
99
|
+
same subnet** with no router hop; DHCP from the designated server should reach both.
|
|
100
|
+
- Large-frame test to confirm MTU.
|
|
101
|
+
|
|
102
|
+
## Bypassing country / DPI restrictions (legitimate circumvention)
|
|
103
|
+
|
|
104
|
+
Lawful privacy/accessibility only. EoIP (protocol 47) is easily filtered:
|
|
105
|
+
|
|
106
|
+
1. **Encrypt** so it rides IPsec ESP/UDP 4500.
|
|
107
|
+
2. If blocked, **carry the bridge over a TLS transport** — OpenVPN in **ethernet
|
|
108
|
+
(TAP) mode** on TCP/443 is L2-capable and looks like HTTPS (see
|
|
109
|
+
`setup-openvpn-tunnel-between-sites`, `mode=ethernet`); bridge that instead of
|
|
110
|
+
EoIP. SSTP is L3/PPP (not L2), so it can't replace EoIP for bridging.
|
|
111
|
+
3. Advanced: obfuscation via `/container` (XRay/Reality, sing-box) — not native.
|
|
112
|
+
For evasion, prefer OpenVPN-TAP/443 over raw EoIP. Never present obfuscation as a
|
|
113
|
+
guarantee.
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
Report per side: EoIP interface, remote/local, tunnel-id, which bridge it joined,
|
|
118
|
+
IPsec SA proof, STP status, MTU/MSS, verification results. State which device each
|
|
119
|
+
change ran on. Never apply changes the user hasn't approved.
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: setup-gre-tunnel-between-sites
|
|
3
|
+
title: Build a GRE tunnel between two MikroTik devices
|
|
4
|
+
description: Configure BOTH routers of a GRE site-to-site tunnel from one conversation — endpoints, addressing, routing, MTU/MSS, and (strongly recommended) IPsec encryption — then verify end to end. Includes DPI/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 GRE 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: encrypt
|
|
16
|
+
description: Whether to secure GRE with IPsec (a shared secret). Strongly recommended — GRE alone is cleartext. "yes" (default) or "no".
|
|
17
|
+
required: false
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
You are building a **GRE (Generic Routing Encapsulation) site-to-site tunnel
|
|
21
|
+
between two MikroTik routers** this server can both reach. GRE is a lightweight L3
|
|
22
|
+
tunnel: it routes IP (and multicast / dynamic-routing protocols like OSPF, which
|
|
23
|
+
plain IPsec can't carry) between two public endpoints. **GRE by itself is
|
|
24
|
+
UNENCRYPTED** — anyone on the path sees the inner packets — so unless the transport
|
|
25
|
+
is already trusted, secure it with IPsec (this flow does so by default). You will
|
|
26
|
+
drive **both** routers in one conversation via the `device` argument. Confirm the
|
|
27
|
+
plan before any change; never write without approval.
|
|
28
|
+
|
|
29
|
+
Device A: {{device_a}}
|
|
30
|
+
Device B: {{device_b}}
|
|
31
|
+
Transit subnet: {{tunnel_subnet}}
|
|
32
|
+
Encrypt with IPsec: {{encrypt}}
|
|
33
|
+
|
|
34
|
+
## 0. Discover and confirm both endpoints (do this FIRST)
|
|
35
|
+
|
|
36
|
+
- Call `list_mikrotik_devices` to enumerate the configured routers (key, label,
|
|
37
|
+
transport target, default).
|
|
38
|
+
- Resolve `{{device_a}}` / `{{device_b}}` against that inventory. If either is
|
|
39
|
+
missing or ambiguous, STOP and show the list — never substitute a similar name.
|
|
40
|
+
If either was omitted, ask the user which two devices to connect.
|
|
41
|
+
- GRE needs each side to reach the **other's public IP** by protocol 47. Both ends
|
|
42
|
+
must have a routable public address (or a DDNS name + a path that permits GRE).
|
|
43
|
+
If a side is behind NAT, GRE only works if the NAT device forwards protocol 47
|
|
44
|
+
(many don't) — in that case prefer IPsec-encrypted GRE on UDP 4500, or switch to
|
|
45
|
+
WireGuard (`setup-wireguard-tunnel-between-sites`). Flag this early.
|
|
46
|
+
|
|
47
|
+
## 1. Gather the facts (read-only, per device)
|
|
48
|
+
|
|
49
|
+
For each of {{device_a}} and {{device_b}} with `device=<name>`:
|
|
50
|
+
`get_system_identity`, `list_interfaces`, `list_ip_addresses`, `get_routing_table`,
|
|
51
|
+
`get_ip_cloud`. Record each side's public/WAN address (or DDNS), WAN MTU, and the
|
|
52
|
+
**LAN subnet(s)** to route. Confirm the two LANs do **not overlap** (overlap breaks
|
|
53
|
+
routing — NAT or renumber one side and 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
|
+
- Decide encryption: if `{{encrypt}}` is empty or "yes", generate a strong shared
|
|
60
|
+
secret (long, random) to pass as `ipsec_secret` on **both** sides — RouterOS then
|
|
61
|
+
auto-creates the IPsec policy that encrypts the GRE. Confirm interface names
|
|
62
|
+
(`gre-<peer>`), transit IPs, and each side's advertised LAN back to the user.
|
|
63
|
+
|
|
64
|
+
## 3. Create the GRE interfaces (symmetric endpoints)
|
|
65
|
+
|
|
66
|
+
On **A** (`device={{device_a}}`): `create_gre_tunnel`
|
|
67
|
+
|
|
68
|
+
- `name` = e.g. `gre-{{device_b}}`
|
|
69
|
+
- `remote_address` = **B's** public IP/DDNS
|
|
70
|
+
- `local_address` = A's own public IP (pin it if A has multiple WANs)
|
|
71
|
+
- `keepalive` = `10s,3` (so the interface goes down fast if the far side dies)
|
|
72
|
+
- `clamp_tcp_mss` = true (avoids PMTU black-holing — see step 6)
|
|
73
|
+
- `ipsec_secret` = the shared secret (only when encrypting)
|
|
74
|
+
- `mtu` = 1476 (GRE overhead is 24 bytes; lower further when also IPsec-wrapped —
|
|
75
|
+
see step 6)
|
|
76
|
+
|
|
77
|
+
On **B** (`device={{device_b}}`): mirror — `remote_address` = **A's** public IP,
|
|
78
|
+
`local_address` = B's public IP, same `keepalive`, `clamp_tcp_mss`, and the
|
|
79
|
+
**identical** `ipsec_secret`.
|
|
80
|
+
|
|
81
|
+
## 4. Address the tunnel
|
|
82
|
+
|
|
83
|
+
`add_ip_address` the transit IP on each GRE interface (A: `10.255.255.1/30` on
|
|
84
|
+
`gre-...`; B: `10.255.255.2/30`). This gives the tunnel a connected route.
|
|
85
|
+
|
|
86
|
+
## 5. Route each far LAN over the tunnel
|
|
87
|
+
|
|
88
|
+
- On A: `add_route` (`device={{device_a}}`) `dst-address=<B's LAN>`
|
|
89
|
+
`gateway=<A's gre interface>` (or `gateway=10.255.255.2`).
|
|
90
|
+
- On B: mirror with A's LAN.
|
|
91
|
+
- For dynamic routing instead of static routes, GRE can carry OSPF — add the GRE
|
|
92
|
+
interface to an OSPF area on both sides (see `setup-ospf-peering`); this is a key
|
|
93
|
+
reason to choose GRE over IPsec-only.
|
|
94
|
+
|
|
95
|
+
## 6. Firewall — safely, per device
|
|
96
|
+
|
|
97
|
+
Per side under Safe Mode (`enable_safe_mode` `device=<name>` → edits → verify →
|
|
98
|
+
`commit_safe_mode`; per-device, independent commit):
|
|
99
|
+
|
|
100
|
+
- If **unencrypted GRE**: `input` chain accept `protocol=gre` from the far side's
|
|
101
|
+
WAN. (Reminder to the user: this is cleartext.)
|
|
102
|
+
- If **IPsec-encrypted GRE**: `input` chain accept `protocol=udp dst-port=500,4500`
|
|
103
|
+
(IKE + NAT-T) and `protocol=ipsec-esp` from the far WAN; the decrypted GRE is then
|
|
104
|
+
handled internally. Ensure any `action=fasttrack`/`accept` for established traffic
|
|
105
|
+
doesn't bypass the IPsec policy (put the IPsec accepts high).
|
|
106
|
+
- `forward` chain: accept traffic between the two LANs both directions.
|
|
107
|
+
- Do not masquerade the tunnel/transit subnet (breaks return routing).
|
|
108
|
+
|
|
109
|
+
## 7. MTU / MSS (the silent-failure trap)
|
|
110
|
+
|
|
111
|
+
Encapsulation shrinks the usable MTU; small pings pass but large TLS/file flows
|
|
112
|
+
stall. GRE = 24 bytes overhead; GRE + IPsec (ESP) = ~70+ bytes. So:
|
|
113
|
+
|
|
114
|
+
- Set the GRE interface MTU ~1476 (plain) or ~1400 (GRE-over-IPsec); lower on PPPoE.
|
|
115
|
+
- Keep `clamp_tcp_mss=true` on the tunnel (set in step 3) and/or add a `forward`
|
|
116
|
+
mangle `change-mss new-mss=clamp-to-pmtu tcp-flags=syn` rule so TCP fits.
|
|
117
|
+
|
|
118
|
+
## 8. Verify end to end
|
|
119
|
+
|
|
120
|
+
- From A (`ping` `device={{device_a}}`): the transit IP (`10.255.255.2`), then a
|
|
121
|
+
host in B's LAN with `src_address` = A's LAN IP. Repeat from B.
|
|
122
|
+
- `get_gre_tunnel` on each side: interface **running=yes** (keepalive up).
|
|
123
|
+
- If encrypted: `get_ipsec_active_peers` on both — an established SA proves the GRE
|
|
124
|
+
is actually protected. If there's no SA but GRE still pings, the traffic is
|
|
125
|
+
flowing in the CLEAR — stop and fix the IPsec policy.
|
|
126
|
+
- Large-payload test: ping size 1400 `do-not-fragment`; failure ⇒ revisit MTU/MSS.
|
|
127
|
+
|
|
128
|
+
## Bypassing country / DPI restrictions (legitimate censorship circumvention)
|
|
129
|
+
|
|
130
|
+
For lawful privacy / accessibility on networks you're authorized to use — comply
|
|
131
|
+
with local law and service terms. GRE is easy for a network to block (protocol 47
|
|
132
|
+
is uncommon and frequently filtered), so bypassing usually means **not sending raw
|
|
133
|
+
GRE across the hostile path**:
|
|
134
|
+
|
|
135
|
+
1. **Always encrypt and ride ESP/NAT-T.** Use `ipsec_secret` so the tunnel travels
|
|
136
|
+
as IPsec ESP over **UDP 4500** (NAT-T) rather than bare protocol 47 — 4500 is far
|
|
137
|
+
more likely to pass and the payload is hidden. This is the single biggest win.
|
|
138
|
+
2. **IKEv2 over a common UDP port.** IPsec IKEv2 (`setup-ipsec-site-to-site`) on
|
|
139
|
+
500/4500 is widely permitted; move to it if 47 and 4500 alike are throttled.
|
|
140
|
+
3. **Wrap the routed tunnel in a TLS-looking transport.** Where DPI blocks IKE/ESP
|
|
141
|
+
too, bring up an **SSTP** tunnel (PPP-over-TLS, **TCP 443** — looks like HTTPS)
|
|
142
|
+
or **OpenVPN TCP/443** between the sites and route the far LANs over that instead
|
|
143
|
+
of GRE, or run GRE _inside_ it. Trades throughput for reachability.
|
|
144
|
+
4. **Port/endpoint agility.** Use DDNS (`/ip cloud`) so a dynamic endpoint stays
|
|
145
|
+
reachable, and prefer common ports (443) for whatever encrypted transport carries
|
|
146
|
+
the tunnel.
|
|
147
|
+
5. **Advanced obfuscation via a RouterOS container.** The strongest anti-DPI tools
|
|
148
|
+
(XRay/VLESS+Reality, sing-box, Shadowsocks, obfs4) are **not native** to
|
|
149
|
+
RouterOS. Run one in a **`/container`** (or a VPS you control) and route the site
|
|
150
|
+
link through it. Heaviest option; confirm container support and spare resources
|
|
151
|
+
first.
|
|
152
|
+
|
|
153
|
+
GRE's strength is carrying multicast/dynamic routing, not stealth — if the user's
|
|
154
|
+
primary goal is _evading blocks_, recommend WireGuard or an SSTP/OpenVPN-TLS
|
|
155
|
+
transport (options above) and use GRE only inside that protected path. Never present
|
|
156
|
+
obfuscation as a guarantee — it is an arms race.
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
Report, per side: GRE interface name, remote/local addresses, transit IP, whether
|
|
161
|
+
IPsec is active (and proof of the SA), routes and firewall rules added, MTU/MSS
|
|
162
|
+
settings, and the verification results. State plainly which device each change ran
|
|
163
|
+
on. Never apply changes the user hasn't approved.
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: setup-ipip-tunnel-between-sites
|
|
3
|
+
title: Build an IPIP tunnel between two MikroTik devices
|
|
4
|
+
description: Configure BOTH routers of an IP-in-IP (IPIP) site-to-site tunnel from one conversation — endpoints, addressing, routing, MTU/MSS, and (recommended) IPsec encryption — then verify end to end. Includes DPI/censorship-bypass notes.
|
|
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 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: encrypt
|
|
16
|
+
description: Secure IPIP with IPsec (shared secret). Recommended — IPIP is cleartext. "yes" (default) or "no".
|
|
17
|
+
required: false
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
You are building an **IPIP (IP-in-IP) site-to-site tunnel between two MikroTik
|
|
21
|
+
routers** this server can both reach. IPIP is the **leanest L3 tunnel** — it
|
|
22
|
+
encapsulates unicast IPv4 in IPv4 with only 20 bytes of overhead (less than GRE),
|
|
23
|
+
but it carries **no multicast and no dynamic-routing protocols** (if you need OSPF
|
|
24
|
+
or multicast over the tunnel, use GRE instead — `setup-gre-tunnel-between-sites`).
|
|
25
|
+
Like GRE, **IPIP is unencrypted**, so secure it with IPsec unless the transport is
|
|
26
|
+
already trusted (this flow does by default). Drive **both** routers in one
|
|
27
|
+
conversation via the `device` argument. Confirm the plan before any change.
|
|
28
|
+
|
|
29
|
+
Device A: {{device_a}}
|
|
30
|
+
Device B: {{device_b}}
|
|
31
|
+
Transit subnet: {{tunnel_subnet}}
|
|
32
|
+
Encrypt with IPsec: {{encrypt}}
|
|
33
|
+
|
|
34
|
+
## 0. Discover and confirm both endpoints (FIRST)
|
|
35
|
+
|
|
36
|
+
- `list_mikrotik_devices`; resolve {{device_a}}/{{device_b}} against it — never
|
|
37
|
+
substitute a similar name. Ask which two if omitted.
|
|
38
|
+
- Both ends need to reach the other's public IP by **protocol 4 (IPIP)**. If a side
|
|
39
|
+
is behind NAT that doesn't forward protocol 4, prefer IPsec-encrypted IPIP (rides
|
|
40
|
+
ESP/UDP 4500) or WireGuard. Flag it.
|
|
41
|
+
|
|
42
|
+
## 1. Facts (read-only, per device)
|
|
43
|
+
|
|
44
|
+
For each side (`device=<name>`): `get_system_identity`, `list_interfaces`,
|
|
45
|
+
`list_ip_addresses`, `get_routing_table`, `get_ip_cloud`. Record public/WAN
|
|
46
|
+
address, WAN MTU, and LAN subnet(s). Confirm the two LANs do **not overlap**.
|
|
47
|
+
|
|
48
|
+
## 2. Addressing
|
|
49
|
+
|
|
50
|
+
Transit `{{tunnel_subnet}}` or a /30 that collides with neither LAN (A=.1, B=.2).
|
|
51
|
+
If encrypting, generate a strong shared secret to use as `ipsec_secret` on **both**
|
|
52
|
+
sides. Confirm interface names (`ipip-<peer>`), transit IPs, advertised LANs.
|
|
53
|
+
|
|
54
|
+
## 3. Create the IPIP interfaces (symmetric)
|
|
55
|
+
|
|
56
|
+
- On **A** (`device={{device_a}}`): `create_ipip_tunnel` — `name`=`ipip-{{device_b}}`,
|
|
57
|
+
`remote_address`=**B's** public IP, `local_address`=A's public IP,
|
|
58
|
+
`keepalive`=`10s,3`, `clamp_tcp_mss`=true, `ipsec_secret`=<secret> (if encrypting),
|
|
59
|
+
`mtu`=1480 (20 B overhead; ~1400 when also IPsec-wrapped).
|
|
60
|
+
- On **B**: mirror — `remote_address`=**A's** IP, `local_address`=B's IP, identical
|
|
61
|
+
`ipsec_secret`.
|
|
62
|
+
|
|
63
|
+
## 4. Address, route
|
|
64
|
+
|
|
65
|
+
- `add_ip_address` the transit IP on each ipip interface (A `10.255.255.1/30`, B `.2`).
|
|
66
|
+
- `add_route` far LAN via the tunnel on each side (A: dst=B-LAN gw=ipip iface; B mirror).
|
|
67
|
+
|
|
68
|
+
## 5. Firewall — safely, per device
|
|
69
|
+
|
|
70
|
+
Per side under Safe Mode (`enable_safe_mode`→edits→verify→`commit_safe_mode`; per-device):
|
|
71
|
+
|
|
72
|
+
- Unencrypted: `input` accept `protocol=ipip` from far WAN (cleartext — remind user).
|
|
73
|
+
- IPsec-encrypted: `input` accept `udp dst-port=500,4500` + `protocol=ipsec-esp`
|
|
74
|
+
from far WAN, placed high.
|
|
75
|
+
- `forward`: accept both LANs both directions. Do not masquerade the transit subnet.
|
|
76
|
+
|
|
77
|
+
## 6. MTU / MSS
|
|
78
|
+
|
|
79
|
+
IPIP = 20 B overhead (+ ~50 with IPsec). Set iface MTU ~1480 (~1400 encrypted),
|
|
80
|
+
keep `clamp_tcp_mss=true`, and/or a `forward` mangle `change-mss
|
|
81
|
+
new-mss=clamp-to-pmtu tcp-flags=syn`. Lower on PPPoE.
|
|
82
|
+
|
|
83
|
+
## 7. Verify
|
|
84
|
+
|
|
85
|
+
- `ping` (`device=A`) the transit IP, then a B-LAN host with `src_address`=A-LAN IP;
|
|
86
|
+
repeat from B.
|
|
87
|
+
- `get_ipip_tunnel` each side: running=yes. If encrypted, `get_ipsec_active_peers`
|
|
88
|
+
must show an established SA — no SA + tunnel pings ⇒ traffic is in the CLEAR, stop.
|
|
89
|
+
- Large payload: ping size 1400 do-not-fragment ⇒ MTU sanity.
|
|
90
|
+
|
|
91
|
+
## Bypassing country / DPI restrictions (legitimate circumvention)
|
|
92
|
+
|
|
93
|
+
Lawful privacy/accessibility only; comply with local law. Raw IPIP (protocol 4) is
|
|
94
|
+
easily filtered, so:
|
|
95
|
+
|
|
96
|
+
1. **Encrypt** so it rides IPsec ESP/UDP 4500 (much more likely to pass, payload
|
|
97
|
+
hidden) — the biggest win.
|
|
98
|
+
2. If IKE/ESP is also blocked, **wrap in a TLS transport** (SSTP or OpenVPN TCP/443,
|
|
99
|
+
see `setup-sstp-tunnel-between-sites` / `setup-openvpn-tunnel-between-sites`) and
|
|
100
|
+
route the far LANs over that.
|
|
101
|
+
3. Advanced: obfuscation (XRay/Reality, sing-box, Shadowsocks, obfs4) in a
|
|
102
|
+
**`/container`** or VPS — not native to RouterOS. Heaviest option.
|
|
103
|
+
IPIP's value is minimal overhead, not stealth — for evasion prefer a TLS transport
|
|
104
|
+
and keep IPIP only inside the protected path. Never present obfuscation as a guarantee.
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
Report per side: interface name, remote/local, transit IP, IPsec SA proof, routes +
|
|
109
|
+
firewall added, MTU/MSS, verification results. State which device each change ran on.
|
|
110
|
+
Never apply changes the user hasn't approved.
|