Class: Trackdown::Configuration
- Inherits:
-
Object
- Object
- Trackdown::Configuration
- Defined in:
- lib/trackdown/configuration.rb
Overview
Runtime choices for providers, MaxMind, and provider-specific source trust.
Constant Summary collapse
- VALID_PROVIDERS =
Available provider types: :auto - Use one IP-corroborated CDN provider, otherwise fall back to MaxMind (recommended) :cloudflare - Only use Cloudflare headers :cloudfront - Only use Amazon CloudFront headers :maxmind - Only use MaxMind database
%i[auto cloudflare cloudfront maxmind].freeze
- TRUSTED_CDN_PROVIDERS =
%i[cloudflare cloudfront].freeze
Instance Attribute Summary collapse
-
#database_path ⇒ Object
Returns the value of attribute database_path.
-
#maxmind_account_id ⇒ Object
Returns the value of attribute maxmind_account_id.
-
#maxmind_license_key ⇒ Object
Returns the value of attribute maxmind_license_key.
-
#memory_mode ⇒ Object
Returns the value of attribute memory_mode.
-
#pool_size ⇒ Object
Returns the value of attribute pool_size.
-
#pool_timeout ⇒ Object
Returns the value of attribute pool_timeout.
-
#provider ⇒ Object
Returns the value of attribute provider.
-
#reject_private_ips ⇒ Object
Returns the value of attribute reject_private_ips.
-
#timeout ⇒ Object
Returns the value of attribute timeout.
Instance Method Summary collapse
-
#initialize ⇒ Configuration
constructor
A new instance of Configuration.
- #reject_private_ips? ⇒ Boolean
-
#request_came_through_trusted_cdn_path?(request, provider_name:) ⇒ Boolean
Did the host vouch for this request? Asked fresh every time, never cached, and a verifier that blows up means "no" — a geolocation lookup must not be able to take an application down.
- #trusted_cdn_path_verifier_for(provider_name) ⇒ Object
-
#verify_request_came_through_trusted_cdn_path_with(provider_name, verifier = nil, &block) ⇒ Object
Provider-aware lower-level form used by the two plain-English helpers above.
-
#verify_request_came_through_trusted_cloudflare_path_with(verifier = nil, &block) ⇒ Object
Tell Trackdown how you know a request really came through Cloudflare, so only Cloudflare results can say
source_trust: :host_verified:. - #verify_request_came_through_trusted_cloudfront_path_with(verifier = nil, &block) ⇒ Object
Constructor Details
#initialize ⇒ Configuration
Returns a new instance of Configuration.
26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/trackdown/configuration.rb', line 26 def initialize @provider = :auto # Safe default: use one verified edge candidate, otherwise MaxMind @maxmind_license_key = nil @maxmind_account_id = nil @database_path = defined?(Rails) ? Rails.root.join('db', 'GeoLite2-City.mmdb').to_s : 'db/GeoLite2-City.mmdb' @timeout = 3 # seconds @pool_size = 5 @pool_timeout = 3 # seconds @memory_mode = MAXMIND_AVAILABLE ? MaxMind::DB::MODE_MEMORY : nil @reject_private_ips = true @trusted_cdn_path_verifiers = {} @warned_verifier_raised = {} @verifier_mutex = Mutex.new end |
Instance Attribute Details
#database_path ⇒ Object
Returns the value of attribute database_path.
15 16 17 |
# File 'lib/trackdown/configuration.rb', line 15 def database_path @database_path end |
#maxmind_account_id ⇒ Object
Returns the value of attribute maxmind_account_id.
15 16 17 |
# File 'lib/trackdown/configuration.rb', line 15 def maxmind_account_id @maxmind_account_id end |
#maxmind_license_key ⇒ Object
Returns the value of attribute maxmind_license_key.
15 16 17 |
# File 'lib/trackdown/configuration.rb', line 15 def maxmind_license_key @maxmind_license_key end |
#memory_mode ⇒ Object
Returns the value of attribute memory_mode.
15 16 17 |
# File 'lib/trackdown/configuration.rb', line 15 def memory_mode @memory_mode end |
#pool_size ⇒ Object
Returns the value of attribute pool_size.
15 16 17 |
# File 'lib/trackdown/configuration.rb', line 15 def pool_size @pool_size end |
#pool_timeout ⇒ Object
Returns the value of attribute pool_timeout.
15 16 17 |
# File 'lib/trackdown/configuration.rb', line 15 def pool_timeout @pool_timeout end |
#provider ⇒ Object
Returns the value of attribute provider.
14 15 16 |
# File 'lib/trackdown/configuration.rb', line 14 def provider @provider end |
#reject_private_ips ⇒ Object
Returns the value of attribute reject_private_ips.
15 16 17 |
# File 'lib/trackdown/configuration.rb', line 15 def reject_private_ips @reject_private_ips end |
#timeout ⇒ Object
Returns the value of attribute timeout.
15 16 17 |
# File 'lib/trackdown/configuration.rb', line 15 def timeout @timeout end |
Instance Method Details
#reject_private_ips? ⇒ Boolean
49 50 51 |
# File 'lib/trackdown/configuration.rb', line 49 def reject_private_ips? @reject_private_ips end |
#request_came_through_trusted_cdn_path?(request, provider_name:) ⇒ Boolean
Did the host vouch for this request? Asked fresh every time, never cached, and a verifier that blows up means "no" — a geolocation lookup must not be able to take an application down.
110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/trackdown/configuration.rb', line 110 def request_came_through_trusted_cdn_path?(request, provider_name:) validate_trusted_cdn_provider!(provider_name) verifier = trusted_cdn_path_verifier_for(provider_name) return false unless request && verifier begin !!verifier.call(request) rescue StandardError => e warn_verifier_raised(provider_name, e) false end end |
#trusted_cdn_path_verifier_for(provider_name) ⇒ Object
123 124 125 126 |
# File 'lib/trackdown/configuration.rb', line 123 def trusted_cdn_path_verifier_for(provider_name) validate_trusted_cdn_provider!(provider_name) @verifier_mutex.synchronize { @trusted_cdn_path_verifiers[provider_name] } end |
#verify_request_came_through_trusted_cdn_path_with(provider_name, verifier = nil, &block) ⇒ Object
Provider-aware lower-level form used by the two plain-English helpers above.
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/trackdown/configuration.rb', line 87 def verify_request_came_through_trusted_cdn_path_with(provider_name, verifier = nil, &block) validate_trusted_cdn_provider!(provider_name) verifier ||= block if verifier.nil? raise ArgumentError, "verify_request_came_through_trusted_#{provider_name}_path_with needs a block or " \ 'a callable saying how you know a request came through that CDN' end unless verifier.respond_to?(:call) raise ArgumentError, "The trusted #{provider_name} path verifier must respond to #call " \ "(a block, proc, lambda, or any callable object), got: #{verifier.inspect}" end @verifier_mutex.synchronize do @warned_verifier_raised.delete(provider_name) @trusted_cdn_path_verifiers[provider_name] = verifier end end |
#verify_request_came_through_trusted_cloudflare_path_with(verifier = nil, &block) ⇒ Object
Tell Trackdown how you know a request really came through Cloudflare, so
only Cloudflare results can say source_trust: :host_verified:
expected = Rails.application.credentials.cloudflare_origin_secret.to_s
raise 'Missing Cloudflare origin secret' if expected.empty?
config.verify_request_came_through_trusted_cloudflare_path_with do |request|
supplied = request.env['HTTP_X_ORIGIN_SECRET'].to_s
!supplied.empty? && ActiveSupport::SecurityUtils.secure_compare(supplied, expected)
end
The non-empty checks are essential: secure_compare('', '') is true. Rails: https://api.rubyonrails.org/classes/ActiveSupport/SecurityUtils.html#method-c-secure_compare
Trackdown never infers trust from headers. Anyone who can reach an unprotected origin can set them. Verify each CDN independently so a trusted CloudFront path can never vouch for forwarded, viewer-supplied CF-* headers: https://developers.cloudflare.com/ssl/origin-configuration/authenticated-origin-pull/ https://developers.cloudflare.com/fundamentals/concepts/cloudflare-ip-addresses/#block-other-ip-addresses-recommended https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/add-origin-custom-headers.html https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-overview.html https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/using-managed-origin-request-policies.html#managed-origin-request-policy-all-viewer-and-cloudfront
Trackdown reports this trust state; it does not act on it. Deciding what an unverified location may be used for is your application's call.
78 79 80 |
# File 'lib/trackdown/configuration.rb', line 78 def verify_request_came_through_trusted_cloudflare_path_with(verifier = nil, &block) verify_request_came_through_trusted_cdn_path_with(:cloudflare, verifier, &block) end |
#verify_request_came_through_trusted_cloudfront_path_with(verifier = nil, &block) ⇒ Object
82 83 84 |
# File 'lib/trackdown/configuration.rb', line 82 def verify_request_came_through_trusted_cloudfront_path_with(verifier = nil, &block) verify_request_came_through_trusted_cdn_path_with(:cloudfront, verifier, &block) end |