94 lines
3.0 KiB
JavaScript
94 lines
3.0 KiB
JavaScript
'use strict';
|
||
|
||
// Generates /etc/krb5.conf from .env values (realm, DC list, domain).
|
||
// Run at every container start before server.js:
|
||
// node scripts/generate-krb5-conf.js
|
||
// Output path defaults to /etc/krb5.conf; override with KRB5_CONF_PATH
|
||
// (useful for tests or when the process has no write access to /etc).
|
||
|
||
const fs = require('fs');
|
||
const path = require('path');
|
||
const config = require('../lib/config');
|
||
|
||
const DEFAULT_OUTPUT = '/etc/krb5.conf';
|
||
|
||
function hostFromUrl(url) {
|
||
const match = /^[a-z0-9+.-]+:\/\/([^/:]+)(?::\d+)?/i.exec(String(url || '').trim());
|
||
return match ? match[1].toLowerCase() : '';
|
||
}
|
||
|
||
function collectKdcServers() {
|
||
const hosts = [];
|
||
const push = (host) => {
|
||
const value = String(host || '').trim().split(':')[0].toLowerCase();
|
||
if (value && !hosts.some((h) => h.toLowerCase() === value)) hosts.push(value);
|
||
};
|
||
push(hostFromUrl(config.ldapUrl));
|
||
for (const item of String(config.kdcServers || '').split(/[\s,]+/)) {
|
||
if (item) push(item);
|
||
}
|
||
return hosts;
|
||
}
|
||
|
||
function buildKrb5Conf({ realm, domain, kdcServers }) {
|
||
const lines = [
|
||
'# Generated by scripts/generate-krb5-conf.js from .env — do not edit manually.',
|
||
'# Overrides: LDAP_REALM (realm), LDAP_KDC_SERVERS (comma-separated DC list),',
|
||
'# LDAP_URL (primary DC host is always included).',
|
||
'',
|
||
'[libdefaults]',
|
||
` default_realm = ${realm}`,
|
||
' dns_lookup_kdc = true',
|
||
' dns_lookup_realm = false',
|
||
' rdns = false',
|
||
' udp_preference_limit = 1',
|
||
' kdc_timeout = 5',
|
||
' max_retries = 2',
|
||
' forwardable = true',
|
||
' ticket_lifetime = 10h',
|
||
''
|
||
];
|
||
|
||
if (kdcServers.length > 0) {
|
||
lines.push('[realms]', ` ${realm} = {`);
|
||
for (const kdc of kdcServers) lines.push(` kdc = ${kdc}`);
|
||
lines.push(' }', '');
|
||
}
|
||
|
||
if (domain) {
|
||
lines.push('[domain_realm]', ` .${domain} = ${realm}`, ` ${domain} = ${realm}`);
|
||
}
|
||
|
||
return lines.join('\n') + '\n';
|
||
}
|
||
|
||
function writeKrb5Conf(content, outputPath) {
|
||
const target = outputPath || DEFAULT_OUTPUT;
|
||
const dir = path.dirname(target);
|
||
fs.mkdirSync(dir, { recursive: true });
|
||
const tmp = `${target}.tmp-${process.pid}`;
|
||
fs.writeFileSync(tmp, content, { encoding: 'utf8', mode: 0o644 });
|
||
fs.renameSync(tmp, target);
|
||
return target;
|
||
}
|
||
|
||
function main() {
|
||
try {
|
||
const realm = config.ldapRealm;
|
||
const domain = config.domain;
|
||
const kdcServers = collectKdcServers();
|
||
const outputPath = process.env.KRB5_CONF_PATH || DEFAULT_OUTPUT;
|
||
const content = buildKrb5Conf({ realm, domain, kdcServers });
|
||
const target = writeKrb5Conf(content, outputPath);
|
||
console.log(`krb5.conf generated -> ${target} (realm ${realm}, kdc: ${kdcServers.join(', ') || '(DNS SRV)'})`);
|
||
} catch (err) {
|
||
console.error(`Не удалось сгенерировать krb5.conf: ${err.message}`);
|
||
process.exit(1);
|
||
}
|
||
}
|
||
|
||
module.exports = { buildKrb5Conf, collectKdcServers, hostFromUrl, writeKrb5Conf, main, DEFAULT_OUTPUT };
|
||
|
||
if (require.main === module) {
|
||
main();
|
||
} |