I want to integrate Bitdefender into Elastic

Hello,

I am trying to integrate Bitdefender. I am using versiion 8.16.1. I have generated the API key and added the Bitdefender integration to the Fleet Server policy with the required details according to the parameters specified in the documentation.
Elastic agent is installed on the Logstash machine and I am unsuccessfully trying to perform the step: Create push notification configuration via BitDefender GravityZone API
using the URL request from the Logstash machine:

curl --tlsv1.2 -sS -k -X POST
https://cloud.gravityzone.bitdefender.com/api/v1.0/jsonrpc/push\
-H 'authorization: Basic <base_64_token>'
-H 'cache-control: no-cache'
-H 'content-type: application/json'
-d '{
"params": {"status": 1,"serviceType": "jsonRPC","serviceSettings":{"authorization":"","requireValidSslCertificate":false,"url": "https://<siem_ip>:443/bitdefender/push/notification"},"subscribeToEventTypes":{"adcloud":true,"antiexploit":true,"aph":true,"av":true,"avc":true,"dp":true,"endpoint-move d-in":true,"endpoint-moved-out":true,"exchange-malware":true,"exchange-user-credentials":true,"fw":true,"hd":true,"hwid-change":true,"install":true,"modules":true,"network -monitor":true,"network-sandboxing":true,"new-incident":true,"ransomware-mitigation":true,"registration":true,"security-container-update-available":true,"supa-update-statu s":true,"sva":true,"sva-load":true,"task-status":true,"troubleshooting-activity":true,"uc":true,"uninstall":true}},"id":1,"jsonrpc":"2.0","method":"setPushEventSettings"}'

I get the error:
"error":{"code":-32602,"message":"Invalid params","data":{"details":"The web server with this URL must support TLS 1.2, at least"}

Help me find a solution
Thank you.

Any updates?

Hello,

Could you please confirm if you have followed exactly the same steps shared under the integration

https://www.bitdefender.com/business/support/en/77209-135319-setpusheventsettings.html

Below is the sample curl request sent from this screenshot :

curl --location --request POST 'https://cloud.gravityzone.bitdefender.com/api/v1.0/jsonrpc/push' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'Authorization: Basic TE9MX05JQ0VfVFJZOgo=' \
--data-raw '{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "setPushEventSettings",
  "params": {
    "status": 1,
    "serviceType": "jsonrpc",
    "serviceSettings": {
      "authorization": "secret value",
      "requireValidSslCertificate": true,
      "url": "https://your.webhook.receiver.domain.tld/bitdefender/push/notification"
    },
    "subscribeToCompanies": [
      "COMPANY IDS HERE IF YOU HAVE A MULTI TENANT ENVIRONMENT",
      "AND YOU WANT TO LIMIT THE SUBSCRIPTION TO ONLY SOME COMPANIES",
      "OTHERWISE DELETE THE ENTIRE subscribeToCompanies NODE TO GET EVERYTHING"
    ],
    "subscribeToEventTypes": {
      "adcloud": true,
      "antiexploit": true,
      "aph": true,
      "av": true,
      "avc": true,
      "dp": true,
      "endpoint-moved-in": true,
      "endpoint-moved-out": true,
      "exchange-malware": true,
      "exchange-user-credentials": true,
      "fw": true,
      "hd": true,
      "hwid-change": true,
      "install": true,
      "modules": true,
      "network-monitor": true,
      "network-sandboxing": true,
      "new-incident": true,
      "ransomware-mitigation": true,
      "registration": true,
      "security-container-update-available": true,
      "supa-update-status": true,
      "sva": true,
      "sva-load": true,
      "task-status": true,
      "troubleshooting-activity": true,
      "uc": true,
      "uninstall": true
    }
  }
}'

Please review this once & confirm if issue still persist?

Thanks!!

Thank you for your help.
Yes. I tried that too.
Note: In the Bitdefender documentation, they changed: "serviceType": "jsonRPC" and not "serviceType": "jsonrpc" like in Elastic.

I think the problem is related to the configuration or serviceType on the Elastic side.

In our Elastic SIEM system, Kibana and Logstash are installed on separate machines and Elastic agent - on the Logstash machine. And from there I run the script for create push notification configuration.
Our settings in Bitdefender policy in Kibana:
Listen Address: 0.0.0.0
Listen Port: 443
Webhook path: /bitdefender/push/notification

I approved the entire list of IPs in your link for the Logstash machine.

What should be correct in my case and from which machine to run the script?

The CURL command can run from any machine, it's just reaching out to bitdefender and configuring the PUSH notification service.

When you activate the BitDefender integration with the "Receive Push Notification Events" enabled, your installed Elastic Agent begins listening on port 443 for incoming webhooks.

In the CURL command you are supposed to populate the url parameter:

  • in the json body "url": "https://your.webhook.receiver.domain.tld/bitdefender/push/notification" }, You need to change this to point to the publicly accessible DNS name for the system running the Elastic Agent. You must ensure that requests from BitDefender's servers are routed to the host and not blocked.
  • The Authorization parameter "authorization":"" needs to be populated with the gravityzone API key you generated during setup. The one that should also be in your integration policy.

Thank you very much for your help.
I took into account everything you wrote.

Now I ran the Create push script from a machine with Elastic agent notification configuration installed (Elastic agent service is running properly):

curl --location --request POST 'https://cloud.gravityzone.bitdefender.com/api/v1.0/jsonrpc/push' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'Authorization: Basic <my_base_64_token>' \
--data-raw '{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "setPushEventSettings",
  "params": {
    "status": 1,
    "serviceType": "jsonRPC",
    "serviceSettings": {
      "authorization": "",
      "requireValidSslCertificate": false,
      "url": "https://<agent_ip>:<agent_port>/bitdefender/push/notification"
    },
    "subscribeToEventTypes": {
      "adcloud": true,
      "antiexploit": true,
      "aph": true,
      "av": true,
      "avc": true,
      "dp": true,
      "endpoint-moved-in": true,
      "endpoint-moved-out": true,
      "exchange-malware": true,
      "exchange-user-credentials": true,
      "fw": true,
      "hd": true,
      "hwid-change": true,
      "install": true,
      "modules": true,
      "network-monitor": true,
      "network-sandboxing": true,
      "new-incident": true,
      "ransomware-mitigation": true,
      "registration": true,
      "security-container-update-available": true,
      "supa-update-status": true,
      "sva": true,
      "sva-load": true,
      "task-status": true,
      "troubleshooting-activity": true,
      "uc": true,
      "uninstall": true
    }
  }
}'

This is the error:

{"id":1,"jsonrpc":"2.0","error":{"code":-32602,"message":"Invalid params","data":{"details":"The web server with this URL must support TLS 1.2, at least"}}}

In addition, I ran a test of getPushEventSettings

curl --location --request POST 'https://cloud.gravityzone.bitdefender.com/api/v1.0/jsonrpc/push' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'Authorization: Basic <my_base_64_token>' \
--data-raw '{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "getPushEventSettings"
  }'

This is the error:

{"id":1,"jsonrpc":"2.0","error":{"code":-32000,"message":"Server error","data":{"details":"Settings for event push service were not set"}}}

I was in contact with Bitdefender support, they can't help and don't understand where the problem is.
At the recommendation of support, I ran a test:

curl --tlsv1.2 -sS -k -X POST \
https://cloud.gravityzone.bitdefender.com/api/v1.0/jsonrpc/push \
-H 'authorization: Basic <my_base_64_token>' \
-H 'cache-control: no-cache' \
-H 'content-type: application/json' \
-d '{"id":"4","jsonrpc":"2.0","method":"sendTestPushEvent","params":{"eventType": "av"}}'

And I got an answer that the test passed. So there is no problem with the API KEY

So I ask, maybe all this is because of a change in serviceType on the Bitdefender side: from jsonrpc to jsonRPC. And on the Elastic side, they didn't make a change to the code?

Please help find where the problem is.

{"id":1,"jsonrpc":"2.0","error":{"code":-32602,"message":"Invalid params","data":{"details":"The web server with this URL must support TLS 1.2, at least"}}}

This is not the error CURL would return if the BitDefender API didn't support TLS 1.2. This makes me think (my guess) the BitDefender API is reaching out to https://<agent_ip>:<agent_port>/bitdefender/push/notification and testing it and finding that it doesn't support TLS 1.2.

Can you do curl --tlsv1.2 -sS -k -X POST against https://<agent_ip>:<agent_port>/bitdefender/push/notification first from a machine inside of the network and then from a machine outside of the network and verify that it doesn't show a TLS error?

How are you exposing this endpoint from your network? Is your elastic agent just exposed on the internet or are you using a reverse proxy?

Machine is on LAN and I can't run command outside network.
We don't use proxy.

I ran curl --tlsv1.2 -sS -k -X POST with the same error "The web server with this URL must support TLS 1.2, at least"
If this helps: Elastic agent installed on Ubuntu 22.04 machine.

You ran curl --tlsv1.2 -sS -k -X POST against https://<agent_ip> <agent_port>/bitdefender/push/notification and it said that?

can you share a full copy of the command and the output, can you also add -v to the curl command

I ran as you requested:

curl --tlsv1.2 -sS -k -v -X POST and https://<agent_ip>:<agent_port>/bitdefender/push/notification

And I received a reply:

*   Trying 35.212.58.191:443...
* Connected to cloud.gravityzone.bitdefender.com (35.212.58.191) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* TLSv1.0 (OUT), TLS header, Certificate Status (22):
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS header, Certificate Status (22):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (OUT), TLS header, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS header, Certificate Status (22):
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS header, Finished (20):
* TLSv1.2 (IN), TLS header, Certificate Status (22):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server accepted to use h2
* Server certificate:
*  subject: C=RO; L=Bucure\U0219ti; O=Bitdefender SRL; CN=*.gravityzone.bitdefender.com
*  start date: Jun 10 00:00:00 2024 GMT
*  expire date: Jun 29 23:59:59 2025 GMT
*  issuer: C=US; O=DigiCert Inc; CN=DigiCert Global G2 TLS RSA SHA256 2020 CA1
*  SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway.
* Using HTTP2, server supports multiplexing
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* Using Stream ID: 1 (easy handle 0x56275214b9f0)
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
> POST /api/v1.0/jsonrpc/push HTTP/2
> Host: cloud.gravityzone.bitdefender.com
> user-agent: curl/7.81.0
> accept: */*
> authorization: Basic <my_base_64_token>
> cache-control: no-cache
> content-type: application/json
> content-length: 1112
>
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* We are completely uploaded and fine
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* old SSL session ID is stale, removing
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* Connection state changed (MAX_CONCURRENT_STREAMS == 128)!
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
< HTTP/2 200
< server: nginx
< date: Wed, 05 Mar 2025 15:16:54 GMT
< content-type: application/json; charset=utf-8
< vary: Accept-Encoding
< vary: Accept-Encoding
< cache-control: max-age=0,must-revalidate,no-transform
< x-frame-options: SAMEORIGIN
<
* Connection #0 to host cloud.gravityzone.bitdefender.com left intact
{"id":1,"jsonrpc":"2.0","error":{"code":-32602,"message":"Invalid params","data":{"details":"The web server with this URL must support TLS 1.2, at least"}}}

It looks a bit like you're running curl against your original url (the gravity zone one) but I mentioned: https://<agent_ip> <agent_port>/bitdefender/push/notification

Which would be your agent's ip address and port with a path of bitdefender/push/notification

This is what I ran. And is the public IP of the FW
Of course there is a rule that directs communication to the machine where the agent was installed.

curl --tlsv1.2 -sS -k -v -X POST
https://cloud.gravityzone.bitdefender.com/api/v1.0/jsonrpc/push
-H 'authorization: Basic <my_base64_token>'
-H 'cache-control: no-cache'
-H 'content-type: application/json'
-d '{
"id": 1,
"jsonrpc": "2.0",
"method": "setPushEventSettings",
"params": {
"status": 1,
"serviceType": "jsonRPC",
"serviceSettings": {
"authorization": "",
"requireValidSslCertificate": false,
"url": "https://<agent_ip>:443/bitdefender/push/notification"
},
"subscribeToEventTypes": {
"adcloud": true,
"antiexploit": true,
"aph": true,
"av": true,
"avc": true,
"dp": true,
"endpoint-moved-in": true,
"endpoint-moved-out": true,
"exchange-malware": true,
"exchange-user-credentials": true,
"fw": true,
"hd": true,
"hwid-change": true,
"install": true,
"modules": true,
"network-monitor": true,
"network-sandboxing": true,
"new-incident": true,
"ransomware-mitigation": true,
"registration": true,
"security-container-update-available": true,
"supa-update-status": true,
"sva": true,
"sva-load": true,
"task-status": true,
"troubleshooting-activity": true,
"uc": true,
"uninstall": true
}
}
}'

This is what I ran. And is the public IP of the FW

Right, but I asked that you run curl --tlsv1.2 -v -sS -k -X POST https://<agent_ip>:<listen_port>/bitdefender/push/notification

and not

https://cloud.gravityzone.bitdefender.com/api/v1.0/jsonrpc/push
-H 'authorization: Basic <my_base64_token>'
-H 'cache-control: no-cache'
-H 'content-type: application/json'
-d '{
"id": 1,
"jsonrpc": "2.0",
"method": "setPushEventSettings",
"params": {
"status": 1,
"serviceType": "jsonRPC",
"serviceSettings": {
"authorization": "",
"requireValidSslCertificate": false,
"url": "https://<agent_ip>:443/bitdefender/push/notification"
},
"subscribeToEventTypes": {
"adcloud": true,
"antiexploit": true,
"aph": true,
"av": true,
"avc": true,
"dp": true,
"endpoint-moved-in": true,
"endpoint-moved-out": true,
"exchange-malware": true,
"exchange-user-credentials": true,
"fw": true,
"hd": true,
"hwid-change": true,
"install": true,
"modules": true,
"network-monitor": true,
"network-sandboxing": true,
"new-incident": true,
"ransomware-mitigation": true,
"registration": true,
"security-container-update-available": true,
"supa-update-status": true,
"sva": true,
"sva-load": true,
"task-status": true,
"troubleshooting-activity": true,
"uc": true,
"uninstall": true
}
}
}'

So here's the steps I would follow.

Open the Integration in Elastic

  1. Make sure the listen address is 0.0.0.0 or the ip of the interface you want to listen to push requests from
  2. Grab the Listen Port

Ok next, get the IP address of the host running Elastic Agent.

Take the IP of your elastic agent and literally run this on the Elastic Agent host that's running the integration.
curl --tlsv1.2 -sS -v -k -X POST https://<agent_ip>:<listen_port>/bitdefender/push/notification

So if my ip was 192.168.0.5and my listen port was 8080 run exactly this curl --tlsv1.2 -sS -k -v -X POST https://192.168.0.5:8080/bitdefender/push/notification

and provide the response.

Then I'd test the firewall. It looks like you've exposed 443 on the firewall. So from a system outside the firewall run, curl --tlsv1.2 -sS -v -k -X POST https://<firewall>:443/bitdefender/push/notification

Ideally, that would have the same response as the first one. But sharing both would be helpful

Hi,
Sorry for the misunderstanding and thanks for such a detailed explanation.
I tried both port 443 and 8080, of course I changed the port in all the relevant configurations.
Here are the results:

  1. Port 443:
    Elastic agent:
curl --tlsv1.2 -v -sS -k -X POST https://192.168.1.122:443/bitdefender/push/notification
*   Trying 192.168.1.122:443...
* Connected to 192.168.1.122 (192.168.1.122) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* TLSv1.0 (OUT), TLS header, Certificate Status (22):
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* (5454) (IN), , Unknown (72):
* error:0A00010B:SSL routines::wrong version number
* Closing connection 0
curl: (35) error:0A00010B:SSL routines::wrong version number

and FW:

curl --tlsv1.2 -sS -v -k -X POST https://<fw_ip>:443/bitdefender/push/notification
*   Trying <fw_ip>:443...
* TCP_NODELAY set
* Connected to <fw_ip> (<fw_ip>) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* error:1408F10B:SSL routines:ssl3_get_record:wrong version number
* Closing connection 0
curl: (35) error:1408F10B:SSL routines:ssl3_get_record:wrong version number
  1. Port 8080:
    Elastic agent:
curl --tlsv1.2 -v -sS -k -X POST http://192.168.1.122:8080/bitdefender/push/notification
*   Trying 192.168.1.122:8080...
* Connected to 192.168.1.122 (192.168.1.122) port 8080 (#0)
> POST /bitdefender/push/notification HTTP/1.1
> Host: 192.168.1.122:8080
> User-Agent: curl/7.81.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 406 Not Acceptable
< Content-Type: application/json
< Date: Tue, 11 Mar 2025 14:10:50 GMT
< Content-Length: 35
<
{"message":"body cannot be empty"}
* Connection #0 to host 192.168.1.122 left intact

and FW:

curl --tlsv1.2 -sS -v -k -X POST http://<fw_ip>:8080/bitdefender/push/notification
*   Trying <fw_ip>:8080...
* TCP_NODELAY set
* Connected to <fw_ip> (<fw_ip>) port 8080 (#0)
> POST /bitdefender/push/notification HTTP/1.1
> Host: <fw_ip>:8080
> User-Agent: curl/7.68.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 406 Not Acceptable
< Content-Type: application/json
< Date: Tue, 11 Mar 2025 14:12:31 GMT
< Content-Length: 35
<
{"message":"body cannot be empty"}
* Connection #0 to host <fw_ip> left intact

Hi @strawgate ,

Do you have any ideas what can be done?