diff --git a/emulators/qemu-guest-agent/Makefile b/emulators/qemu-guest-agent/Makefile
new file mode 100644
index 000000000..1f9c4268f
--- /dev/null
+++ b/emulators/qemu-guest-agent/Makefile
@@ -0,0 +1,8 @@
+PLUGIN_NAME= qemu-guest-agent
+PLUGIN_VERSION= 0.1
+PLUGIN_DEVEL= yes
+PLUGIN_COMMENT= QEMU Guest Agent for OPNsense
+PLUGIN_DEPENDS= qemu-guest-agent
+PLUGIN_MAINTAINER= opnsense@moov.de
+
+.include "../../Mk/plugins.mk"
diff --git a/emulators/qemu-guest-agent/pkg-descr b/emulators/qemu-guest-agent/pkg-descr
new file mode 100644
index 000000000..2ff691560
--- /dev/null
+++ b/emulators/qemu-guest-agent/pkg-descr
@@ -0,0 +1,5 @@
+QEMU Guest Agent for FreeBSD
+
+Port homepage https://github.com/aborche/qemu-guest-agent
+
+WWW: http://wiki.qemu.org/Main_Page
diff --git a/emulators/qemu-guest-agent/src/etc/inc/plugins.inc.d/qemuguestagent.inc b/emulators/qemu-guest-agent/src/etc/inc/plugins.inc.d/qemuguestagent.inc
new file mode 100644
index 000000000..50ad2acc9
--- /dev/null
+++ b/emulators/qemu-guest-agent/src/etc/inc/plugins.inc.d/qemuguestagent.inc
@@ -0,0 +1,70 @@
+ gettext('QEMU Guest Agent'),
+ 'pidfile' => '/var/run/qemu-ga.pid',
+ 'configd' => array(
+ 'restart' => array('qemuguestagent restart'),
+ 'start' => array('qemuguestagent start'),
+ 'stop' => array('qemuguestagent stop'),
+ ),
+ 'name' => 'qemu-ga',
+ );
+
+ return $services;
+}
+
+function qemuguestagent_xmlrpc_sync()
+{
+ $result = array();
+ $result['id'] = 'qemuguestagent';
+ $result['section'] = 'OPNsense.QemuGuestAgent';
+ $result['description'] = gettext('QEMU Guest Agent');
+ return array($result);
+}
diff --git a/emulators/qemu-guest-agent/src/opnsense/mvc/app/controllers/OPNsense/QemuGuestAgent/Api/ServiceController.php b/emulators/qemu-guest-agent/src/opnsense/mvc/app/controllers/OPNsense/QemuGuestAgent/Api/ServiceController.php
new file mode 100644
index 000000000..c07d9ff99
--- /dev/null
+++ b/emulators/qemu-guest-agent/src/opnsense/mvc/app/controllers/OPNsense/QemuGuestAgent/Api/ServiceController.php
@@ -0,0 +1,46 @@
+view->pick('OPNsense/QemuGuestAgent/index');
+ // fetch form data "general" in
+ $this->view->generalForm = $this->getForm("general");
+ }
+}
diff --git a/emulators/qemu-guest-agent/src/opnsense/mvc/app/controllers/OPNsense/QemuGuestAgent/forms/general.xml b/emulators/qemu-guest-agent/src/opnsense/mvc/app/controllers/OPNsense/QemuGuestAgent/forms/general.xml
new file mode 100644
index 000000000..86ff2811d
--- /dev/null
+++ b/emulators/qemu-guest-agent/src/opnsense/mvc/app/controllers/OPNsense/QemuGuestAgent/forms/general.xml
@@ -0,0 +1,23 @@
+
diff --git a/emulators/qemu-guest-agent/src/opnsense/mvc/app/models/OPNsense/QemuGuestAgent/ACL/ACL.xml b/emulators/qemu-guest-agent/src/opnsense/mvc/app/models/OPNsense/QemuGuestAgent/ACL/ACL.xml
new file mode 100644
index 000000000..05a218ed5
--- /dev/null
+++ b/emulators/qemu-guest-agent/src/opnsense/mvc/app/models/OPNsense/QemuGuestAgent/ACL/ACL.xml
@@ -0,0 +1,11 @@
+
+
+ Services: QEMU Guest Agent
+
+ ui/qemuguestagent/*
+ api/qemuguestagent/*
+ ui/diagnostics/log/core/qemu-ga/*
+ api/diagnostics/log/core/qemu-ga/*
+
+
+
diff --git a/emulators/qemu-guest-agent/src/opnsense/mvc/app/models/OPNsense/QemuGuestAgent/Menu/Menu.xml b/emulators/qemu-guest-agent/src/opnsense/mvc/app/models/OPNsense/QemuGuestAgent/Menu/Menu.xml
new file mode 100644
index 000000000..8cecba521
--- /dev/null
+++ b/emulators/qemu-guest-agent/src/opnsense/mvc/app/models/OPNsense/QemuGuestAgent/Menu/Menu.xml
@@ -0,0 +1,8 @@
+
diff --git a/emulators/qemu-guest-agent/src/opnsense/mvc/app/models/OPNsense/QemuGuestAgent/QemuGuestAgent.php b/emulators/qemu-guest-agent/src/opnsense/mvc/app/models/OPNsense/QemuGuestAgent/QemuGuestAgent.php
new file mode 100644
index 000000000..e84d734e4
--- /dev/null
+++ b/emulators/qemu-guest-agent/src/opnsense/mvc/app/models/OPNsense/QemuGuestAgent/QemuGuestAgent.php
@@ -0,0 +1,49 @@
+general->Enabled === "1") {
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/emulators/qemu-guest-agent/src/opnsense/mvc/app/models/OPNsense/QemuGuestAgent/QemuGuestAgent.xml b/emulators/qemu-guest-agent/src/opnsense/mvc/app/models/OPNsense/QemuGuestAgent/QemuGuestAgent.xml
new file mode 100644
index 000000000..8c037740b
--- /dev/null
+++ b/emulators/qemu-guest-agent/src/opnsense/mvc/app/models/OPNsense/QemuGuestAgent/QemuGuestAgent.xml
@@ -0,0 +1,60 @@
+
+ //OPNsense/QemuGuestAgent
+ 1.0.0
+ QEMU Guest Agent for OPNsense
+
+
+
+ 1
+ Y
+
+
+ 0
+ N
+
+
+ N
+
+ Y
+ Y
+
+ guest-exec
+ guest-exec-status
+ guest-file-close
+ guest-file-flush
+ guest-file-open
+ guest-file-read
+ guest-file-seek
+ guest-file-write
+ guest-fsfreeze-freeze
+ guest-fsfreeze-freeze-list
+ guest-fsfreeze-status
+ guest-fsfreeze-thaw
+ guest-fstrim
+ guest-get-fsinfo
+ guest-get-host-name
+ guest-get-memory-block-info
+ guest-get-memory-blocks
+ guest-get-osinfo
+ guest-get-time
+ guest-get-timezone
+ guest-get-users
+ guest-get-vcpus
+ guest-info
+ guest-network-get-interfaces
+ guest-ping
+ guest-set-memory-blocks
+ guest-set-time
+ guest-set-user-password
+ guest-set-vcpus
+ guest-shutdown
+ guest-suspend-disk
+ guest-suspend-hybrid
+ guest-suspend-ram
+ guest-sync
+ guest-sync-delimited
+
+
+
+
+
diff --git a/emulators/qemu-guest-agent/src/opnsense/mvc/app/views/OPNsense/QemuGuestAgent/index.volt b/emulators/qemu-guest-agent/src/opnsense/mvc/app/views/OPNsense/QemuGuestAgent/index.volt
new file mode 100644
index 000000000..49563e73e
--- /dev/null
+++ b/emulators/qemu-guest-agent/src/opnsense/mvc/app/views/OPNsense/QemuGuestAgent/index.volt
@@ -0,0 +1,63 @@
+{#
+
+OPNsense® is Copyright © 2021 Frank Wall
+OPNsense® is Copyright © 2014 – 2015 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.
+
+#}
+
+
+
+
+
+
+
+
+ {{ partial("layout_partials/base_form",['fields':generalForm,'id':'frm_GeneralSettings'])}}
+
+
+
+
+
+
+
+
diff --git a/emulators/qemu-guest-agent/src/opnsense/scripts/OPNsense/QemuGuestAgent/setup.sh b/emulators/qemu-guest-agent/src/opnsense/scripts/OPNsense/QemuGuestAgent/setup.sh
new file mode 100755
index 000000000..f3e18ed33
--- /dev/null
+++ b/emulators/qemu-guest-agent/src/opnsense/scripts/OPNsense/QemuGuestAgent/setup.sh
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+# Check if the kernel module exists
+KERNMOD='virtio_console'
+if [ -e /boot/kernel/${KERNMOD}.ko ]; then
+ # Load module
+ kldload $KERNMOD 2>&1
+fi
+
+exit 0
diff --git a/emulators/qemu-guest-agent/src/opnsense/service/conf/actions.d/actions_qemuguestagent.conf b/emulators/qemu-guest-agent/src/opnsense/service/conf/actions.d/actions_qemuguestagent.conf
new file mode 100644
index 000000000..c236540b2
--- /dev/null
+++ b/emulators/qemu-guest-agent/src/opnsense/service/conf/actions.d/actions_qemuguestagent.conf
@@ -0,0 +1,29 @@
+[start]
+command:/usr/local/opnsense/scripts/OPNsense/QemuGuestAgent/setup.sh; /usr/local/etc/rc.d/qemu-guest-agent start
+parameters:
+type:script
+message:starting qemu-guest-agent
+
+[stop]
+command:/usr/local/etc/rc.d/qemu-guest-agent stop; exit 0
+parameters:
+type:script
+message:stopping qemu-guest-agent
+
+[restart]
+command:/usr/local/opnsense/scripts/OPNsense/QemuGuestAgent/setup.sh; /usr/local/etc/rc.d/qemu-guest-agent restart
+parameters:
+type:script
+message:restarting qemu-guest-agent
+
+[reload]
+command:/usr/local/opnsense/scripts/OPNsense/QemuGuestAgent/setup.sh; /usr/local/etc/rc.d/qemu-guest-agent restart
+parameters:
+type:script
+message:restarting qemu-guest-agent
+
+[status]
+command:/usr/local/etc/rc.d/qemu-guest-agent status; exit 0
+parameters:
+type:script_output
+message:requesting qemu-guest-agent status
diff --git a/emulators/qemu-guest-agent/src/opnsense/service/templates/OPNsense/QemuGuestAgent/+TARGETS b/emulators/qemu-guest-agent/src/opnsense/service/templates/OPNsense/QemuGuestAgent/+TARGETS
new file mode 100644
index 000000000..3bc91f3c9
--- /dev/null
+++ b/emulators/qemu-guest-agent/src/opnsense/service/templates/OPNsense/QemuGuestAgent/+TARGETS
@@ -0,0 +1 @@
+rc.conf.d:/etc/rc.conf.d/qemu_guest_agent
diff --git a/emulators/qemu-guest-agent/src/opnsense/service/templates/OPNsense/QemuGuestAgent/rc.conf.d b/emulators/qemu-guest-agent/src/opnsense/service/templates/OPNsense/QemuGuestAgent/rc.conf.d
new file mode 100644
index 000000000..ea9c80f8c
--- /dev/null
+++ b/emulators/qemu-guest-agent/src/opnsense/service/templates/OPNsense/QemuGuestAgent/rc.conf.d
@@ -0,0 +1,15 @@
+{# Default setting is enabled, so that no GUI interaction is required. #}
+{% if not (helpers.exists('OPNsense.QemuGuestAgent.general.LogDebug')) or OPNsense.QemuGuestAgent.general.Enabled|default("0") != "0" %}
+{% set optional_flags = [] %}
+{% do optional_flags.append('-d -l /var/log/qemu-ga.log') %}
+{% if helpers.exists('OPNsense.QemuGuestAgent.general.LogDebug') and OPNsense.QemuGuestAgent.general.LogDebug|default("0") == "1" %}
+{% do optional_flags.append('-v') %}
+{% endif %}
+{% if helpers.exists('OPNsense.QemuGuestAgent.general.DisabledRPCs') and not helpers.empty('OPNsense.QemuGuestAgent.general.DisabledRPCs') %}
+{% do optional_flags.append('--blacklist=' ~ OPNsense.QemuGuestAgent.general.DisabledRPCs) %}
+{% endif %}
+qemu_guest_agent_enable="YES"
+qemu_guest_agent_flags="{{optional_flags|join(' ')}}"
+{% else %}
+qemu_guest_agent_enable="NO"
+{% endif %}