Oracle cloud custom logs plugin (#1997)

* initial oraclecloud logs
---------

Co-authored-by: Michel Oosterhof <micheloosterhof@users.noreply.github.com>
This commit is contained in:
Mattia Moretti 2023-11-13 13:26:50 +01:00 committed by GitHub
parent de148c34a5
commit 3b6c3c1d76
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 123 additions and 0 deletions

View File

@ -1066,3 +1066,22 @@ api_key = abcdef1234567890fedcba0987654321
ddsource = cowrie
ddtags = env:dev
service = honeypot
# Oracle Cloud custom logs output module
# sends JSON directly to Oracle Cloud custom logs
# mandatory field: authtype, log_ocid
# optional fields (to be set if user_principals is selected as authtype): user_ocid, fingerprint, tenancy_ocid, region, keyfile
# For more information on Oracle Cloud custom logs: https://docs.oracle.com/en-us/iaas/Content/Logging/Concepts/custom_logs.htm
# For more information on Oracle Cloud user principal authentication method: https://docs.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm#five
# For more information on Oracle Cloud instance principal authentication method: https://blogs.oracle.com/developers/post/accessing-the-oracle-cloud-infrastructure-api-using-instance-principals
[output_oraclecloud]
enabled = false
# authtype must be set either to user_principals or to instance_principals
authtype = instance_principals
# following parameters must be set in case user_principals is used. keyfile is the absolute path to your API pem key file.
#log_ocid = ocid1.log.oc1.eu-stockholm-1.xxx
#user_ocid = ocid1.user.oc1..xxx
#fingerprint = 77:9c:4xxxxx
#tenancy_ocid = ocid1.tenancy.oc1..xxx
#region = eu-stockholm-1
#keyfile = /home/xx/key.pem

View File

@ -38,3 +38,5 @@ pymisp==2.4.178
# redis
redis==5.0.1
# Oracle Cloud
oci==2.115.1

View File

@ -0,0 +1,102 @@
from __future__ import annotations
import datetime
import json
import secrets
import string
import oci
from twisted.python import log
import cowrie.core.output
from cowrie.core.config import CowrieConfig
class Output(cowrie.core.output.Output):
"""
Oracle Cloud output
"""
def generate_random_log_id(self):
charset = string.ascii_letters + string.digits
random_log_id = "".join(secrets.choice(charset) for _ in range(32))
return f"cowrielog-{random_log_id}"
def sendLogs(self, logentry):
log_id = self.generate_random_log_id()
# Initialize service client with default config file
current_time = datetime.datetime.utcnow()
self.log_ocid = CowrieConfig.get("output_oraclecloud", "log_ocid")
self.hostname = CowrieConfig.get("honeypot", "hostname")
try:
# Send the request to service, some parameters are not required, see API
# doc for more info
self.loggingingestion_client.put_logs(
log_id=self.log_ocid,
put_logs_details=oci.loggingingestion.models.PutLogsDetails(
specversion="1.0",
log_entry_batches=[
oci.loggingingestion.models.LogEntryBatch(
entries=[
oci.loggingingestion.models.LogEntry(
data=logentry,
id=log_id,
time=current_time.strftime("%Y-%m-%dT%H:%M:%S.%fZ"))],
source=self.hostname,
type="cowrie")]),
timestamp_opc_agent_processing=current_time.strftime("%Y-%m-%dT%H:%M:%S.%fZ"))
except oci.exceptions.ServiceError as ex:
log.err(
f"Oracle Cloud plugin Error: {ex.message}\n" +
f"Oracle Cloud plugin Status Code: {ex.status}\n"
)
except Exception as ex:
log.err(f"Oracle Cloud plugin Error: {ex}")
raise
def start(self):
"""
Initialize Oracle Cloud LoggingClient with user or instance principal authentication
"""
authtype=CowrieConfig.get("output_oraclecloud", "authtype")
if authtype == "instance_principals":
signer = oci.auth.signers.InstancePrincipalsSecurityTokenSigner()
# In the base case, configuration does not need to be provided as the region and tenancy are obtained from the InstancePrincipalsSecurityTokenSigner
# identity_client = oci.identity.IdentityClient(config={}, signer=signer)
self.loggingingestion_client = oci.loggingingestion.LoggingClient(config={}, signer=signer)
elif authtype == "user_principals":
tenancy_ocid=CowrieConfig.get("output_oraclecloud", "tenancy_ocid")
user_ocid=CowrieConfig.get("output_oraclecloud", "user_ocid")
region=CowrieConfig.get("output_oraclecloud", "region")
fingerprint=CowrieConfig.get("output_oraclecloud", "fingerprint")
keyfile=CowrieConfig.get("output_oraclecloud", "keyfile")
config_with_key_content = {
"user": user_ocid,
"key_file": keyfile,
"fingerprint": fingerprint,
"tenancy": tenancy_ocid,
"region": region
}
oci.config.validate_config(config_with_key_content)
self.loggingingestion_client = oci.loggingingestion.LoggingClient(config_with_key_content)
else:
raise ValueError("Invalid authentication type")
def stop(self):
pass
def write(self, logentry):
"""
Push to Oracle Cloud put_logs
"""
# Add the entry to redis
for i in list(logentry.keys()):
# Remove twisted 15 legacy keys
if i.startswith("log_"):
del logentry[i]
self.sendLogs(json.dumps(logentry))