newrelic / newrelic-salesforce-exporter

New Relic integration for Salesforce logs.
Apache License 2.0
10 stars 15 forks source link

Error with private key | Not OpenSSH private key format #30

Closed Ashutosh2547 closed 4 months ago

Ashutosh2547 commented 5 months ago

I am getting error while running the main.py file on local bench. I have updated the config.yml to point to new relic and SDFC. Getting error "Not OpenSSH private key format" in load_ssh_private_key method

Description

Getting "Not OpenSSH private key format" error in "load_ssh_private_key" method of "ssh.py" I have created the private key and certificate using this link also I tried other methods too but this one look official. Still the application is throwing this exception. I have added the log statements to confirm that the file content was read.

Steps to Reproduce

  1. Clone the solution.
  2. Update the config.yml to with new relic keys.
  3. Create a new self signed certificate using this documentation and upload it on the connected app.
  4. Update the config.yml to use the private key created in above step.
  5. Run the solution

Expected Behavior

The solution shouldn't throw exception.

Relevant Logs / Console output

2024-05-23 13:44:10,065 (28128/MainThread) newrelic.core.agent INFO - New Relic Python Agent (9.7.0) 2024-05-23 13:44:15,475 (28128/NR-Activate-Session/New Relic Salesforce Exporter) newrelic.core.agent_protocol INFO - Reporting to: https://rpm.newrelic.com/accounts//applications/ {"message": "Integration start. Using program arguments []", "timestamp": 1716452055475, "level": "info"} {"message": "Cache disabled", "timestamp": 1716452055491, "level": "info"} {"message": "Running instance \"sfdc-logs\"", "timestamp": 1716452055491, "level": "info"} {"message": "unknown exception occurred: 'Authenticator' object has no attribute 'instance_name'", "timestamp": 1716452055491, "level": "error"} Traceback (most recent call last): File "\newrelic-salesforce-exporter\src\newrelic_logging\auth.py", line 114, in authenticate_with_jwt key = serialization.load_ssh_private_key(private_key.encode(), password=b'') ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "\newrelic-salesforce-exporter\sfdcexport\Lib\site-packages\cryptography\hazmat\primitives\serialization\ssh.py", line 614, in load_ssh_private_key raise ValueError("Not OpenSSH private key format") ValueError: Not OpenSSH private key format

During handling of the above exception, another exception occurred:

Traceback (most recent call last): File "C:\Application_Development\Personal\newrelic-salesforce-exporter\src__main.py", line 278, in main() File "C:\Application_Development\Personal\newrelic-salesforce-exporter\sfdcexport\Lib\site-packages\newrelic\packages\wrapt\wrappers.py", line 598, in call return self._self_wrapper(self.wrapped, self._self_instance, ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Application_Development\Personal\newrelic-salesforce-exporter\sfdcexport\Lib\site-packages\newrelic\api\background_task.py", line 111, in wrapper return wrapped(*args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^ File "\newrelic-salesforce-exporter\src__main__.py", line 272, in main run(config, event_type_fields_mapping, numeric_fields_list) File "\newrelic-salesforce-exporter\src__main__.py", line 213, in run run_once( File "\newrelic-salesforce-exporter\src\main__.py", line 165, in run_once ).run() ^^^^^ File "\newrelic-salesforce-exporter\src\newrelic_logging\integration.py", line 53, in run raise e File "\newrelic-salesforce-exporter\src\newrelic_logging\integration.py", line 37, in run instance.harvest(session) File "\newrelic-salesforce-exporter\src\newrelic_logging\instance.py", line 24, in harvest self.api.authenticate(session) File "\newrelic-salesforce-exporter\src\newrelic_logging\api.py", line 81, in authenticate self.authenticator.authenticate(session) File "\newrelic-salesforce-exporter\src\newrelic_logging\auth.py", line 197, in authenticate self.authenticate_with_jwt(session) File "\newrelic-salesforce-exporter\src\newrelic_logging\auth.py", line 116, in authenticate_with_jwt raise LoginException(f'authentication failed for {self.instance_name}. error message: {str(e)}') ^^^^^^^^^^^^^^^^^^ AttributeError: 'Authenticator' object has no attribute 'instance_name'. Did you mean: 'instance_url'? 2024-05-23 13:44:15,516 (28128/MainThread) newrelic.core.agent INFO - New Relic Python Agent Shutdown

Your Environment

Local bench

Additional context

sdewitt-newrelic commented 5 months ago

@Ashutosh2547 , the library we use to load the private key expects the key to be in the "OpenSSH Private Key Format". Here are two resources I found when investigating this for another customer that talk about this format:

My understanding is that ssh-keygen on MacOS defaults to this format. You will know it's an OpenSSH format private key if you see this in the encoded key.

-----BEGIN OPENSSH PRIVATE KEY-----

Could you try creating a key in this format? I believe you will need to update the connected app settings with the new key and certificate as well but after doing that, I think the exporter will be able to load the key.

Ashutosh2547 commented 5 months ago

Generating the secret using below steps resolved the issue for me. Below are the steps (recommended by ChatGPT 💯 ) Generate an OpenSSH Private Key ssh-keygen -t rsa -b 2048 -m PEM -f server.key Convert the OpenSSH Private Key to PEM Format openssl rsa -in server.key -outform PEM -out server.pem Generate a Self-Signed Certificate openssl req -new -x509 -key server.pem -out server.crt -days 365

After creating the secret use the path of server.pem in the config.yml in corresponding to private_key.

Ashutosh2547 commented 5 months ago

Another alternative that works without following the above steps is to comment/remove the below line from auth.py file key = serialization.load_ssh_private_key(private_key.encode(), password=b'')

Even if we create the secret using the Salesforce recommended method , commenting/removing the above line would eliminate the issue.

kanwaljit-mq commented 5 months ago

@Ashutosh2547 > Generate an OpenSSH Private K

For me just converting to openSSH and point to it in confir.yml works ssh-keygen -p -f <filename>

sdewitt-newrelic commented 5 months ago

@Ashutosh2547 that line is historical and I'm not sure why that particular serialization method was chosen. What type of key is generated with the recommended method you pointed to? It seems like we should align with whatever is in the Salesforce docs.

Also, are you saying that if you just use the raw result of this line that everything works?

sdewitt-newrelic commented 5 months ago

@Ashutosh2547 any updates on my questions above? Thanks.

sdewitt-newrelic commented 5 months ago

Hi @Ashutosh2547 Any update? I will go ahead and close this issue next week if there aren't any updates at this time. Feel free to reopen if necessary.

Ashutosh2547 commented 5 months ago

Hey @sdewitt-newrelic , You may close this issue. I will reopen this if needed. Thank you

sdewitt-newrelic commented 4 months ago

Thanks @Ashutosh2547. Closing per above.