Skip to content

Conversation

@adamlazik1
Copy link
Contributor

No description provided.

@adamlazik1
Copy link
Contributor Author

Only drafting stage.

Comment on lines 161 to 165
ssh_options << "-o CertificateFile=#{@client_ca_cert_file}" if @use_ssh_certificates && @client_ca_cert_file
ssh_options << "-o IdentitiesOnly=yes"
ssh_options << "-o StrictHostKeyChecking=accept-new"
ssh_options << "-o UserKnownHostsFile=#{prepare_known_hosts}" if @host_public_key
ssh_options << "-o UserKnownHostsFile=#{@client_ca_known_hosts_file}" if @use_ssh_certificates && @client_ca_known_hosts_file
ssh_options << "-o UserKnownHostsFile=#{prepare_known_hosts}" if !@use_ssh_certificates && @host_public_key
Copy link
Contributor

Choose a reason for hiding this comment

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

If client_ca_cert_file are client_ca_known_hosts_file are set, but the client doesn't accept them, will it fallback to traditional non-ca pubkey authentication?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I will need to test this once I have the ssh cert setup in a functional state.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It appears that the known hosts file does not need to exist at all, but the authentication seems to fail if the client does not accept the certificate. I will do some further testing, but I would say that authentication attempt failing upon not accepting the certificate is the desired outcome in regards to security.

@adamlazik1 adamlazik1 force-pushed the ssh-cert-support branch 2 times, most recently from 3103fb7 to ca0debd Compare June 10, 2025 10:30
@adamlazik1 adamlazik1 force-pushed the ssh-cert-support branch 3 times, most recently from 10ac419 to dd262da Compare June 19, 2025 14:53
@adamlazik1
Copy link
Contributor Author

I will keep this in draft because there will be four PRs in total that should get merged at roughly the same time, but I do believe that this is now ready for review.

@adamlazik1 adamlazik1 force-pushed the ssh-cert-support branch 3 times, most recently from 1702658 to d3f27fa Compare July 11, 2025 06:46
@adamlazik1 adamlazik1 marked this pull request as ready for review July 11, 2025 06:47
Comment on lines +24 to +26
def cert_file
File.expand_path("#{private_key_file}-cert.pub")
end
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Should we require this strict naming convention for cert file
similarly as we do for public key file, or should we make this an editable
value in settings, with this format being the possible default?

if @host_public_key
ssh_options << "-o UserKnownHostsFile=#{prepare_known_hosts}"
elsif @client_ca_known_hosts_file
ssh_options << "-o UserKnownHostsFile=#{@client_ca_known_hosts_file}"
Copy link
Contributor Author

Choose a reason for hiding this comment

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

If we have a known_hosts file with cert authorities listed, should we change StrictHostKeyChecking to yes? To me, it doesn't make much sense to have it otherwise.

Choose a reason for hiding this comment

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

IMO yes. Otherwise, we get "if you trust this cert, connect and if you don't, connect anyway".

Copy link
Contributor

@adamruzicka adamruzicka Jul 11, 2025

Choose a reason for hiding this comment

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

For host keys, those should be all the combinations that can happen:

Proxy Host Result
No record for host plain SSH key TOFU - success + save key
Record for host plain SSH key, matching record success
Record for host plain SSH key, not matching record failure
CA cert plain SSH key Fallback to rows 1-3 failure
CA cert trusted certificate success
CA cert untrusted certificate failure
No record for host, no CA cert untrusted certificate Fallback to row 1
Record for host, no CA cert untrusted certificate Fallback to rows 2-3

Could we agree that this table describes the expected behaviour?

One could argue that proxy expecting a cert and host not providing any (row 4) should fail rather than falling back to traditional pubkey auth.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I too would say that row 4 could fail, but there is currently option to only have one host CA per smart proxy so it would be setting behavior for all hosts that use that proxy for REX. That is probably the only point that I see why it should fallback to plain SSH key instead of fail.

Copy link
Contributor Author

@adamlazik1 adamlazik1 Jul 14, 2025

Choose a reason for hiding this comment

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

Until we decide on one or the other, I will treat the expected behavior of row 4 to be failure. I updated the StrictHostKeyChecking param accordingly. I will also make the same edits to ansible.

Copy link
Contributor

Choose a reason for hiding this comment

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

So row 4 should indeed result in a failure, added two more rows to the table describing one other case that we previously missed.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I can confirm that rows 7 and 8 also behave as intended, so the behavior of the whole feature should work as expected.

@client_ca_known_hosts_file = settings.ssh_ca_known_hosts_file
@client_ca_public_key_file = settings.ssh_user_ca_public_key_file
@client_ca_cert_file = settings.ssh_ca_cert_file
@client_cert_file = Proxy::RemoteExecution::Ssh.cert_file

Choose a reason for hiding this comment

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

Why do you treat these inconsistently? There is also Proxy::RemoteExecution::Ssh.ca_public_key_file but you don't use it. And for the others, there is no such method.

Copy link
Contributor Author

@adamlazik1 adamlazik1 Jul 11, 2025

Choose a reason for hiding this comment

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

It relates to my question to the comment above: #126 (comment)

cert_file is, for now, a non-editable value whose name depends on the private key file, so it is not in settings. Personally, I do not see any problem to making the cert file name an editable value, I just wanted to confirm first whether there are any objections against it. For example, public key file name is also a non-editable value and depends on the private key file.

@adamlazik1 adamlazik1 force-pushed the ssh-cert-support branch 2 times, most recently from c3b0ef1 to f8928c2 Compare July 14, 2025 14:56
@adamlazik1
Copy link
Contributor Author

Switching back to draft since the feature got postponed to 3.16

@adamlazik1 adamlazik1 marked this pull request as draft July 21, 2025 09:05
@lhellebr
Copy link

lhellebr commented Dec 3, 2025

I have been able to verify the SSH CA cert feature as a complex of the following 4 PRs:
#126
theforeman/foreman#10571
theforeman/foreman_remote_execution#977
theforeman/puppet-foreman_proxy#867

Including the following use cases:
SSH REX
Ansible REX
Pull mode REX
Cockpit

Including hosts created by:
Global registration
Provisioning

Including scenarios:
SSH CA on Satellite side
SSH CA on host side
SSH CA on both sides

Both positive scenarios and negative scenarios, that is incorrect CA, incorrect cert, incorrect principal.

=> ACK to this PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants