diff --git a/sysutils/git-backup/Makefile b/sysutils/git-backup/Makefile
new file mode 100644
index 000000000..4ef79984b
--- /dev/null
+++ b/sysutils/git-backup/Makefile
@@ -0,0 +1,6 @@
+PLUGIN_NAME= git-backup
+PLUGIN_VERSION= 0.1
+PLUGIN_COMMENT= Track config changes using git
+PLUGIN_MAINTAINER= ad@opnsense.org
+
+.include "../../Mk/plugins.mk"
\ No newline at end of file
diff --git a/sysutils/git-backup/pkg-descr b/sysutils/git-backup/pkg-descr
new file mode 100644
index 000000000..8aa28fb79
--- /dev/null
+++ b/sysutils/git-backup/pkg-descr
@@ -0,0 +1,3 @@
+This package adds a backup option using git version control.
+
+Due to the sensitive nature of the data being send to the backup, we strongly advise to not use a public service to send backups to.
diff --git a/sysutils/git-backup/src/opnsense/mvc/app/library/OPNsense/Backup/Git.php b/sysutils/git-backup/src/opnsense/mvc/app/library/OPNsense/Backup/Git.php
new file mode 100644
index 000000000..7bf0d47f1
--- /dev/null
+++ b/sysutils/git-backup/src/opnsense/mvc/app/library/OPNsense/Backup/Git.php
@@ -0,0 +1,127 @@
+ "enabled",
+ "type" => "checkbox",
+ "label" => gettext("Enable"),
+ "value" => null
+ ],
+ [
+ "name" => "url",
+ "type" => "text",
+ "label" => gettext("URL"),
+ "help" => gettext("Target location, which defined transport protocol, such as ssh://server/project.git or https://server/project.git."),
+ "value" => null
+ ],
+ [
+ "name" => "privkey",
+ "type" => "textarea",
+ "label" => gettext("SSH private key"),
+ "help" => gettext("When provided, ssh based authentication will be used."),
+ "value" => null
+ ],
+ [
+ "name" => "user",
+ "type" => "text",
+ "label" => gettext("User Name"),
+ "value" => null
+ ],
+ [
+ "name" => "password",
+ "type" => "password",
+ "label" => gettext("Password"),
+ "value" => null
+ ]
+ ];
+ $mdl = new GitSettings();
+ foreach ($fields as &$field) {
+ $field['value'] = (string)$mdl->getNodeByReference($field['name']);
+ }
+ return $fields;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function getName()
+ {
+ return gettext("Git");
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function setConfiguration($conf)
+ {
+ $mdl = new GitSettings();
+ $this->setModelProperties($mdl, $conf);
+ $validation_messages = $this->validateModel($mdl);
+ if (empty($validation_messages)) {
+ $mdl->serializeToConfig();
+ Config::getInstance()->save();
+ }
+ return $validation_messages;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function backup()
+ {
+ return ['config.xml'];
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function isEnabled()
+ {
+ return (string)(new GitSettings())->enabled === "1";
+ }
+}
diff --git a/sysutils/git-backup/src/opnsense/mvc/app/models/OPNsense/Backup/GitSettings.php b/sysutils/git-backup/src/opnsense/mvc/app/models/OPNsense/Backup/GitSettings.php
new file mode 100644
index 000000000..a1627abcd
--- /dev/null
+++ b/sysutils/git-backup/src/opnsense/mvc/app/models/OPNsense/Backup/GitSettings.php
@@ -0,0 +1,39 @@
+
+ //system/backup/git
+ 1.0.0
+ OPNsense Git Backup Settings
+
+
+ 0
+ Y
+
+
+ user.check001
+
+
+ url.check001
+
+
+
+
+ N
+ /^((https)|(ssh))?:\/\/.*[^\/]$/
+ A valid git location must be provided. e.g. ssh://server/project.git, https://server/project.git
+
+
+ A backup location (url) is required.
+ DependConstraint
+
+ enabled
+
+
+
+
+
+ N
+
+
+
+
+ A username is required.
+ DependConstraint
+
+ enabled
+
+
+
+
+
+
+
+