Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes #29974 - allow subnet helpers #7713

Merged

Conversation

lzap
Copy link
Member

@lzap lzap commented Jun 1, 2020

SSIA

@theforeman-bot
Copy link
Member

Issues: #29974

@@ -172,6 +172,6 @@ def get_features
end

class Jail < ::Safemode::Jail
allow :id, :name
allow :id, :name, :hostname, :hosts_count
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can it be a problem that Katello also defines the hostname?
https://github.com/Katello/katello/blob/a9abccc2c10f5f2c1194d564834d131d57b28401/app/models/katello/concerns/smart_proxy_extensions.rb#L336-L338

Either way, after merging this that can be removed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we need the hosts_count?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will do a followup PR into Katello.

That hosts_count was added by accident, not needed.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lzap lzap force-pushed the allow-bootdisk-efi-macros-29974 branch from f436b8d to e30c1ce Compare June 2, 2020 09:03
@@ -172,6 +172,6 @@ def get_features
end

class Jail < ::Safemode::Jail
allow :id, :name
allow :id, :name, :hostname, :hosts_count, :setting
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does setting allow to retrieve any secret settings?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It allows retrieving settings of a smart proxy feature. I don't think those contain any secrets

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we perhaps expose those explicitly? Features are just strings and exposed on the individual proxies without any authentication so that's IMHO safe. If you're talking about exposed settings from a proxy then those can contain private information and they're only available via an authenticated endpoint (though I'm not aware of any secrets being passed now).

Copy link
Contributor

@adamruzicka adamruzicka Jun 3, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From my testing machine:

SmartProxyFeature.all.each { |f| puts "#{f.feature.name}: #{f.settings}" }
Pulp: {"pulp_url"=>"https://centos7-katello-nightly-stable.example.com/pulp"}
Pulpcore: {"pulp_url"=>"https://centos7-katello-nightly-stable.example.com", "mirror"=>false, "content_app_url"=>"https://centos7-katello-nightly-stable.example.com/pulp/content"}
TFTP: {"tftp_servername"=>nil}
Puppet CA: {"puppet_url"=>"https://centos7-katello-nightly-stable.example.com:8140", "use_provider"=>["puppetca_hostname_whitelisting", "puppetca_http_api"]}
Puppet: {"puppet_url"=>"https://centos7-katello-nightly-stable.example.com:8140", "use_provider"=>["puppet_proxy_puppet_api"]}
Logs: {}
Templates: {}
HTTPBoot: {"http_port"=>8000, "https_port"=>9090}

it looks like those don't contain any secrets, but that is no guarrantee that they never will

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://github.com/theforeman/smart_proxy_pulp/blob/55ff29f4cfab971f71bc00273c7623ee8dc5af96/lib/smart_proxy_pulp_plugin/pulpcore_plugin.rb#L17-L18 does expose a username/password. It's mostly used in the development workflow if you don't have certificates set up so you won't see it in production, but exposing this is a security risk.

Another thing to consider is that these settings are IMHO internal implementation details. You should always wrap them in high level logic. For example, the puppet server url has a one that also provides compatibility with older releases which didn't expose this:

def puppet_server_uri
return unless puppet_proxy
url = puppet_proxy.setting('Puppet', 'puppet_url')
url ||= "https://#{puppet_proxy}:8140"
URI(url)
end

That particular helper should be exposed rather than raw settings.

👎 on exposing setting.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok how about that, I have implemented whitelisting.

@lzap lzap force-pushed the allow-bootdisk-efi-macros-29974 branch from e30c1ce to 1194a15 Compare June 3, 2020 12:52
"https_port",
]
def safe_setting(feature, setting)
raise ::Foreman::Exception.new(N_("Setting is not whitelisted: %s"), ALLOWED_SETTINGS) unless ALLOWED_SETTINGS.include?(setting)
Copy link
Contributor

@adamruzicka adamruzicka Jun 3, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This shows what settings are allowed, but not which setting was actually requested

::Foreman::Exception.new(N_("Setting is not whitelisted: %s"), ALLOWED_SETTINGS).message
=> "ERF42-4295 [Foreman::Exception]: Setting is not whitelisted: [\"http_port\", \"https_port\"]"

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixing and adding tests for this.

@lzap lzap force-pushed the allow-bootdisk-efi-macros-29974 branch from 1194a15 to 5361a33 Compare June 3, 2020 13:07
@lzap
Copy link
Member Author

lzap commented Jun 3, 2020

Rebased, can I get a quick blessing for this @tbrisker and @ekohl ? This patch is actually needed to have bootdisk working with EFI HTTP BOOT. Added tests so we are safe.

Copy link
Member

@ekohl ekohl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👎 because I still think explicit wrappers are better. For example, this doesn't look at the feature at all. You will also end up with duplicated logic.

if host.subnet&.httpboot?
if host.pxe_loader =~ /UEFI HTTPS/
port = host.subnet.httpboot.setting(:HTTPBoot, 'https_port') || raise(::Foreman::Exception.new(N_("HTTPS boot requires proxy with httpboot feature and https_port exposed setting")))
else
port = host.subnet.httpboot.setting(:HTTPBoot, 'http_port') || raise(::Foreman::Exception.new(N_("HTTP boot requires proxy with httpboot feature and http_port exposed setting")))
end
hostname = URI.parse(host.subnet.httpboot.url).hostname
self.class.all_loaders_map(architecture, "#{hostname}:#{port}")[host.pxe_loader]
else
raise(::Foreman::Exception.new(N_("HTTP UEFI boot requires proxy with httpboot feature"))) if host.pxe_loader =~ /UEFI HTTP/
self.class.all_loaders_map(architecture)[host.pxe_loader]
end

That logic block contains a lot of the same things. We've already seen multiple times that users couldn't even manage to debug that error message. If we expose raw settings it'll be even harder. The wrapper can raise a proper error.

@lzap
Copy link
Member Author

lzap commented Jun 4, 2020

Okay, I've extracted this into two methods. How about now?

@lzap
Copy link
Member Author

lzap commented Jun 4, 2020

Tests are passing now @ekohl

Copy link
Contributor

@adamruzicka adamruzicka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It exposes all the settings we need in a safe manner without exposing things we don't need. 👍 from me

Copy link
Member

@ekohl ekohl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! @tbrisker any last thoughts?

@@ -100,6 +100,14 @@ def setting(feature, setting)
smart_proxy_features.find_by(:feature_id => Feature.find_by(:name => feature)).try(:settings).try(:[], setting)
end

def httpboot_http_port
setting(:HTTPBoot, 'http_port') || raise(::Foreman::Exception.new(N_("HTTP boot requires proxy with httpboot feature and http_port exposed setting")))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to check if the proxy has the appropriate feature?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIRC the data model is that the settings are stored in the Feature model. So having a setting implies the feature. It may be useful to check it separate when you want to raise more explicit exceptions. I can imagine a FeatureMissingException or something. However, that's not a requirement for this PR.

Copy link
Member Author

@lzap lzap Jun 4, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code actually does this. Method settings uses try. If you scroll to the right, you will see the error saying either feature is missing or port is not exposed.

@adamruzicka
Copy link
Contributor

Katello failures seem unrelated, merging

@adamruzicka adamruzicka merged commit 89c1e28 into theforeman:develop Jun 5, 2020
@adamruzicka
Copy link
Contributor

Thank you @lzap!

@lzap lzap deleted the allow-bootdisk-efi-macros-29974 branch June 5, 2020 07:49
lzap added a commit to lzap/foreman that referenced this pull request Jun 5, 2020
@lzap
Copy link
Member Author

lzap commented Jun 5, 2020

tbrisker pushed a commit that referenced this pull request Jun 7, 2020
MariaAga pushed a commit to MariaAga/foreman that referenced this pull request Jun 17, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
6 participants