Skip to content

Commit

Permalink
chore: platform services authentication for Core RPC
Browse files Browse the repository at this point in the history
  • Loading branch information
shumkov committed Jun 12, 2024
1 parent 52aff41 commit d0ce81e
Show file tree
Hide file tree
Showing 21 changed files with 144 additions and 59 deletions.
41 changes: 39 additions & 2 deletions packages/dashmate/configs/defaults/getBaseConfigFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,45 @@ export default function getBaseConfigFactory(homeDir) {
rpc: {
host: '127.0.0.1',
port: 9998,
user: 'dashrpc',
password: 'rpcpassword',
users: {
dashmate: {
password: 'rpcpassword',
whitelist: null,
lowPriority: false,
},
dapi: {
password: 'rpcpassword',
whitelist: [
'getbestblockhash', 'getblockhash', 'sendrawtransaction', 'getrawtransaction',
'getblockstats', 'getmerkleblocks', 'getrawtransactionmulti', 'getrawmempool',
'getblockcount', 'getbestchainlock', 'getblock', 'getblockheader', 'getblockheaders',
'protx diff', 'getnetworkinfo', 'getblockchaininfo', 'mnsync status', 'masternode status',
],
lowPriority: true,
},
drive_consensus: {
password: 'rpcpassword',
whitelist: [
'getbestchainlock', 'getblockchaininfo', 'getrawtransaction', 'submitchainlock',
'verifychainlock', 'protx listdiff', 'quorum listextended', 'quorum info',
'getassetunlockstatuses', 'sendrawtransaction', 'mnsync status',
],
lowPriority: false,
},
drive_other: {
password: 'rpcpassword',
whitelist: ['getrawtransaction'],
lowPriority: true,
},
tenderdash: {
password: 'rpcpassword',
whitelist: [
'quorum info', 'quorum verify', 'quorum sign', 'masternode status', 'masternodelist',
'ping', 'getnetworkinfo',
],
lowPriority: false,
},
},
allowIps: ['127.0.0.1', '172.16.0.0/12', '192.168.0.0/16'],
},
spork: {
Expand Down
12 changes: 12 additions & 0 deletions packages/dashmate/configs/getConfigFileMigrationsFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -613,6 +613,18 @@ export default function getConfigFileMigrationsFactory(homeDir, defaultConfigs)

return configFile;
},
'1.0.0-dev.16': (configFile) => {
Object.entries(configFile.configs)
.forEach(([, options]) => {
options.core.rpc.users = base.get('core.rpc.users');
options.core.rpc.users.dashmate = options.core.rpc.password;

delete options.core.rpc.user;
delete options.core.rpc.password;
});

return configFile;
},
};
}

Expand Down
8 changes: 4 additions & 4 deletions packages/dashmate/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,8 @@ services:
- API_GRPC_PORT=3005
- DASHCORE_RPC_HOST=core
- DASHCORE_RPC_PORT=${CORE_RPC_PORT:?err}
- DASHCORE_RPC_USER=${CORE_RPC_USER:?err}
- DASHCORE_RPC_PASS=${CORE_RPC_PASSWORD:?err}
- DASHCORE_RPC_USER=dapi
- DASHCORE_RPC_PASS=${CORE_RPC_USERS_DAPI_PASSWORD:?err}
- DASHCORE_ZMQ_HOST=core
- DASHCORE_ZMQ_PORT=29998
- DASHCORE_P2P_HOST=core
Expand Down Expand Up @@ -158,8 +158,8 @@ services:
- TX_FILTER_STREAM_GRPC_PORT=3006
- DASHCORE_RPC_HOST=core
- DASHCORE_RPC_PORT=${CORE_RPC_PORT:?err}
- DASHCORE_RPC_USER=${CORE_RPC_USER:?err}
- DASHCORE_RPC_PASS=${CORE_RPC_PASSWORD:?err}
- DASHCORE_RPC_USER=dapi
- DASHCORE_RPC_PASS=${CORE_RPC_USERS_DAPI_PASSWORD:?err}
- DASHCORE_ZMQ_HOST=core
- DASHCORE_ZMQ_PORT=29998
- DASHCORE_P2P_HOST=core
Expand Down
38 changes: 30 additions & 8 deletions packages/dashmate/src/config/configJsonSchema.js
Original file line number Diff line number Diff line change
Expand Up @@ -231,13 +231,35 @@ export default {
port: {
$ref: '#/definitions/port',
},
user: {
type: 'string',
minLength: 1,
},
password: {
type: 'string',
minLength: 1,
users: {
type: 'object',
minProperties: 1,
propertyNames: {
type: 'string',
minLength: 1,
},
additionalProperties: {
type: 'object',
properties: {
password: {
type: 'string',
minLength: 1,
},
whitelist: {
type: ['null', 'array'],
items: {
type: 'string',
minLength: 1,
},
minItems: 1,
},
lowPriority: {
type: 'boolean',
},
},
required: ['password', 'whitelist', 'lowPriority'],
additionalProperties: false,
},
},
allowIps: {
type: 'array',
Expand All @@ -246,7 +268,7 @@ export default {
},
},
},
required: ['host', 'port', 'user', 'password'],
required: ['host', 'port', 'users', 'allowIps'],
additionalProperties: false,
},
spork: {
Expand Down
4 changes: 2 additions & 2 deletions packages/dashmate/src/core/startCoreFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@ export default function startCoreFactory(
const rpcClient = createRpcClient(
{
port: config.get('core.rpc.port'),
user: config.get('core.rpc.user'),
pass: config.get('core.rpc.password'),
user: 'dashmate',
pass: config.get('core.rpc.users.dashmate.password'),
host: await getConnectionHost(config, 'core', 'core.rpc.host'),
},
);
Expand Down
4 changes: 2 additions & 2 deletions packages/dashmate/src/listr/tasks/reindexNodeTaskFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,8 @@ export default function reindexNodeTaskFactory(
// Wait until Core is started
const rpcClient = createRpcClient({
port: config.get('core.rpc.port'),
user: config.get('core.rpc.user'),
pass: config.get('core.rpc.password'),
user: 'dashmate',
pass: config.get('core.rpc.users.dashmate.password'),
host: await getConnectionHost(config, 'core', 'core.rpc.host'),
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,8 +175,12 @@ export default function setupLocalPresetTaskFactory(
config.set('group', 'local');
config.set('core.p2p.port', config.get('core.p2p.port') + (i * 100));
config.set('core.rpc.port', config.get('core.rpc.port') + (i * 100));
config.set('core.rpc.user', generateRandomString(8));
config.set('core.rpc.password', generateRandomString(12));

Object.values(config.get('core.rpc.users')).forEach((options) => {
// eslint-disable-next-line no-param-reassign
options.password = generateRandomString(12);
});

config.set('externalIp', hostDockerInternalIp);

const subnet = config.get('docker.network.subnet')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,10 @@ export default function setupRegularPresetTaskFactory(
ctx.config.set('platform.drive.tenderdash.mode', 'full');
}

ctx.config.set('core.rpc.user', generateRandomString(8));
ctx.config.set('core.rpc.password', generateRandomString(12));
Object.values(ctx.config.get('core.rpc.users')).forEach((options) => {
// eslint-disable-next-line no-param-reassign
options.password = generateRandomString(12);
});

// eslint-disable-next-line no-param-reassign
task.output = ctx.nodeType ? ctx.nodeType : nodeTypeName;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ export default function startGroupNodesTaskFactory(
task: async () => {
const rpcClient = createRpcClient({
port: config.get('core.rpc.port'),
user: config.get('core.rpc.user'),
pass: config.get('core.rpc.password'),
user: 'dashmate',
pass: config.get('core.rpc.users.dashmate.password'),
host: await getConnectionHost(config, 'core', 'core.rpc.host'),
});

Expand Down
4 changes: 2 additions & 2 deletions packages/dashmate/src/listr/tasks/startNodeTaskFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,8 @@ export default function startNodeTaskFactory(
task: async () => {
const rpcClient = createRpcClient({
port: config.get('core.rpc.port'),
user: config.get('core.rpc.user'),
pass: config.get('core.rpc.password'),
user: 'dashmate',
pass: config.get('core.rpc.users.dashmate.password'),
host: await getConnectionHost(config, 'core', 'core.rpc.host'),
});

Expand Down
12 changes: 6 additions & 6 deletions packages/dashmate/src/listr/tasks/stopNodeTaskFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ export default function stopNodeTaskFactory(
task: async () => {
const rpcClient = createRpcClient({
port: config.get('core.rpc.port'),
user: config.get('core.rpc.user'),
pass: config.get('core.rpc.password'),
user: 'dashmate',
pass: config.get('core.rpc.users.dashmate.password'),
host: await getConnectionHost(config, 'core', 'core.rpc.host'),
});

Expand All @@ -62,8 +62,8 @@ export default function stopNodeTaskFactory(
enabled: (ctx) => config.get('core.masternode.enable') && !ctx.isForce && ctx.isSafe,
task: async () => waitForDKGWindowPass(createRpcClient({
port: config.get('core.rpc.port'),
user: config.get('core.rpc.user'),
pass: config.get('core.rpc.password'),
user: 'dashmate',
pass: config.get('core.rpc.users.dashmate.password'),
host: await getConnectionHost(config, 'core', 'core.rpc.host'),
})),
},
Expand All @@ -74,8 +74,8 @@ export default function stopNodeTaskFactory(
task: async () => {
const rpcClient = createRpcClient({
port: config.get('core.rpc.port'),
user: config.get('core.rpc.user'),
pass: config.get('core.rpc.password'),
user: 'dashmate',
pass: config.get('core.rpc.users.dashmate.password'),
host: await getConnectionHost(config, 'core', 'core.rpc.host'),
});

Expand Down
4 changes: 2 additions & 2 deletions packages/dashmate/src/status/scopes/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ export default function getCoreScopeFactory(
try {
const rpcClient = createRpcClient({
port: config.get('core.rpc.port'),
user: config.get('core.rpc.user'),
pass: config.get('core.rpc.password'),
user: 'dashmate',
pass: config.get('core.rpc.users.dashmate.password'),
host: await getConnectionHost(config, 'core', 'core.rpc.host'),
});

Expand Down
8 changes: 4 additions & 4 deletions packages/dashmate/src/status/scopes/masternode.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ export default function getMasternodeScopeFactory(
async function getSyncAsset(config) {
const rpcClient = createRpcClient({
port: config.get('core.rpc.port'),
user: config.get('core.rpc.user'),
pass: config.get('core.rpc.password'),
user: 'dashmate',
pass: config.get('core.rpc.users.dashmate.password'),
host: await getConnectionHost(config, 'core', 'core.rpc.host'),
});

Expand All @@ -31,8 +31,8 @@ export default function getMasternodeScopeFactory(
async function getMasternodeInfo(config) {
const rpcClient = createRpcClient({
port: config.get('core.rpc.port'),
user: config.get('core.rpc.user'),
pass: config.get('core.rpc.password'),
user: 'dashmate',
pass: config.get('core.rpc.users.dashmate.password'),
host: await getConnectionHost(config, 'core', 'core.rpc.host'),
});

Expand Down
4 changes: 2 additions & 2 deletions packages/dashmate/src/status/scopes/platform.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ export default function getPlatformScopeFactory(
async function getMNSync(config) {
const rpcClient = createRpcClient({
port: config.get('core.rpc.port'),
user: config.get('core.rpc.user'),
pass: config.get('core.rpc.password'),
user: 'dashmate',
pass: config.get('core.rpc.users.dashmate.password'),
host: await getConnectionHost(config, 'core', 'core.rpc.host'),
});

Expand Down
3 changes: 2 additions & 1 deletion packages/dashmate/src/templates/renderTemplateFactory.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import fs from 'fs';
import dots from 'dot';
import crypto from 'crypto';

/**
* @return {renderTemplate}
Expand All @@ -18,7 +19,7 @@ export default function renderTemplateFactory() {
const templateString = fs.readFileSync(templatePath, 'utf-8');
const template = dots.template(templateString);

return template(variables);
return template({ ...variables, crypto });
}

return renderTemplate;
Expand Down
23 changes: 15 additions & 8 deletions packages/dashmate/templates/core/dash.conf.dot
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,28 @@ debuglogfile=/var/log/dash/{{= it.core.log.file.path.split('/').pop() }}
logips={{=it.core.logIps }}
fallbackfee=0.00001

# JSONRPC
# JSON RPC
server=1
rpcuser={{=it.core.rpc.user}}
rpcpassword={{=it.core.rpc.password}}
rpcbind=0.0.0.0
rpcport={{=it.core.rpc.port}}
rpcwallet=main
deprecatedrpc=hpmn
rpcworkqueue=96
rpcthreads=12
rpcwhitelistdefault=0
rpcexternaluser={{= Object.entries(it.core.rpc.users).filter(([username, options]) => options.lowPriority).map(([username, options]) => username).join(',') }}
{{~ Object.keys(it.core.rpc.users) :user}}
{{ salt = it.crypto.randomBytes(16).toString('hex'); }}
{{ hmac = it.crypto.createHmac('sha256', salt).update(it.core.rpc.users[user].password); }}
rpcauth={{=user}}:{{=salt}}${{=hmac.digest('hex') }}
{{? it.core.rpc.users[user].whitelist !== null }}
rpcwhitelist={{=user}}:{{=it.core.rpc.users[user].whitelist.join(',')}}
{{?}}
{{~}}

{{~it.core.rpc.allowIps :host}}
rpcallowip={{=host}}{{~}}

rpcworkqueue=64
rpcthreads=16

# external network
listen=1
dnsseed=0
Expand Down Expand Up @@ -94,6 +103,4 @@ addnode={{=seed.host}}:{{=seed.port}}{{~}}
# network
port={{=it.core.p2p.port}}
bind=0.0.0.0
rpcbind=0.0.0.0
rpcport={{=it.core.rpc.port}}

Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
"connect": [{
"rpchost": "core",
"rpcport": {{= it.core.rpc.port }},
"rpcuser": "{{= it.core.rpc.user }}",
"rpcpassword": "{{= it.core.rpc.password }}",
"rpcuser": "dashmate",
"rpcpassword": "{{= it.core.rpc.users.dashmate.password }}",
"zmqpubrawtx": "tcp://core:29998",
"zmqpubhashblock": "tcp://core:29998"
}]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,10 @@ laddr = ""
core-rpc-host = "core:{{= it.core.rpc.port}}"

# Local Dash Core RPC Username
core-rpc-username = "{{= it.core.rpc.user}}"
core-rpc-username = "tenderdash"

# Local Dash Core RPC Password
core-rpc-password = "{{= it.core.rpc.password}}"
core-rpc-password = "{{= it.core.rpc.users.tenderdash.password}}"

# Path to the client certificate generated while creating needed files for secure connection.
# If a remote validator address is provided but no certificate, the connection will be insecure
Expand Down
4 changes: 2 additions & 2 deletions packages/dashmate/test/e2e/testnetEvonode.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,8 @@ describe('Testnet Evonode', function main() {
const coreRpcClient = createRpcClient({
host: config.get('core.rpc.host'),
port: config.get('core.rpc.port'),
user: config.get('core.rpc.user'),
pass: config.get('core.rpc.password'),
user: 'dashmate',
pass: config.get('core.rpc.users.dashmate.password'),
});

waitForCoreData = waitForCoreDataFactory(coreRpcClient);
Expand Down
4 changes: 2 additions & 2 deletions packages/dashmate/test/e2e/testnetFullnode.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,8 @@ describe('Testnet Fullnode', function main() {
const coreRpcClient = createRpcClient({
host: config.get('core.rpc.host'),
port: config.get('core.rpc.port'),
user: config.get('core.rpc.user'),
pass: config.get('core.rpc.password'),
user: 'dashmate',
pass: config.get('core.rpc.users.dashmate.password'),
});

waitForCoreData = waitForCoreDataFactory(coreRpcClient);
Expand Down
Loading

0 comments on commit d0ce81e

Please sign in to comment.