From 39e9c0f23c2c459285df473de8011221f429dbad Mon Sep 17 00:00:00 2001 From: Tom Hughes Date: Fri, 2 Dec 2022 09:15:38 +0000 Subject: [PATCH] Improve sandboxing of prometheus collectors --- cookbooks/fail2ban/recipes/default.rb | 2 ++ cookbooks/hardware/recipes/default.rb | 16 ++++++++++++++ cookbooks/nominatim/recipes/default.rb | 1 + cookbooks/overpass/recipes/default.rb | 1 + cookbooks/php/resources/fpm.rb | 1 + cookbooks/postgresql/recipes/default.rb | 1 + cookbooks/prometheus/recipes/default.rb | 5 +++++ cookbooks/prometheus/resources/collector.rb | 20 ++++++++++++----- cookbooks/prometheus/resources/exporter.rb | 22 ++++++++++++++----- cookbooks/systemd/resources/service.rb | 1 + .../systemd/templates/default/service.erb | 3 +++ 11 files changed, 62 insertions(+), 11 deletions(-) diff --git a/cookbooks/fail2ban/recipes/default.rb b/cookbooks/fail2ban/recipes/default.rb index ca03d37d6..0a4c479f4 100644 --- a/cookbooks/fail2ban/recipes/default.rb +++ b/cookbooks/fail2ban/recipes/default.rb @@ -49,4 +49,6 @@ munin_plugin "fail2ban" prometheus_exporter "fail2ban" do port 9635 + user "root" + restrict_address_families "AF_UNIX" end diff --git a/cookbooks/hardware/recipes/default.rb b/cookbooks/hardware/recipes/default.rb index 6679bb178..d8bfadbe5 100644 --- a/cookbooks/hardware/recipes/default.rb +++ b/cookbooks/hardware/recipes/default.rb @@ -219,6 +219,10 @@ if node[:kernel][:modules].include?("ipmi_si") prometheus_exporter "ipmi" do port 9290 + user "root" + private_devices false + protect_clock false + system_call_filter ["@system-service", "@raw-io"] options "--config.file=/etc/prometheus/ipmi_local.yml" subscribes :restart, "template[/etc/prometheus/ipmi_local.yml]" end @@ -253,6 +257,7 @@ end prometheus_exporter "rasdaemon" do port 9797 + user "root" end tools_packages = [] @@ -530,6 +535,11 @@ if disks.count.positive? prometheus_collector "smart" do interval "15m" + user "root" + capability_bounding_set "CAP_SYS_ADMIN" + private_devices false + private_users false + protect_clock false end # Don't try and do munin monitoring of disks behind @@ -688,4 +698,10 @@ end prometheus_collector "ohai" do interval "15m" + user "root" + proc_subset "all" + capability_bounding_set "CAP_SYS_ADMIN" + private_devices false + private_users false + protect_clock false end diff --git a/cookbooks/nominatim/recipes/default.rb b/cookbooks/nominatim/recipes/default.rb index 75f06fa56..537de83f5 100644 --- a/cookbooks/nominatim/recipes/default.rb +++ b/cookbooks/nominatim/recipes/default.rb @@ -512,6 +512,7 @@ end prometheus_exporter "nominatim" do port 8082 user "www-data" + restrict_address_families "AF_UNIX" options [ "--nominatim.query-log=#{node[:nominatim][:logdir]}/query.log", "--nominatim.database-name=#{node[:nominatim][:dbname]}" diff --git a/cookbooks/overpass/recipes/default.rb b/cookbooks/overpass/recipes/default.rb index 9908e330b..720b11321 100644 --- a/cookbooks/overpass/recipes/default.rb +++ b/cookbooks/overpass/recipes/default.rb @@ -250,6 +250,7 @@ end prometheus_exporter "overpass" do port 9898 user username + restrict_address_families "AF_UNIX" options [ "--overpass.base-directory=#{basedir}" ] diff --git a/cookbooks/php/resources/fpm.rb b/cookbooks/php/resources/fpm.rb index 49df4effe..f8cc208b5 100644 --- a/cookbooks/php/resources/fpm.rb +++ b/cookbooks/php/resources/fpm.rb @@ -53,6 +53,7 @@ action :create do if new_resource.prometheus_port prometheus_exporter "phpfpm" do port new_resource.prometheus_port + restrict_address_families "AF_UNIX" service service_name command "server" options "--phpfpm.scrape-uri=#{scrape_uri}" diff --git a/cookbooks/postgresql/recipes/default.rb b/cookbooks/postgresql/recipes/default.rb index 721cd6bab..a57e1b348 100644 --- a/cookbooks/postgresql/recipes/default.rb +++ b/cookbooks/postgresql/recipes/default.rb @@ -181,5 +181,6 @@ prometheus_exporter "postgres" do environment "DATA_SOURCE_URI" => uris.sort.uniq.first, "PG_EXPORTER_AUTO_DISCOVER_DATABASES" => "true", "PG_EXPORTER_EXCLUDE_DATABASES" => "postgres,template0,template1" + restrict_address_families "AF_UNIX" subscribes :restart, "template[/etc/prometheus/exporters/postgres_queries.yml]" end diff --git a/cookbooks/prometheus/recipes/default.rb b/cookbooks/prometheus/recipes/default.rb index de601b766..7b281b03c 100644 --- a/cookbooks/prometheus/recipes/default.rb +++ b/cookbooks/prometheus/recipes/default.rb @@ -99,6 +99,11 @@ end prometheus_exporter "node" do port 9100 + user "root" + proc_subset "all" + protect_clock false + restrict_address_families ["AF_UNIX", "AF_NETLINK"] + system_call_filter ["@system-service", "@clock"] options %w[ --collector.textfile.directory=/var/lib/prometheus/node-exporter --collector.interrupts diff --git a/cookbooks/prometheus/resources/collector.rb b/cookbooks/prometheus/resources/collector.rb index e82984b14..0ae8320f7 100644 --- a/cookbooks/prometheus/resources/collector.rb +++ b/cookbooks/prometheus/resources/collector.rb @@ -23,23 +23,33 @@ default_action :create property :collector, :kind_of => String, :name_property => true property :interval, :kind_of => [Integer, String], :required => [:create] +property :user, :kind_of => String property :options, :kind_of => [String, Array] property :environment, :kind_of => Hash, :default => {} +property :proc_subset, String +property :capability_bounding_set, [String, Array] +property :private_devices, [true, false] +property :private_users, [true, false] +property :protect_clock, [true, false] action :create do systemd_service service_name do description "Prometheus #{new_resource.collector} collector" - user "root" + user new_resource.user + dynamic_user new_resource.user.nil? + group "adm" environment new_resource.environment standard_output "file:/var/lib/prometheus/node-exporter/#{new_resource.collector}.new" standard_error "journal" exec_start "#{executable_path} #{executable_options}" exec_start_post "/bin/mv /var/lib/prometheus/node-exporter/#{new_resource.collector}.new /var/lib/prometheus/node-exporter/#{new_resource.collector}.prom" - private_tmp true - protect_system "strict" - protect_home true + sandbox true + proc_subset new_resource.proc_subset if new_resource.property_is_set?(:proc_subset) + capability_bounding_set new_resource.capability_bounding_set if new_resource.property_is_set?(:capability_bounding_set) + private_devices new_resource.private_devices if new_resource.property_is_set?(:private_devices) + private_users new_resource.private_users if new_resource.property_is_set?(:private_users) + protect_clock new_resource.protect_clock if new_resource.property_is_set?(:protect_clock) read_write_paths ["/var/lib/prometheus/node-exporter", "/var/lock", "/var/log"] - no_new_privileges true end systemd_timer service_name do diff --git a/cookbooks/prometheus/resources/exporter.rb b/cookbooks/prometheus/resources/exporter.rb index c8b4e0cd8..2d6a7cbc8 100644 --- a/cookbooks/prometheus/resources/exporter.rb +++ b/cookbooks/prometheus/resources/exporter.rb @@ -26,10 +26,15 @@ property :address, :kind_of => String property :port, :kind_of => Integer, :required => [:create] property :listen_switch, :kind_of => String, :default => "web.listen-address" property :listen_type, :kind_of => String, :default => "address" -property :user, :kind_of => String, :default => "root" +property :user, :kind_of => String property :command, :kind_of => String property :options, :kind_of => [String, Array] property :environment, :kind_of => Hash, :default => {} +property :proc_subset, String +property :private_devices, [true, false] +property :protect_clock, [true, false] +property :restrict_address_families, [String, Array] +property :system_call_filter, [String, Array] property :service, :kind_of => String property :scrape_interval, :kind_of => String property :scrape_timeout, :kind_of => String @@ -43,12 +48,15 @@ action :create do description "Prometheus #{new_resource.exporter} exporter" type "simple" user new_resource.user + dynamic_user new_resource.user.nil? environment new_resource.environment exec_start "#{executable_path} #{new_resource.command} #{executable_options}" - private_tmp true - protect_system "strict" - protect_home true - no_new_privileges true + sandbox :enable_network => true + proc_subset new_resource.proc_subset if new_resource.property_is_set?(:proc_subset) + private_devices new_resource.private_devices if new_resource.property_is_set?(:private_devices) + protect_clock new_resource.protect_clock if new_resource.property_is_set?(:protect_clock) + restrict_address_families new_resource.restrict_address_families if new_resource.property_is_set?(:restrict_address_families) + system_call_filter new_resource.system_call_filter if new_resource.property_is_set?(:system_call_filter) end service service_name do @@ -140,7 +148,9 @@ action_class do end def listen_address - if new_resource.address + if true + "127.0.0.1:#{new_resource.port}" + elsif new_resource.address "#{new_resource.address}:#{new_resource.port}" elsif node[:prometheus][:mode] == "wireguard" "[#{node[:prometheus][:address]}]:#{new_resource.port}" diff --git a/cookbooks/systemd/resources/service.rb b/cookbooks/systemd/resources/service.rb index 94d0217c6..662528c2b 100644 --- a/cookbooks/systemd/resources/service.rb +++ b/cookbooks/systemd/resources/service.rb @@ -40,6 +40,7 @@ property :environment, Hash, :default => {} property :environment_file, [String, Hash] property :user, String property :group, String +property :dynamic_user, [true, false] property :working_directory, String property :exec_start_pre, [String, Array] property :exec_start, [String, Array] diff --git a/cookbooks/systemd/templates/default/service.erb b/cookbooks/systemd/templates/default/service.erb index e64ead225..1f11ffbf6 100644 --- a/cookbooks/systemd/templates/default/service.erb +++ b/cookbooks/systemd/templates/default/service.erb @@ -54,6 +54,9 @@ User=<%= @user %> <% if @group -%> Group=<%= @group %> <% end -%> +<% if @dynamic_user -%> +DynamicUser=<%= @dynamic_user %> +<% end -%> <% if @working_directory -%> WorkingDirectory=<%= @working_directory %> <% end -%> -- 2.39.5