diff --git a/global/overlay/etc/puppet/modules/cdn/manifests/cache.pp b/global/overlay/etc/puppet/modules/cdn/manifests/cache.pp index 2b89f72..15c9da1 100644 --- a/global/overlay/etc/puppet/modules/cdn/manifests/cache.pp +++ b/global/overlay/etc/puppet/modules/cdn/manifests/cache.pp @@ -78,6 +78,14 @@ class cdn::cache( content => template('cdn/cache/haproxy.cfg.erb'), } + file { "/opt/sunet-cdn/customers/$customer/conf/varnish.vcl": + ensure => file, + owner => $customer_uid, + group => $customer_uid, + mode => '0440', + content => template('cdn/cache/varnish.vcl.erb'), + } + sunet::docker_compose { "sunet-cdn-cache-$customer": content => template('cdn/cache/docker-compose.yml.erb'), service_name => "cdn-cache-$customer", diff --git a/global/overlay/etc/puppet/modules/cdn/templates/cache/docker-compose.yml.erb b/global/overlay/etc/puppet/modules/cdn/templates/cache/docker-compose.yml.erb index f1f925a..bd7e74e 100644 --- a/global/overlay/etc/puppet/modules/cdn/templates/cache/docker-compose.yml.erb +++ b/global/overlay/etc/puppet/modules/cdn/templates/cache/docker-compose.yml.erb @@ -44,7 +44,7 @@ services: # Use the same custom user as is used for haproxy. user: <%= @customer_uid %>:<%= @customer_uid %> volumes: - - /opt/sunet-cdn/customers/<%= @customer %>/conf/default.vcl:/etc/varnish/default.vcl:ro + - /opt/sunet-cdn/customers/<%= @customer %>/conf/varnish.vcl:/etc/varnish/varnish.vcl:ro - /opt/sunet-cdn/customers/<%= @customer %>/shared:/shared - /opt/sunet-cdn/customers/<%= @customer %>/cache:/cache # From https://www.varnish-software.com/developers/tutorials/running-varnish-docker/: @@ -65,7 +65,7 @@ services: "-a", "/shared/varnish.sock,PROXY,mode=600", "-f", - "/etc/varnish/default.vcl", + "/etc/varnish/varnish.vcl", "-p", "feature=+http2", "-s", diff --git a/global/overlay/etc/puppet/modules/cdn/templates/cache/varnish.vcl.erb b/global/overlay/etc/puppet/modules/cdn/templates/cache/varnish.vcl.erb new file mode 100644 index 0000000..ee75b67 --- /dev/null +++ b/global/overlay/etc/puppet/modules/cdn/templates/cache/varnish.vcl.erb @@ -0,0 +1,90 @@ +# The builtin VCL is called when there is no explicit +# return statement. +# +# See the VCL chapters in the Users Guide for a comprehensive documentation +# at https://www.varnish-cache.org/docs/. + +# Marker to tell the VCL compiler that this VCL has been written with the +# 4.0 or 4.1 syntax. +vcl 4.1; + +import std; +# https://www.varnish-software.com/developers/tutorials/avoid-http-to-https-redirect-loops-varnish/#create-cache-variations-based-on-the-x-forwarded-proto-header +import proxy; + +# https://varnish-cache.org/docs/trunk/users-guide/vcl-backends.html#connecting-through-a-proxy +backend haproxy_https { + .path = "/shared/haproxy_https"; +} + +backend haproxy_http { + .path = "/shared/haproxy_http"; +} + +backend destination_https { + .host = "<%= @cache_secrets['customers'][@customer]['host'] %>"; + .port = "80"; + .via = haproxy_http; +} + +backend destination_https { + .host = "<%= @cache_secrets['customers'][@customer]['host'] %>; + .port = "443"; + .via = haproxy_https; +} + +sub vcl_recv { + # Happens before we check if we have this in cache already. + # + # Typically you clean up the request here, removing cookies you don't need, + # rewriting the request, etc. + # + + # The usage of the proxy module is possible because haproxy is configured + # to set PROXY SSL headers for us. + if (proxy.is_ssl()) { + std.syslog(180, "RECV: this is https"); + if (req.http.host == "<%= @cache_secrets['customers'][@customer]['host'] %>") { + set req.backend_hint = destination_https; + } + } else { + std.syslog(180, "RECV: this is http"); + if (req.http.host == "<%= @cache_secrets['customers'][@customer]['host'] %>") { + set req.backend_hint = destination_http; + } + } + if (req.method == "PURGE") { + if (req.http.x-sunet-cdn-key == "<%= @cache_secrets['customers'][@customer]['key'] %>") { + return (purge); + } + return(synth(405,"Not allowed.")); + } +} + +sub vcl_backend_response { + # Happens after we have read the response headers from the backend. + # + # Here you clean the response headers, removing silly Set-Cookie headers + # and other mistakes your backend does. + + # Use slash/fellow for storage + set beresp.storage = storage.fellow; + + # Hold stale objects (where TTL has expired) for a longer time + set beresp.grace = 30m; + + # https://www.varnish-software.com/developers/tutorials/avoid-http-to-https-redirect-loops-varnish/#create-cache-variations-based-on-the-x-forwarded-proto-header + if(beresp.http.Vary) { + set beresp.http.Vary = beresp.http.Vary + ", X-Forwarded-Proto"; + } else { + set beresp.http.Vary = "X-Forwarded-Proto"; + } +} + +sub vcl_deliver { + # Happens when we have all the pieces we need, and are about to send the + # response to the client. + # + # You can do accounting or modifying the final object here. + unset resp.http.Vary; +}