diff --git a/.gitignore b/.gitignore index 8951906..fdab21d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .ignore/ .idea/ .vscode/ +.agents/ diff --git a/README.md b/README.md index afee68c..d18aadc 100644 --- a/README.md +++ b/README.md @@ -14,9 +14,9 @@ This script allows you to generate daily backups of MikroTik and send them to an - Routerboard firmware can be upgraded automatically based on the installed RouterOS version. ## Script operating modes: -**Backups only** - The script generates system and configuration backups and forwards them to a specified email as attachments. It uses your email account as a storage for these backups. -**Backups and notifications about new RouterOS release** - In addition to creating backups, the script also monitors for any new releases of RouterOS firmware and communicates this information via email. -**Backups and automatic RouterOS upgrade** - The script begins by creating a backup, followed by a check for any new versions of RouterOS. If a newer firmware version is detected, the script initiates the upgrade process. Upon completion, two emails are sent: the first includes the system backups from the prior RouterOS version, and the second, sent post-upgrade, contains backups of the updated system. +- **Backups only** - The script generates system and configuration backups and forwards them to a specified email as attachments. It uses your email account as a storage for these backups. +- **Backups and notifications about new RouterOS release** - In addition to creating backups, the script also monitors for any new releases of RouterOS firmware and communicates this information via email. +- **Backups and automatic RouterOS upgrade** - The script begins by creating a backup, followed by a check for any new versions of RouterOS. If a newer firmware version is detected, the script initiates the upgrade process. Upon completion, two emails are sent: the first includes the system backups from the prior RouterOS version, and the second, sent post-upgrade, contains backups of the updated system. ## How to use > ❗️ **Important** @@ -24,18 +24,20 @@ This script allows you to generate daily backups of MikroTik and send them to an ##### 1. Configure parameters Take the [script](https://github.com/beeyev/Mikrotik-RouterOS-automatic-backup-and-update/raw/master/BackupAndUpdate.rsc) and configure it's parameters at the beginning of the file. -This step is straightforward as all parameters are well-commented. +This step is straightforward as all parameters are well-commented. **Important!** Don't forget to provide correct email address for backups and pay attention to `scriptMode` variable. ##### 2. Create new script -System -> Scripts [Add] +> In this example we use [WinBox](https://mikrotik.com/download/winbox) + +Go to: `System` -> `Scripts` and click the `[New]` button. **Important!** Script name must be `BackupAndUpdate` Insert the script which you configured earlier into the source area. ![](https://github.com/beeyev/Mikrotik-RouterOS-automatic-backup-and-update/raw/master/howto/script-name.png) ##### 3. Configure mail server -Tools -> Email +Go to: `Tools` -> `Email` and click the `[New]` button. Configure your email server parameters. If you don't have one, i recommend using the [smtp2go.com](https://smtp2go.com "smtp2go.com") service, which allows sending a thousand emails per month for free. ![](https://github.com/beeyev/Mikrotik-RouterOS-automatic-backup-and-update/raw/master/howto/email-config.png) @@ -45,7 +47,7 @@ To check email settings, send a test message by running the following command in ``` ##### 4. Create scheduled task -System -> Scheduler [Add] +Go to: `System` -> `Scheduler` and click the `[Add]` button. Name: `Backup And Update` Start Time: `03:10:00` (the start time has to be different for all your mikrotik devices in a chain) Interval: `1d 00:00:00` @@ -61,11 +63,6 @@ Once everything is set up, it's important to verify that the script is functioni To do this, open a New Terminal and a Log window in your WinBox, then manually execute the script by typing `/system script run BackupAndUpdate;` in the Terminal. You will see the script the script's operation in the log window. If the script completes without any errors, check your email. You'll find a new message with backups from your MikroTik awaiting you. 🎉 - - - - - ## Acknowledgements I would like to extend my sincere gratitude to the following individuals who have contributed to this project: - DJ5KP, website: [dj5kp.de](http://dj5kp.de/) diff --git a/howto/email-config.png b/howto/email-config.png index a29ed51..8a92120 100644 Binary files a/howto/email-config.png and b/howto/email-config.png differ diff --git a/howto/scheduler-task.png b/howto/scheduler-task.png index 60ad5ef..23d5547 100644 Binary files a/howto/scheduler-task.png and b/howto/scheduler-task.png differ diff --git a/howto/script-name.png b/howto/script-name.png index 5242b4a..3f1e936 100644 Binary files a/howto/script-name.png and b/howto/script-name.png differ diff --git a/lab/Makefile b/lab/Makefile new file mode 100644 index 0000000..e08c010 --- /dev/null +++ b/lab/Makefile @@ -0,0 +1,62 @@ +-include .docker-compose.env + +#export COMPOSE_FILE=docker-compose-dev.yml +# export COMPOSE_PROJECT_NAME=dev +export DOCKER_BUILDKIT?=1 +export COMPOSE_CONVERT_WINDOWS_PATHS?=1 +export TZ?=UTC +export BUILD_DATE?=$(shell TZ=":UTC" date '+%Y-%m-%d %H:%M:%S (%Z)') +.EXPORT_ALL_VARIABLES: +.PHONY: * +.DEFAULT_GOAL := help + +THIS_FILE := $(abspath $(lastword $(MAKEFILE_LIST))) +CURRENT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST)))) + +DOCKER_COMPOSE_COMMAND := $(shell \ + if docker compose version >/dev/null 2>&1; then echo "docker compose"; \ + elif docker-compose version >/dev/null 2>&1; then echo "docker-compose"; \ + else echo ""; fi) + +ifeq ($(DOCKER_COMPOSE_COMMAND),) + $(error "docker compose is required") +endif + +help: ## Show this help + @echo "Make Application Docker Images and Containers using Docker-Compose files in 'docker' Dir." + @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m (default: help)\n\nTargets:\n"} /^[a-zA-Z_-]+:.*?##/ { printf " \033[36m%-12s\033[0m %s\n", $$1, $$2 }' $(MAKEFILE_LIST) + +up: ## Docker compose up + $(DOCKER_COMPOSE_COMMAND) up --build --no-deps --detach --remove-orphans + +start: ## Alias for up + $(MAKE) up + +down: ## Docker compose down + $(DOCKER_COMPOSE_COMMAND) down --remove-orphans + +stop: ## Docker compose stop + $(DOCKER_COMPOSE_COMMAND) stop + +restart: ## Restart containers + $(MAKE) down + $(MAKE) up + $(info Restart completed) + +update: ## Update containers + $(DOCKER_COMPOSE_COMMAND) pull + $(MAKE) up + +destroy: ## Destroy containers/volumes (keep sources app folders) + $(MAKE) stop + $(DOCKER_COMPOSE_COMMAND) down --rmi all --remove-orphans + +rebuild: ## Rebuild docker container (destroy & upgrade) + $(MAKE) destroy + $(MAKE) up + +state: ## Show current state + $(DOCKER_COMPOSE_COMMAND) ps + +logs: ## Show docker logs + $(DOCKER_COMPOSE_COMMAND) logs -f --tail=100 $(ARGS) diff --git a/lab/README.md b/lab/README.md new file mode 100644 index 0000000..ccc5f98 --- /dev/null +++ b/lab/README.md @@ -0,0 +1,51 @@ +# Local RouterOS test lab + +This lab runs MikroTik RouterOS CHR for development and manual tests. + +## Start the lab + +```sh +make start +make state +``` + +RouterOS can take up to two minutes to accept SSH connections on its first boot. +The `routeros-init` container retries during that period and exits after it applies the mail settings. + +## Access + +| Service | Address | +| --- | --- | +| Mailpit web interface | | +| RouterOS WebFig | | +| RouterOS WinBox | `localhost:18291` | +| RouterOS SSH | `localhost:12222` | +| RouterOS Telnet | `localhost:12223` | +| RouterOS API | `localhost:18728` | +| RouterOS API over TLS | `localhost:18729` | + +!! Use the RouterOS user `admin` with an empty password. Use this account inside the isolated lab. + +## Mailpit and ping + +Expect `ping mailpit` from RouterOS to time out. Docker DNS still resolves the `mailpit` name, and SMTP traffic can reach port `1025`. +The Docker and QEMU network path does not provide a useful ICMP health check for this service. + +Test SMTP from a RouterOS terminal: + +```routeros +/tool e-mail send to="lab@example.test" subject="lab test" body="mail works" +``` + +Open and check that Mailpit received the message. Use message delivery as the health check for this lab. + +## Usage + +```routeros +/system script run BackupAndUpdate +``` + +Follow the script log while it runs: +```routeros +/log print follow where message~"Bkp&Upd" +``` diff --git a/lab/compose.yaml b/lab/compose.yaml new file mode 100644 index 0000000..f7f620b --- /dev/null +++ b/lab/compose.yaml @@ -0,0 +1,60 @@ +services: + + mailpit: + container_name: '${COMPOSE_PROJECT_NAME}-mailpit' + image: axllent/mailpit:latest + tty: true + restart: unless-stopped + environment: + - 'TZ=${TZ:-UTC}' + - 'MP_SMTP_AUTH_ACCEPT_ANY=1' + - 'MP_SMTP_AUTH_ALLOW_INSECURE=1' + - 'MP_ALLOW_UNTRUSTED_TLS=1' + ports: + - '8025:8025' # Web UI + networks: + - default + + routeros: + # https://github.com/EvilFreelancer/docker-routeros + # https://hub.docker.com/r/evilfreelancer/docker-routeros/ + container_name: '${COMPOSE_PROJECT_NAME}-routeros' + image: evilfreelancer/docker-routeros:7.21.4 + restart: unless-stopped + tty: true + depends_on: + mailpit: + condition: service_healthy + cap_add: + - NET_ADMIN + devices: + - /dev/net/tun + - /dev/kvm + ports: + - "12280:80" + - "12222:22" + - "12223:23" + - "18728:8728" + - "18729:8729" + - "18291:8291" + # The image keeps eth0 for QEMU host forwarding and bridges eth1 into CHR. + networks: + default: + interface_name: eth0 + routeros-lan: + interface_name: eth1 + + routeros-init: + build: + context: ./docker/routeros-init + restart: "no" + depends_on: + routeros: + condition: service_started + networks: + - default + + +networks: + routeros-lan: + driver: bridge diff --git a/lab/docker/routeros-init/Dockerfile b/lab/docker/routeros-init/Dockerfile new file mode 100644 index 0000000..4beefbd --- /dev/null +++ b/lab/docker/routeros-init/Dockerfile @@ -0,0 +1,9 @@ +FROM alpine:3.23 + +RUN apk add --no-cache openssh-client + +COPY routeros-init.sh /usr/local/bin/routeros-init + +RUN chmod +x /usr/local/bin/routeros-init + +ENTRYPOINT ["/usr/local/bin/routeros-init"] diff --git a/lab/docker/routeros-init/routeros-init.sh b/lab/docker/routeros-init/routeros-init.sh new file mode 100644 index 0000000..a6dd827 --- /dev/null +++ b/lab/docker/routeros-init/routeros-init.sh @@ -0,0 +1,23 @@ +#!/bin/sh +set -eu + +deadline="$(($(date +%s) + 120))" + +while [ "$(date +%s)" -lt "$deadline" ]; do + if ssh \ + -o StrictHostKeyChecking=no \ + -o UserKnownHostsFile=/dev/null \ + -o ConnectTimeout=5 \ + -o PreferredAuthentications=none \ + -o LogLevel=ERROR \ + admin@routeros \ + "/tool e-mail set server=mailpit port=1025 from=routeros@example.test tls=no"; then + echo "RouterOS e-mail settings applied." + exit 0 + fi + + sleep 2 +done + +echo "Timed out waiting for RouterOS SSH." >&2 +exit 1