diff --git a/net-mgmt/zabbix-agent/Makefile b/net-mgmt/zabbix-agent/Makefile
new file mode 100644
index 000000000..9aad3a194
--- /dev/null
+++ b/net-mgmt/zabbix-agent/Makefile
@@ -0,0 +1,8 @@
+PLUGIN_NAME= zabbix-agent
+PLUGIN_VERSION= 0.1
+PLUGIN_COMMENT= Enterprise-class open source distributed monitoring agent
+PLUGIN_DEPENDS= zabbix32-agent
+PLUGIN_DEVEL= yes
+PLUGIN_MAINTAINER= opnsense@moov.de
+
+.include "../../Mk/plugins.mk"
diff --git a/net-mgmt/zabbix-agent/pkg-descr b/net-mgmt/zabbix-agent/pkg-descr
new file mode 100644
index 000000000..e16a89206
--- /dev/null
+++ b/net-mgmt/zabbix-agent/pkg-descr
@@ -0,0 +1 @@
+Manage the Zabbix Agent to allow OPNsense to be monitored by a Zabbix Server.
diff --git a/net-mgmt/zabbix-agent/src/etc/inc/plugins.inc.d/zabbixagent.inc b/net-mgmt/zabbix-agent/src/etc/inc/plugins.inc.d/zabbixagent.inc
new file mode 100644
index 000000000..709d9c49c
--- /dev/null
+++ b/net-mgmt/zabbix-agent/src/etc/inc/plugins.inc.d/zabbixagent.inc
@@ -0,0 +1,86 @@
+registerAnchor('zabbix-agent/*', 'nat');
+ $fw->registerAnchor('zabbix-agent/*', 'rdr');
+ $fw->registerAnchor('zabbix-agent/*', 'fw');
+}
+
+/**
+ * register legacy service
+ * @return array
+ */
+function zabbixagent_services()
+{
+ $services = array();
+
+ if (!zabbixagent_enabled()) {
+ return $services;
+ }
+
+ $services[] = array(
+ 'description' => gettext('Enterprise-class open source distributed monitoring agent'),
+ 'pidfile' => '/var/run/zabbix/zabbix_agentd.pid',
+ 'configd' => array(
+ 'restart' => array('zabbix_agentd restart'),
+ 'start' => array('zabbix_agentd start'),
+ 'stop' => array('zabbix_agentd stop'),
+ ),
+ 'name' => 'zabbix_agentd',
+ );
+
+ return $services;
+}
+
+/**
+ * sync configuration via xmlrpc
+ * @return array
+ */
+
+function zabbixagent_xmlrpc_sync()
+{
+ $result = array();
+ $result['id'] = 'zabbixagent';
+ $result['section'] = 'OPNsense.zabbixagent.settings';
+ $result['description'] = gettext('Enterprise-class open source distributed monitoring agent');
+ return array($result);
+}
diff --git a/net-mgmt/zabbix-agent/src/opnsense/mvc/app/controllers/OPNsense/ZabbixAgent/Api/ServiceController.php b/net-mgmt/zabbix-agent/src/opnsense/mvc/app/controllers/OPNsense/ZabbixAgent/Api/ServiceController.php
new file mode 100644
index 000000000..35c66c70b
--- /dev/null
+++ b/net-mgmt/zabbix-agent/src/opnsense/mvc/app/controllers/OPNsense/ZabbixAgent/Api/ServiceController.php
@@ -0,0 +1,153 @@
+request->isPost()) {
+ $backend = new Backend();
+ $response = $backend->configdRun("zabbixagent start", true);
+ return array("response" => $response);
+ } else {
+ return array("response" => array());
+ }
+ }
+
+ /**
+ * stop zabbix agent service
+ * @return array
+ */
+ public function stopAction()
+ {
+ if ($this->request->isPost()) {
+ $backend = new Backend();
+ $response = $backend->configdRun("zabbixagent stop");
+ return array("response" => $response);
+ } else {
+ return array("response" => array());
+ }
+ }
+
+ /**
+ * restart zabbix agent service
+ * @return array
+ */
+ public function restartAction()
+ {
+ if ($this->request->isPost()) {
+ $backend = new Backend();
+ $response = $backend->configdRun("zabbixagent restart");
+ return array("response" => $response);
+ } else {
+ return array("response" => array());
+ }
+ }
+
+ /**
+ * retrieve status of zabbix agent service
+ * @return array
+ * @throws \Exception
+ */
+ public function statusAction()
+ {
+ $backend = new Backend();
+ $mdlAgent = new ZabbixAgent();
+ $response = $backend->configdRun("zabbixagent status");
+
+ if (strpos($response, "not running") > 0) {
+ if ($mdlAgent->settings->main->enabled->__toString() == "1") {
+ $status = "stopped";
+ } else {
+ $status = "disabled";
+ }
+ } elseif (strpos($response, "is running") > 0) {
+ $status = "running";
+ } elseif ($mdlAgent->settings->main->enabled->__toString() == "0") {
+ $status = "disabled";
+ } else {
+ $status = "unkown";
+ }
+
+ return array("status" => $status);
+ }
+
+ /**
+ * reconfigure zabbix agent, generate config and reload
+ */
+ public function reconfigureAction()
+ {
+ if ($this->request->isPost()) {
+ $force_restart = false;
+ // close session for long running action
+ $this->sessionClose();
+
+ $mdlAgent = new ZabbixAgent();
+ $backend = new Backend();
+
+ $runStatus = $this->statusAction();
+
+ // stop zabbix agent when disabled
+ if ($runStatus['status'] == "running" &&
+ ($mdlAgent->settings->main->enabled->__toString() == "0" || $force_restart)) {
+ $this->stopAction();
+ }
+
+ // generate template
+ $backend->configdRun('template reload OPNsense/ZabbixAgent');
+
+ // (res)start daemon
+ if ($mdlAgent->settings->main->enabled->__toString() == "1") {
+ if ($runStatus['status'] == "running" && !$force_restart) {
+ $backend->configdRun("zabbixagent reconfigure");
+ } else {
+ $this->startAction();
+ }
+ }
+
+ return array("status" => "ok");
+ } else {
+ return array("status" => "failed");
+ }
+ }
+}
diff --git a/net-mgmt/zabbix-agent/src/opnsense/mvc/app/controllers/OPNsense/ZabbixAgent/Api/SettingsController.php b/net-mgmt/zabbix-agent/src/opnsense/mvc/app/controllers/OPNsense/ZabbixAgent/Api/SettingsController.php
new file mode 100644
index 000000000..8140652f0
--- /dev/null
+++ b/net-mgmt/zabbix-agent/src/opnsense/mvc/app/controllers/OPNsense/ZabbixAgent/Api/SettingsController.php
@@ -0,0 +1,45 @@
+view->title = gettext('Zabbix Agent Settings');
+ // include form definitions
+ $this->view->settingsForm = $this->getForm("settings");
+ // pick the template to serve
+ $this->view->pick('OPNsense/ZabbixAgent/index');
+ }
+}
diff --git a/net-mgmt/zabbix-agent/src/opnsense/mvc/app/controllers/OPNsense/ZabbixAgent/forms/settings.xml b/net-mgmt/zabbix-agent/src/opnsense/mvc/app/controllers/OPNsense/ZabbixAgent/forms/settings.xml
new file mode 100644
index 000000000..9eeb9c64c
--- /dev/null
+++ b/net-mgmt/zabbix-agent/src/opnsense/mvc/app/controllers/OPNsense/ZabbixAgent/forms/settings.xml
@@ -0,0 +1,129 @@
+
+ {% for tab in settingsForm['tabs']|default([]) %}
+ {% if tab['subtabs']|default(false) %}
+ {# Tab with dropdown #}
+ {% for subtab in tab['subtabs']|default({})%}
+
+ {{ partial("layout_partials/base_form",['fields':subtab[2],'id':'frm_'~subtab[0],'data_title':subtab[1],'apply_btn_id':'save_'~subtab[0]])}}
+
+ {% endfor %}
+ {% endif %}
+ {% if tab['subtabs']|default(false)==false %}
+
+ {{ partial("layout_partials/base_form",['fields':tab[2],'id':'frm_'~tab[0],'apply_btn_id':'save_'~tab[0]])}}
+
+ {% endif %}
+ {% endfor %}
+
diff --git a/net-mgmt/zabbix-agent/src/opnsense/scripts/OPNsense/ZabbixAgent/setup.sh b/net-mgmt/zabbix-agent/src/opnsense/scripts/OPNsense/ZabbixAgent/setup.sh
new file mode 100755
index 000000000..29ed6bcb8
--- /dev/null
+++ b/net-mgmt/zabbix-agent/src/opnsense/scripts/OPNsense/ZabbixAgent/setup.sh
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+AGENT_DIRS="/var/run/zabbix /var/log/zabbix /usr/local/etc/zabbix_agentd.conf.d"
+
+for directory in ${AGENT_DIRS}; do
+ mkdir -p ${directory}
+ chown -R zabbix:zabbix ${directory}
+ chmod -R 770 ${directory}
+done
+
+exit 0
diff --git a/net-mgmt/zabbix-agent/src/opnsense/service/conf/actions.d/actions_zabbixagent.conf b/net-mgmt/zabbix-agent/src/opnsense/service/conf/actions.d/actions_zabbixagent.conf
new file mode 100644
index 000000000..ec61e646b
--- /dev/null
+++ b/net-mgmt/zabbix-agent/src/opnsense/service/conf/actions.d/actions_zabbixagent.conf
@@ -0,0 +1,29 @@
+[start]
+command:/usr/local/opnsense/scripts/OPNsense/ZabbixAgent/setup.sh; /usr/local/etc/rc.d/zabbix_agentd start
+parameters:
+type:script
+message:starting zabbix_agentd
+
+[stop]
+command:/usr/local/etc/rc.d/zabbix_agentd stop; /usr/bin/killall zabbix_agentd; exit 0
+parameters:
+type:script
+message:stopping zabbix_agentd
+
+[restart]
+command:/usr/local/opnsense/scripts/OPNsense/ZabbixAgent/setup.sh; /usr/local/etc/rc.d/zabbix_agentd restart
+parameters:
+type:script
+message:restarting zabbix_agentd
+
+[status]
+command:/usr/local/etc/rc.d/zabbix_agentd status
+parameters:
+type:script_output
+message:requesting zabbix_agentd status
+
+[reconfigure]
+command:/usr/local/opnsense/scripts/OPNsense/ZabbixAgent/setup.sh; /usr/local/etc/rc.d/zabbix_agentd restart
+parameters:
+type:script
+message:reconfiguring zabbix_agentd
diff --git a/net-mgmt/zabbix-agent/src/opnsense/service/templates/OPNsense/ZabbixAgent/+TARGETS b/net-mgmt/zabbix-agent/src/opnsense/service/templates/OPNsense/ZabbixAgent/+TARGETS
new file mode 100644
index 000000000..bf7196672
--- /dev/null
+++ b/net-mgmt/zabbix-agent/src/opnsense/service/templates/OPNsense/ZabbixAgent/+TARGETS
@@ -0,0 +1,2 @@
+zabbix_agentd.conf:/usr/local/etc/zabbix_agentd.conf
+rc.conf.d:/etc/rc.conf.d/zabbix_agentd
diff --git a/net-mgmt/zabbix-agent/src/opnsense/service/templates/OPNsense/ZabbixAgent/rc.conf.d b/net-mgmt/zabbix-agent/src/opnsense/service/templates/OPNsense/ZabbixAgent/rc.conf.d
new file mode 100644
index 000000000..2e9281997
--- /dev/null
+++ b/net-mgmt/zabbix-agent/src/opnsense/service/templates/OPNsense/ZabbixAgent/rc.conf.d
@@ -0,0 +1,7 @@
+{% if helpers.exists('OPNsense.ZabbixAgent.settings.main.enabled') and OPNsense.ZabbixAgent.settings.main.enabled|default("0") == "1" %}
+zabbix_agentd_enable=YES
+zabbix_agentd_opnsense_bootup_run="/usr/local/opnsense/scripts/OPNsense/ZabbixAgent/setup.sh"
+{% else %}
+zabbix_agentd_enable=NO
+{% endif %}
+zabbix_agentd_config=/usr/local/etc/zabbix_agentd.conf
diff --git a/net-mgmt/zabbix-agent/src/opnsense/service/templates/OPNsense/ZabbixAgent/zabbix_agentd.conf b/net-mgmt/zabbix-agent/src/opnsense/service/templates/OPNsense/ZabbixAgent/zabbix_agentd.conf
new file mode 100644
index 000000000..abc2e806e
--- /dev/null
+++ b/net-mgmt/zabbix-agent/src/opnsense/service/templates/OPNsense/ZabbixAgent/zabbix_agentd.conf
@@ -0,0 +1,308 @@
+#
+# Automatically generated configuration.
+# Do not edit this file manually.
+
+{% if helpers.exists('OPNsense.ZabbixAgent.settings') %}
+
+# This is a config file for zabbix agent (unix)
+# to get more information about zabbix, visit http://www.zabbix.com
+
+############ GENERAL PARAMETERS #################
+
+### Option: PidFile
+# Name of PID file.
+#
+PidFile=/var/run/zabbix/zabbix_agentd.pid
+
+### Option: LogType
+# Specifies where log messages are written to:
+# system - syslog
+# file - file specified with LogFile parameter
+# console - standard output
+#
+LogType=file
+
+### Option: LogFile
+# Log file name for LogType 'file' parameter.
+#
+LogFile=/var/log/zabbix/zabbix_agentd.log
+
+### Option: LogFileSize
+# Maximum size of log file in MB.
+# 0 - disable automatic log rotation.
+#
+LogFileSize={{OPNsense.ZabbixAgent.settings.main.logFileSize}}
+
+### Option: DebugLevel
+# Specifies debug level
+# 0 - basic information about starting and stopping of Zabbix processes
+# 1 - critical information
+# 2 - error information
+# 3 - warnings
+# 4 - for debugging (produces lots of information)
+# 5 - extended debugging (produces even more information)
+DebugLevel={{OPNsense.ZabbixAgent.settings.main.debugLevel|replace("val_", "")}}
+
+### Option: SourceIP
+# Source IP address for outgoing connections.
+#
+{% if helpers.exists('OPNsense.ZabbixAgent.settings.main.sourceIP') %}
+SourceIP={{OPNsense.ZabbixAgent.settings.main.sourceIP}}
+{% endif %}
+
+### Option: EnableRemoteCommands
+# Whether remote commands from Zabbix server are allowed.
+# 0 - not allowed
+# 1 - allowed
+#
+EnableRemoteCommands={{OPNsense.ZabbixAgent.settings.features.enableRemoteCommands}}
+
+### Option: LogRemoteCommands
+# Enable logging of executed shell commands as warnings.
+# 0 - disabled
+# 1 - enabled
+#
+LogRemoteCommands={{OPNsense.ZabbixAgent.settings.features.logRemoteCommands}}
+
+##### Passive checks related
+
+### Option: Server
+# List of comma delimited IP addresses (or hostnames) of Zabbix servers.
+# Incoming connections will be accepted only from the hosts listed here.
+# If IPv6 support is enabled then '127.0.0.1', '::127.0.0.1', '::ffff:127.0.0.1' are treated equally.
+#
+Server={{OPNsense.ZabbixAgent.settings.main.serverList}}
+
+### Option: ListenPort
+# Agent will listen on this port for connections from the server.
+#
+ListenPort={{OPNsense.ZabbixAgent.settings.main.listenPort}}
+
+### Option: ListenIP
+# List of comma delimited IP addresses that the agent should listen on.
+# First IP address is sent to Zabbix server if connecting to it to retrieve list of active checks.
+#
+ListenIP={{OPNsense.ZabbixAgent.settings.main.listenIP}}
+
+### Option: StartAgents
+# Number of pre-forked instances of zabbix_agentd that process passive checks.
+# If set to 0, disables passive checks and the agent will not listen on any TCP port.
+#
+StartAgents={{OPNsense.ZabbixAgent.settings.tuning.startAgents}}
+
+##### Active checks related
+
+### Option: ServerActive
+# List of comma delimited IP:port (or hostname:port) pairs of Zabbix servers for active checks.
+# If port is not specified, default port is used.
+# IPv6 addresses must be enclosed in square brackets if port for that host is specified.
+# If port is not specified, square brackets for IPv6 addresses are optional.
+# If this parameter is not specified, active checks are disabled.
+# Example: ServerActive=127.0.0.1:20051,zabbix.domain,[::1]:30051,::1,[12fc::1]
+#
+{% if OPNsense.ZabbixAgent.settings.features.enableActiveChecks == '1' and OPNsense.ZabbixAgent.settings.features.activeCheckServers|default("") != "" %}
+ServerActive={{OPNsense.ZabbixAgent.settings.features.activeCheckServers}}
+{% endif %}
+
+### Option: Hostname
+# Unique, case sensitive hostname.
+# Required for active checks and must match hostname as configured on the server.
+# Value is acquired from HostnameItem if undefined.
+#
+{% if OPNsense.ZabbixAgent.local.hostname|default("") != "" %}
+Hostname={{OPNsense.ZabbixAgent.local.hostname}}
+{% endif %}
+
+### Option: HostnameItem
+# Item used for generating Hostname if it is undefined. Ignored if Hostname is defined.
+# Does not support UserParameters or aliases.
+#
+### Option: HostMetadata
+# Optional parameter that defines host metadata.
+# Host metadata is used at host auto-registration process.
+# An agent will issue an error and not start if the value is over limit of 255 characters.
+# If not defined, value will be acquired from HostMetadataItem.
+#
+### Option: HostMetadataItem
+# Optional parameter that defines an item used for getting host metadata.
+# Host metadata is used at host auto-registration process.
+# During an auto-registration request an agent will log a warning message if
+# the value returned by specified item is over limit of 255 characters.
+# This option is only used when HostMetadata is not defined.
+#
+
+### Option: RefreshActiveChecks
+# How often list of active checks is refreshed, in seconds.
+#
+RefreshActiveChecks={{OPNsense.ZabbixAgent.settings.features.refreshActiveChecks}}
+
+### Option: BufferSend
+# Do not keep data longer than N seconds in buffer.
+#
+BufferSend={{OPNsense.ZabbixAgent.settings.tuning.bufferSend}}
+
+### Option: BufferSize
+# Maximum number of values in a memory buffer. The agent will send
+# all collected data to Zabbix Server or Proxy if the buffer is full.
+#
+BufferSize={{OPNsense.ZabbixAgent.settings.tuning.bufferSize}}
+
+### Option: MaxLinesPerSecond
+# Maximum number of new lines the agent will send per second to Zabbix Server
+# or Proxy processing 'log' and 'logrt' active checks.
+# The provided value will be overridden by the parameter 'maxlines',
+# provided in 'log' or 'logrt' item keys.
+#
+MaxLinesPerSecond={{OPNsense.ZabbixAgent.settings.tuning.maxLinesPerSecond}}
+
+############ ADVANCED PARAMETERS #################
+
+### Option: Alias
+# Sets an alias for an item key. It can be used to substitute long and complex item key with a smaller and simpler one.
+# Multiple Alias parameters may be present. Multiple parameters with the same Alias key are not allowed.
+# Different Alias keys may reference the same item key.
+# For example, to retrieve the ID of user 'zabbix':
+# Alias=zabbix.userid:vfs.file.regexp[/etc/passwd,^zabbix:.:([0-9]+),,,,\1]
+# Now shorthand key zabbix.userid may be used to retrieve data.
+# Aliases can be used in HostMetadataItem but not in HostnameItem parameters.
+#
+
+### Option: Timeout
+# Spend no more than Timeout seconds on processing
+#
+Timeout={{OPNsense.ZabbixAgent.settings.tuning.timeout}}
+
+### Option: AllowRoot
+# Allow the agent to run as 'root'. If disabled and the agent is started by 'root', the agent
+# will try to switch to the user specified by the User configuration option instead.
+# Has no effect if started under a regular user.
+# 0 - do not allow
+# 1 - allow
+#
+AllowRoot=0
+
+### Option: User
+# Drop privileges to a specific, existing user on the system.
+# Only has effect if run as 'root' and AllowRoot is disabled.
+#
+User=zabbix
+
+### Option: Include
+# You may include individual files or all files in a directory in the configuration file.
+# Installing Zabbix will create include directory in /usr/local/etc, unless modified during the compile time.
+#
+Include=/usr/local/etc/zabbix_agentd.conf.d
+
+####### USER-DEFINED MONITORED PARAMETERS #######
+
+### Option: UnsafeUserParameters
+# Allow all characters to be passed in arguments to user-defined parameters.
+# The following characters are not allowed:
+# \ ' " ` * ? [ ] { } ~ $ ! & ; ( ) < > | # @
+# Additionally, newline characters are not allowed.
+# 0 - do not allow
+# 1 - allow
+#
+### Option: UserParameter
+# User-defined parameter to monitor. There can be several user-defined parameters.
+# Format: UserParameter=