mirror of
https://github.com/kernelkit/infix.git
synced 2026-07-22 01:13:00 +02:00
confd: add support for user configurable https certificate
- Add x509-public-key-format identity to crypto-types - Add certificate node to web services container - Use certificate from ietf-keystore as web cert Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
@@ -1 +0,0 @@
|
||||
task [S] <service/confd/ready> /usr/libexec/infix/mkcert -- Verifying self-signed https certificate
|
||||
@@ -1 +0,0 @@
|
||||
../available/mkcert.conf
|
||||
@@ -1,7 +1,12 @@
|
||||
#!/bin/sh
|
||||
# Generate a self-signed TLS certificate. Called from confd keystore
|
||||
# on first boot (or factory reset) when the gencert entry has empty
|
||||
# keys. Output is written to a temporary directory that confd reads
|
||||
# and then removes after importing into the keystore.
|
||||
|
||||
KEY=/cfg/ssl/private/self-signed.key
|
||||
CRT=/cfg/ssl/certs/self-signed.crt
|
||||
TMPDIR=/tmp/ssl
|
||||
KEY=$TMPDIR/self-signed.key
|
||||
CRT=$TMPDIR/self-signed.crt
|
||||
|
||||
country=US
|
||||
state=California
|
||||
@@ -20,23 +25,11 @@ if [ -z "$cn" ]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
generate()
|
||||
{
|
||||
mkdir -p /cfg/ssl/private /cfg/ssl/certs
|
||||
chmod 700 /cfg/ssl/private
|
||||
mkdir -p "$TMPDIR"
|
||||
chmod 700 "$TMPDIR"
|
||||
|
||||
gencert --country "$country" --state "$state" --city "$city" --organisation "$org" \
|
||||
--organisation-unit "$unit" --common-name "$cn" \
|
||||
--out-certificate $CRT --out-key $KEY
|
||||
}
|
||||
gencert --country "$country" --state "$state" --city "$city" --organisation "$org" \
|
||||
--organisation-unit "$unit" --common-name "$cn" \
|
||||
--out-certificate "$CRT" --out-key "$KEY"
|
||||
|
||||
CN=$(openssl x509 -noout -subject -in "${CRT}" 2>/dev/null |sed 's/.*CN=//')
|
||||
if [ -z "$CN" ] || [ "$CN" != "$cn" ]; then
|
||||
generate "$cn"
|
||||
fi
|
||||
|
||||
cp "${KEY}" "/etc/ssl/private/"
|
||||
cp "${CRT}" "/etc/ssl/certs/"
|
||||
initctl cond set mkcert
|
||||
|
||||
exit 0
|
||||
exit $?
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
service <usr/mkcert> env:-/etc/default/nginx \
|
||||
service <usr/mkcert,service/confd/ready> env:-/etc/default/nginx \
|
||||
[2345] nginx -g 'daemon off;' $NGINX_ARGS -- Web server
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
"hostkey": [ "genkey" ]
|
||||
},
|
||||
"infix-services:web": {
|
||||
"certificate": "gencert",
|
||||
"enabled": true,
|
||||
"console": {
|
||||
"enabled": true
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"ietf-keystore:keystore": {
|
||||
"asymmetric-keys": {
|
||||
"asymmetric-key": [
|
||||
{
|
||||
"name": "genkey",
|
||||
"public-key-format": "infix-crypto-types:ssh-public-key-format",
|
||||
"public-key": "",
|
||||
"private-key-format": "infix-crypto-types:rsa-private-key-format",
|
||||
"cleartext-private-key": "",
|
||||
"certificates": {}
|
||||
},
|
||||
{
|
||||
"name": "gencert",
|
||||
"public-key-format": "infix-crypto-types:x509-public-key-format",
|
||||
"public-key": "",
|
||||
"private-key-format": "infix-crypto-types:rsa-private-key-format",
|
||||
"cleartext-private-key": "",
|
||||
"certificates": {
|
||||
"certificate": [
|
||||
{ "name": "self-signed", "cert-data": "" }
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,4 @@
|
||||
{
|
||||
"ietf-keystore:keystore": {
|
||||
"asymmetric-keys": {
|
||||
"asymmetric-key": [
|
||||
{
|
||||
"name": "genkey",
|
||||
"public-key-format": "infix-crypto-types:ssh-public-key-format",
|
||||
"public-key": "",
|
||||
"private-key-format": "infix-crypto-types:rsa-private-key-format",
|
||||
"cleartext-private-key": "",
|
||||
"certificates": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"ietf-netconf-server:netconf-server": {
|
||||
"listen": {
|
||||
"endpoints": {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
factorydir = $(pkgdatadir)/factory.d
|
||||
dist_factory_DATA = 10-nacm.json 10-netconf-server.json \
|
||||
dist_factory_DATA = 10-keystore.json 10-nacm.json \
|
||||
10-netconf-server.json \
|
||||
10-infix-services.json 10-system.json
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
"enabled": true
|
||||
},
|
||||
"infix-services:web": {
|
||||
"certificate": "gencert",
|
||||
"enabled": true,
|
||||
"restconf": {
|
||||
"enabled": true
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
../factory.d/10-keystore.json
|
||||
@@ -1,4 +1,5 @@
|
||||
failuredir = $(pkgdatadir)/failure.d
|
||||
dist_failure_DATA = 10-nacm.json 10-netconf-server.json \
|
||||
dist_failure_DATA = 10-keystore.json 10-nacm.json \
|
||||
10-netconf-server.json \
|
||||
10-infix-services.json 10-system.json
|
||||
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
../factory.d/10-keystore.json
|
||||
@@ -1,4 +1,4 @@
|
||||
testdir = $(pkgdatadir)/test.d
|
||||
dist_test_DATA = 10-nacm.json 10-netconf-server.json \
|
||||
10-infix-services.json 10-system.json
|
||||
dist_test_DATA = 10-keystore.json 10-nacm.json 10-netconf-server.json \
|
||||
10-infix-services.json 10-system.json
|
||||
|
||||
|
||||
@@ -99,6 +99,7 @@ static confd_dependency_t handle_dependencies(struct lyd_node **diff, struct lyd
|
||||
dkeys = lydx_get_descendant(*diff, "keystore", "asymmetric-keys", "asymmetric-key", NULL);
|
||||
LYX_LIST_FOR_EACH(dkeys, dkey, "asymmetric-key") {
|
||||
struct ly_set *hostkeys;
|
||||
struct lyd_node *webcert;
|
||||
uint32_t i;
|
||||
|
||||
key_name = lydx_get_cattr(dkey, "name");
|
||||
@@ -116,6 +117,15 @@ static confd_dependency_t handle_dependencies(struct lyd_node **diff, struct lyd
|
||||
}
|
||||
ly_set_free(hostkeys, NULL);
|
||||
}
|
||||
|
||||
webcert = lydx_get_xpathf(config, "/infix-services:web/certificate[.='%s']", key_name);
|
||||
if (webcert) {
|
||||
result = add_dependencies(diff, "/infix-services:web/certificate", key_name);
|
||||
if (result == CONFD_DEP_ERROR) {
|
||||
ERROR("Failed to add web certificate to diff for key %s", key_name);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hostname = lydx_get_xpathf(*diff, "/ietf-system:system/hostname");
|
||||
|
||||
@@ -31,6 +31,11 @@
|
||||
|
||||
#include "dagger.h"
|
||||
|
||||
#define SSH_HOSTKEYS "/etc/ssh/hostkeys"
|
||||
#define SSH_HOSTKEYS_NEXT SSH_HOSTKEYS"+"
|
||||
#define SSL_CERT_DIR "/etc/ssl/certs"
|
||||
#define SSL_KEY_DIR "/etc/ssl/private"
|
||||
|
||||
#define CB_PRIO_PRIMARY 65535
|
||||
#define CB_PRIO_PASSIVE 65000
|
||||
|
||||
@@ -238,8 +243,6 @@ int hardware_candidate_init(struct confd *confd);
|
||||
int hardware_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd);
|
||||
|
||||
/* keystore.c */
|
||||
#define SSH_HOSTKEYS "/etc/ssh/hostkeys"
|
||||
#define SSH_HOSTKEYS_NEXT SSH_HOSTKEYS"+"
|
||||
int keystore_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd);
|
||||
|
||||
/* firewall.c */
|
||||
|
||||
+156
-14
@@ -12,6 +12,11 @@
|
||||
|
||||
#define XPATH_KEYSTORE_ASYM "/ietf-keystore:keystore/asymmetric-keys"
|
||||
#define XPATH_KEYSTORE_SYM "/ietf-keystore:keystore/symmetric-keys"
|
||||
#define SSH_PRIVATE_KEY "/tmp/ssh.key"
|
||||
#define SSH_PUBLIC_KEY "/tmp/ssh.pub"
|
||||
#define TLS_TMPDIR "/tmp/ssl"
|
||||
#define TLS_PRIVATE_KEY TLS_TMPDIR "/self-signed.key"
|
||||
#define TLS_CERTIFICATE TLS_TMPDIR "/self-signed.crt"
|
||||
|
||||
/* return file size */
|
||||
static size_t filesz(const char *fn)
|
||||
@@ -68,6 +73,7 @@ static int gen_hostkey(const char *name, struct lyd_node *change)
|
||||
rc = SR_ERR_INTERNAL;
|
||||
}
|
||||
|
||||
AUDIT("Installing SSH host key \"%s\".", name);
|
||||
if (systemf("/usr/libexec/infix/mksshkey %s %s %s %s", name,
|
||||
SSH_HOSTKEYS_NEXT, public_key, private_key))
|
||||
rc = SR_ERR_INTERNAL;
|
||||
@@ -75,6 +81,72 @@ static int gen_hostkey(const char *name, struct lyd_node *change)
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int gen_webcert(const char *name, struct lyd_node *change)
|
||||
{
|
||||
const char *private_key, *cert_data, *certname;
|
||||
struct lyd_node *certs, *cert;
|
||||
int new_cert;
|
||||
FILE *fp;
|
||||
|
||||
private_key = lydx_get_cattr(change, "cleartext-private-key");
|
||||
if (!private_key || !*private_key) {
|
||||
ERROR("Cannot find private key for \"%s\"", name);
|
||||
return SR_ERR_OK;
|
||||
}
|
||||
|
||||
certs = lydx_get_descendant(lyd_child(change), "certificates", "certificate", NULL);
|
||||
if (!certs) {
|
||||
ERROR("Cannot find any certificates for \"%s\"", name);
|
||||
return SR_ERR_OK;
|
||||
}
|
||||
|
||||
cert = certs; /* Use first certificate */
|
||||
|
||||
certname = lydx_get_cattr(cert, "name");
|
||||
if (!certname || !*certname) {
|
||||
ERROR("Cannot find certificate name for \"%s\"", name);
|
||||
return SR_ERR_OK;
|
||||
}
|
||||
|
||||
cert_data = lydx_get_cattr(cert, "cert-data");
|
||||
if (!cert_data || !*cert_data) {
|
||||
ERROR("Cannot find certificate data \"%s\"", name);
|
||||
return SR_ERR_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Only stop nginx (by clearing usr/mkcert) if the cert file does not
|
||||
* yet exist. When updating an existing cert, nginx can keep running
|
||||
* and will reload via SIGHUP from finit_reload("nginx") in web_change.
|
||||
*/
|
||||
new_cert = !fexistf("%s/%s.crt", SSL_CERT_DIR, certname);
|
||||
if (new_cert)
|
||||
erase("/run/finit/cond/usr/mkcert");
|
||||
|
||||
AUDIT("Installing HTTPS %s certificate \"%s\"", name, certname);
|
||||
fp = fopenf("w", "%s/%s.key", SSL_KEY_DIR, certname);
|
||||
if (!fp) {
|
||||
ERRNO("Failed creating key file for \"%s\"", certname);
|
||||
return SR_ERR_INTERNAL;
|
||||
}
|
||||
fprintf(fp, "-----BEGIN RSA PRIVATE KEY-----\n%s\n-----END RSA PRIVATE KEY-----\n", private_key);
|
||||
fclose(fp);
|
||||
systemf("chmod 600 %s/%s.key", SSL_KEY_DIR, certname);
|
||||
|
||||
fp = fopenf("w", "%s/%s.crt", SSL_CERT_DIR, certname);
|
||||
if (!fp) {
|
||||
ERRNO("Failed creating crt file for \"%s\"", certname);
|
||||
return SR_ERR_INTERNAL;
|
||||
}
|
||||
fprintf(fp, "-----BEGIN CERTIFICATE-----\n%s\n-----END CERTIFICATE-----\n", cert_data);
|
||||
fclose(fp);
|
||||
|
||||
if (new_cert)
|
||||
symlink("/run/finit/cond/reconf", "/run/finit/cond/usr/mkcert");
|
||||
|
||||
return SR_ERR_OK;
|
||||
}
|
||||
|
||||
static int keystore_update(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff)
|
||||
{
|
||||
const char *xpath = "/ietf-keystore:keystore/asymmetric-keys/asymmetric-key";
|
||||
@@ -163,6 +235,84 @@ static int keystore_update(sr_session_ctx_t *session, struct lyd_node *config, s
|
||||
free(private_key_format);
|
||||
}
|
||||
|
||||
if (list)
|
||||
sr_free_values(list, count);
|
||||
|
||||
/* Second pass: generate X.509 certificates for TLS */
|
||||
list = NULL;
|
||||
count = 0;
|
||||
rc = sr_get_items(session, xpath, 0, 0, &list, &count);
|
||||
if (rc != SR_ERR_OK)
|
||||
return 0;
|
||||
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
char *name = srx_get_str(session, "%s/name", list[i].xpath);
|
||||
char *public_key_format = NULL, *private_key_format = NULL;
|
||||
char *pub_key = NULL, *priv_key = NULL, *cert = NULL;
|
||||
sr_val_t *entry = &list[i];
|
||||
|
||||
if (srx_isset(session, "%s/cleartext-private-key", entry->xpath) ||
|
||||
srx_isset(session, "%s/public-key", entry->xpath))
|
||||
goto next_x509;
|
||||
|
||||
public_key_format = srx_get_str(session, "%s/public-key-format", entry->xpath);
|
||||
if (!public_key_format)
|
||||
goto next_x509;
|
||||
|
||||
private_key_format = srx_get_str(session, "%s/private-key-format", entry->xpath);
|
||||
if (!private_key_format)
|
||||
goto next_x509;
|
||||
|
||||
if (strcmp(private_key_format, "infix-crypto-types:rsa-private-key-format") ||
|
||||
strcmp(public_key_format, "infix-crypto-types:x509-public-key-format"))
|
||||
goto next_x509;
|
||||
|
||||
NOTE("X.509 certificate (%s) does not exist, generating...", name);
|
||||
if (systemf("/usr/libexec/infix/mkcert")) {
|
||||
ERROR("Failed generating X.509 certificate for %s", name);
|
||||
goto next_x509;
|
||||
}
|
||||
|
||||
priv_key = filerd(TLS_PRIVATE_KEY, filesz(TLS_PRIVATE_KEY));
|
||||
if (!priv_key)
|
||||
goto next_x509;
|
||||
|
||||
pub_key = filerd(TLS_CERTIFICATE, filesz(TLS_CERTIFICATE));
|
||||
if (!pub_key)
|
||||
goto next_x509;
|
||||
|
||||
/* Use cert data also for public-key (X.509 SubjectPublicKeyInfo) */
|
||||
rc = srx_set_str(session, priv_key, 0, "%s/cleartext-private-key", entry->xpath);
|
||||
if (rc) {
|
||||
ERROR("Failed setting private key for %s... rc: %d", name, rc);
|
||||
goto next_x509;
|
||||
}
|
||||
|
||||
rc = srx_set_str(session, pub_key, 0, "%s/public-key", entry->xpath);
|
||||
if (rc != SR_ERR_OK) {
|
||||
ERROR("Failed setting public key for %s... rc: %d", name, rc);
|
||||
goto next_x509;
|
||||
}
|
||||
|
||||
cert = filerd(TLS_CERTIFICATE, filesz(TLS_CERTIFICATE));
|
||||
if (cert) {
|
||||
rc = srx_set_str(session, cert, 0,
|
||||
"%s/certificates/certificate[name='self-signed']/cert-data",
|
||||
entry->xpath);
|
||||
if (rc)
|
||||
ERROR("Failed setting cert-data for %s... rc: %d", name, rc);
|
||||
}
|
||||
|
||||
next_x509:
|
||||
rmrf(TLS_TMPDIR);
|
||||
free(public_key_format);
|
||||
free(private_key_format);
|
||||
free(priv_key);
|
||||
free(pub_key);
|
||||
free(cert);
|
||||
free(name);
|
||||
}
|
||||
|
||||
if (list)
|
||||
sr_free_values(list, count);
|
||||
|
||||
@@ -209,21 +359,13 @@ int keystore_change(sr_session_ctx_t *session, struct lyd_node *config, struct l
|
||||
changes = lydx_get_descendant(config, "keystore", "asymmetric-keys", "asymmetric-key", NULL);
|
||||
LYX_LIST_FOR_EACH(changes, change, "asymmetric-key") {
|
||||
const char *name = lydx_get_cattr(change, "name");
|
||||
const char *type;
|
||||
const char *pubfmt;
|
||||
|
||||
type = lydx_get_cattr(change, "private-key-format");
|
||||
if (strcmp(type, "infix-crypto-types:rsa-private-key-format")) {
|
||||
INFO("Private key %s is not of SSH type (%s)", name, type);
|
||||
continue;
|
||||
}
|
||||
|
||||
type = lydx_get_cattr(change, "public-key-format");
|
||||
if (strcmp(type, "infix-crypto-types:ssh-public-key-format")) {
|
||||
INFO("Public key %s is not of SSH type (%s)", name, type);
|
||||
continue;
|
||||
}
|
||||
|
||||
gen_hostkey(name, change);
|
||||
pubfmt = lydx_get_cattr(change, "public-key-format");
|
||||
if (!strcmp(pubfmt, "infix-crypto-types:ssh-public-key-format"))
|
||||
gen_hostkey(name, change);
|
||||
else if (!strcmp(pubfmt, "infix-crypto-types:x509-public-key-format"))
|
||||
gen_webcert(name, change);
|
||||
}
|
||||
|
||||
return rc;
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#define GENERATE_ENUM(ENUM) ENUM,
|
||||
#define GENERATE_STRING(STRING) #STRING,
|
||||
|
||||
#define NGINX_SSL_CONF "/etc/nginx/ssl.conf"
|
||||
#define AVAHI_SVC_PATH "/etc/avahi/services"
|
||||
|
||||
#define LLDP_CONFIG "/etc/lldpd.d/confd.conf"
|
||||
@@ -625,6 +626,48 @@ out:
|
||||
}
|
||||
|
||||
|
||||
static void web_ssl_conf(struct lyd_node *srv, struct lyd_node *config)
|
||||
{
|
||||
const char *keyref, *certname = "self-signed";
|
||||
struct lyd_node *key, *certs;
|
||||
FILE *fp;
|
||||
|
||||
keyref = lydx_get_cattr(srv, "certificate");
|
||||
if (!keyref)
|
||||
keyref = "gencert";
|
||||
|
||||
key = lydx_get_xpathf(config, "/ietf-keystore:keystore/asymmetric-keys"
|
||||
"/asymmetric-key[name='%s']", keyref);
|
||||
if (key) {
|
||||
certs = lydx_get_descendant(lyd_child(key), "certificates", "certificate", NULL);
|
||||
if (certs) {
|
||||
const char *name = lydx_get_cattr(certs, "name");
|
||||
|
||||
if (name && *name)
|
||||
certname = name;
|
||||
}
|
||||
}
|
||||
|
||||
fp = fopen(NGINX_SSL_CONF, "w");
|
||||
if (!fp) {
|
||||
ERRNO("failed creating %s", NGINX_SSL_CONF);
|
||||
return;
|
||||
}
|
||||
|
||||
fprintf(fp,
|
||||
"ssl_certificate %s/%s.crt;\n"
|
||||
"ssl_certificate_key %s/%s.key;\n"
|
||||
"\n"
|
||||
"ssl_protocols TLSv1.3 TLSv1.2;\n"
|
||||
"ssl_ciphers HIGH:!aNULL:!MD5;\n"
|
||||
"ssl_prefer_server_ciphers on;\n"
|
||||
"\n"
|
||||
"ssl_session_cache shared:SSL:1m;\n"
|
||||
"ssl_session_timeout 5m;\n",
|
||||
SSL_CERT_DIR, certname, SSL_KEY_DIR, certname);
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
static int web_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
|
||||
{
|
||||
struct lyd_node *srv = NULL;
|
||||
@@ -638,6 +681,8 @@ static int web_change(sr_session_ctx_t *session, struct lyd_node *config, struct
|
||||
if (!cfg)
|
||||
return SR_ERR_OK;
|
||||
|
||||
web_ssl_conf(srv, config);
|
||||
|
||||
ena = lydx_is_enabled(srv, "enabled");
|
||||
if (ena) {
|
||||
svc_enadis(srx_enabled(session, "%s/enabled", WEB_CONSOLE_XPATH), ttyd, "ttyd");
|
||||
|
||||
@@ -43,13 +43,13 @@ MODULES=(
|
||||
"infix-firewall-icmp-types@2025-04-26.yang"
|
||||
"infix-meta@2025-12-10.yang"
|
||||
"infix-system@2026-03-09.yang"
|
||||
"infix-services@2026-03-04.yang"
|
||||
"infix-services@2026-03-20.yang"
|
||||
"ieee802-ethernet-interface@2019-06-21.yang"
|
||||
"infix-ethernet-interface@2024-02-27.yang"
|
||||
"infix-factory-default@2023-06-28.yang"
|
||||
"infix-interfaces@2025-11-06.yang -e vlan-filtering"
|
||||
"ietf-crypto-types -e cleartext-symmetric-keys"
|
||||
"infix-crypto-types@2025-11-09.yang"
|
||||
"infix-crypto-types@2026-02-14.yang"
|
||||
"ietf-keystore -e symmetric-keys"
|
||||
"infix-ntp@2026-03-09.yang"
|
||||
"infix-keystore@2025-12-17.yang"
|
||||
|
||||
@@ -6,6 +6,9 @@ module infix-crypto-types {
|
||||
prefix ct;
|
||||
}
|
||||
|
||||
revision 2026-02-14 {
|
||||
description "Add X.509 public key format for TLS certificates.";
|
||||
}
|
||||
revision 2025-11-09 {
|
||||
description "Add Wireguard public/private key and sha";
|
||||
}
|
||||
@@ -44,6 +47,13 @@ module infix-crypto-types {
|
||||
Used for SSH host keys.";
|
||||
}
|
||||
|
||||
identity x509-public-key-format {
|
||||
base public-key-format;
|
||||
base ct:subject-public-key-info-format;
|
||||
description
|
||||
"X.509 SubjectPublicKeyInfo format. Used for TLS certificates.";
|
||||
}
|
||||
|
||||
identity symmetric-key-format {
|
||||
base ct:symmetric-key-format;
|
||||
description
|
||||
|
||||
@@ -31,9 +31,11 @@ module infix-services {
|
||||
contact "kernelkit@googlegroups.com";
|
||||
description "Infix services, generic.";
|
||||
|
||||
revision 2026-03-04 {
|
||||
description "Add hostname leaf to mdns container for avahi host-name override.
|
||||
Add neighbors container to mdns for mDNS-SD neighbor table.";
|
||||
revision 2026-03-20 {
|
||||
description "Add hostname leaf to mdns container for avahi host-name override.
|
||||
Add neighbors container to mdns for mDNS-SD neighbor table.
|
||||
Add certificate leaf to web container for TLS keystore reference.";
|
||||
reference "internal";
|
||||
}
|
||||
revision 2025-12-10 {
|
||||
description "Adapt to changes in final version of ietf-keystore";
|
||||
@@ -266,6 +268,12 @@ module infix-services {
|
||||
container web {
|
||||
description "Web services";
|
||||
|
||||
leaf certificate {
|
||||
description "Reference to asymmetric key in central keystore with an
|
||||
associated certificate. By default 'gencert' is used.";
|
||||
type ks:central-asymmetric-key-ref;
|
||||
}
|
||||
|
||||
leaf enabled {
|
||||
description "Enable or disable on all web services.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user