Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option to restrict API access to specific hosts #856

Merged
merged 5 commits into from
Feb 13, 2023

Conversation

teluq-pbrideau
Copy link
Contributor

Pull Request (PR) description

By default, the api is open to everyone. I would like to restrict it to only the zabbix server.

I’m not sure if it should be included in this module like I suggest, or if I should manage my own apache config by disabling this module apache management manage_vhost => false in web.pp, but I think the changes are simple enough to include in this module

My suggestion in this PR allow to add restriction to the api like so:

class { 'zabbix::web' :
  [...]
  zabbix_api_access => [$facts['networking']['fqdn']],
}

This creates this location entry in apache config (or equivalent in apache 2.2):

<Location "/api_jsonrpc.php" >
  Require host zabbix.example.com
</Location>

This Pull Request (PR) fixes the following issues

manifests/init.pp Outdated Show resolved Hide resolved
manifests/init.pp Outdated Show resolved Hide resolved
manifests/web.pp Outdated Show resolved Hide resolved
@teluq-pbrideau teluq-pbrideau force-pushed the feat/restrict_api branch 2 times, most recently from b2bdbdd to ec4ddc5 Compare December 14, 2022 14:54
@teluq-pbrideau
Copy link
Contributor Author

teluq-pbrideau commented Dec 14, 2022

I’ve banged my head to try to write a test but I cannot find the right syntax… Would someone have a pointer about it?

        describe 'with restriction to api access' do
          let :params do
            super().merge(
              zabbix_api_access: [ '127.0.0.1' ],
            )
          end

          it { is_expected.to contain_apache__vhost('zabbix.example.com').with_directories(
            including(
              {"path"=>"/api_jsonrpc.php", "provider"=>"location", "require"=>["host 127.0.0.1"]}
            )
          )}
        end

I’ve tried include, including, a_hash_including

The closer I got it to run is by defining the entire array:

          it { is_expected.to contain_apache__vhost('zabbix.example.com').with_directories([
            {"path"=>"/usr/share/zabbix", "provider"=>"directory", "require"=>"all granted"},
            {"path"=>"/usr/share/zabbix/conf", "provider"=>"directory", "require"=>"all denied"},
            {"path"=>"/usr/share/zabbix/api", "provider"=>"directory", "require"=>"all denied"},
            {"path"=>"/usr/share/zabbix/include", "provider"=>"directory", "require"=>"all denied"},
            {"path"=>"/usr/share/zabbix/include/classes", "provider"=>"directory", "require"=>"all denied"},
            {"path"=>"/api_jsonrpc.php", "provider"=>"location", "require"=>["host 127.0.0.1"]}
          ])}

But this does not work in every tests because there is conditions :

    if $facts['os']['family'] == 'RedHat' and versioncmp($facts['os']['release']['major'], '7') >= 0 and versioncmp($zabbix_version, '5') >= 0 {
      if versioncmp($facts['os']['release']['major'], '7') == 0 {
        $fpm_service = 'rh-php72-php-fpm'
        # PHP parameters are moved to /etc/opt/rh/rh-php72/php-fpm.d/zabbix.conf per package zabbix-web-deps-scl
        $fpm_scl_prefix = '/opt/rh/rh-php72'
      } else {
        $fpm_service = 'php-fpm'
        $fpm_scl_prefix = ''
      }
      $fcgi_filematch = {
        path     => '/usr/share/zabbix',
        provider => 'directory',
        addhandlers => [
          {
            extensions => [
              'php',
              'phar',
            ],
            handler => "proxy:unix:/var${fpm_scl_prefix}/run/php-fpm/zabbix.sock|fcgi://localhost",
          },
        ],
      }
    apache::vhost { $zabbix_url:
      directories     => [
        merge( {
            path     => '/usr/share/zabbix',
            provider => 'directory',
            require  => 'all granted',
          }, $fcgi_filematch
        ),
    [...]

It feels wrong to me to duplicate all this logic inside the test, is it the way to go?

@teluq-pbrideau
Copy link
Contributor Author

teluq-pbrideau commented Dec 14, 2022

Or should I make a less precise test like what is done in apache module:

              it {
                is_expected.to contain_concat__fragment('zabbix.example.com-directories').with(
                  content: %r{^\s+Require host 127.0.0.1$},
                )
              }

@root-expert
Copy link
Member

Or should I make a less precise test like what is done in apache module:

              it {
                is_expected.to contain_concat__fragment('zabbix.example.com-directories').with(
                  content: %r{^\s+Require host 127.0.0.1$},
                )
              }

Although the first option is better that's also okay for me. Probably you need something like this though:

               it {
                 is_expected.to contain_concat__fragment('zabbix.example.com-directories').with(
                   content: %r{^\s*Require host 127\.0\.0.\1$},
                 )
               }

Dot matches everything except new lines, so you need to escape it 😄

@teluq-pbrideau teluq-pbrideau force-pushed the feat/restrict_api branch 2 times, most recently from 9a14521 to c6fa640 Compare December 20, 2022 14:43
@teluq-pbrideau

This comment was marked as outdated.

@root-expert root-expert added the enhancement New feature or request label Dec 21, 2022
@root-expert
Copy link
Member

@teluq-pbrideau Can you please rebase with our master branch one last time before merging this?

@root-expert root-expert changed the title Restrict api access Add option to restrict API access to specific hosts Feb 13, 2023
@root-expert root-expert merged commit 99bf82c into voxpupuli:master Feb 13, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants