allow /metrics to be reached from private subnets only

this commit is not approved by the IPv6 crowd.  patches welcome
This commit is contained in:
Georg Gadinger 2023-02-13 21:53:40 +01:00
parent c338a0c8cc
commit 64adbb5707
3 changed files with 78 additions and 2 deletions

View File

@ -49,8 +49,9 @@ Rails.application.routes.draw do
get "/linkfilter", to: "link_filter#index", as: :linkfilter get "/linkfilter", to: "link_filter#index", as: :linkfilter
get "/manifest.json", to: "manifests#show", as: :webapp_manifest get "/manifest.json", to: "manifests#show", as: :webapp_manifest
# TODO: limit this endpoint constraints(Constraints::LocalNetwork) do
get "/metrics", to: "metrics#show" get "/metrics", to: "metrics#show"
end
# Devise routes # Devise routes
devise_for :users, path: "user", skip: %i[sessions registrations] devise_for :users, path: "user", skip: %i[sessions registrations]

View File

@ -0,0 +1,22 @@
# frozen_string_literal: true
module Constraints
module LocalNetwork
module_function
SUBNETS = %w[
10.0.0.0/8
127.0.0.0/8
172.16.0.0/12
192.168.0.0/16
].map { IPAddr.new(_1) }.freeze
def matches?(request)
SUBNETS.find do |net|
net.include? request.remote_ip
rescue
false
end
end
end
end

View File

@ -0,0 +1,53 @@
# frozen_string_literal: true
require "rails_helper"
describe Constraints::LocalNetwork do
describe ".matches?" do
let(:request) { double("Rack::Request", remote_ip:) }
subject { described_class.matches?(request) }
context "with a private address from the 10.0.0.0/8 range" do
let(:remote_ip) { "10.0.2.100" }
it { is_expected.to be_truthy }
end
context "with a private address from the 127.0.0.0/8 range" do
let(:remote_ip) { "127.0.0.1" }
it { is_expected.to be_truthy }
end
context "with a private address from the 172.16.0.0/12 range" do
let(:remote_ip) { "172.31.33.7" }
it { is_expected.to be_truthy }
end
context "with a private address from the 192.168.0.0/16 range" do
let(:remote_ip) { "192.168.123.45" }
it { is_expected.to be_truthy }
end
context "with a non-private/loopback address" do
let(:remote_ip) { "193.186.6.83" }
it { is_expected.to be_falsey }
end
context "with some fantasy address" do
let(:remote_ip) { "fe80:3::1ff:fe23:4567:890a" }
it { is_expected.to be_falsey }
end
context "with an actual invalid address" do
let(:remote_ip) { "herbert" }
it { is_expected.to be_falsey }
end
end
end