Skip to content

Conversation

@adamruzicka
Copy link
Contributor

@adamruzicka adamruzicka commented Nov 20, 2025

Very rough draft at the moment, but the happy path seems to work.

Borrows ideas from theforeman/puppet-foreman#1172 and theforeman/puppet-foreman#1203

TODOs:

  • test on a fresh machine not tainted by previous attempts
  • test hammer part - in theory this could deprecate section 3.4 and step 2 in section 3.5
  • check that it can be turned off
    • ipa users can't log in anymore
    • httpd modules are not loaded (packages are left installed though)
    • sssd config remains modified - the modifications are done in a way we can't easily undo
  • check that it doesn't stomp over user modifications suggested by docs
  • check that pam service override still works in section 3.3

Comment on lines 17 to 26
ipa_manage_sssd:
help: Whether to manage SSSD service and configuration for IPA authentication
action: store_true
pam_service:
help: Name of the PAM service to use for IPA authentication
gssapi_local_name:
help: Whether to use the local name for GSSAPI authentication
action: store_true
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Do we want to explicitly expose those or leave EXTRA_VARS as the only option for overriding those?

Copy link
Member

Choose a reason for hiding this comment

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

It's currently exposed in the Puppet-based installer, but not documented in our docs, so I'd err on the side of leaving it out, but I also don't recall when this is needed.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

but I also don't recall when this is needed

The original redmine which introduced it says it might be useful to workaround bugs like https://bugzilla.redhat.com/show_bug.cgi?id=1787630 . Let's not expose it for the time being

Comment on lines 105 to 109
cmd: |
KRB5CCNAME=KEYRING:session:get-http-service-keytab kinit -k || true
KRB5CCNAME=KEYRING:session:get-http-service-keytab /usr/sbin/ipa-getkeytab -k {{ httpd_ipa_keytab }} -p HTTP/{{ ansible_facts['fqdn'] }}
kdestroy -c KEYRING:session:get-http-service-keytab || true
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This could be probably broken into several individual single-command tasks, but I'm not sure if it's worth it

@adamruzicka adamruzicka force-pushed the external-auth branch 7 times, most recently from 265bc56 to 80a3bcd Compare November 21, 2025 11:53
Comment on lines +17 to +18
- ipa
- ipa_with_api
Copy link
Member

Choose a reason for hiding this comment

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

What is the difference between the two? ipa is UI only, while ipa_with_api does UI and API?

Copy link
Member

Choose a reason for hiding this comment

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

And to extend that, later we can add other methods here, like oidc etc?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ipa is UI only, while ipa_with_api does UI and API?

exactly

later we can add other methods here, like oidc etc?

Yes, that was the intent here

Copy link
Member

@evgeni evgeni Nov 21, 2025

Choose a reason for hiding this comment

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

and those are mutually exclusive, right? as in, there can be only one external auth?

(LDAP probably always works, but that's not terminated on the httpd level)

Copy link
Contributor Author

@adamruzicka adamruzicka Nov 21, 2025

Choose a reason for hiding this comment

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

Correct. I wanted to avoid the situation we had in the old installer where all the methods could be enabled individually, but some conflicted with others.

Comment on lines 22 to 20
pam_service:
help: Name of the PAM service to use for IPA authentication
Copy link
Member

Choose a reason for hiding this comment

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

as there is no foreman user on the new host, one needs to pass something else here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There is no foreman user, but as part of this we deploy a configuration for a foreman pam service, which seems to be enough.

Copy link
Member

Choose a reason for hiding this comment

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

Interesting!

@evgeni
Copy link
Member

evgeni commented Nov 21, 2025

While I am not a fan of adding another non-containerized service (sssd), I guess that's the only way to make it work right now.

As such this looks like the right way to me

Comment on lines +45 to +50
- name: Create PAM service file for IPA authentication
ansible.builtin.template:
src: pam_service.j2
dest: "/etc/pam.d/{{ httpd_ipa_pam_service }}"
mode: "0644"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

In theory this is not needed if httpd_ipa_pam_service != foreman

Copy link
Member

Choose a reason for hiding this comment

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

But when is it not foreman?

Copy link
Contributor Author

@adamruzicka adamruzicka Nov 24, 2025

Choose a reason for hiding this comment

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

Then the service either needs to be defined manually by the user as a yet another pam service or it has to be the name of a user-created HBAC service in ipa

Edit: in either case, deploying our custom service config shouldn't be needed, but also doesn't really hurt anything

@adamruzicka adamruzicka marked this pull request as ready for review November 24, 2025 09:47
Comment on lines 53 to 55
| `--foreman-ipa-authentication` | Enable configuration for external authentication via IPA for web UI | `--external-authentication=ipa` |
| `--foreman-ipa-authentication-api` | Enable configuration for external authentication via IPA for web UI and API | `--external-authentication=ipa_with_api` |
| `--pam-service` | PAM service used for host-based access control in IPA | `--foreman-pam-service` |
Copy link
Member

Choose a reason for hiding this comment

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

you have the columns the wrong way round, the last column is the "old version", the first is "this is how it's done now"

Copy link
Member

Choose a reason for hiding this comment

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

I'd also probably fold the two "authentication" ones into one line, given the difference is minimal (and just explain it in the description)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

@evgeni
Copy link
Member

evgeni commented Nov 24, 2025

Ansible/structure wise this is fine.

I think it should get a short reference to https://docs.theforeman.org/3.16/Configuring_User_Authentication/index-katello.html#enrolling-foreman-server-in-freeipa-domain as in "this is how you need to prepare you machine for this to work".

And then someone who knows Krb should verify this actually works fine (which I did not)

@adamruzicka adamruzicka force-pushed the external-auth branch 2 times, most recently from bdf0d0f to 9da9011 Compare November 24, 2025 12:56
@adamruzicka adamruzicka force-pushed the external-auth branch 5 times, most recently from ec99bdc to bcddb3a Compare December 4, 2025 14:14
@lhellebr
Copy link

The correct workflow here is to do exactly what documentation says currently (Chapter 3. Configuring Kerberos SSO with Identity Management in Satellite) but in the satellite-installer step, run the foremanctl instead?

@adamruzicka
Copy link
Contributor Author

Yes, although the options don't map one to one between the installer and foremanctl. See docs/parameters.md for details on how they translate.

@lhellebr
Copy link

Thanks, @adamruzicka , I have successfully verified that this basically works with IDM in UI, using both user/pass and kinit. There's more to do but it looks good.
Question, is there a way to reverse the setting, that is, disable IDM/AD/Kerberos auth? There was --reset-foreman-ipa-authentication in the classical installer. Is it --reset-external-authnetication? I can't see it in this PR but it's in the --help, so is it something more general that also works in this case?

@adamruzicka
Copy link
Contributor Author

--reset-external-authnetication should work to some extent. The external authentication will be disabled, some of the extra files (like apache configuration drop-ins will be removed), but some things (like sssd config) will remain in the modified state as we can't reasonably know the previous state

@lhellebr
Copy link

Then it should be documented that this is irreversible and the reset operation leaves the machine in an undefined state. Although I understand it "works" and AFAIK is the same as in classical installer.

@lhellebr
Copy link

Update, it also works with IDM using API. Just AD to do.

@ekohl
Copy link
Member

ekohl commented Dec 12, 2025

When I read https://docs.theforeman.org/3.17/Configuring_User_Authentication/index-katello.html we do document the reset "softly". Not an explicit procedure. IMHO this is something we should change for foremanctl: either have an explicit disable procedure or not at all. In the short term I'm OK with no documented/supported procedure and we can re-evaluate this when there are questions about it.

@aneta-petrova now that we have the new foremanctl docs structure, do you think we could start updating https://docs.theforeman.org/nightly/Configuring_User_Authentication/index-foremanctl-katello.html#configuring-kerberos-sso-with-FreeIPA-in-foreman and prepare the docs PR? It'll be a good way to verify we've covered all the user stories. Ideally I'd like to merge them in tandem.

@aneta-petrova
Copy link
Member

@aneta-petrova now that we have the new foremanctl docs structure, do you think we could start updating https://docs.theforeman.org/nightly/Configuring_User_Authentication/index-foremanctl-katello.html#configuring-kerberos-sso-with-FreeIPA-in-foreman and prepare the docs PR? It'll be a good way to verify we've covered all the user stories. Ideally I'd like to merge them in tandem.

Sure. Can you create a ticket that we could refine and plan for a future sprint?

@lhellebr
Copy link

lhellebr commented Dec 15, 2025

Verified with UPstream + packit on RHEL9. According to documentation, set up {ipa, ipa with api, ad} and tested using {webui, hammer, curl}. In WebUI, I tested both using kinit + browser negotiate and inserting credentials directly to the form. In all cases, I've been able to login except for cases where I used API or Hammer and ipa_with_api wasn't configured - which is correct.

Steps:

  1. have a RHEL machine with RHEL repos enabled
  2. enable foremanctl copr repo and packit repo for this PR
  3. dnf install -y foremanctl
  4. foremanctl deploy --external-authentication {ipa,ipa-with-api} --add-feature hammer (optionally with --pam-service satellite-prod)
  5. login to WebUI using kinit or credentials from the auth source
# foremanctl deploy --help | grep auth
                         [--external-authentication {ipa,ipa_with_api}]
                         [--reset-external-authentication]
  --external-authentication {ipa,ipa_with_api}
                        External authentication method to use
  --reset-external-authentication
                        Reset external_authentication
                        Name of the PAM service to use for IPA authentication
  1. hammer bookmark list # notice that hammer has been setup with sessions and negotiation automatically
  2. curl -k -u : --negotiate -X GET https://$(hostname)/api/v2/users/extlogin --cookie-jar jar
  3. curl -k -X GET https://$(hostname)/api/v2/hosts --cookie jar
  4. foremanctl deploy --reset-external-authentication
  5. Can't login anymore

I've hit an unrelated issue when setting up AD and reported it as [0], it's not a blocker for this PR.
[0] https://issues.redhat.com/browse/SAT-41186

@adamruzicka
Copy link
Contributor Author

2025-12-17 13:45:55.118 logging.py        INFO   tar: foremanctl-1.0.0-127-g8380644/build/collections/foremanctl/ansible_collections/community/general/tests/unit/plugins/modules/interfaces_file/interfaces_file_fixtures/golden_output/no_leading_spaces_set_aggi_and_eth0_mtu.exceptions.txt.license: file name is too long (cannot be split); not dumped
2025-12-17 13:45:55.118 logging.py        INFO   tar: foremanctl-1.0.0-127-g8380644/build/collections/foremanctl/ansible_collections/community/general/tests/unit/plugins/modules/interfaces_file/interfaces_file_fixtures/golden_output/no_leading_spaces_add_and_delete_aggi_up.exceptions.txt.license: file name is too long (cannot be split); not dumped
2025-12-17 13:45:55.163 logging.py        INFO   tar: Exiting with failure status due to previous errors
2025-12-17 13:45:55.163 logging.py        INFO   make: *** [Makefile:9: foremanctl-1.0.0-127-g8380644.tar.gz] Error 2
2025-12-17 13:45:55.164 commands.py       ERROR  Command 'make dist' failed.

Uhh, what?

@adamruzicka adamruzicka force-pushed the external-auth branch 2 times, most recently from dccf29c to 77db6fc Compare December 17, 2025 14:19
@adamruzicka
Copy link
Contributor Author

Now based on top of #362

@lhellebr
Copy link

QA ACK

@aneta-petrova
Copy link
Member

theforeman/foreman-documentation#4543 has received all the necessary acks and is ready to be merged after this PR is merged.

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.

5 participants