diff --git a/README.md b/README.md index 804645a2d..00a175b57 100644 --- a/README.md +++ b/README.md @@ -573,6 +573,7 @@ There are many `apache::mod::[name]` classes within this module that can be decl * `proxy_http` * `python` * `reqtimeout` +* `remoteip`* * `rewrite` * `rpaf`* * `setenvif` diff --git a/manifests/mod/remoteip.pp b/manifests/mod/remoteip.pp new file mode 100644 index 000000000..564390e94 --- /dev/null +++ b/manifests/mod/remoteip.pp @@ -0,0 +1,27 @@ +class apache::mod::remoteip ( + $header = 'X-Forwarded-For', + $proxy_ips = [ '127.0.0.1' ], + $proxies_header = undef, + $trusted_proxy_ips = undef, + $apache_version = $::apache::apache_version +) { + if versioncmp($apache_version, '2.4') < 0 { + fail('mod_remoteip is only available in Apache 2.4') + } + + ::apache::mod { 'remoteip': } + + # Template uses: + # - $header + # - $proxy_ips + # - $proxies_header + # - $trusted_proxy_ips + file { 'remoteip.conf': + ensure => file, + path => "${::apache::mod_dir}/remoteip.conf", + content => template('apache/mod/remoteip.conf.erb'), + require => Exec["mkdir ${::apache::mod_dir}"], + before => File[$::apache::mod_dir], + notify => Service['httpd'], + } +} diff --git a/spec/classes/mod/remoteip_spec.rb b/spec/classes/mod/remoteip_spec.rb new file mode 100644 index 000000000..e3d095351 --- /dev/null +++ b/spec/classes/mod/remoteip_spec.rb @@ -0,0 +1,53 @@ +require 'spec_helper' + +describe 'apache::mod::remoteip', :type => :class do + let :pre_condition do + [ + 'include apache', + ] + end + context "on a Debian OS" do + let :facts do + { + :osfamily => 'Debian', + :operatingsystemrelease => '8', + :concat_basedir => '/dne', + :lsbdistcodename => 'jessie', + :operatingsystem => 'Debian', + :id => 'root', + :kernel => 'Linux', + :path => '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin', + } + end + let :params do + { :apache_version => '2.4' } + end + it { is_expected.to contain_class("apache::params") } + it { is_expected.to contain_apache__mod('remoteip') } + it { is_expected.to contain_file('remoteip.conf').with({ + 'path' => '/etc/apache2/mods-available/remoteip.conf', + }) } + + describe "with header X-Forwarded-For" do + let :params do + { :header => 'X-Forwarded-For' } + end + it { is_expected.to contain_file('remoteip.conf').with_content(/^RemoteIPHeader X-Forwarded-For$/) } + end + describe "with proxy_ips => [ 10.42.17.8, 10.42.18.99 ]" do + let :params do + { :proxy_ips => [ '10.42.17.8', '10.42.18.99' ] } + end + it { is_expected.to contain_file('remoteip.conf').with_content(/^RemoteIPInternalProxy 10.42.17.8$/) } + it { is_expected.to contain_file('remoteip.conf').with_content(/^RemoteIPInternalProxy 10.42.18.99$/) } + end + describe "with Apache version < 2.4" do + let :params do + { :apache_version => '2.2' } + end + it 'should fail' do + expect { subject }.to raise_error(Puppet::Error, /mod_remoteip is only available in Apache 2.4/) + end + end + end +end diff --git a/templates/mod/remoteip.conf.erb b/templates/mod/remoteip.conf.erb new file mode 100644 index 000000000..b4518f9b0 --- /dev/null +++ b/templates/mod/remoteip.conf.erb @@ -0,0 +1,23 @@ +# Declare the header field which should be parsed for useragent IP addresses +RemoteIPHeader <%= @header %> + +<%- if @proxy_ips -%> +# Declare client intranet IP addresses trusted to present +# the RemoteIPHeader value +<%- [@proxy_ips].flatten.each do |proxy| -%> +RemoteIPInternalProxy <%= proxy %> +<%- end -%> +<%- end -%> + +<%- if @proxies_header -%> +# Declare the header field which will record all intermediate IP addresses +RemoteIPProxiesHeader <%= @proxies_header %> +<%- end -%> + +<%- if @trusted_proxy_ips -%> +# Declare client intranet IP addresses trusted to present +# the RemoteIPHeader value + <%- [@trusted_proxy_ips].flatten.each do |proxy| -%> +RemoteIPTrustedProxy <%= proxy %> + <%- end -%> +<%- end -%>