cloud_discovery: add certificate paths to gateway.json

Extend gateway.json to include cert and ca fields specifying which
certificate files the client should use for the connection.

Certificate naming strategy:
- Centralized (redirector discovery): operational.pem/operational.ca
- Air-gapped (DHCP/FQDN/Flash): <fqdn>.pem/<fqdn>.ca

Write discovery method to /tmp/discovery.method so est_client can
determine appropriate certificate naming when enrolling.

This enables APs to maintain separate operational certificates for
multiple controllers and automatically select the correct certificates
based on which controller they're connecting to.

Signed-off-by: John Crispin <john@phrozen.org>
This commit is contained in:
John Crispin 2025-11-25 07:31:08 +01:00
parent 4865aabdb3
commit 2009b5eb90

View File

@ -123,7 +123,7 @@ function gateway_write(data) {
gateway ??= {};
let new = {};
let changed = false;
for (let key in [ 'server', 'port', 'valid', 'hostname_validate' ]) {
for (let key in [ 'server', 'port', 'valid', 'hostname_validate', 'cert', 'ca' ]) {
if (exists(data, key))
new[key] = data[key];
else if (exists(gateway, key))
@ -192,8 +192,17 @@ function set_state(set) {
function discover_dhcp() {
let dhcp = readjsonfile('/tmp/cloud.json');
if (dhcp?.dhcp_server && dhcp?.dhcp_port) {
if (gateway_write({ server: dhcp.dhcp_server, port:dhcp.dhcp_port, valid: false, hostname_validate: dhcp.no_validation ? 0 : 1 })) {
let fqdn = split(dhcp.dhcp_server, ':')[0];
if (gateway_write({
server: dhcp.dhcp_server,
port: dhcp.dhcp_port,
valid: false,
hostname_validate: dhcp.no_validation ? 0 : 1,
cert: `/etc/ucentral/${fqdn}.pem`,
ca: `/etc/ucentral/${fqdn}.ca`
})) {
ulog(LOG_INFO, `Discovered cloud via DHCP ${dhcp.dhcp_server}:${dhcp.dhcp_port}\n`);
fs.writefile('/tmp/discovery.method', DISCOVER_DHCP);
client_start();
set_state(VALIDATING);
}
@ -214,10 +223,18 @@ function redirector_lookup() {
let redir = readjsonfile(path);
if (redir?.controller_endpoint) {
let controller_endpoint = split(redir.controller_endpoint, ':');
if (gateway_write({ server: controller_endpoint[0], port: controller_endpoint[1] || 15002, valid: false, hostname_validate: 1 })) {
if (gateway_write({
server: controller_endpoint[0],
port: controller_endpoint[1] || 15002,
valid: false,
hostname_validate: 1,
cert: '/etc/ucentral/operational.pem',
ca: '/etc/ucentral/operational.ca'
})) {
ulog(LOG_INFO, `Discovered cloud via lookup service ${controller_endpoint[0]}:${controller_endpoint[1] || 15002}\n`);
client_start();
set_state(VALIDATING);
fs.writefile('/tmp/discovery.method', DISCOVER_LOOKUP);
client_start();
set_state(VALIDATING);
}
} else {
ulog(LOG_INFO, 'Failed to discover cloud endpoint\n');
@ -229,6 +246,7 @@ function discover_flash() {
return 1;
ulog(LOG_INFO, 'Using pre-populated cloud information\n');
fs.writefile('/etc/ucentral/gateway.json', fs.readfile('/etc/ucentral/gateway.flash'));
fs.writefile('/tmp/discovery.method', DISCOVER_FLASH);
client_start();
set_state(VALIDATING);
return 0;
@ -246,8 +264,16 @@ function discover_standard_fqdn() {
let address = result[STANDARD_FQDN].A[0];
ulog(LOG_INFO, `Resolved ${STANDARD_FQDN} to ${address}\n`);
if (gateway_write({ server: STANDARD_FQDN, port: STANDARD_FQDN_PORT, valid: false, hostname_validate: 1 })) {
if (gateway_write({
server: STANDARD_FQDN,
port: STANDARD_FQDN_PORT,
valid: false,
hostname_validate: 1,
cert: `/etc/ucentral/${STANDARD_FQDN}.pem`,
ca: `/etc/ucentral/${STANDARD_FQDN}.ca`
})) {
ulog(LOG_INFO, `Discovered cloud via standard FQDN ${STANDARD_FQDN}\n`);
fs.writefile('/tmp/discovery.method', DISCOVER_FQDN);
client_start();
set_state(VALIDATING);
return true;