Code Monkey home page Code Monkey logo

scripts-mikrotik's Introduction

n3t.uk Mikrotik RouterOS Scripts

This repository hosts a set of scripts, templates, and a Taskfile to manage the building of RouterOS scripts for multiple Mikrotik hosts (including routers, switches, and access points) using a centralised defined configuration, with emphasis on the management of VLANs and Firewall Rules.

Overview Diagram for Mikrotik Scripts

Warning

This repository is designed to specifically configure the multiple routers, switches, and access points that are used as part of the network for the n3t.uk Lab and Home environments. However, this is open-source and can be used by anyone for their own hosts if they so wish. Updates are welcome to help generalise and secure, if suitable.

Feel free to fork it, and if you wish to contribute back to the repository, see the document CONTRIBUTE.md for further details.

How Mikrotik Scripts Operates

The script is ultimately designed to take complete control of the hosts its configured for, although not every feature is supported. It's been written to support the most common and currently needed features for the n3t.uk network at this time.

This repository therefore operates in two parts:

Step Name Description
1. netinstall.scr Provide a baseline for each MikroTik host which should be installed as the default configuration using the netinstall-cli utility, and ensures that when a host is initiall configured or reset to the default configuration, it has secure settings and the management VLAN configured, allowing easy remote access to reconfigure.
2. update.scr Provides the up-to-date current configuration for each MikroTik host, installing the full initial configuration for all VLANs, Firewalls, User, Ports, etc., and updaing them as needed over time.

Once the netinstall.scr script is loaded onto a MikroTik host, and the define initialised, it should always be accessible within the network without needing physical access. The configuration will also facilitate the passing of management VLAN traffic over it (if configured to do so), so all MikroTik hosts, and other hosts directly connected to the management VLAN should remain accessible, even if no other traffic is allowed to pass.

That should allow each host to be loaded with the update.rsc script which sets it to the current full configuration of the interfaces, bridge, ports, VLANs, firewalls, and users, with that same script or similar exports) to then keep the host up-to-date.

Using Taskfile

Taskfiles is used to manage the running of the scripts, including the operation and dependencies of the scripts to build the configurations for all hosts, or just for selected hosts or exports, as required.

Run task --list to see all supported tasks:

$ task --list
task: Available tasks for this project:
* clean:         Clean up the temporary files from the repository
* default:       Run the default task (export)
* export:        Build and export the scripts for all hosts
* force:         Clean up and then re-export all scripts
* lint:          Check and lint files for correctness

Exporting Mikrotik Scripts

To build and export the configuration scripts for all known hosts and all known export types, just use force (which calls clean and then export) or just export.

Note

This repository does not, by default, include any configuration files for hosts or networks. As such, running export will not output any scripts. Instead example hosts and an example network are found within the examples/ directory, and can be test exported using examples rather than export.

$ task clean examples
task: [lint-yaml] yamllint -c .yamllint.yaml \
  {examples,hosts,networks}/*.yaml
task: [examples] scripts/exports  \
  | parallel -kj 10 scripts/export
==> ap/firewall
 -> Sourcing local://examples/ap.yaml
==> ap/netinstall
 -> Sourcing local://examples/ap.yaml
==> router/firewall
 -> Sourcing local://examples/router.yaml
==> switch/firewall
 -> Sourcing local://examples/switch.yaml
==> router/netinstall
 -> Sourcing local://examples/router.yaml
==> switch/netinstall
 -> Sourcing local://examples/switch.yaml

Or, when using export (or examples), you can select specific hosts or export types through a fuzzy search by appending the search term to the end of command-line (following --):

$ task clean examples -- switchfirewall
task: [lint-yaml] yamllint -c .yamllint.yaml \
  {examples,hosts,networks}/*.yaml
task: [examples] scripts/exports switchfirewall \
  | parallel -kj 10 scripts/export
==> switch/firewall
 -> Sourcing local://examples/switch.yaml

Export Types

netinstall.scr

task export -- netinstall

This is the "part 1" of the configuration and provides an .scr script which can be used with [netinstall-cli] to load a host with the default configuration that prepares that host for the network on first boot or configuration reset.

Specifically, most services are pre-configured (logging, graphing, services, DNS, NTP) and users are added with public SSH key for remote access.

Important

Users will be added by netinstall.scr with passwords (as this is required for /user add in RouterOS) but the password is thrown away. This is chosen as otherwise the password must be output to the system log or to a local file which would be open for all other users who have access. Users must first log in with their SSH private key and then set the password if WinBox or WebFig access is required. This will ensure that no one user can know more than their own password on any host.

The network is also configured by netinstall.scr, but only to support access to management VLAN. The management and blocked VLANs are created and interfaces are attached based on three rules:

  • If vlans: is set on the interface, and vlans contains the management VLAN, that interface is configured as tagged on management and untagged for blocked (and only VLAN-tagged frames are allowed);
  • If the above doesn't match, but vlan: is set, and its value is management, that interface is configured as untagged on management (and only untagged or priority tagged frames are allowed);
  • All other interfaces are configured as untagged on blocked (and only untagged or priority tagged frames are allowed).

As any host should have access to the management VLAN on its initial installation, or when reset to the default configuration, it should be possible to remotely access the host without any further access to the host. Additionally, as the management VLAN is supported in both tagged and untagged modes, any switch or router may connect to multiple MikroTik hosts, allowing them to all communicate over the management VLAN as normal.

As such, easy remote access to a host should be possible on reset, enabling an administrator to remotely log in over SSH and run the update scripts to install the full configuration of the current known network quickly.

Testing Default Configurations

Due to the way scripts are structured when making changes to resources (see Safe Changes of Live Configurations below), the netinstall.scr is not dependent on there being no resources present on the host to run successfully.

Although it is not recommended to run on a fully-configured system (it will most likely still work, even in this case, but it should remove all "unknown" VLANs and remove all but the basic Firewall rules, etc.), it is safe to run on a reset host. As such it allows for the rapid testing of the configuration on a fully reset host, including repeated re-running on the same host to validate the configuration.

update.rsc

task export -- update

The update.rsc export is in effect a superset of the following exports, with two exceptions:

  1. The SSH Host Private Key is not exported as this should normally only be set once. Use certificates.rsc to set the host private key, and as such should be exported and run explicitly once the host has been initialised or reset.
  2. The TLS Certificates needed to provide access to the WebFig and API services over HTTPS.
  3. The CAPsMAN Host Certificate and Client Authority Certificate will not be set, nor the Client Certificate on any Access Points.

This exported script is therefore the default script to be run once a device has been initialised or reset, and will bring the host up to the current network configuration. It is also probably the general script to run on most updates.

If the update needs to be more targeted, there are exported scripts to facilitate smaller sub-sets of changes, such as network.rsc and firewall.rsc.

certificates.rsc

task export -- certificates

The certificates.rsc export provides SSH- and certificate-specific and settings, should they be changed. More explicitly, this allows the configuration of the Host Private Key (and hence public key provided for clients to verify the host is who we expect them to be) and certificate public and private keys, which should be protected.

network.rsc

task export -- network

The network.rsc script is for the configuration of network settings, specifically:

  1. Update the basic settings on all physical interfaces (except mtu and l2mtu settings, as this can cause temporary interface resets and therefore packet drops);
  2. Update the bridge on the host and all of the bridge ports on the bridge, including default VLAN settings and frames permitted on ports, as well as costs and MSTP settings on the bridge and ports.
  3. CRUD the VLANs based on network changes as defined, and ensure that they are associated with the bridge ports and as tagged or untagged.

firewall.rsc

task export -- firewall

The firewall.rsc script is for the configuration of the firewall (both IPv4 and IPv6) on each host, updating the address lists as needed, and then update the firewall with the current set of rules.

Regardless of if there are IPv4 or IPv6 address settings defined, both versions of the firewall are installed; which ones are used therefore depend on which traffic the host is configured to support.

users.rsc

task export -- users

The users.rsc script is for the configuration of users on each host, and any SSH public keys for each users.

Important

Users will be added by users.rcs (like netinstall.scr above) with passwords (as this is required for /user add in RouterOS) but the password is thrown away. Users must either first log in with their SSH private key and then set the password if WinBox or WebFig access is required, or the administrator running user.rcs should manually update and then expire the password and pass it on to the user. This will ensure that no one user can know more than their own password on any host.

dns.rsc

task export -- dns

The dns.rsc script is for the configuration of static DNS records and the overall DNS settings of each host (i.e. the DNS server and DNS over HTTPS settings).

Safe Changes of Live Configurations

Although there are different ways to handle changes in configurations, such as by clearing out the existing settings and then replacing them, the templates here are designed to handle changes for live systems in a safe way. In most situations any change applied should not effect running system in a way which breaks existing processing (even momentarily).

For example, for static DNS records:

  1. Each record is wrapped into an :if () do={} statement which checks for its presence first, and if not present, then it is created;
  2. Any additional information which do not form part of the minimum required values (e.g. comment) is/are updated; then
  3. All entries for the record which do not match the known configuration are removed.

Note

This method ensures that new records are created before then removing those no longer required. Even if all records are changed in a single pass, both sets of records are present before the old set is removed. At no point should there be an empty set.

Alternately, for firewall rules:

  1. Each existing (or new) address list is (re)created with a new prefix (as set in the $rubId variable for each run of the script) within which contains the latest set of entries for each of the address lists (Any prefixed as dynamic: are not managed by scripts so are not touched);
  2. Each existing (or new) chain is (re)created with a new prefix (as set in the $runId variable for each run of the script) within which contains the latest set of rules for each chain;
  3. A new jump target is set in each of the default chains for each table which redirects traffic to the new set of chains, and then all other rules in the default chain which do not jump to the new $runId chains are removed.
  4. All existing address lists which do not have the $runId prefix are removed from the tables.
  5. All existing chains which do not have the $runId prefix are removed from the tables.

Note

This method ensures that two full sets of firewall chains, with jump rules in the default chains, are configured in all tables before the traffic is then switched by removing the old jump rule. This ensures that there are no partially complete chains while packets are being processed, and therefore not unintentionally blocked or allowing live packets in connections during updates. As all firewall chains either accept or deny traffic, traffic in the new chains will not be processed until the old jump rule is removed; an atomic change.

This is not a truly idempotent configuration in that there should be no changes made if the resources match what is defined, but it should make the changes atomic (e.g. packets are not processed by the new chain until the chain is fully created and the parent rule directing the jump to the chain is replaced).

Opinionated Network Settings

This script is designed with a specific purpose: To ease the day-to-day management of the network of the n3t.uk network for general home operation as well as the setup and communications in the n3t.uk Lab and Home environments. As such this script is not specifically for general configuration of any networks, but can be used as a base for that. Many of the names, options chose, and settings used, are opinionated for what I like to use and how I need the network to run.

Bridge and VLANs

Every connected MikroTik host operates though a combination of a single Bridge (not all hosts support hardware-accelerated multiple Bridges) and 802.1q VLANs to segment networks as required.

The Bridge (named bri01) is by default tagged, and the bridge and all trunk interfaces (i.e those with only vlans configured) are set to only accept packets with 802.1q tagged packets. Edge ports can have a combination of tagged and untagged support for various VLANs, as needed.

Management Port

Where a host has a Management Port, that will be named mgt01 and associated, untagged, with the management VLAN. This will allow access to the management network for maintenance and debugging on both the host itself, as well local connected hosts over the management VLAN.

Blocked VLAN

All ports which are unconnected and unused will be both disabled and associated with the Blocked VLAN (i.e. 99). As such, in the event that any port is accidentally enabled, the VLAN ensures that the connected host is still not able to access anything on the network, other than any other potential host connected to a blocked (but enabled) port.

This VLAN has no interface on any bridge on any host and has no DHCP server (either via IPv4 or IPv6, nor SLAAC enabled via IPv6). Any communications are local to the host itself too as this does not transit over any trunked physical interface.

Interface Naming

The following list is the set of standard base names of all interfaces within the n3t.uk network. These will be configured by the netinstall script, although the actual names are arbitrary and defined by the host configuration itself (hosts/{host}.yaml), and not the templates themselves. However, any default configurations may reference these (e.g. the default bridge name is set to bri01, but this may be configurable eventually).

Type Original Name Example
1000BASE-T ether{x} gbe{xx} gbe01
2500BASE-T ether{x} tge{xx} tge01
10GBASE-T ether{x} xge{xx} xge01
SFP sfp{x} sfp{xx} sfp01
SFP+ sfp-sfpplus{x} xfp{xx} xfp01
SFP28 sfp28-{x} tfp{xx} tfp01
QSFP+ qsftpplus{x}-{y} qfp{x}{y} qfp21
QSFP28 qsftp28-{x}-{y} ofp{x}{y} ofp32
Bridge bridge{x} bri{xx} bri01
VLAN vlan{x} bri{xx}.{yy} bri01.10
WAN ether{x} wan{xx} wan01
Management ether{x} mgt{xx} mgt01
WireGuard wg{x} wgd{xx} wgd01
WiFi (Main) wlan{x} wfi{ghz} wfi24 or wfi50
WiFi (Children) n/a wfi{ghz}.{xx} wfi24.22

Fixed Defaults

The following items are fixed defaults and should always be present for the templates to work correctly:

Type Name Description
VLAN management (name:) This VLAN name is searched for when managing some network interfaces, e.g. when setting network baseline during the netinstall export to inititally configure the network ports, so it should always be preset and be set to the VLAN ID associated with management network.
VLAN blocked (name:) This VLAN name is searched for when managing some network interfaces, e.g. when there is no pre-defined VLAN configuration on an interface, so it should always be present and set to the VLAN ID associated with blocked interfaces.
VLAN 1 (id:) This VLAN ID is a default when the blocked VLAN cannot be found, so it is not recommended to be used in normal circumstances. (This is also the default VLAN for ports without VLANs assigned to them too, and as such is a reserved VLAN ID.)
VLAN 2 (id:) This VLAN ID is a possible default when the management VLAN cannot be found, so it is not recommended to be used in normal circumstances.
VLAN 4095 (id:) This VLAN ID is not recommended for use in VLANs as it's a reserved ID.
Bridge bri01 (name:) This is the name of the default and only bridge configured by these scripts and when setting up the bridge ports it is this bridge they are connected to (unless bridge: false is set for the interface).

Configuration

The configuration for the networks and the associated host are handled by a number of configuration files within the repository, and potentially within Hashicorp Vault. Each level overrides the next and allows for general configurations with specific overrides, as needed.

File Description
networks/{name}.yaml This is the general settings of the local network, including the VLANs to be configured, and their network settings, as well as address lists, intereface lists, users, and other general settings. The file to be used is selected by the network: {name} setting in the host's configuration file.
hosts/{name}.yaml This is the configuration file for the specific MikroTik host. This should configure the local settings specific to each host, such as interface names, which VLANs are attached to ports, etc..
vault://{host}/{path} This is the configuration location for Vault-managed configurations and will be used to access (typically) secrets which should override values hosts/{name}.yaml. See examples/vault.json for an example of what can be supported.

Layout of Exports and Parts

The templates (exports) used within this repository are heavily broken down into smaller sections (parts), allowing them to be easily understood, and also to allow the to be re-used when building up the configuration for the different types of exports.

For example, the users.rsc.t file, which is used to manage /users and their public SSH keys for remote access, is used by the netinstall.scr.t export type when generating the initial configuration to be loaded onto a host, alongside the general deployment export type (update.rsc.t), and of course a dedicated users.rsc.t for exporting just changes to /users on hosts.

It is not included in the firewall.rsc.t export type as you don't need to update /users if you're just deploying changes to the firewall configuration.

Exporting is quick too. When run on an Intel 12th-gen laptop, it can generally export about 20-30 configurations per second, so even with a large number of hosts, or export types, it doesn't take long to collate the data and then build the scripts for the hosts. This can be improved further by limiting the outputs using a fuzzy matcher to build only selected configurations when needed as well (see #Using Taskfile above for details).

Authors

scripts-mikrotik's People

Contributors

jonathanio avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

scripts-mikrotik's Issues

Fix IPv6 BOGONs RAW Rules

The BOGON rules in the raw/prerouting chain seem to block significant types of traffic, including DHCPv6 traffic, causing issues.

The rules must be re-evaluated regarding what they capture and, subsequently, block, with a few to ensure that regular legitimate traffic is allowed through as expected.

Notes

Additional internal work may be needed to ensure IPv6 traffic is forwarded from the current edge router to the new edge router to facilitate testing.

Acceptance Criteria

  • Review the BOGONs for IPv6 and ensure that the allow and blocked lists contain everything they should do
  • Review the :bogon:check chain and determine why legitimate traffic is blocked.

Simplify SSH Checking Across Non-External Hosts

As a Network Engineer,
I want to simplify the rules for SSH traffic,
So that it is easier to control SSH traffic internally and externally.

Description

Currently, the :check:ssh rules are the same regardless of whether the host is internal-only or has external access. Although this is somewhat mute over IPv4 and IPv6 access, we should take a look at the :check:ssh to make sure that they are effective in both situations and also how the following address lists all work together:

  • :ssh:trusted
  • :ssh:controlled
  • ranges.ssh in {network}.yaml

Notes

There are multiple places to set allowed IP addresses, which cover /ip settings, /user set and :check:ssh rules in the filter table of the firewall. This should be analysed to ensure we effectively manage supersets and controls.

Acceptance Criteria

  • Ensure update of SSH settings for internal hosts only allowed accessible addresses.
  • Reduce the number of addresses that can configure the SSH service access.
  • Simplify :check:ssh for internal hosts.

Implemement IPv4/IPv6 Forwarding Rules Generation

As a Network Engineer
I want to control what traffic enters and leaves VLANs on a network
So that I can limit access to systems as services, as needed.

Description

Currently, the FORWARD chains are only ACCEPT for all traffic, which needs to be properly managed. We need a way to generate the address lists and/or rules in the FORWARD chains so they can be deployed and secure the network.

Notes

This will likely be a set of per-VLAN rules, although we probably want a way to group them, especially for some of my networks, which are grouped and will behave the same.

Acceptance Criteria

  • Update /ip settings and /ipv6 settings to blow IP forwarding on non-routing devices.
  • Create the templates required to generate IPv4 and IPv6 rules.
  • Create the address lists needed to build the forwarding rules to be deployed.

Implement CAPsMAN Support for Wireless Networks

As a Network Engineer,
I want to be able to configure CAPsMAN and link Access Points,
So that we can build and deploy a resilient wireless network.

Description

Currently, all networking configured is of the physical type (i.e., ethernet or sfp), but a wireless network is an important requirement. We need a way to set up CAPsMAN with the required certificates, link any access points, and configure the required wireless networks.

Notes

Do we want to combine all certificate exports into a single export?

Acceptance Criteria

  • Create the Intermediate CA Certificate for CAPsMAN and the Server Certificate.
  • Create the Client Certificates for each of the Access Points.
  • Create the template for configuring CAPsMAN on the management node and any required DNS entries.
  • Create the template for configuring access points with the client certificate and link to CAPsMAN.
  • Detech CAPsMAN management of wireless interfaces to bypass updates to some settings.
  • Create the export type for configuring certificates on a host.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.