Load the account server datastore signature secret from an environment variable

This removes the only uses of the certs directory in the account server.
This commit is contained in:
Matthew Lopez 2024-02-22 13:06:04 -05:00
parent 58e0b0120c
commit 8f191df06b
No known key found for this signature in database
GPG Key ID: 302A6EE3D63B7E0E
5 changed files with 24 additions and 157 deletions

View File

@ -218,9 +218,6 @@ services:
- type: bind
source: ./logs/account/
target: /app/logs/
- type: volume
source: account-certificates
target: /app/certs
networks:
internal:
dns: 172.20.0.200

View File

@ -1,8 +1,8 @@
diff --git i/Dockerfile w/Dockerfile
index a810a90..49d3fa5 100644
index a810a90..39fa5ad 100644
--- i/Dockerfile
+++ w/Dockerfile
@@ -1,16 +1,14 @@
@@ -1,16 +1,13 @@
-FROM node:18-alpine
+FROM node:20-alpine
@ -17,7 +17,6 @@ index a810a90..49d3fa5 100644
COPY . ./
+RUN npm run build
+RUN node generate-keys.js nex datastore
-VOLUME [ "/app/config.json", "/app/certs" ]
+VOLUME [ "/app/certs" ]

View File

@ -1,151 +0,0 @@
diff --git i/generate-keys.js w/generate-keys.js
index b1a311b..df80793 100644
--- i/generate-keys.js
+++ w/generate-keys.js
@@ -2,7 +2,7 @@ const NodeRSA = require('node-rsa');
const crypto = require('crypto');
const fs = require('fs-extra');
const yesno = require('yesno');
-const logger = require('./logger');
+const logger = require('./dist/logger');
require('colors');
const ALLOWED_CHARS_REGEX = /[^a-zA-Z0-9_-]/g;
@@ -11,7 +11,7 @@ async function main() {
const args = process.argv.slice(2);
if (args.length < 1) {
- logger.error('Must pass in type and optional name');
+ logger.LOG_ERROR('Must pass in type and optional name');
usage();
return;
}
@@ -24,25 +24,25 @@ async function main() {
name = name.toLowerCase().trim();
if (ALLOWED_CHARS_REGEX.test(name)) {
- logger.error(`Invalid name. Names must only contain [^a-zA-Z0-9_-]. Got ${name}`);
+ logger.LOG_ERROR(`Invalid name. Names must only contain [^a-zA-Z0-9_-]. Got ${name}`);
return;
}
}
if (!['nex', 'service', 'account'].includes(type)) {
- logger.error(`Invalid type. Expected nex, service, or account. Got ${type}`);
+ logger.LOG_ERROR(`Invalid type. Expected nex, service, or account. Got ${type}`);
usage();
return;
}
if (type !== 'account' && (!name || name === '')) {
- logger.error('If type is not account, a name MUST be passed');
+ logger.LOG_ERROR('If type is not account, a name MUST be passed');
usage();
return;
}
if (type === 'service' && name === 'account') {
- logger.error('Cannot use service name \'account\'. Reserved');
+ logger.LOG_ERROR('Cannot use service name \'account\'. Reserved');
usage();
return;
}
@@ -61,7 +61,7 @@ async function main() {
});
if (!overwrite) {
- logger.info('Not overwriting existing keys. Exiting program');
+ logger.LOG_INFO('Not overwriting existing keys. Exiting program');
return;
}
}
@@ -72,9 +72,9 @@ async function main() {
const secretKeyPath = `${path}/secret.key`;
// Ensure the output directories exist
- logger.info('Creating output directories...');
+ logger.LOG_INFO('Creating output directories...');
fs.ensureDirSync(path);
- logger.success('Created output directories!');
+ logger.LOG_SUCCESS('Created output directories!');
const key = new NodeRSA({ b: 1024 }, null, {
environment: 'browser',
@@ -84,50 +84,49 @@ async function main() {
});
// Generate new key pair
- logger.info('Generating RSA key pair...');
- logger.warn('(this may take a while)')
+ logger.LOG_INFO('Generating RSA key pair...');
key.generateKeyPair(1024);
- logger.success('Generated RSA key pair!');
+ logger.LOG_SUCCESS('Generated RSA key pair!');
// Export the keys
- logger.info('Exporting public key...');
+ logger.LOG_INFO('Exporting public key...');
const publicKey = key.exportKey('public');
- logger.success('Exported public key!');
+ logger.LOG_SUCCESS('Exported public key!');
// Saving public key
- logger.info('Saving public key to disk...');
+ logger.LOG_INFO('Saving public key to disk...');
fs.writeFileSync(publicKeyPath, publicKey);
- logger.success(`Saved public key to ${publicKeyPath}!`);
+ logger.LOG_SUCCESS(`Saved public key to ${publicKeyPath}!`);
- logger.info('Exporting private key...');
+ logger.LOG_INFO('Exporting private key...');
const privateKey = key.exportKey('private');
- logger.success('Exported private key!');
+ logger.LOG_SUCCESS('Exported private key!');
// Saving private key
- logger.info('Saving private key to disk...');
+ logger.LOG_INFO('Saving private key to disk...');
fs.writeFileSync(privateKeyPath, privateKey);
- logger.success(`Saved private key to ${privateKeyPath}!`);
+ logger.LOG_SUCCESS(`Saved private key to ${privateKeyPath}!`);
// Generate new AES key
- logger.info('Generating AES key...');
+ logger.LOG_INFO('Generating AES key...');
const aesKey = crypto.randomBytes(16);
- logger.success('Generated AES key!');
+ logger.LOG_SUCCESS('Generated AES key!');
// Saving AES key
- logger.info('Saving AES key to disk...');
+ logger.LOG_INFO('Saving AES key to disk...');
fs.writeFileSync(aesKeyPath, aesKey.toString('hex'));
- logger.success(`Saved AES key to ${aesKeyPath}!`);
+ logger.LOG_SUCCESS(`Saved AES key to ${aesKeyPath}!`);
// Create HMAC secret key
- logger.info('Generating HMAC secret...');
+ logger.LOG_INFO('Generating HMAC secret...');
const secret = crypto.randomBytes(16);
- logger.success('Generated RSA key pair!');
+ logger.LOG_SUCCESS('Generated RSA key pair!');
- logger.info('Saving HMAC secret to disk...');
+ logger.LOG_INFO('Saving HMAC secret to disk...');
fs.writeFileSync(secretKeyPath, secret.toString('hex'));
- logger.success(`Saved HMAC secret to ${secretKeyPath}!`);
+ logger.LOG_SUCCESS(`Saved HMAC secret to ${secretKeyPath}!`);
- logger.success('Keys generated successfully');
+ logger.LOG_SUCCESS('Keys generated successfully');
}
// Display usage information
@@ -142,4 +141,4 @@ function usage() {
console.log('Name: Service or NEX server name. Not used in account type');
}
-main().catch(logger.error);
\ No newline at end of file
+main().catch(logger.LOG_ERROR);
\ No newline at end of file

View File

@ -0,0 +1,18 @@
diff --git i/src/services/datastore/routes/upload.ts w/src/services/datastore/routes/upload.ts
index 3ceccda..12f853b 100644
--- i/src/services/datastore/routes/upload.ts
+++ w/src/services/datastore/routes/upload.ts
@@ -1,4 +1,3 @@
-import fs from 'node:fs';
import crypto from 'node:crypto';
import express from 'express';
import Dicer from 'dicer';
@@ -6,7 +5,7 @@ import { uploadCDNAsset } from '@/util';
const router: express.Router = express.Router();
-const signatureSecret: Buffer = fs.readFileSync(`${__dirname}/../../../../certs/nex/datastore/secret.key`);
+const signatureSecret: Buffer = Buffer.from(process.env.PN_ACT_CONFIG_DATASTORE_SIGNATURE_SECRET || '', 'hex');
function multipartParser(request: express.Request, response: express.Response, next: express.NextFunction): void {
const RE_BOUNDARY: RegExp = /^multipart\/.+?(?:; boundary=(?:(?:"(.+)")|(?:([^\s]+))))$/i;

View File

@ -50,6 +50,10 @@ fi
account_aes_key=$(generate_hex 64)
echo "PN_ACT_CONFIG_AES_KEY=$account_aes_key" >>./account.local.env
# Generate a secret key for account server datastore signatures
account_datastore_secret=$(generate_hex 32)
echo "PN_ACT_CONFIG_DATASTORE_SIGNATURE_SECRET=$account_datastore_secret" >>./account.local.env
# Generate master API keys for the account gRPC server
# The Juxtaposition UI uses the same API key for both the account and API
# servers, so both keys need to be the same