diff --git a/site-modules/profile/files/varnish/early_vcl_recv.vcl b/site-modules/profile/files/varnish/early_vcl_recv.vcl new file mode 100644 index 00000000..86013883 --- /dev/null +++ b/site-modules/profile/files/varnish/early_vcl_recv.vcl @@ -0,0 +1,13 @@ +# 00_early_vcl_recv.vcl +# +# Do early manglement of the host header to simplify its future handling +# +# File managed by puppet. All modifications will be lost. + +sub vcl_recv { + # Keep original Host header in X-Swh-Original-Host. + set req.http.x-swh-original-host = req.http.host; + + # Set Host header to lower case and trim trailing port number. + set req.http.host = regsub(req.http.host.lower(), ":[0-9]+$", ""); +} diff --git a/site-modules/profile/manifests/varnish.pp b/site-modules/profile/manifests/varnish.pp index f6f59c8e..9ff83aef 100644 --- a/site-modules/profile/manifests/varnish.pp +++ b/site-modules/profile/manifests/varnish.pp @@ -1,99 +1,104 @@ # Varnish configuration class profile::varnish { $includes_dir = '/etc/varnish/includes' $includes_vcl_name = 'includes.vcl' $includes_vcl = "/etc/varnish/${includes_vcl_name}" $http_port = lookup('varnish::http_port') $backend_http_port = lookup('varnish::backend_http_port') $listen = lookup('varnish::listen') $admin_listen = lookup('varnish::admin_listen') $admin_port = lookup('varnish::admin_port') $http2_support = lookup('varnish::http2_support') $secret = lookup('varnish::secret') $storage_type = lookup('varnish::storage_type') $storage_size = lookup('varnish::storage_size') $storage_file = lookup('varnish::storage_file') if $http2_support { $runtime_params = { feature => '+http2', } } else { $runtime_params = {} } if $::lsbdistcodename == 'stretch' { $extra_class_params = {} } else { $extra_class_params = { vcl_reload_cmd => '/usr/share/varnish/varnishreload', } } $extra_packages = ["varnish-modules"]; package {$extra_packages: ensure => installed, } class {'::varnish': addrepo => false, listen => $listen, admin_listen => $admin_listen, admin_port => $admin_port, secret => $secret, storage_type => $storage_type, storage_size => $storage_size, storage_file => $storage_file, runtime_params => $runtime_params, * => $extra_class_params, } ::varnish::vcl {'/etc/varnish/default.vcl': content => template('profile/varnish/default.vcl.erb'), require => [ Concat[$includes_vcl], Package[$extra_packages], ], } file {$includes_dir: ensure => directory, owner => 'root', group => 'root', mode => '0644', require => Class['varnish::install'], notify => Exec['vcl_reload'], } concat {$includes_vcl: ensure => present, owner => 'root', group => 'root', mode => '0644', ensure_newline => true, require => Class['varnish::install'], notify => Exec['vcl_reload'], } concat::fragment {"${includes_vcl}:header": target => $includes_vcl, content => "# File managed with puppet (module profile::varnish)\n# All modifications will be lost\n\n", order => '00', } + ::profile::varnish::vcl_include {'early_vcl_recv': + order => '00', + content => file('profile/varnish/early_vcl_recv.vcl'), + } + ::profile::varnish::vcl_include {'synth_redirect': order => '10', content => file('profile/varnish/synth_redirect.vcl'), } ::profile::varnish::vcl_include {'unknown_vhost_then_forbidden_access': order => '99', content => file('profile/varnish/unknown_vhost_then_forbidden_access.vcl'), } include profile::prometheus::varnish } diff --git a/site-modules/profile/templates/varnish/vhost.vcl.erb b/site-modules/profile/templates/varnish/vhost.vcl.erb index b8b9dc92..1c00d12c 100644 --- a/site-modules/profile/templates/varnish/vhost.vcl.erb +++ b/site-modules/profile/templates/varnish/vhost.vcl.erb @@ -1,85 +1,81 @@ # vhost_<%= @servername %>.vcl # # Settings for the <%= @servername %> vhost # # File managed by puppet. All modifications will be lost. sub vcl_recv { if ( <% @aliases.each do |alias_| -%> - req.http.host ~ "^(?i)<%= Regexp.escape(alias_) %>(:[0-9]+)?$" || + req.http.host == "<%= alias_.downcase %>" || <% end -%> - req.http.host ~ "^(?i)<%= Regexp.escape(@servername) %>(:[0-9]+)?$" + req.http.host == "<%= @servername.downcase %>" ) { var.set("known-vhost", "yes"); + var.set("current-vhost", "<%= @backend_name %>"); + } + + if (var.get("current-vhost") == "<%= @backend_name %>") { if (std.port(server.ip) == <%= scope['::profile::varnish::http_port'] %>) { set req.http.x-redir = "https://" + req.http.host + req.url; return(synth(850, "Moved permanently")); } else { set req.backend_hint = <%= @backend_name %>; <%- if @basic_auth -%> if ( 1 == 1 # noop expression to be syntactically correct with the following && <%- @basic_auth_strings.each do | basic_auth_string | -%> && ! req.http.Authorization ~ "Basic <%= basic_auth_string %>" <%- end -%> ) { return(synth(401, "Restricted")); } <%- end -%> <% if @websocket_support -%> if (req.http.upgrade ~ "(?i)websocket") { return (pipe); } <% end -%> set req.http.X-Forwarded-Proto = "https"; } <% if @vcl_recv_extra -%> <%= @vcl_recv_extra %> <% end -%> } } <% if @websocket_support -%> sub vcl_pipe { - if (req.http.upgrade) { - set bereq.http.upgrade = req.http.upgrade; - set bereq.http.connection = req.http.connection; + if (var.get("current-vhost") == "<%= @backend_name %>") { + if (req.http.upgrade) { + set bereq.http.upgrade = req.http.upgrade; + set bereq.http.connection = req.http.connection; + } } } <% end -%> <% if @hsts_max_age or @vcl_deliver_extra -%> sub vcl_deliver { - if ( -<% @aliases.each do |alias_| -%> - req.http.host ~ "^(?i)<%= Regexp.escape(alias_) %>(:[0-9]+)?$" || -<% end -%> - req.http.host ~ "^(?i)<%= Regexp.escape(@servername) %>(:[0-9]+)?$" - ) { + if (var.get("current-vhost") == "<%= @backend_name %>") { <% if @hsts_max_age -%> if (std.port(server.ip) != <%= scope['::profile::varnish::http_port'] %>) { set resp.http.Strict-Transport-Security = "max-age=<%= @hsts_max_age %>;"; } <% end -%> <% if @vcl_deliver_extra -%> <%= @vcl_deliver_extra %> <% end -%> } } sub vcl_synth { - if ( -<% @aliases.each do |alias_| -%> - req.http.host ~ "^(?i)<%= Regexp.escape(alias_) %>(:[0-9]+)?$" || -<% end -%> - req.http.host ~ "^(?i)<%= Regexp.escape(@servername) %>(:[0-9]+)?$" - ) { + if (var.get("current-vhost") == "<%= @backend_name %>") { if (resp.status == 401) { set resp.http.WWW-Authenticate = "Basic"; return(deliver); } } } <% end -%>