From e2c7d473a59911d2686fb59aac48fe120440b8e0 Mon Sep 17 00:00:00 2001 From: Francois Date: Tue, 19 Mar 2024 18:28:52 +0100 Subject: [PATCH 1/3] draft reconfig --- src/reconfig/_utils/dto/reconfig.proto | 14 ++++++++ .../dto/request/reconfig-request.dto.ts | 7 ++++ src/reconfig/reconfig.controller.ts | 17 ++++++++++ src/reconfig/reconfig.module.ts | 10 ++++++ src/reconfig/reconfig.service.ts | 32 +++++++++++++++++++ 5 files changed, 80 insertions(+) create mode 100644 src/reconfig/_utils/dto/reconfig.proto create mode 100644 src/reconfig/_utils/dto/request/reconfig-request.dto.ts create mode 100644 src/reconfig/reconfig.controller.ts create mode 100644 src/reconfig/reconfig.module.ts create mode 100644 src/reconfig/reconfig.service.ts diff --git a/src/reconfig/_utils/dto/reconfig.proto b/src/reconfig/_utils/dto/reconfig.proto new file mode 100644 index 0000000..7636f54 --- /dev/null +++ b/src/reconfig/_utils/dto/reconfig.proto @@ -0,0 +1,14 @@ +syntax = "proto3"; + +package reconfigure; + +service Reconfigure { + rpc ReconfigHoneypot (ReconfigRequest) returns (ReconfigReply) {} +} + +message ReconfigRequest { + string config = 1; +} + +message ReconfigReply { +} \ No newline at end of file diff --git a/src/reconfig/_utils/dto/request/reconfig-request.dto.ts b/src/reconfig/_utils/dto/request/reconfig-request.dto.ts new file mode 100644 index 0000000..4311b4c --- /dev/null +++ b/src/reconfig/_utils/dto/request/reconfig-request.dto.ts @@ -0,0 +1,7 @@ +import { IsString } from "class-validator"; + +export class ReConfigDto { + + @IsString() + config: string; +} \ No newline at end of file diff --git a/src/reconfig/reconfig.controller.ts b/src/reconfig/reconfig.controller.ts new file mode 100644 index 0000000..0ba1e69 --- /dev/null +++ b/src/reconfig/reconfig.controller.ts @@ -0,0 +1,17 @@ +import { ApiTags } from '@nestjs/swagger'; +import { Controller } from '@nestjs/common'; +import { ReConfigDto } from './_utils/dto/request/reconfig-request.dto'; +import { GrpcMethod } from '@nestjs/microservices'; +import { ReconfigureService } from './reconfig.service' + +@Controller('reconfig') +@ApiTags('ReconfigTag') + +export class ReconfigureController{ + constructor(private reconfigureService: ReconfigureService){} + + @GrpcMethod('Reconfigure', 'ReconfigHoneypot') + public async ReconfigHoneypot(ReconfigData: ReConfigDto) { + return this.reconfigureService.ReconfigHoneypot(ReconfigData); + } +} \ No newline at end of file diff --git a/src/reconfig/reconfig.module.ts b/src/reconfig/reconfig.module.ts new file mode 100644 index 0000000..8ed5c4d --- /dev/null +++ b/src/reconfig/reconfig.module.ts @@ -0,0 +1,10 @@ +import { Module } from "@nestjs/common"; +import { ReconfigureService } from "./reconfig.service"; +import { ReconfigureController } from "./reconfig.controller"; + +@Module({ + controllers: [ReconfigureController], + providers: [ReconfigureService], + exports: [ReconfigureService], +}) +export class ReconfigureModule {} \ No newline at end of file diff --git a/src/reconfig/reconfig.service.ts b/src/reconfig/reconfig.service.ts new file mode 100644 index 0000000..b76d7db --- /dev/null +++ b/src/reconfig/reconfig.service.ts @@ -0,0 +1,32 @@ +import { Injectable } from '@nestjs/common'; +import { Subject } from 'rxjs'; +import { ReConfigDto } from './_utils/dto/request/reconfig-request.dto'; +import * as Docker from 'dockerode'; +import { RpcException } from '@nestjs/microservices'; + + +@Injectable() +export class ReconfigureService { + + private docker = new Docker(); + + +public async ReconfigHoneypot(Reconfig: ReConfigDto) { + //check config + if (!Reconfig.config) throw new RpcException('Config cannot be empty') + //recup liste dockers + const network = await this.docker.getNetwork('honeypot_network').inspect(); + + const networkContainers = network.Containers; + const containerIds = Object.keys(networkContainers); + + const containers = await this.docker.listContainers({ all: true }); + + const buildContainers = containers.filter((container) => container.Names[0].startsWith('/honeypot_')); + + buildContainers.forEach(element => { + this.docker.getContainer('fb607059a048').stop(); + }); + //creer docker depuis config + } +} \ No newline at end of file From b944960cb1c8d2c0278b67a40eddd94e800dfced Mon Sep 17 00:00:00 2001 From: Alexandre Titeux Date: Tue, 19 Mar 2024 18:42:42 +0100 Subject: [PATCH 2/3] =?UTF-8?q?:bug:=20Fix=20buf=20from=20fran=C3=A7ois?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app.module.ts | 3 ++- src/grpc-client.options.ts | 3 ++- src/reconfig/_utils/{dto => }/reconfig.proto | 10 +++++----- src/reconfig/reconfig.controller.ts | 21 ++++++++++---------- src/reconfig/reconfig.module.ts | 13 ++++++------ 5 files changed, 25 insertions(+), 25 deletions(-) rename src/reconfig/_utils/{dto => }/reconfig.proto (66%) diff --git a/src/app.module.ts b/src/app.module.ts index a34a4f5..971d742 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -1,7 +1,6 @@ import { Module } from '@nestjs/common'; import { ConfigModule, ConfigService } from '@nestjs/config'; import { EnvironmentVariables, validateEnv } from './_utils/config/config'; -import { HelloworldModule } from './helloworld/helloworld.module'; import { LogsModule } from './logs/logs.module'; import { DashboardModule } from './dashboard/dashboard.module'; import { ContainersModule } from './containers/containers.module'; @@ -13,6 +12,7 @@ import { MailsModule } from './mails/mails.module'; import { RulesModule } from './rules/rules.module'; import { MobileModule } from './mobile/mobile.module'; import { HistoryModule } from './history/history.module'; +import { ReconfigureModule } from './reconfig/reconfig.module'; @Module({ imports: [ @@ -35,6 +35,7 @@ import { HistoryModule } from './history/history.module'; RulesModule, MobileModule, HistoryModule, + ReconfigureModule, ], }) export class AppModule {} diff --git a/src/grpc-client.options.ts b/src/grpc-client.options.ts index 17852d1..feadd83 100644 --- a/src/grpc-client.options.ts +++ b/src/grpc-client.options.ts @@ -5,7 +5,7 @@ export const grpcClientOptions: ClientOptions = { transport: Transport.GRPC, options: { url: process.env.GRPC_URL, - package: ['logs', 'dashboard', 'containers', 'blacklist', 'user', 'rules', 'mobile'], // proto package name + package: ['logs', 'dashboard', 'containers', 'blacklist', 'user', 'rules', 'mobile', 'reconfigure'], // proto package name protoPath: [ './logs/_utils/logs.proto', './dashboard/_utils/dashboard.proto', @@ -14,6 +14,7 @@ export const grpcClientOptions: ClientOptions = { './user/_utils/user.proto', './rules/_utils/rules.proto', './mobile/_utils/mobile.proto', + './reconfig/_utils/reconfig.proto', ].map((x) => join(__dirname, x)), // proto file path }, }; diff --git a/src/reconfig/_utils/dto/reconfig.proto b/src/reconfig/_utils/reconfig.proto similarity index 66% rename from src/reconfig/_utils/dto/reconfig.proto rename to src/reconfig/_utils/reconfig.proto index 7636f54..f4c88ab 100644 --- a/src/reconfig/_utils/dto/reconfig.proto +++ b/src/reconfig/_utils/reconfig.proto @@ -2,13 +2,13 @@ syntax = "proto3"; package reconfigure; -service Reconfigure { - rpc ReconfigHoneypot (ReconfigRequest) returns (ReconfigReply) {} -} - message ReconfigRequest { string config = 1; } message ReconfigReply { -} \ No newline at end of file +} + +service Reconfigure { + rpc ReconfigHoneypot(ReconfigRequest) returns (ReconfigReply); +} diff --git a/src/reconfig/reconfig.controller.ts b/src/reconfig/reconfig.controller.ts index 0ba1e69..206938c 100644 --- a/src/reconfig/reconfig.controller.ts +++ b/src/reconfig/reconfig.controller.ts @@ -2,16 +2,15 @@ import { ApiTags } from '@nestjs/swagger'; import { Controller } from '@nestjs/common'; import { ReConfigDto } from './_utils/dto/request/reconfig-request.dto'; import { GrpcMethod } from '@nestjs/microservices'; -import { ReconfigureService } from './reconfig.service' +import { ReconfigureService } from './reconfig.service'; -@Controller('reconfig') -@ApiTags('ReconfigTag') +@Controller('reconfigure') +@ApiTags('Reconfigure') +export class ReconfigureController { + constructor(private reconfigureService: ReconfigureService) {} -export class ReconfigureController{ - constructor(private reconfigureService: ReconfigureService){} - - @GrpcMethod('Reconfigure', 'ReconfigHoneypot') - public async ReconfigHoneypot(ReconfigData: ReConfigDto) { - return this.reconfigureService.ReconfigHoneypot(ReconfigData); - } -} \ No newline at end of file + @GrpcMethod('Reconfigure', 'ReconfigHoneypot') + reconfigHoneypot(ReconfigData: ReConfigDto) { + return this.reconfigureService.reconfigHoneypot(ReconfigData); + } +} diff --git a/src/reconfig/reconfig.module.ts b/src/reconfig/reconfig.module.ts index 8ed5c4d..5bd4135 100644 --- a/src/reconfig/reconfig.module.ts +++ b/src/reconfig/reconfig.module.ts @@ -1,10 +1,9 @@ -import { Module } from "@nestjs/common"; -import { ReconfigureService } from "./reconfig.service"; -import { ReconfigureController } from "./reconfig.controller"; +import { Module } from '@nestjs/common'; +import { ReconfigureService } from './reconfig.service'; +import { ReconfigureController } from './reconfig.controller'; @Module({ - controllers: [ReconfigureController], - providers: [ReconfigureService], - exports: [ReconfigureService], + controllers: [ReconfigureController], + providers: [ReconfigureService], }) -export class ReconfigureModule {} \ No newline at end of file +export class ReconfigureModule {} From 1f3ba472cd5f9ea2b5e729db96b6e3d7a95e63cb Mon Sep 17 00:00:00 2001 From: Francois Date: Wed, 20 Mar 2024 11:29:49 +0100 Subject: [PATCH 3/3] reconfig done --- src/reconfig/reconfig.service.ts | 59 +++++++++++++++++++++++++------- 1 file changed, 47 insertions(+), 12 deletions(-) diff --git a/src/reconfig/reconfig.service.ts b/src/reconfig/reconfig.service.ts index b76d7db..fcadb65 100644 --- a/src/reconfig/reconfig.service.ts +++ b/src/reconfig/reconfig.service.ts @@ -4,29 +4,64 @@ import { ReConfigDto } from './_utils/dto/request/reconfig-request.dto'; import * as Docker from 'dockerode'; import { RpcException } from '@nestjs/microservices'; +interface dummies { + num_services: number; + ip_addresses: Array; +} + +interface ftps { + ip_address: string; + port: string; +} + +interface NewConfig { + dummy_pc: dummies; + ftp: ftps; +} + +function delay(ms: number) { + return new Promise( resolve => setTimeout(resolve, ms) ); +} @Injectable() export class ReconfigureService { private docker = new Docker(); +/*private validate_config(configJson: NewConfig) { -public async ReconfigHoneypot(Reconfig: ReConfigDto) { - //check config - if (!Reconfig.config) throw new RpcException('Config cannot be empty') - //recup liste dockers - const network = await this.docker.getNetwork('honeypot_network').inspect(); + if (configJson.dummy_pc.num_services = 0) + return +}*/ - const networkContainers = network.Containers; - const containerIds = Object.keys(networkContainers); +public async reconfigHoneypot(Reconfig: ReConfigDto) { + //check config + if (!Reconfig.config) throw new RpcException('Config cannot be empty') - const containers = await this.docker.listContainers({ all: true }); + //recup liste dockers + const containers = await this.docker.listContainers({ all: true }); + const buildContainers = containers.filter((container) => container.Names[0].startsWith('/honeypot_')); - const buildContainers = containers.filter((container) => container.Names[0].startsWith('/honeypot_')); + buildContainers.forEach(element => { + this.docker.getContainer(element.Id).stop().catch((e) => console.log(e)); + }); + + //creer docker depuis config + let configJson: NewConfig = JSON.parse(Reconfig.config); - buildContainers.forEach(element => { - this.docker.getContainer('fb607059a048').stop(); + //this.validate_config(configJson); + await delay(1000) + var newDocker = new Docker() + //newDocker.createContainer({Image: 'ubuntu', Cmd: ['/bin/bash'], name: 'honeypot_dummy_pc_123'}, function(err, container){container?.start({})}) + for (let i=0; i < configJson.dummy_pc.num_services; i++) { + newDocker.run('ubuntu', ['bash', '-c', 'sleep infinity'], process.stdout, {Hostname: configJson.dummy_pc.ip_addresses[i], name:'honeypot_dummy_pc_'+i},function() { + console.log("running new dummy pc on " + configJson.dummy_pc.ip_addresses[i]); }); - //creer docker depuis config + } + if (configJson.ftp.ip_address != "") { + newDocker.run('ubuntu', ['bash', '-c', 'sleep infinity'], process.stdout, {Hostname: configJson.ftp.ip_address, name:'honeypot_dummy_ftp_1 '},function() { + console.log("running new dummy ftp on " + configJson.ftp.ip_address + " on port " + configJson.ftp.port); + }) + } } } \ No newline at end of file