Merge pull request #1 from BrandonSk/ftp_v2

Ftp v2
This commit is contained in:
Branislav Susila 2021-11-23 10:58:41 +01:00 committed by GitHub
commit 557994453e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 102 additions and 54 deletions

View file

@ -5,38 +5,61 @@
# Script: Mikrotik RouterOS automatic backup & update # Script: Mikrotik RouterOS automatic backup & update
# Version: 21.09.27 # Version: 21.09.27
# Created: 07/08/2018 # Created: 07/08/2018
# Updated: 27/09/2021 # Updated: 14/11/2021
# Author: Alexander Tebiev # Author: Alexander Tebiev
# Website: https://github.com/beeyev # Website: https://github.com/beeyev
# You can contact me by e-mail at tebiev@mail.com # You can contact me by e-mail at tebiev@mail.com
# #
# Fork author: Branislav Susila (https://github.com/BrandonSk)
# IMPORTANT! # IMPORTANT!
# Minimum supported RouterOS version is v6.43.7 # Minimum supported RouterOS version is v6.43.7; for SFTP 6.47.4 (bug fix)
# #
#----------MODIFY THIS SECTION AS NEEDED---------------------------------------- #----------MODIFY THIS SECTION AS NEEDED----------------------------------------
## ##
## FTP variables ## Define backup storage methods
## ##
# Set to true if you want to backup also to FTP, otherwise set to false # Set to true if you want to backup also to FTP, otherwise set to false
:local ftpBackupToFtp false; :local backupToFtp false;
# Specify FTP server address and port # Set to true if you want to send backups to email address
# When false and email address is specified, sumamry email will be sent
:local backupToEmail false;
##
## FTP definition
##
# Specify (S)FTP server address, port and if to use secure connection
:local ftpAddress 1.2.3.4; :local ftpAddress 1.2.3.4;
:local ftpPort 21; :local ftpPort 21;
:local ftpUseSecure false;
# Specify ftp user name and password # Specify ftp user name and password
:local ftpUser "ftp_user"; :local ftpUser "ftp_user";
:local ftpPass "ftp_password"; :local ftpPass "ftp_password";
# Define path on the FTP server where to store backups (! must end with / !). # Define path on the FTP server where to store backups (! must end with / !).
:local ftpDest "Path/On/FTP/Server/"; :local ftpDest "Path/On/FTP/Server/";
## Include backup files in email? When set to true, backups will be attached to email message. ##
## When false, email will include only text information, but no attachements. ## E-Mail settings
:local sendBackupToEmail false; ##
## Notification e-mail ## Notification e-mail
## (Make sure you have configurated Email settings in Tools -> Email) ## (Make sure you have configurated Email settings in Tools -> Email)
:local emailAddress "yourmail@example.com"; :local emailAddress "yourmail@example.com";
## Script mode, possible values: backup, osupdate, osnotify. ##
## BACKUP settings
##
## Additional parameter if you set `scriptMode` to `osupdate` or `osnotify` (see below)
# Set `true` if you want the script to perform backup every time it's fired, whatever script mode is set.
:local forceBackup false;
# Backup encryption password, no encryption if no password.
:local backupPassword ""
# If true, passwords will be included in exported config.
:local sensetiveDataInConfig false;
##
## UPDATE settings
##
# Script mode, possible values: backup, osupdate, osnotify.
# backup - Only backup will be performed. (default value, if none provided) # backup - Only backup will be performed. (default value, if none provided)
# #
# osupdate - The Script will install a new RouterOS if it is available. # osupdate - The Script will install a new RouterOS if it is available.
@ -47,26 +70,14 @@
# osnotify - The script will send email notification only (without backups) if a new RouterOS is available. # osnotify - The script will send email notification only (without backups) if a new RouterOS is available.
# Change parameter `forceBackup` if you need the script to create backups every time when it runs. # Change parameter `forceBackup` if you need the script to create backups every time when it runs.
:local scriptMode "backup"; :local scriptMode "backup";
# Update channel. Possible values: stable, long-term, testing, development
## Additional parameter if you set `scriptMode` to `osupdate` or `osnotify`
# Set `true` if you want the script to perform backup every time it's fired, whatever script mode is set.
:local forceBackup false;
## Backup encryption password, no encryption if no password.
:local backupPassword ""
## If true, passwords will be included in exported config.
:local sensetiveDataInConfig false;
## Update channel. Possible values: stable, long-term, testing, development
:local updateChannel "stable"; :local updateChannel "stable";
# Install only patch versions of RouterOS updates.
## Install only patch versions of RouterOS updates. # Works only if you set scriptMode to "osupdate"
## Works only if you set scriptMode to "osupdate" # Means that new update will be installed only if MAJOR and MINOR version numbers remained the same as currently installed RouterOS.
## Means that new update will be installed only if MAJOR and MINOR version numbers remained the same as currently installed RouterOS.
## Example: v6.43.6 => major.minor.PATCH
## Script will send information if new version is greater than just patch.
:local installOnlyPatchUpdates false; :local installOnlyPatchUpdates false;
# (Example: v6.43.6 => major.minor.PATCH)
# (Script will e-mail information if new version is greater than just patch.)
##------------------------------------------------------------------------------------------## ##------------------------------------------------------------------------------------------##
# !!!! DO NOT CHANGE ANYTHING BELOW THIS LINE, IF YOU ARE NOT SURE WHAT YOU ARE DOING !!!! # # !!!! DO NOT CHANGE ANYTHING BELOW THIS LINE, IF YOU ARE NOT SURE WHAT YOU ARE DOING !!!! #
@ -77,11 +88,14 @@
:log info "\r\n$SMP script \"Mikrotik RouterOS automatic backup & update\" started."; :log info "\r\n$SMP script \"Mikrotik RouterOS automatic backup & update\" started.";
:log info "$SMP Script Mode: $scriptMode, forceBackup: $forceBackup"; :log info "$SMP Script Mode: $scriptMode, forceBackup: $forceBackup";
:log info "$SMP backup to FTP: $backupToFtp, backup to E-mail: $backupToEmail";
#Check proper email config #Check proper email config
:if ([:len $emailAddress] = 0 or [:len [/tool e-mail get address]] = 0 or [:len [/tool e-mail get from]] = 0) do={ :if ([:len $emailAddress] = 0 or [:len [/tool e-mail get address]] = 0 or [:len [/tool e-mail get from]] = 0) do={
:log error ("$SMP Email configuration is not correct, please check Tools -> Email. Script stopped."); :log warning ("$SMP Email configuration is not correct, please check Tools -> Email.");
:error "$SMP bye!"; # :error "$SMP bye!";
# Set emailAddress to "" which will later indicate not to send any email.
:set emailAddress "";
} }
#Check if proper identity name is set #Check if proper identity name is set
@ -187,6 +201,9 @@ if ([:len [/system identity get name]] = 0 or [/system identity get name] = "Mik
:global buGlobalVarUpdateStep; :global buGlobalVarUpdateStep;
############### ^^^^^^^^^ GLOBALS ^^^^^^^^^ ############### ############### ^^^^^^^^^ GLOBALS ^^^^^^^^^ ###############
# For updates, we count how many 'external' storages (email, ftp) were successful. At least 1 is required for backup to proceed.
:local storedBackupsCounter 0;
# Counter for successfully uploaded files via FTP # Counter for successfully uploaded files via FTP
:local ftpUploadSuccess 0; :local ftpUploadSuccess 0;
@ -214,7 +231,7 @@ if ([:len [/system identity get name]] = 0 or [/system identity get name] = "Mik
:local mailBody ""; :local mailBody "";
:local mailBodyDeviceInfo "\r\n\r\nDevice information: \r\nIdentity: $deviceIdentityName \r\nModel: $deviceRbModel \r\nSerial number: $deviceRbSerialNumber \r\nCurrent RouterOS: $deviceOsVerInst ($[/system package update get channel]) $[/system resource get build-time] \r\nCurrent routerboard FW: $deviceRbCurrentFw \r\nDevice uptime: $[/system resource get uptime]"; :local mailBodyDeviceInfo "\r\n\r\nDevice information: \r\nIdentity: $deviceIdentityName \r\nModel: $deviceRbModel \r\nSerial number: $deviceRbSerialNumber \r\nCurrent RouterOS: $deviceOsVerInst ($[/system package update get channel]) $[/system resource get build-time] \r\nCurrent routerboard FW: $deviceRbCurrentFw \r\nDevice uptime: $[/system resource get uptime]";
:local mailBodyCopyright "\r\n\r\nMikrotik RouterOS automatic backup & update \r\nhttps://github.com/beeyev/Mikrotik-RouterOS-automatic-backup-and-update"; :local mailBodyCopyright "\r\n\r\nMikrotik RouterOS automatic backup & update \r\nhttps://github.com/BrandonSk/Mikrotik-RouterOS-automatic-backup-and-update-With-FTP \r\n(forked from: https://github.com/beeyev/Mikrotik-RouterOS-automatic-backup-and-update)";
:local changelogUrl ("Check RouterOS changelog: https://mikrotik.com/download/changelogs/" . $updateChannel . "-release-tree"); :local changelogUrl ("Check RouterOS changelog: https://mikrotik.com/download/changelogs/" . $updateChannel . "-release-tree");
:local backupName "$deviceIdentityName.$deviceRbModel.$deviceRbSerialNumber.v$deviceOsVerInst.$deviceUpdateChannel.$dateTime"; :local backupName "$deviceIdentityName.$deviceRbModel.$deviceRbSerialNumber.v$deviceOsVerInst.$deviceUpdateChannel.$dateTime";
@ -231,7 +248,7 @@ if ([:len [/system identity get name]] = 0 or [/system identity get name] = "Mik
} }
## STEP ONE: Creating backups, checking for new RouterOs version and sending email with backups, ## STEP ONE: Creating backups, checking for new RouterOs version and storing backups,
## steps 2 and 3 are fired only if script is set to automatically update device and if new RouterOs is available. ## steps 2 and 3 are fired only if script is set to automatically update device and if new RouterOs is available.
:if ($updateStep = 1) do={ :if ($updateStep = 1) do={
:log info ("$SMP Performing the first step."); :log info ("$SMP Performing the first step.");
@ -268,7 +285,7 @@ if ([:len [/system identity get name]] = 0 or [/system identity get name] = "Mik
:set scriptMode "backup"; :set scriptMode "backup";
}; };
if ($forceBackup = true and $sendBackupToEmail = true) do={ if ($forceBackup = true and $backupToEmail = true) do={
# In this case the script will always send email, because it has to create backups # In this case the script will always send email, because it has to create backups
:set isSendEmailRequired true; :set isSendEmailRequired true;
} }
@ -321,15 +338,15 @@ if ([:len [/system identity get name]] = 0 or [/system identity get name] = "Mik
:set mailSubject ($mailSubject . " Backup was created."); :set mailSubject ($mailSubject . " Backup was created.");
:set mailBody ($mailBody . "System backups were created "); :set mailBody ($mailBody . "System backups were created ");
if ($sendBackupToEmail = true) do={ if ($backupToEmail = true) do={
:set mailBody ($mailBody . "and attached to this email"); :set mailBody ($mailBody . "and attached to this email");
} }
if ($ftpBackupToFtp = true) do={ if ($backupToFtp = true) do={
:set mailBody ($mailBody . " and will be sent to FTP server."); :set mailBody ($mailBody . " and will be sent to FTP server.");
} else={ } else={
:set mailBody ($mailBody . "."); :set mailBody ($mailBody . ".");
} }
:set mailBody ($mailBody . "\r\n\r\n$mailBodyDeviceInfo $mailBodyCopyright");
:set mailAttachments [$buGlobalFuncCreateBackups backupName=$backupNameFinal backupPassword=$backupPassword sensetiveDataInConfig=$sensetiveDataInConfig]; :set mailAttachments [$buGlobalFuncCreateBackups backupName=$backupNameFinal backupPassword=$backupPassword sensetiveDataInConfig=$sensetiveDataInConfig];
} else={ } else={
:log info ("$SMP There is no need to create a backup."); :log info ("$SMP There is no need to create a backup.");
@ -372,7 +389,16 @@ if ([:len [/system identity get name]] = 0 or [/system identity get name] = "Mik
:log info "$SMP The final email with report and backups of upgraded system will be sent in a minute."; :log info "$SMP The final email with report and backups of upgraded system will be sent in a minute.";
:delay 1m; :delay 1m;
:set mailSubject ($mailSubject . " RouterOS Upgrade is completed, new version: v.$deviceOsVerInst!"); :set mailSubject ($mailSubject . " RouterOS Upgrade is completed, new version: v.$deviceOsVerInst!");
:set mailBody "RouterOS and routerboard upgrade process was completed. \r\nNew RouterOS version: v.$deviceOsVerInst, routerboard firmware: v.$deviceRbCurrentFw. \r\n$changelogUrl \r\n\r\nBackups of the upgraded system are in the attachment of this email. $mailBodyDeviceInfo $mailBodyCopyright"; :set mailBody "RouterOS and routerboard upgrade process was completed. \r\nNew RouterOS version: v.$deviceOsVerInst, routerboard firmware: v.$deviceRbCurrentFw. \r\n$changelogUrl \r\n\r\nBackups of the upgraded system were created ";
if ($backupToEmail = true) do={
:set mailBody ($mailBody . "and attached to this email");
}
if ($backupToFtp = true) do={
:set mailBody ($mailBody . " and will be sent to FTP server.");
} else={
:set mailBody ($mailBody . ".");
}
:set mailBody ($mailBody . "\r\n\r\n$mailBodyDeviceInfo $mailBodyCopyright");
:set mailAttachments [$buGlobalFuncCreateBackups backupName=$backupNameAfterUpd backupPassword=$backupPassword sensetiveDataInConfig=$sensetiveDataInConfig]; :set mailAttachments [$buGlobalFuncCreateBackups backupName=$backupNameAfterUpd backupPassword=$backupPassword sensetiveDataInConfig=$sensetiveDataInConfig];
} }
@ -381,14 +407,19 @@ if ([:len [/system identity get name]] = 0 or [/system identity get name] = "Mik
:do {/system script environment remove buGlobalFuncCreateBackups;} on-error={} :do {/system script environment remove buGlobalFuncCreateBackups;} on-error={}
## ##
## UPLOAD VIA FTP ## UPLOAD VIA (S)FTP
## ##
# Try to upload backup files to FTP server # Try to upload backup files to FTP server
:if ($ftpBackupToFtp = true) do={ :if ($backupToFtp = true) do={
:log info "$SMP Trying to upload backup files to server $ftpAddress"; :log info "$SMP Trying to upload backup files to server $ftpAddress";
:foreach flnm in=$mailAttachments do={ :foreach flnm in=$mailAttachments do={
:do {/tool fetch mode=ftp address="$ftpAddress" port="$ftpPort" user="$ftpUser" password="$ftpPass" src-path="$flnm" dst-path=("$ftpDest" . "$flnm") upload=yes; :do {
if ($ftpUseSecure = true) do={
/tool fetch upload=yes url=("sftp://" . $ftpAddress . ":" . $ftpPort . "/" . $ftpDest . $flnm) src-path="$flnm" user="$ftpUser" password="$ftpPass";
} else {
/tool fetch mode=ftp address="$ftpAddress" port="$ftpPort" user="$ftpUser" password="$ftpPass" src-path="$flnm" dst-path=("$ftpDest" . "$flnm") upload=yes;
}
# Increase number of successfully uploaded files # Increase number of successfully uploaded files
:set ftpUploadSuccess ($ftpUploadSuccess +1); :set ftpUploadSuccess ($ftpUploadSuccess +1);
} on-error={ } on-error={
@ -400,6 +431,7 @@ if ([:len [/system identity get name]] = 0 or [/system identity get name] = "Mik
:set mailBody ($mailBody . "\r\n\r\nWARNING!\r\nBackups of the system failed to upload to FTP server.\r\n"); :set mailBody ($mailBody . "\r\n\r\nWARNING!\r\nBackups of the system failed to upload to FTP server.\r\n");
} }
} }
:if ($ftpUploadSuccess = 2) do={:set storedBackupsCounter ($storedBackupsCounter +1);}
} }
## ##
@ -409,21 +441,18 @@ if ([:len [/system identity get name]] = 0 or [/system identity get name] = "Mik
:if ($isSendEmailRequired = true) do={ :if ($isSendEmailRequired = true) do={
:log info "$SMP Sending email message, it will take around half a minute..." :log info "$SMP Sending email message, it will take around half a minute..."
:if ($sendBackupToEmail = true) do={ :if ($backupToEmail = true) do={
:do {/tool e-mail send to=$emailAddress subject=$mailSubject body=$mailBody file=$mailAttachments; :do {/tool e-mail send to=$emailAddress subject=$mailSubject body=$mailBody file=$mailAttachments;
:set storedBackupsCounter ($storedBackupsCounter +1);
} on-error={ } on-error={
:delay 5s; :delay 5s;
:log error "$SMP could not send email message ($[/tool e-mail get last-status]). Going to try it again in a while."; :log error "$SMP could not send email message ($[/tool e-mail get last-status]). Going to try it again in a while.";
:delay 5m; :delay 5m;
:do {/tool e-mail send to=$emailAddress subject=$mailSubject body=$mailBody file=$mailAttachments; :do {/tool e-mail send to=$emailAddress subject=$mailSubject body=$mailBody file=$mailAttachments;
:set storedBackupsCounter ($storedBackupsCounter +1);
} on-error={ } on-error={
:delay 5s; :delay 5s;
:log error "$SMP could not send email message ($[/tool e-mail get last-status]) for the second time." :log error "$SMP could not send email message ($[/tool e-mail get last-status]) for the second time."
if ($isOsNeedsToBeUpdated = true and $ftpBackupToFtp = false) do={
:set isOsNeedsToBeUpdated false;
:log warning "$SMP script is not going to initialise update process due to inability to send backups to email and FTP."
}
} }
} }
} else={ } else={
@ -436,11 +465,6 @@ if ([:len [/system identity get name]] = 0 or [/system identity get name] = "Mik
:do {/tool e-mail send to=$emailAddress subject=$mailSubject body=$mailBody;} on-error={ :do {/tool e-mail send to=$emailAddress subject=$mailSubject body=$mailBody;} on-error={
:delay 5s; :delay 5s;
:log error "$SMP could not send email message ($[/tool e-mail get last-status]) for the second time." :log error "$SMP could not send email message ($[/tool e-mail get last-status]) for the second time."
if ($ftpBackupToFtp = false) do={
:set isOsNeedsToBeUpdated false;
:log warning "$SMP script is not going to initialise update process due to inability to send backups to FTP."
}
} }
} }
} }
@ -448,16 +472,15 @@ if ([:len [/system identity get name]] = 0 or [/system identity get name] = "Mik
:delay 30s; :delay 30s;
# Cleanup will be performed if there are backup files AND at least one of the email or ftp upload had succeeded. # Cleanup will be performed if there are backup files AND at least one of the email or ftp upload had succeeded.
:if ([:len $mailAttachments] > 0 and ([/tool e-mail get last-status] = "succeeded" or ([:len $mailAttachments] = $ftpUploadSuccess))) do={ :if ($storedBackupsCounter > 0) do={
:log info "$SMP File system cleanup." :log info "$SMP File system cleanup."
/file remove $mailAttachments; /file remove $mailAttachments;
:delay 2s; :delay 2s;
} }
} }
# Fire RouterOs update process # Fire RouterOs update process
if ($isOsNeedsToBeUpdated = true) do={ if ($isOsNeedsToBeUpdated = true and $storedBackupsCounter > 0) do={
## Set scheduled task to upgrade routerboard firmware on the next boot, task will be deleted when upgrade is done. (That is why you should keep original script name) ## Set scheduled task to upgrade routerboard firmware on the next boot, task will be deleted when upgrade is done. (That is why you should keep original script name)
/system schedule add name=BKPUPD-UPGRADE-ON-NEXT-BOOT on-event=":delay 5s; /system scheduler remove BKPUPD-UPGRADE-ON-NEXT-BOOT; :global buGlobalVarUpdateStep 2; :delay 10s; /system script run BackupAndUpdate;" start-time=startup interval=0; /system schedule add name=BKPUPD-UPGRADE-ON-NEXT-BOOT on-event=":delay 5s; /system scheduler remove BKPUPD-UPGRADE-ON-NEXT-BOOT; :global buGlobalVarUpdateStep 2; :delay 10s; /system script run BackupAndUpdate;" start-time=startup interval=0;
@ -465,6 +488,11 @@ if ($isOsNeedsToBeUpdated = true) do={
:log info "$SMP everything is ready to install new RouterOS, going to reboot in a moment!" :log info "$SMP everything is ready to install new RouterOS, going to reboot in a moment!"
## command is reincarnation of the "upgrade" command - doing exactly the same but under a different name ## command is reincarnation of the "upgrade" command - doing exactly the same but under a different name
/system package update install; /system package update install;
} else {
if ($isOsNeedsToBeUpdated = true) do {
:set isOsNeedsToBeUpdated false;
:log warning "$SMP script is not going to initialise update process due to inability to send backups to email and/or FTP."
}
} }
:log info "$SMP script \"Mikrotik RouterOS automatic backup & update\" completed it's job.\r\n"; :log info "$SMP script \"Mikrotik RouterOS automatic backup & update\" completed it's job.\r\n";

View file

@ -2,6 +2,26 @@
This script provides an ability to create Mikrotik's daily backups to email. You can also enable automatic RouterOS upgrade or leave only notifications about new firmware versions. This script provides an ability to create Mikrotik's daily backups to email. You can also enable automatic RouterOS upgrade or leave only notifications about new firmware versions.
# (S)FTP v2 fork
## Added features:
- Ability to store backups via FTP or SFTP
#### New/Modified configuration options
At the beginning of the file are added these variables:
- backupToFtp -> set to true if you want to backup to FTP or SFTP server
- backupToEmail -> set to true if you want to send backup files to email address
- (you may use both options at the same time)
FTP parameters:
- ftpAddress 1.2.3.4 -> specify IP address of the (S)FTP server
- ftpPort -> set (S)FTP address port;
- ftpUseSecure -> set to true if you want to use SFTP, otherwise FTP will be used.
- ftpUser -> Set your FTP username
- ftpPass -> Set your FTP user password
- ftpDest -> Set path on your S(FTP) server. Must include trailing "/".
### The rest of the original README:
## Features: ## Features:
- Ability to choose script operating mode according to your needs. *(Read below)* - Ability to choose script operating mode according to your needs. *(Read below)*
- Script creates backups of the whole system and exported config. - Script creates backups of the whole system and exported config.