/
sudokill.js
executable file
·77 lines (62 loc) · 2.06 KB
/
sudokill.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#!/usr/bin/env node
// kill all processes that outside SSH and root
import cli from 'cli'
import shelljs from 'shelljs';
import { existsSync, readdirSync } from 'fs';
const LOGINLINGERDIR = process.env.LOGINLINGERDIR || '/var/lib/systemd/linger';
const { exec } = shelljs;
const opts = cli.parse({
test: ['t', 'Test mode', 'bool', false],
ignore: ['i', 'Ignore user list', 'string', ''],
verbose: ['v', 'verbose', 'bool', false],
});
const psOutput = exec('ps -eo user:20,pid,etimes,command --forest --no-headers', {
silent: true,
fatal: true,
}).stdout.trim().split('\n');
const whoOutput = exec('who', {
silent: true,
fatal: true,
}).stdout.trim().split('\n');
const ignoreUsers = opts.ignore.split(',')
.reduce((acc, cur) => {
acc[cur] = true;
return acc;
}, {});
if (existsSync(LOGINLINGERDIR)) {
const lingerFiles = readdirSync(LOGINLINGERDIR, { withFileTypes: true });
Object.assign(ignoreUsers, lingerFiles.map(x => x.name).filter(x => x).reduce((acc, cur) => {
acc[cur] = true;
return acc;
}, {}))
}
ignoreUsers.root = true;
if (opts.verbose) {
console.log('Ignoring users: ' + Object.keys(ignoreUsers).join(','));
}
// process and filter output
const splitTest = /^([\w.-]+\+?) +(\d+) +(\d+) (.+)$/;
const lists = psOutput
.map(x => splitTest.exec(x))
.filter(x => x !== null && !ignoreUsers[x[1]]).map(match => ({
raw: match[0],
user: match[1],
pid: match[2],
etimes: parseInt(match[3]),
command: match[4],
}));
for (const item of whoOutput) {
ignoreUsers[item.match(/^[\w.-]+/)[0]] = true;
}
// scan for any processes not in ssh sessions or longer than 3 hours
let candidates = lists.filter(x => x.etimes > 10800 || (x.command[0] != ' ' && !ignoreUsers[x.user] && x.etimes > 60));
if (opts.test) {
console.log(candidates.map(x => x.raw).join('\n'));
} else {
for (let x of candidates) {
if (opts.verbose) {
console.log(`Killing ${x.user}: ${x.pid} (${x.command})`);
}
exec(`kill -9 ${x.pid}`);
}
}