api: randomize cipherlist for making requests to services ()

this makes cobalt less prone to TLS client fingerprinting, as it
avoids having the default node.js TLS fingerprint that is shared by
all node.js applications.
This commit is contained in:
jj 2024-06-15 18:20:33 +02:00 committed by GitHub
parent 1d5fa62271
commit d2e5b6542f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 32 additions and 0 deletions
src

View file

@ -10,6 +10,7 @@ import loc from "../localization/manager.js";
import { createResponse, normalizeRequest, getIP } from "../modules/processing/request.js";
import { verifyStream, getInternalStream } from "../modules/stream/manage.js";
import { randomizeCiphers } from '../modules/sub/randomize-ciphers.js';
import { extract } from "../modules/processing/url.js";
import match from "../modules/processing/match.js";
import stream from "../modules/stream/stream.js";
@ -215,6 +216,9 @@ export function runAPI(express, app, gitCommit, gitBranch, __dirname) {
res.redirect('/api/serverInfo')
})
randomizeCiphers();
setInterval(randomizeCiphers, 1000 * 60 * 30); // shuffle ciphers every 30 minutes
app.listen(env.apiPort, env.listenAddress, () => {
console.log(`\n` +
`${Cyan("cobalt")} API ${Bright(`v.${version}-${gitCommit} (${gitBranch})`)}\n` +

View file

@ -0,0 +1,28 @@
import tls from 'node:tls';
import { randomBytes } from 'node:crypto';
const ORIGINAL_CIPHERS = tls.DEFAULT_CIPHERS;
// How many ciphers from the top of the list to shuffle.
// The remaining ciphers are left in the original order.
const TOP_N_SHUFFLE = 8;
// Modified variation of https://stackoverflow.com/a/12646864
const shuffleArray = (array) => {
for (let i = array.length - 1; i > 0; i--) {
const j = randomBytes(4).readUint32LE() % array.length;
[array[i], array[j]] = [array[j], array[i]];
}
return array;
}
export const randomizeCiphers = () => {
do {
const cipherList = ORIGINAL_CIPHERS.split(':');
const shuffled = shuffleArray(cipherList.slice(0, TOP_N_SHUFFLE));
const retained = cipherList.slice(TOP_N_SHUFFLE);
tls.DEFAULT_CIPHERS = [ ...shuffled, ...retained ].join(':');
} while (tls.DEFAULT_CIPHERS === ORIGINAL_CIPHERS);
}