diff --git a/src/Dockerfile b/src/Dockerfile index 24d480a..9f1d8c2 100644 --- a/src/Dockerfile +++ b/src/Dockerfile @@ -4,7 +4,7 @@ RUN /usr/local/openresty/luajit/bin/luarocks install lua-resty-http RUN /usr/local/openresty/luajit/bin/luarocks install lua-resty-cookie RUN /usr/local/openresty/luajit/bin/luarocks install lua-resty-iputils -RUN apk add openssl certbot +RUN apk add --no-cache ca-certificates certbot openssl RUN /usr/local/openresty/luajit/bin/luarocks install lua-resty-auto-ssl RUN mkdir /etc/resty-auto-ssl && chown -R nobody /etc/resty-auto-ssl diff --git a/src/default.conf b/src/default.conf index 4f13639..771305e 100644 --- a/src/default.conf +++ b/src/default.conf @@ -6,6 +6,8 @@ lua_package_path "/opt/sitelen-tu/?.lua;;"; lua_shared_dict auto_ssl 1m; lua_shared_dict auto_ssl_settings 64k; +lua_ssl_trusted_certificate "/etc/ssl/certs/ca-certificates.crt"; + resolver 127.0.0.11 valid=60 ipv6=off; init_by_lua_block { @@ -44,6 +46,7 @@ server { # These variables are set in the access_by_lua stage # TODO: These might be better to set with a set_by_lua_block set $jasima_host "fallback.invalid"; + set $jasima_host_connect "fallback.invalid"; set $jasima_host_header "fallback.invalid"; set $jasima_host_ssl "fallback.invalid"; diff --git a/src/lua/access.lua b/src/lua/access.lua index 6a0dcc0..b304e67 100644 --- a/src/lua/access.lua +++ b/src/lua/access.lua @@ -1,7 +1,6 @@ -local http = require "resty.http" - local config = require "config" local geo = require "geo" +local psl = require "psl" local utils = require "utils" local jasima_host = config.get_jasima_host() @@ -61,11 +60,45 @@ if ngx.ctx.jasima_config.headers then end end --- Look up the IP to connect to the origin local host_connect = ngx.ctx.jasima_config.host_connect or jasima_host +local host_header = ngx.ctx.jasima_config.host_header or jasima_host +local host_ssl = ngx.ctx.jasima_config.host_ssl or jasima_host + +-- Handle first party Tealium installations +if ngx.ctx.jasima_config.first_party_tealium then + local tealium = ngx.ctx.jasima_config.first_party_tealium + if tealium.subdomain and tealium.account then + local _, _, _, matched = ngx.var.request_uri:match("^/utag/([^/]+)/([^/]+)/([^/]+)/utag(.-)js") + if matched then + ngx.log(ngx.DEBUG, "Matched as a Tealium universal tag script " .. tostring(matched)) + host_connect = "tags.tiqcdn.com" + host_header = "tags.tiqcdn.com" + host_ssl = "tags.tiqcdn.com" + end + ngx.ctx.jasima_host_tealium = tealium.subdomain .. "." .. psl.get_registered_domain(ngx.ctx.jasima_host) + ngx.log(ngx.DEBUG, "Using first-party Tealium hostname " .. ngx.ctx.jasima_host_tealium) + end +end + +-- Handle first party Adobe Analytics +if ngx.ctx.jasima_config.first_party_adobe then + local adobe = ngx.ctx.jasima_config.first_party_adobe + if adobe.subdomain and adobe.account then + local matched = ngx.var.request_uri:match("^/b/ss/") + if matched then + ngx.log(ngx.DEBUG, "Matched as an Adobe Analytics request " .. tostring(matched)) + host_connect = adobe.account .. ".sc.omtrdc.net" + host_header = host_connect + host_ssl = host_connect + end + ngx.ctx.jasima_host_adobe = adobe.subdomain .. "." .. psl.get_registered_domain(ngx.ctx.jasima_host) + ngx.log(ngx.DEBUG, "Using first-party Adobe Analytics hostname " .. ngx.ctx.jasima_host_adobe) + end +end + +-- Look up the IP to connect to the origin local upstream_ips = utils.resolve_origin(host_connect) ngx.ctx.upstream_ips = utils.filter_bogons(upstream_ips) - if #ngx.ctx.upstream_ips == 0 then ngx.log(ngx.ERR, "no A records found") return ngx.exit(500) @@ -73,5 +106,6 @@ end -- Set the nginx host variables ngx.var.jasima_host = jasima_host -ngx.var.jasima_host_header = ngx.ctx.jasima_config.host_header or jasima_host -ngx.var.jasima_host_ssl = ngx.ctx.jasima_config.host_ssl or jasima_host +ngx.var.jasima_host_connect = host_connect +ngx.var.jasima_host_header = host_header +ngx.var.jasima_host_ssl = host_ssl diff --git a/src/lua/body_filter.lua b/src/lua/body_filter.lua index d309048..5e35be4 100644 --- a/src/lua/body_filter.lua +++ b/src/lua/body_filter.lua @@ -39,6 +39,21 @@ local function rewrite_body(body, eof) body = body:gsub("", matomo_tracking_code(ngx.ctx.jasima_config.matomo_site_id)) -- TODO: Ensure that tracking code was added when it's HTML, but only for HTML end + -- Handle first party Tealium installations + if ngx.ctx.jasima_host_tealium then + local escaped_host = ngx.ctx.jasima_host_tealium:gsub("%.", "%%.") + body = body:gsub("(https:)??//" .. escaped_host .. "/", "/utag/" .. ngx.ctx.jasima_config.first_party_tealium.account .. "/") + body = body:gsub("//tags.tiqcdn.com/", "/") + if ngx.var.jasima_host_connect == "tags.tiqcdn.com" and ngx.ctx.jasima_host_adobe then + body, count = body:gsub([[return"http"%+%(a%.ssl%?"s":""%)%+"://"%+b%+"/b/ss/]], [[return"/b/ss/]]) + ngx.log(ngx.DEBUG, "Performing rewrite for Adobe Analytics in Tealium tag " .. count) + end + end + -- Handle first party Adobe Analytics + if ngx.ctx.jasima_host_adobe then + local escaped_host = ngx.ctx.jasima_host_adobe:gsub("%.", "%%.") + body = body:gsub("(https:)??//" .. escaped_host .. "/", "/") + end return body end