diff --git a/README.md b/README.md
index ce67f4ca5..16ad199a7 100644
--- a/README.md
+++ b/README.md
@@ -41,9 +41,10 @@ net-mgmt/collectd -- Collect system and application performance metrics periodic
net-mgmt/snmp -- SNMP Server via bsnmpd
net-mgmt/telegraf -- Agent for collecting metrics and data
net-mgmt/zabbix-agent -- Enterprise-class open source distributed monitoring agent
-net-mgmt/zabbix-proxy -- Zabbix-Proxy enables decentralized monitoring
+net-mgmt/zabbix-proxy -- Zabbix Proxy enables decentralized monitoring
net/arp-scan -- Get all peers connected to a local network
net/freeradius -- RADIUS Authentication, Authorization and Accounting Server
+net/frr -- FRR Routing Suite
net/ftp-proxy -- Control ftp-proxy processes
net/haproxy -- Reliable, high performance TCP/HTTP load balancer
net/igmp-proxy -- IGMP-Proxy Service
@@ -66,6 +67,7 @@ security/tinc -- Tinc VPN
security/tor -- The Onion Router
sysutils/boot-delay -- Apply a persistent 10 second boot delay
sysutils/monit -- Proactive system monitoring
+sysutils/nut -- Network UPS Tools
sysutils/smart -- SMART tools
sysutils/vmware -- VMware tools
sysutils/xen -- Xen guest utilities
diff --git a/sysutils/nut/Makefile b/sysutils/nut/Makefile
new file mode 100644
index 000000000..8b162e71c
--- /dev/null
+++ b/sysutils/nut/Makefile
@@ -0,0 +1,8 @@
+PLUGIN_NAME= nut
+PLUGIN_VERSION= 0.1
+PLUGIN_COMMENT= Network UPS Tools
+PLUGIN_DEPENDS= nut
+PLUGIN_MAINTAINER= m.muenz@gmail.com
+PLUGIN_DEVEL= yes
+
+.include "../../Mk/plugins.mk"
diff --git a/sysutils/nut/pkg-descr b/sysutils/nut/pkg-descr
new file mode 100644
index 000000000..81bf4f70d
--- /dev/null
+++ b/sysutils/nut/pkg-descr
@@ -0,0 +1,7 @@
+The primary goal of the Network UPS Tools (NUT) project is to provide
+support for Power Devices, such as Uninterruptible Power Supplies,
+Power Distribution Units, Automatic Transfer Switch, Power Supply Units
+and Solar Controllers.
+
+NUT provides many control and monitoring features, with a uniform control
+and management interface.
diff --git a/sysutils/nut/src/etc/inc/plugins.inc.d/nut.inc b/sysutils/nut/src/etc/inc/plugins.inc.d/nut.inc
new file mode 100644
index 000000000..43e95f2b4
--- /dev/null
+++ b/sysutils/nut/src/etc/inc/plugins.inc.d/nut.inc
@@ -0,0 +1,56 @@
+general->enabled == '1') {
+ return true;
+ }
+
+ return false;
+}
+
+function nut_services()
+{
+ $services = array();
+
+ if (nut_enabled()) {
+ $services[] = array(
+ 'description' => gettext('Network UPS Tools'),
+ 'configd' => array(
+ 'restart' => array('nut restart'),
+ 'start' => array('nut start'),
+ 'stop' => array('nut stop'),
+ ),
+ 'name' => 'nut',
+ 'pidfile' => '/var/run/nut.pid'
+ );
+ }
+ return $services;
+}
diff --git a/sysutils/nut/src/opnsense/mvc/app/controllers/OPNsense/Nut/Api/ServiceController.php b/sysutils/nut/src/opnsense/mvc/app/controllers/OPNsense/Nut/Api/ServiceController.php
new file mode 100644
index 000000000..48befe674
--- /dev/null
+++ b/sysutils/nut/src/opnsense/mvc/app/controllers/OPNsense/Nut/Api/ServiceController.php
@@ -0,0 +1,143 @@
+request->isPost()) {
+ // close session for long running action
+ $this->sessionClose();
+ $backend = new Backend();
+ $response = $backend->configdRun('nut restart');
+ return array('response' => $response);
+ } else {
+ return array('response' => array());
+ }
+ }
+
+ /**
+ * retrieve status of nut
+ * @return array
+ * @throws \Exception
+ */
+ public function statusAction()
+ {
+ $backend = new Backend();
+ $nut = new Nut();
+ $response = $backend->configdRun('nut status');
+
+ if (strpos($response, 'not running') > 0) {
+ if ((string)$nut->general->enabled == 1) {
+ $status = 'stopped';
+ } else {
+ $status = 'disabled';
+ }
+ } elseif (strpos($response, 'is running') > 0) {
+ $status = 'running';
+ } elseif ((string)$nut->general->enabled == 0) {
+ $status = 'disabled';
+ } else {
+ $status = 'unknown';
+ }
+
+ return array('status' => $status);
+ }
+
+ /**
+ * reconfigure nut, generate config and reload
+ */
+ public function reconfigureAction()
+ {
+ if ($this->request->isPost()) {
+ // close session for long running action
+ $this->sessionClose();
+
+ $nut = new Nut();
+ $backend = new Backend();
+
+ $this->stopAction();
+
+ // generate template
+ $backend->configdRun('template reload OPNsense/Nut');
+
+ // (re)start daemon
+ if ((string)$nut->general->enabled == '1') {
+ $this->startAction();
+ }
+
+ return array('status' => 'ok');
+ } else {
+ return array('status' => 'failed');
+ }
+ }
+
+ /**
+ * stop nut service
+ * @return array
+ */
+ public function stopAction()
+ {
+ if ($this->request->isPost()) {
+ // close session for long running action
+ $this->sessionClose();
+ $backend = new Backend();
+ $response = $backend->configdRun('nut stop');
+ return array('response' => $response);
+ } else {
+ return array('response' => array());
+ }
+ }
+ /**
+ * start nut service
+ * @return array
+ */
+ public function startAction()
+ {
+ if ($this->request->isPost()) {
+ // close session for long running action
+ $this->sessionClose();
+ $backend = new Backend();
+ $response = $backend->configdRun('nut start');
+ return array('response' => $response);
+ } else {
+ return array('response' => array());
+ }
+ }
+}
diff --git a/sysutils/nut/src/opnsense/mvc/app/controllers/OPNsense/Nut/Api/SettingsController.php b/sysutils/nut/src/opnsense/mvc/app/controllers/OPNsense/Nut/Api/SettingsController.php
new file mode 100644
index 000000000..55edbc802
--- /dev/null
+++ b/sysutils/nut/src/opnsense/mvc/app/controllers/OPNsense/Nut/Api/SettingsController.php
@@ -0,0 +1,38 @@
+view->settings = $this->getForm("settings");
+ $this->view->pick('OPNsense/Nut/index');
+ }
+}
diff --git a/sysutils/nut/src/opnsense/mvc/app/controllers/OPNsense/Nut/forms/settings.xml b/sysutils/nut/src/opnsense/mvc/app/controllers/OPNsense/Nut/forms/settings.xml
new file mode 100644
index 000000000..d2c659f35
--- /dev/null
+++ b/sysutils/nut/src/opnsense/mvc/app/controllers/OPNsense/Nut/forms/settings.xml
@@ -0,0 +1,50 @@
+
diff --git a/sysutils/nut/src/opnsense/mvc/app/models/OPNsense/Nut/ACL/ACL.xml b/sysutils/nut/src/opnsense/mvc/app/models/OPNsense/Nut/ACL/ACL.xml
new file mode 100644
index 000000000..93706ce70
--- /dev/null
+++ b/sysutils/nut/src/opnsense/mvc/app/models/OPNsense/Nut/ACL/ACL.xml
@@ -0,0 +1,9 @@
+
+
+ Nut
+
+ ui/nut/*
+ api/nut/*
+
+
+
diff --git a/sysutils/nut/src/opnsense/mvc/app/models/OPNsense/Nut/Menu/Menu.xml b/sysutils/nut/src/opnsense/mvc/app/models/OPNsense/Nut/Menu/Menu.xml
new file mode 100644
index 000000000..3d23309cc
--- /dev/null
+++ b/sysutils/nut/src/opnsense/mvc/app/models/OPNsense/Nut/Menu/Menu.xml
@@ -0,0 +1,5 @@
+
diff --git a/sysutils/nut/src/opnsense/mvc/app/models/OPNsense/Nut/Nut.php b/sysutils/nut/src/opnsense/mvc/app/models/OPNsense/Nut/Nut.php
new file mode 100644
index 000000000..7909c9f15
--- /dev/null
+++ b/sysutils/nut/src/opnsense/mvc/app/models/OPNsense/Nut/Nut.php
@@ -0,0 +1,34 @@
+
+ //OPNsense/Nut
+ Network UPS Tools
+
+
+
+ 0
+ Y
+
+
+
+
+
+ Y
+ Password
+
+
+ Y
+ Password
+
+
+
+
+
+ Y
+ 0
+
+
+ UPS-Name
+ Y
+
+
+ port=auto
+ N
+
+
+
+
diff --git a/sysutils/nut/src/opnsense/mvc/app/views/OPNsense/Nut/index.volt b/sysutils/nut/src/opnsense/mvc/app/views/OPNsense/Nut/index.volt
new file mode 100644
index 000000000..fa9c9c08d
--- /dev/null
+++ b/sysutils/nut/src/opnsense/mvc/app/views/OPNsense/Nut/index.volt
@@ -0,0 +1,145 @@
+{#
+
+ Copyright (C) 2017 Michael Muenz
+ OPNsense® is Copyright © 2014 – 2017 by Deciso B.V.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+
+#}
+
+
+
+
+{% for tab in settings['tabs']|default([]) %}
+ {% if tab['subtabs']|default(false) %}
+ {# Tab with dropdown #}
+
+ {# Find active subtab #}
+ {% set active_subtab="" %}
+ {% for subtab in tab['subtabs']|default({}) %}
+ {% if subtab[0]==settings['activetab']|default("") %}
+ {% set active_subtab=subtab[0] %}
+ {% endif %}
+ {% endfor %}
+
+ -
+
+
+
+ {{ tab[1] }}
+
+
+ {% else %}
+ {# Standard Tab #}
+ -
+
+ {{ tab[1] }}
+
+
+ {% endif %}
+{% endfor %}
+
+
+
+ {% for tab in settings['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/sysutils/nut/src/opnsense/scripts/OPNsense/Nut/setup.sh b/sysutils/nut/src/opnsense/scripts/OPNsense/Nut/setup.sh
new file mode 100755
index 000000000..582348f05
--- /dev/null
+++ b/sysutils/nut/src/opnsense/scripts/OPNsense/Nut/setup.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+mkdir -p /var/db/nut
+
+chown uucp:uucp /var/db/nut
diff --git a/sysutils/nut/src/opnsense/service/conf/actions.d/actions_nut.conf b/sysutils/nut/src/opnsense/service/conf/actions.d/actions_nut.conf
new file mode 100644
index 000000000..7637019ce
--- /dev/null
+++ b/sysutils/nut/src/opnsense/service/conf/actions.d/actions_nut.conf
@@ -0,0 +1,23 @@
+[start]
+command:/usr/local/opnsense/scripts/OPNsense/Nut/setup.sh;/usr/local/etc/rc.d/nut start
+parameters:
+type:script
+message:starting nut
+
+[stop]
+command:/usr/local/etc/rc.d/nut onestop
+parameters:
+type:script
+message:stopping nut
+
+[restart]
+command:/usr/local/opnsense/scripts/OPNsense/Nut/setup.sh;/usr/local/etc/rc.d/nut restart
+parameters:
+type:script
+message:restarting nut
+
+[status]
+command:/usr/local/etc/rc.d/nut status;exit 0
+parameters:
+type:script_output
+message:request nut status
diff --git a/sysutils/nut/src/opnsense/service/templates/OPNsense/Nut/+TARGETS b/sysutils/nut/src/opnsense/service/templates/OPNsense/Nut/+TARGETS
new file mode 100644
index 000000000..6b77fcd28
--- /dev/null
+++ b/sysutils/nut/src/opnsense/service/templates/OPNsense/Nut/+TARGETS
@@ -0,0 +1,6 @@
+nut:/etc/rc.conf.d/nut
+nut.conf:/usr/local/etc/nut/nut.conf
+ups.conf:/usr/local/etc/nut/ups.conf
+upsd.conf:/usr/local/etc/nut/upsd.conf
+upsd.users:/usr/local/etc/nut/upsd.users
+upsmon.conf:/usr/local/etc/nut/upsmon.conf
diff --git a/sysutils/nut/src/opnsense/service/templates/OPNsense/Nut/nut b/sysutils/nut/src/opnsense/service/templates/OPNsense/Nut/nut
new file mode 100644
index 000000000..f41bd9b00
--- /dev/null
+++ b/sysutils/nut/src/opnsense/service/templates/OPNsense/Nut/nut
@@ -0,0 +1,7 @@
+{% if helpers.exists('OPNsense.Nut.general.enable') and OPNsense.Nut.general.enable == '1' %}
+nut_opnsense_bootup_run="/usr/local/opnsense/scripts/OPNsense/Nut/setup.sh"
+nut_var_script="/usr/local/opnsense/scripts/OPNsense/Nut/setup.sh"
+nut_enable="YES"
+{% else %}
+nut_enable="NO"
+{% endif %}
diff --git a/sysutils/nut/src/opnsense/service/templates/OPNsense/Nut/nut.conf b/sysutils/nut/src/opnsense/service/templates/OPNsense/Nut/nut.conf
new file mode 100644
index 000000000..3ac32575f
--- /dev/null
+++ b/sysutils/nut/src/opnsense/service/templates/OPNsense/Nut/nut.conf
@@ -0,0 +1,6 @@
+# Please don't modify this file as your changes might be overwritten with
+# the next update.
+#
+{% if helpers.exists('OPNsense.Nut.general.enable') and OPNsense.Nut.general.enable == '1' %}
+MODE=standalone
+{% endif %}
diff --git a/sysutils/nut/src/opnsense/service/templates/OPNsense/Nut/ups.conf b/sysutils/nut/src/opnsense/service/templates/OPNsense/Nut/ups.conf
new file mode 100644
index 000000000..e9b4e204a
--- /dev/null
+++ b/sysutils/nut/src/opnsense/service/templates/OPNsense/Nut/ups.conf
@@ -0,0 +1,12 @@
+# Please don't modify this file as your changes might be overwritten with
+# the next update.
+#
+{% if helpers.exists('OPNsense.Nut.general.enable') and OPNsense.Nut.general.enable == '1' %}
+{% if helpers.exists('OPNsense.Nut.usbhid.enable') and OPNsense.Nut.usbhid.enable == '1' %}
+[{{ OPNsense.Nut.usbhid.name }}]
+driver=usbhid-ups
+{% if helpers.exists('OPNsense.Nut.usbhid.args') and OPNsense.Nut.usbhid.args != '' %}
+{{ OPNsense.Nut.usbhid.args }}
+{% endif %}
+{% endif %}
+{% endif %}
diff --git a/sysutils/nut/src/opnsense/service/templates/OPNsense/Nut/upsd.conf b/sysutils/nut/src/opnsense/service/templates/OPNsense/Nut/upsd.conf
new file mode 100644
index 000000000..8e715095d
--- /dev/null
+++ b/sysutils/nut/src/opnsense/service/templates/OPNsense/Nut/upsd.conf
@@ -0,0 +1,7 @@
+# Please don't modify this file as your changes might be overwritten with
+# the next update.
+#
+{% if helpers.exists('OPNsense.Nut.general.enable') and OPNsense.Nut.general.enable == '1' %}
+LISTEN 127.0.0.1
+LISTEN ::1
+{% endif %}
diff --git a/sysutils/nut/src/opnsense/service/templates/OPNsense/Nut/upsd.users b/sysutils/nut/src/opnsense/service/templates/OPNsense/Nut/upsd.users
new file mode 100644
index 000000000..60675121b
--- /dev/null
+++ b/sysutils/nut/src/opnsense/service/templates/OPNsense/Nut/upsd.users
@@ -0,0 +1,16 @@
+# Please don't modify this file as your changes might be overwritten with
+# the next update.
+#
+{% if helpers.exists('OPNsense.Nut.general.enable') and OPNsense.Nut.general.enable == '1' %}
+{% if helpers.exists('OPNsense.Nut.account.admin_password') and OPNsense.Nut.account.admin_password != '' %}
+[admin]
+password={{ OPNsense.Nut.account.admin_password }}
+actions=set
+instcmds=all
+{% endif %}
+{% if helpers.exists('OPNsense.Nut.account.mon_password') and OPNsense.Nut.account.mon_password != '' %}
+[monuser]
+password={{ OPNsense.Nut.account.mon_password }}
+upsmon master
+{% endif %}
+{% endif %}
diff --git a/sysutils/nut/src/opnsense/service/templates/OPNsense/Nut/upsmon.conf b/sysutils/nut/src/opnsense/service/templates/OPNsense/Nut/upsmon.conf
new file mode 100644
index 000000000..4784c6569
--- /dev/null
+++ b/sysutils/nut/src/opnsense/service/templates/OPNsense/Nut/upsmon.conf
@@ -0,0 +1,8 @@
+# Please don't modify this file as your changes might be overwritten with
+# the next update.
+#
+{% if helpers.exists('OPNsense.Nut.usbhid.enable') and OPNsense.Nut.usbhid.enable == '1' %}
+MONITOR {{ OPNsense.Nut.usbhid.name }} 1 monuser {{ OPNsense.Nut.account.mon_password }} master
+SHUTDOWNCMD "/sbin/shutdown -p +0"
+POWERDOWNFLAG /etc/killpower
+{% endif %}