Skip to content

Commit

Permalink
Merge pull request #752 from mlibrary/cloudflare-haproxy
Browse files Browse the repository at this point in the history
Restrict Cloudflare protected HAProxy services to published IP ranges
  • Loading branch information
botimer authored Nov 22, 2024
2 parents 84ec081 + fe2b82a commit 63f68e9
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 0 deletions.
5 changes: 5 additions & 0 deletions manifests/haproxy/service.pp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@
# @param dynamic_weight_smoothing This value is added to the weight for each
# backend server regardless of server load to help "smooth" the effect of the weighting
#
# @param cloudflare_protected This service is protected by Cloudflare's WAF / bot / DDoS
# service, so restrict all requests to Cloudflare's IP ranges. For now, we are only
# considering IPv4 and the list is kept at: /etc/haproxy/cloudflare-ipv4.txt
#
# @param check_timeout_milliseconds How long to wait for http status
# checks; defaults to 5 seconds
#
Expand Down Expand Up @@ -74,6 +78,7 @@
Boolean $custom_503 = false,
Boolean $dynamic_weighting = false,
Integer $dynamic_weight_smoothing = 2,
Boolean $cloudflare_protected = false,
String $badrobots = '/etc/haproxy/global_badrobots.txt',
Optional[Integer] $check_timeout_milliseconds = undef
) {
Expand Down
4 changes: 4 additions & 0 deletions manifests/profile/haproxy.pp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@
content => $global_badrobots;
}

file { '/etc/haproxy/cloudflare-ipv4.txt':
source => 'https://www.cloudflare.com/ips-v4',
}

file { '/etc/ssl/private' :
ensure => 'directory',
mode => '0700',
Expand Down
7 changes: 7 additions & 0 deletions spec/classes/profile/haproxy_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,13 @@
end
end

describe 'Cloudflare proxy IP ranges' do
it 'saves Cloudflare trusted ranges in /etc/haproxy' do
expect(subject).to contain_file('/etc/haproxy/cloudflare-ipv4.txt')
.with_source('https://www.cloudflare.com/ips-v4')
end
end

describe 'global_badrobots.txt file' do
it 'lists ips to block' do
expect(subject).to contain_file('/etc/haproxy/global_badrobots.txt').with_content("1.2.3.0/24\n5.6.7.8\n")
Expand Down
33 changes: 33 additions & 0 deletions spec/defines/haproxy_service_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,39 @@
end
end

describe 'Cloudflare proxy ACL' do
let(:service_config) { '/etc/haproxy/services.d/svc1-http.cfg' }

context 'with the cloudflare_protected setting' do
let(:params) { super().merge(cloudflare_protected: true) }

it do
expect(subject).to contain_concat_fragment('svc1-dc1-http frontend').with(
target: service_config,
content: %r{acl cloudflare_proxied src -n -f /etc/haproxy/cloudflare-ipv4.txt},
)
end

it do
expect(subject).to contain_concat_fragment('svc1-dc1-http frontend').with(
target: service_config,
content: %r{http-request deny unless cloudflare_proxied},
)
end
end

context 'without the cloudflare_protected setting' do
let(:params) { super().merge(cloudflare_protected: false) }

it do
expect(subject).not_to contain_concat_fragment('svc1-dc1-http frontend').with(
target: service_config,
content: %r{http-request deny unless cloudflare_proxied},
)
end
end
end

describe 'ssl certs' do
let(:dest) { '/etc/ssl/private/svc1' }

Expand Down
4 changes: 4 additions & 0 deletions templates/profile/haproxy/frontend.erb
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,7 @@ use_backend <%= @service_prefix %>-back-exempt if <%= exemption_condition %>
default_backend <%= @service_prefix %>-back
acl blocked-ip src -f <%= @badrobots %>
http-request deny if blocked-ip
<% if @cloudflare_protected -%>
acl cloudflare_proxied src -n -f /etc/haproxy/cloudflare-ipv4.txt
http-request deny unless cloudflare_proxied
<% end -%>

0 comments on commit 63f68e9

Please sign in to comment.