diff --git a/src/etc/inc/system.inc b/src/etc/inc/system.inc
index 50ce99cea..35fcbe87f 100644
--- a/src/etc/inc/system.inc
+++ b/src/etc/inc/system.inc
@@ -673,6 +673,8 @@ EOD;
}
}
+ // deploy certificates (separate caller in case we ever remove clog, in which case we can move all to configd)
+ mwexecf("/usr/local/opnsense/scripts/syslog/generate_certs");
if (!empty($config['syslog']['disable_clog'])) {
// non legacy mode
if (isvalidpid('/var/run/syslog.pid')) {
diff --git a/src/opnsense/mvc/app/controllers/OPNsense/Syslog/forms/dialogDestination.xml b/src/opnsense/mvc/app/controllers/OPNsense/Syslog/forms/dialogDestination.xml
index 484c9040e..36ad7bd96 100644
--- a/src/opnsense/mvc/app/controllers/OPNsense/Syslog/forms/dialogDestination.xml
+++ b/src/opnsense/mvc/app/controllers/OPNsense/Syslog/forms/dialogDestination.xml
@@ -39,6 +39,16 @@
text
+
+ destination.certificate
+
+
+ dropdown
+ this is a good
+ resource for tracking common issues.]]>
+
+
destination.description
diff --git a/src/opnsense/mvc/app/models/OPNsense/Syslog/Syslog.php b/src/opnsense/mvc/app/models/OPNsense/Syslog/Syslog.php
index c5f11c409..2fb911dd5 100644
--- a/src/opnsense/mvc/app/models/OPNsense/Syslog/Syslog.php
+++ b/src/opnsense/mvc/app/models/OPNsense/Syslog/Syslog.php
@@ -51,14 +51,26 @@ class Syslog extends BaseModel
$parentNode = $node->getParentNode();
$ptagname = $parentNode->getInternalXMLTagName();
$tagname = $node->getInternalXMLTagName();
- if ($ptagname == 'destination' && in_array($tagname, array('hostname', 'transport'))) {
- // protocol family check
- if (in_array((string)$parentNode->transport, array('udp4', 'udp6', 'tcp4', 'tcp6'))) {
- $ipproto = ((string)$parentNode->transport)[3];
- $hostproto = strpos((string)$parentNode->hostname, ":") === false ? "4" : "6";
- if (Util::isIpAddress((string)$parentNode->hostname) && $ipproto != $hostproto) {
+ $transport = (string)$parentNode->transport;
+ if ($ptagname == 'destination') {
+ if (in_array($tagname, array('hostname', 'transport'))) {
+ // protocol family check
+ if (in_array($transport, ['udp4', 'udp6', 'tcp4', 'tcp6', 'tls4', 'tls6'])) {
+ $ipproto = ((string)$parentNode->transport)[3];
+ $hostproto = strpos((string)$parentNode->hostname, ":") === false ? "4" : "6";
+ if (Util::isIpAddress((string)$parentNode->hostname) && $ipproto != $hostproto) {
+ $messages->appendMessage(new Message(
+ gettext("Transport protocol does not match address in hostname"),
+ $key
+ ));
+ }
+ }
+ }
+ if (in_array($tagname, ['certificate', 'transport']) && in_array($transport, ['tls4', 'tls6'])) {
+ // certificate availability
+ if (empty((string)$parentNode->certificate)) {
$messages->appendMessage(new Message(
- gettext("Transport protocol does not match address in hostname"),
+ gettext("A certificate is required for tls types"),
$key
));
}
diff --git a/src/opnsense/mvc/app/models/OPNsense/Syslog/Syslog.xml b/src/opnsense/mvc/app/models/OPNsense/Syslog/Syslog.xml
index d2362c0cf..6ed227d99 100644
--- a/src/opnsense/mvc/app/models/OPNsense/Syslog/Syslog.xml
+++ b/src/opnsense/mvc/app/models/OPNsense/Syslog/Syslog.xml
@@ -22,6 +22,8 @@
TCP(4)
UDP(6)
TCP(6)
+ TLS(4)
+ TLS(6)
@@ -80,6 +82,10 @@
Y
+
+ N
+ Please select a valid certificate from the list
+
Y
514
diff --git a/src/opnsense/mvc/app/views/OPNsense/Syslog/index.volt b/src/opnsense/mvc/app/views/OPNsense/Syslog/index.volt
index ee5fa2ac4..5f80efa2e 100644
--- a/src/opnsense/mvc/app/views/OPNsense/Syslog/index.volt
+++ b/src/opnsense/mvc/app/views/OPNsense/Syslog/index.volt
@@ -48,6 +48,17 @@
*/
$("#reconfigureAct").SimpleActionButton();
updateServiceControlUI('syslog');
+
+ $("#destination\\.transport").change(function(){
+ let transport_type = $(this).val();
+ $(".transport_type").each(function(){
+ if ($(this).hasClass("transport_type_" + transport_type)) {
+ $(this).closest("tr").show();
+ } else {
+ $(this).closest("tr").hide();
+ }
+ });
+ });
});
diff --git a/src/opnsense/scripts/syslog/generate_certs b/src/opnsense/scripts/syslog/generate_certs
new file mode 100755
index 000000000..ac8730ce2
--- /dev/null
+++ b/src/opnsense/scripts/syslog/generate_certs
@@ -0,0 +1,63 @@
+#!/usr/local/bin/php
+object();
+@mkdir("/usr/local/etc/syslog-ng/cert.d", 0700, true);
+foreach ((new OPNsense\Syslog\Syslog())->destinations->destination->iterateItems() as $id => $item) {
+ if (in_array($item->transport, ['tls4', 'tls6']) && !empty($configObj->cert) && (string)$item->enabled == "1"){
+ $dest_key = str_replace("-", "", $id);
+ $instances[] = $dest_key;
+ $cert_refid = (string)$item->certificate;
+ foreach ($configObj->cert as $cert) {
+ if ($cert_refid == (string)$cert->refid) {
+ file_put_contents("/usr/local/etc/syslog-ng/cert.d/{$dest_key}.key", base64_decode((string)$cert->prv));
+ file_put_contents("/usr/local/etc/syslog-ng/cert.d/{$dest_key}.crt", base64_decode((string)$cert->crt));
+ $cert = (array)$cert;
+ $ca = ca_chain($cert);
+ file_put_contents("/usr/local/etc/syslog-ng/cert.d/{$dest_key}.ca", (string)$ca);
+ }
+ }
+ }
+}
+
+// cleanup old/unused certs
+foreach (glob("/usr/local/etc/syslog-ng/cert.d/*") as $filename) {
+ $instance = explode(".", basename($filename))[0];
+ $ext = pathinfo($filename)['extension'];
+ if (!in_array($instance, $instances) && in_array($ext, ['crt', 'key', 'ca'])) {
+ unlink($filename);
+ }
+}
diff --git a/src/opnsense/service/templates/OPNsense/Syslog/syslog-ng-destinations.conf b/src/opnsense/service/templates/OPNsense/Syslog/syslog-ng-destinations.conf
index 047d176db..5c0c8569f 100644
--- a/src/opnsense/service/templates/OPNsense/Syslog/syslog-ng-destinations.conf
+++ b/src/opnsense/service/templates/OPNsense/Syslog/syslog-ng-destinations.conf
@@ -30,7 +30,20 @@ destination d_{{dest_key}} {
ip-protocol({{destination.transport[3]}})
persist-name("{{dest_key}}")
);
-{% endif %}
+{% elif destination.transport in ['tls4', 'tls6'] %}
+ network(
+ "{{destination.hostname}}"
+ transport("tls")
+ port({{destination.port}})
+ ip-protocol({{destination.transport[3]}})
+ persist-name("{{dest_key}}")
+ tls(
+ ca-file("/usr/local/etc/syslog-ng/cert.d/{{dest_key}}.ca")
+ key-file("/usr/local/etc/syslog-ng/cert.d/{{dest_key}}.key")
+ cert-file("/usr/local/etc/syslog-ng/cert.d/{{dest_key}}.crt")
+ )
+ );
+{% endif %}
};
log {