Skip to content

Commit

Permalink
feat: rename agent to repeater (#69)
Browse files Browse the repository at this point in the history
BREAKING CHANGES:

* **agent**: `agent` command has been renamed to `repeater`. It affected all its options and arguments.

    Before:
    ```bash
    docker run neuralegion/agent \
    -e 'AGENT_API_KEY=my-api-tey' \
    -e 'AGENT_ID=my-agent-id' \
    -e 'AGENT_HEADERS={ "X-Header": "my-header" }'
    -e 'AGENT_PROXY=socks5://my-proxy:1080/'
    ```
    After:
    ```bash
    docker run neuralegion/repeater \
      -e 'REPEATER_TOKEN=my-api-tey' \
      -e 'REPEATER_AGENT=my-agent-id' \
      -e 'REPEATER_HEADERS={ "X-Header": "my-header" }'
      -e 'REPEATER_PROXY=socks5://my-proxy:1080/'
    ```

* **archive:generate**: command has been reworking to accept `mockfile` as positional argument. `archive` options has been renamed to `output`.

    Before:

    ```bash
    nexploit-cli archive:generate \
        --archive archive.har \
        --target url-tested-application \
        --mockfile .nexmock \
        --header "Authorization: Bearer my-jwt-authentication-token"
    ```

    After:

    ```bash
    nexploit-cli archive:generate \
        --output archive.har \
        --target url-tested-application \
        --header "Authorization: Bearer my-jwt-authentication-token" \
        .nexmock
    ```

* `api-key` option has been removed. You should use `token` option instead.

    Before:

    ```bash
    nexploit-cli scan:run \
        --name scan-name \
        --archive received-archive-id \
        --api-key my-jwt-authentication-token
    ```

    After:

    ```bash
    nexploit-cli scan:run \
          --name scan-name \
          --archive received-archive-id \
          --token my-jwt-authentication-token
    ```

closes #68
  • Loading branch information
derevnjuk authored Aug 21, 2020
1 parent a38df39 commit c0bb81c
Show file tree
Hide file tree
Showing 16 changed files with 255 additions and 245 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,6 @@ jobs:
env:
NODE_AUTH_TOKEN: ${{ secrets.GPR_TOKEN }}

- run: docker build . --file Dockerfile --tag "neuralegion/agent:$VERSION"
- run: docker build . --file Dockerfile --tag "neuralegion/repeater:$VERSION"
- run: docker login --username=${{ secrets.DOCKER_USER }} --password=${{ secrets.DOCKER_TOKEN }}
- run: docker push neuralegion/agent
- run: docker push neuralegion/repeater
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
FROM node:10-alpine as base

LABEL org.opencontainers.image.vendor="NeuraLegion"
LABEL org.opencontainers.image.title="Agent"
LABEL org.opencontainers.image.title="Repeater"
LABEL org.opencontainers.image.source="https://github.com/NeuraLegion/nexploit-cli"
LABEL org.opencontainers.image.authors="Arten Derevnjuk <artem.derevnjuk@neuralegion.com>"

Expand All @@ -20,4 +20,4 @@ RUN npm config -g set user $(whoami)
RUN npm i -g -q @neuralegion/nexploit-cli

ENTRYPOINT [ "nexploit-cli" ]
CMD ["agent"]
CMD ["repeater"]
260 changes: 142 additions & 118 deletions README.md

Large diffs are not rendered by default.

29 changes: 17 additions & 12 deletions src/Commands/GenerateArchive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,53 +11,58 @@ import { Har } from 'har-format';
import { basename } from 'path';

export class GenerateArchive implements CommandModule {
public readonly command = 'archive:generate';
public readonly command = 'archive:generate [options] <mockfile>';
public readonly describe = 'Generates a new archive on base unit-tests.';

public builder(args: Argv): Argv {
return args
.option('mockfile', {
alias: 'm',
normalize: true,
describe: 'Mock file.',
demandOption: true
})
.option('pool', {
alias: 'p',
number: true,
requiresArg: true,
default: 250,
describe: 'Size of the worker pool.'
})
.option('timeout', {
number: true,
requiresArg: true,
default: 5000,
describe:
'Time to wait for a server to send response headers (and start the response body) before aborting the request.'
})
.option('split', {
alias: 's',
number: true,
requiresArg: true,
default: 1,
describe:
'Number of the HAR chunks. Allows to split a mock file to into multiple HAR files.'
})
.option('archive', {
alias: 'f',
.option('output', {
alias: 'o',
normalize: true,
requiresArg: true,
describe: 'Name of the archive.',
demandOption: true
})
.option('target', {
alias: 't',
alias: 'T',
requiresArg: true,
describe: 'Target hostname or IP address.',
demandOption: true
})
.option('header', {
alias: 'H',
requiresArg: true,
default: [],
array: true,
describe:
'A list of specific headers that should be included into request.'
})
.positional('mockfile', {
normalize: true,
describe: 'Mock file.',
demandOption: true
});
}

Expand All @@ -78,7 +83,7 @@ export class GenerateArchive implements CommandModule {

logger.log(`${log.entries.length ?? 0} requests were prepared.`);

const harSplitter = new HarSplitter(args.archive as string);
const harSplitter = new HarSplitter(args.output as string);

const fileNames: string[] = await harSplitter.split(
args.split as number,
Expand All @@ -96,7 +101,7 @@ export class GenerateArchive implements CommandModule {
);
process.exit(0);
} catch (e) {
logger.error(`Error during "archive:generate" run: ${e.message}`);
logger.error(`Error during "archive:generate": ${e.message}`);
process.exit(1);
}
}
Expand Down
15 changes: 4 additions & 11 deletions src/Commands/PollingScanStatus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,12 @@ export class PollingScanStatus implements CommandModule {

public builder(args: Argv): Argv {
return args
.option('api', {
default: 'https://nexploit.app/',
hidden: true,
describe: 'NexPloit base url'
})
.option('api-key', {
alias: 'K',
.option('token', {
alias: 't',
describe: 'NexPloit API-key',
requiresArg: true,
demandOption: true
})
.option('proxy', {
describe: 'SOCKS4 or SOCKS5 url to proxy all traffic'
})
.option('interval', {
requiresArg: true,
describe:
Expand All @@ -43,6 +35,7 @@ export class PollingScanStatus implements CommandModule {
'Eg: 60, "2min", "10h", "7d". A numeric value is interpreted as a milliseconds count.'
})
.option('breakpoint', {
alias: 'b',
choices: Helpers.toArray(BreakpointType),
string: true,
describe:
Expand All @@ -61,7 +54,7 @@ export class PollingScanStatus implements CommandModule {
try {
const scanManager = new RestScans({
baseUrl: args.api as string,
apiKey: args.apiKey as string,
apiKey: args.token as string,
proxyUrl: args.proxy as string
});
const polling = new DefaultPolling({
Expand Down
14 changes: 3 additions & 11 deletions src/Commands/RetestScan.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,12 @@ export class RetestScan implements CommandModule {

public builder(args: Argv): Argv {
return args
.option('api', {
default: 'https://nexploit.app/',
hidden: true,
describe: 'NexPloit base url'
})
.option('api-key', {
alias: 'K',
.option('token', {
alias: 't',
describe: 'NexPloit API-key',
requiresArg: true,
demandOption: true
})
.option('proxy', {
describe: 'SOCKS4 or SOCKS5 url to proxy all traffic'
})
.positional('scan', {
describe: 'ID of an existing scan which you want to re-run.',
type: 'string',
Expand All @@ -34,7 +26,7 @@ export class RetestScan implements CommandModule {
try {
const scanManager = new RestScans({
baseUrl: args.api as string,
apiKey: args.apiKey as string,
apiKey: args.token as string,
proxyUrl: args.proxy as string
});

Expand Down
56 changes: 28 additions & 28 deletions src/Commands/RunAgent.ts → src/Commands/RunRepeater.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,36 +6,32 @@ import logger from '../Utils/Logger';
import { Arguments, Argv, CommandModule } from 'yargs';

const onError = (e: Error) => {
logger.error(`Error during "agent": ${e.message}`);
logger.error(`Error during "repeater": ${e.message}`);
process.exit(1);
};

export class RunAgent implements CommandModule {
public readonly command = 'agent';
public readonly describe = 'Starts an agent by its ID.';
export class RunRepeater implements CommandModule {
public readonly command = 'repeater [options]';
public readonly describe = 'Starts an on-prem agent.';

public builder(args: Argv): Argv {
return args
.option('api', {
default: 'https://nexploit.app/',
hidden: true,
describe: 'NexPloit base url'
})
.option('bus', {
default: 'amqps://amq.nexploit.app:5672',
hidden: true,
demandOption: true,
describe: 'NexPloit Event Bus'
})
.option('api-key', {
alias: 'K',
.option('token', {
alias: 't',
describe: 'NexPloit API-key',
requiresArg: true,
demandOption: true
})
.option('id', {
.option('agent', {
describe:
'ID of an existing agent which you want to use to run a new scan.',
type: 'string',
requiresArg: true,
demandOption: true
})
.option('header', {
Expand All @@ -49,30 +45,32 @@ export class RunAgent implements CommandModule {
.option('headers', {
requiresArg: true,
conflicts: ['header'],
default: '{}',
describe:
'JSON string which contains header list, which is initially empty and consists of zero or more name and value pairs.'
})
.option('proxy', {
describe: 'SOCKS4 or SOCKS5 url to proxy all traffic'
})
.env('AGENT')
.env('REPEATER')
.exitProcess(false);
}

public async handler(args: Arguments): Promise<void> {
let bus: Bus;
try {
const stop: () => Promise<void> = async (): Promise<void> => {
await bus.destroy();
process.exit(0);
};
process.on('SIGTERM', stop).on('SIGINT', stop).on('SIGHUP', stop);

const headers: Record<string, string> = (args.header as string[])?.length
let headers: Record<string, string> = {};

try {
headers = (args.header as string[])?.length
? Helpers.parseHeaders(args.header as string[])
: JSON.parse(args.headers as string);
} catch {
// noop
}

const stop: () => Promise<void> = async (): Promise<void> => {
await bus.destroy();
process.exit(0);
};

try {
const requestExecutor = new DefaultRequestExecutor({
headers,
timeout: 5000,
Expand All @@ -85,18 +83,20 @@ export class RunAgent implements CommandModule {
{
onError,
exchange: 'EventBus',
clientQueue: `agent:${args.id as string}`,
clientQueue: `agent:${args.agent as string}`,
connectTimeout: 10000,
url: args.bus as string,
proxyUrl: args.proxy as string,
credentials: {
username: args.id as string,
password: args.apiKey as string
username: args.agent as string,
password: args.token as string
}
},
handlerRegistry
);

process.on('SIGTERM', stop).on('SIGINT', stop).on('SIGHUP', stop);

await bus.init();

await bus.subscribe(SendRequestHandler);
Expand Down
16 changes: 4 additions & 12 deletions src/Commands/RunScan.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,17 @@ import { AttackParamLocation } from '../Scan/Scans';
import { Arguments, Argv, CommandModule } from 'yargs';

export class RunScan implements CommandModule {
public readonly command = 'scan:run';
public readonly command = 'scan:run [options]';
public readonly describe = 'Start a new scan for the received configuration.';

public builder(args: Argv): Argv {
return args
.option('api', {
default: 'https://nexploit.app/',
hidden: true,
describe: 'NexPloit base url'
})
.option('api-key', {
alias: 'K',
.option('token', {
alias: 't',
describe: 'NexPloit API-key',
requiresArg: true,
demandOption: true
})
.option('proxy', {
describe: 'SOCKS4 or SOCKS5 url to proxy all traffic'
})
.option('name', {
alias: 'n',
describe: 'Name of the scan.',
Expand Down Expand Up @@ -138,7 +130,7 @@ export class RunScan implements CommandModule {
try {
const scanManager = new RestScans({
baseUrl: args.api as string,
apiKey: args.apiKey as string,
apiKey: args.token as string,
proxyUrl: args.proxy as string
});

Expand Down
16 changes: 5 additions & 11 deletions src/Commands/StopScan.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,16 @@ export class StopScan implements CommandModule {

public builder(args: Argv): Argv {
return args
.option('api', {
default: 'https://nexploit.app/',
hidden: true,
describe: 'NexPloit base url'
})
.option('api-key', {
alias: 'K',
.option('token', {
alias: 't',
describe: 'NexPloit API-key',
requiresArg: true,
demandOption: true
})
.option('proxy', {
describe: 'SOCKS4 or SOCKS5 url to proxy all traffic'
})
.positional('scan', {
describe: 'ID of an existing scan which you want to stop.',
requiresArg: true,
demandOption: true,
type: 'string'
});
}
Expand All @@ -32,7 +26,7 @@ export class StopScan implements CommandModule {
try {
const scanManager = new RestScans({
baseUrl: args.api as string,
apiKey: args.apiKey as string,
apiKey: args.token as string,
proxyUrl: args.proxy as string
});

Expand Down
Loading

0 comments on commit c0bb81c

Please sign in to comment.