11package com .akto .utils ;
22
33import com .akto .log .LoggerMaker ;
4- import com .akto .action .IngestionAction ;
54import com .akto .dao .context .Context ;
65import com .akto .dto .IngestDataBatch ;
76import com .akto .kafka .Kafka ;
7+ import com .akto .kafka .KafkaConfig ;
8+ import com .akto .kafka .Serializer ;
9+ import com .akto .kafka .KafkaProtoProducer ;
10+ import com .akto .kafka .KafkaProducerConfig ;
811import com .mongodb .BasicDBObject ;
12+ import com .akto .proto .http_response_param .v1 .HttpResponseParam ;
13+ import com .akto .proto .http_response_param .v1 .StringList ;
14+ import java .util .HashMap ;
15+ import java .util .Map ;
916
1017public class KafkaUtils {
1118
1219 private static final LoggerMaker logger = new LoggerMaker (KafkaUtils .class , LoggerMaker .LogDb .DATA_INGESTION );
1320 private static Kafka kafkaProducer ;
21+ private static KafkaProtoProducer kafkaProtoProducer ;
1422
1523 public void initKafkaProducer () {
1624 String kafkaBrokerUrl = System .getenv ().getOrDefault ("AKTO_KAFKA_BROKER_URL" , "localhost:29092" );
1725 int batchSize = Integer .parseInt (System .getenv ().getOrDefault ("AKTO_KAFKA_PRODUCER_BATCH_SIZE" , "100" ));
1826 int kafkaLingerMS = Integer .parseInt (System .getenv ().getOrDefault ("AKTO_KAFKA_PRODUCER_LINGER_MS" , "10" ));
1927 kafkaProducer = new Kafka (kafkaBrokerUrl , kafkaLingerMS , batchSize , LoggerMaker .LogDb .DATA_INGESTION );
20- logger .infoAndAddToDb ("Kafka Producer Init " + Context .now (), LoggerMaker .LogDb .DATA_INGESTION );
28+
29+ // Initialize protobuf kafka producer
30+ KafkaConfig protoKafkaConfig = KafkaConfig .newBuilder ()
31+ .setBootstrapServers (kafkaBrokerUrl )
32+ .setKeySerializer (Serializer .STRING )
33+ .setValueSerializer (Serializer .BYTE_ARRAY )
34+ .setProducerConfig (KafkaProducerConfig .newBuilder ()
35+ .setLingerMs (kafkaLingerMS )
36+ .setBatchSize (batchSize )
37+ .build ())
38+ .build ();
39+ kafkaProtoProducer = new KafkaProtoProducer (protoKafkaConfig );
40+
41+ logger .infoAndAddToDb ("Kafka Producer Init " + Context .now ());
42+ }
43+
44+ public static boolean shouldSendToThreatTopic (String requestHeaders ){
45+
46+ if (requestHeaders == null || requestHeaders .isEmpty ()) {
47+ return false ;
48+ }
49+
50+ String lowerHeaders = requestHeaders .toLowerCase ();
51+ if (lowerHeaders .contains ("\" host\" :" ) || lowerHeaders .contains ("\" host \" :" )) {
52+ if (lowerHeaders .contains ("hollywoodbets" ) ||
53+ lowerHeaders .contains ("betsolutions" ) ||
54+ lowerHeaders .contains ("betnix" ) ||
55+ lowerHeaders .contains ("betsoft" )) {
56+ return true ;
57+ }
58+ }
59+ return false ;
60+ }
61+
62+ private static Map <String , StringList > parseHeadersToProto (String headersJson ) {
63+ Map <String , StringList > headers = new HashMap <>();
64+ if (headersJson == null || headersJson .isEmpty ()) {
65+ return headers ;
66+ }
67+
68+ try {
69+ // Parse JSON string to extract headers
70+ headersJson = headersJson .trim ();
71+ if (headersJson .startsWith ("{" ) && headersJson .endsWith ("}" )) {
72+ headersJson = headersJson .substring (1 , headersJson .length () - 1 );
73+ String [] pairs = headersJson .split ("," );
74+
75+ for (String pair : pairs ) {
76+ String [] keyValue = pair .split (":" , 2 );
77+ if (keyValue .length == 2 ) {
78+ String key = keyValue [0 ].trim ().replaceAll ("\" " , "" );
79+ String value = keyValue [1 ].trim ().replaceAll ("\" " , "" );
80+ headers .put (key , StringList .newBuilder ().addValues (value ).build ());
81+ }
82+ }
83+ }
84+ } catch (Exception e ) {
85+ logger .errorAndAddToDb ("Error parsing headers: " + e .getMessage (), LoggerMaker .LogDb .DATA_INGESTION );
86+ }
87+
88+ return headers ;
2189 }
2290
2391 public static void insertData (IngestDataBatch payload ) {
@@ -47,6 +115,36 @@ public static void insertData(IngestDataBatch payload) {
47115 obj .put ("tag" , payload .getTag ());
48116 kafkaProducer .send (obj .toString (), "akto.api.logs" );
49117 //IngestionAction.printLogs("Inserted to kafka: " + obj.toString());
118+
119+ if (shouldSendToThreatTopic (payload .getRequestHeaders ())){
120+ // create a HttpResponseParam protobuf object from payload send to akto.api.logs2 topic
121+ HttpResponseParam .Builder builder = HttpResponseParam .newBuilder ();
122+
123+ // Parse headers to protobuf format
124+ Map <String , StringList > requestHeaders = parseHeadersToProto (payload .getRequestHeaders ());
125+ Map <String , StringList > responseHeaders = parseHeadersToProto (payload .getResponseHeaders ());
126+
127+ builder .setMethod (payload .getMethod () != null ? payload .getMethod () : "" )
128+ .setPath (payload .getPath () != null ? payload .getPath () : "" )
129+ .setType (payload .getType () != null ? payload .getType () : "HTTP/1.1" )
130+ .putAllRequestHeaders (requestHeaders )
131+ .putAllResponseHeaders (responseHeaders )
132+ .setRequestPayload (payload .getRequestPayload () != null ? payload .getRequestPayload () : "" )
133+ .setResponsePayload (payload .getResponsePayload () != null ? payload .getResponsePayload () : "" )
134+ .setStatusCode (payload .getStatusCode () != null ? Integer .parseInt (payload .getStatusCode ()) : 0 )
135+ .setStatus (payload .getStatus () != null ? payload .getStatus () : "" )
136+ .setTime (payload .getTime () != null ? Integer .parseInt (payload .getTime ()) : (int )(System .currentTimeMillis () / 1000 ))
137+ .setAktoAccountId (payload .getAkto_account_id () != null ? payload .getAkto_account_id () : "" )
138+ .setAktoVxlanId (payload .getAkto_vxlan_id () != null ? payload .getAkto_vxlan_id () : "" )
139+ .setIp (payload .getIp () != null ? payload .getIp () : "" )
140+ .setDestIp (payload .getDestIp () != null ? payload .getDestIp () : "" )
141+ .setDirection (payload .getDirection () != null ? payload .getDirection () : "" )
142+ .setIsPending (payload .getIs_pending () != null ? Boolean .parseBoolean (payload .getIs_pending ()) : false )
143+ .setSource (payload .getSource () != null ? payload .getSource () : "" );
144+
145+ HttpResponseParam httpResponseParam = builder .build ();
146+ kafkaProtoProducer .send ("akto.api.logs2" , httpResponseParam );
147+ }
50148 }
51149
52150}
0 commit comments