NagiosEnterprises / ncpa

Nagios Cross-Platform Agent
Other
176 stars 95 forks source link

community_string password requirements #1035

Closed mx500 closed 7 months ago

mx500 commented 7 months ago

Just installed the ncpa-3.0.0-beta02.x86_64 agent and the agent communication broke.

Used: ncpa-3.0.0-beta02.x86_64

Issue: the community_string no longer accepts the "%" character. In version 2.4.1, the community_string accepted the "%" character.

Error noted: configparser.InterpolationSyntaxError: '%' must be followed by '%' or '(',

Testing: removed the '%' character from the community string and the check succeeds.

ne-bbahn commented 7 months ago

I would like to note that the beta02 version is not the most recent version and that this may have been patched since then, but I will check.

MrPippin66 commented 7 months ago

This could be a code change within configparser, which is part of the python distribution. Keep mind there's a lot of changes between Python2 and Python3, of which NCPA 3.x is coded for.

Docs for configparser state:

If a user needs to use a bare % in a configuration file, she can escape it by writing %%.

Can you try that? Not sure if using quotes for the string in question would negate this need.

mx500 commented 7 months ago

This issue is that the '%' symbol is used in the "community_string" token used to authenticate Nagios to the clients. The 2.4.1 ncpa client allowed the use of the '%' key in the community_string and agent version 3.0.0 does not.

Escaping the '%' symbol in the "community_string" would involve making changes both on the Nagios server and on all clients.

The beta ncpa agent that was installed during a maintenance patching cycle and was obtained automatically from the Nagios repo ( https://repo.nagios.com/nagios-test/7/ ).

As I wrote this reply I noticed that the configured repo was "nagios-test" which explains the older beta02, I reconfigured the repo to use the production repo and installed the latest ncpa version ( yum clean all && yum update ncpa -y ).

Installed: ncpa-3.0.0-latest.x86_64

After installing the 3.0.0-latest agent, I re-tested and the configparser.InterpolationSyntaxError message persists and remote service checks fail.

Rather than go to the effort and escape the community_string by writing %% on all the monitored nodes, it would require the same effort to change the community string and remove the '%' the parser is complaining about.


From: MrPippin66 @.> Sent: Tuesday, November 21, 2023 2:00 PM To: NagiosEnterprises/ncpa @.> Cc: Brad Beckenhauer @.>; Author @.> Subject: Re: [NagiosEnterprises/ncpa] community_string password requirements (Issue #1035)

CAUTION: This email came from an EXTERNAL address. Use caution when clicking links or opening attachments.

This could be a code change within configparser, which is part of the python distribution. Keep mind there's a lot of changes between Python2 and Python3, of which NCPA 3.x is coded for.

Docs for configparser state:

If a user needs to use a bare % in a configuration file, she can escape it by writing %%.

Can you try that?

— Reply to this email directly, view it on GitHubhttps://github.com/NagiosEnterprises/ncpa/issues/1035#issuecomment-1821596175, or unsubscribehttps://github.com/notifications/unsubscribe-auth/BEEOFESMYLPHSN427MS7FWTYFUB6BAVCNFSM6AAAAAA7TQO7D2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQMRRGU4TMMJXGU. You are receiving this because you authored the thread.Message ID: @.***>

MrPippin66 commented 7 months ago

Are you stating a previous 3.x beta was working without problems?

A code maintainer will need to comment on this. As I stated, there have been many changes in configparser since Python2 (and even Python3 in earlier releases) regarding interpolation.

I would seem the required resolution for this situation is to set the Interpolation method during initialization of the class to 'None', though I would assume there are instances where someone could have been using interpolation in their config files.

pittagurneyi commented 7 months ago

I've been looking into the occurences of OptionParser in the source code:

/tmp/ncpa $ grep -ER '^[[:space:]]+(self.config|cp|test_config|nscparser)\..*=' * | grep -Ev '\.(add|set)'
agent/ncpa.py:    cp.optionxform = str
test/unused/test_nrdshandler.py:        self.config.optionxform = str
test/unused/test_nrdshandler.py:        self.config.file_path = os.path.join(self.testing_plugin_dir, "test.cfg")
test/test_nrdphandler.py:        self.config.optionxform = str

OptionParser by default has case-insensitive options, i.e. left-hand-side variable names in the config files.

Thus when reading the config file it will convert all option names to lowercase and allow case-insensitive matching when you try accessing or setting their values.

I haven't tested it yet, but that seems to mean that were you to use the ConfigParser to write the (modified) config file, it would then write lowercase option names.

Using optionxform = str after the instantiation of the ConfigParser modifies this behavior and makes it act case-sensitive.

As I haven't looked further into the source code, I can't be sure which config files are loaded, but the usage of this is not consequently enforced. These are all the instantiations I could find. If you compare it with the above you'll see that sometimes optionxform = str is missing:

/tmp/ncpa $ grep -ER '^[[:space:]]+(self.config|cp|test_config|nscparser) =' * | grep -Ev '\.(add|set)'
agent/passive/nrds.py:                test_config = cp.ConfigParser()
agent/passive/ncpacheck.py:        self.config = config
agent/passive/nagioshandler.py:        self.config = config
agent/ncpa.py:        self.config = config
agent/ncpa.py:        self.config = config
agent/ncpa.py:            self.config = get_configuration()
agent/ncpa.py:    cp = ConfigParser()
dist/nsclient_migration/NSC2NCPA.py:    nscparser = configparser.ConfigParser()
test/unused/test_nrdshandler.py:        self.config = configparser.ConfigParser()
test/test_nrdphandler.py:        self.config = configparser.ConfigParser()
test/test_ncpacheck.py:        self.config = configparser.ConfigParser()

There don't seem to be any other modifications of the default behavior of ConfigParser. I also couldn't find any usage of "interpolation", thus it would be best to just turn it off. Then there is no question of whether the OptionParser interferes with the value given to options.

All that needs to be changed is to invoke it via, as @MrPippin66 mentioned:

ConfigParser(interpolation=None)
mx500 commented 7 months ago

I'll restate the issue.

Short version. When updating the ncpa agent from v2.4.1 to v3.0.0 the community_string no longer accepts the '%' symbol unless it is escaped. This was a behavior change for the community_string which prompted the opening of this issue. The forum has suggested that the underlying issue could be due to a parser change.

Detailed version: The v2.4.1 ncpa client allowed the use of the '%' key in the community_string. During an OS update, the ncpa agent was updated to v3.0.0beta02. Troubleshooting showed that the ncpa 3.0.0beta02 no longer accepts a "community_string" token that contains a '%' symbol. I reported the finding as it seemed to be a behavior change in the agent. Responses to the findings mentioned that the '%' in the community_string needed to be escaped by writing %%.

While researching further, it was found that the repo was pointing to the "nagios-test" which explains how the beta02 version was installed. The repo was updated to use the production nagios repo (shown below). [nagios-base] name=Nagios baseurl=https://repo.nagios.com/nagios/8/ enabled=1 gpgcheck=1

The beta02 agent was removed and the v3.0.0-latest was installed. Additional testing then showed the same issue:

I expect that anyone using the '%' in the community_string will need to address this issue.

How to reproduce the issue: Install the ncpa agent v2.4.1 Set a community string that contains one or more '%' characters (non-escaped). Test server-agent connectivity. Update the client agent to version 3.0.0-latest. Re-test ncpa checks, Connectivity failed during our tests.

Given our current agent deployment and the level-of-effort required to change the community_string on both the server and the monitor-clients, we are postponing the agent update to v3.0.0-latest until the community_string can be changed system-wide.


From: pittagurneyi @.> Sent: Monday, November 27, 2023 6:42 AM To: NagiosEnterprises/ncpa @.> Cc: Brad Beckenhauer @.>; Author @.> Subject: Re: [NagiosEnterprises/ncpa] community_string password requirements (Issue #1035)

CAUTION: This email came from an EXTERNAL address. Use caution when clicking links or opening attachments.

I've been looking into the occurences of OptionParser in the source code:

/tmp/ncpa $ grep -ER '^[[:space:]]+(self.config|cp|test_config|nscparser)..=' | grep -Ev '.(add|set)' agent/ncpa.py: cp.optionxform = str test/unused/test_nrdshandler.py: self.config.optionxform = str test/unused/test_nrdshandler.py: self.config.file_path = os.path.join(self.testing_plugin_dir, "test.cfg") test/test_nrdphandler.py: self.config.optionxform = str

OptionParser by default has case-insensitive options, i.e. left-hand-side variable names in the config files.

Thus when reading the config file it will convert all option names to lowercase and allow case-insensitive matching when you try accessing or setting their values.

I haven't tested it yet, but that seems to mean that were you to use the ConfigParser to write the (modified) config file, it would then write lowercase option names.

Using optionxform = str after the instantiation of the ConfigParser modifies this behavior and makes it act case-sensitive.

As I haven't looked further into the source code, I can't be sure which config files are loaded, but the usage of this is not consequently enforced. These are all the instantiations I could find. If you compare it with the above you'll see that sometimes optionxform = str is missing:

/tmp/ncpa $ grep -ER '^[[:space:]]+(self.config|cp|test_config|nscparser) =' * | grep -Ev '.(add|set)' agent/passive/nrds.py: test_config = cp.ConfigParser() agent/passive/ncpacheck.py: self.config = config agent/passive/nagioshandler.py: self.config = config agent/ncpa.py: self.config = config agent/ncpa.py: self.config = config agent/ncpa.py: self.config = get_configuration() agent/ncpa.py: cp = ConfigParser() dist/nsclient_migration/NSC2NCPA.py: nscparser = configparser.ConfigParser() test/unused/test_nrdshandler.py: self.config = configparser.ConfigParser() test/test_nrdphandler.py: self.config = configparser.ConfigParser() test/test_ncpacheck.py: self.config = configparser.ConfigParser()

There don't seem to be any other modifications of the default behavior of ConfigParser. I also couldn't find any usage of "interpolation", thus it would be best to just turn it off. Then there is no question of whether the OptionParser interferes with the value given to options.

All that needs to be changed is to invoke it via, as @MrPippin66https://github.com/MrPippin66 mentioned:

ConfigParser(interpolation=None)

— Reply to this email directly, view it on GitHubhttps://github.com/NagiosEnterprises/ncpa/issues/1035#issuecomment-1827762282, or unsubscribehttps://github.com/notifications/unsubscribe-auth/BEEOFEVFD6B2ONKBZUNZSTTYGSDBXAVCNFSM6AAAAAA7TQO7D2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQMRXG43DEMRYGI. You are receiving this because you authored the thread.Message ID: @.***>

ne-bbahn commented 7 months ago

https://github.com/NagiosEnterprises/ncpa/pull/1054 I checked the behavior of NCPA 2 and it seems to match interpolation=None in the ConfigParser constructor.

ne-bbahn commented 7 months ago

v3.0.1 will have ConfigParser set to interpolation=None for the ncpa.cfg, which will solve this.