FreeIPA: whoami via curl

Assuming PRINCIPAL is your Kerberos principal and $IPASERVER is the FQDN of your server, you can query your identity on the IPA server via curl:

kinit $PRINCIPAL
curl -k -H referer:https://$IPASERVER/ipa   -H "Content-Type:application/json"    -H "Accept:applicaton/json"   --negotiate -u :   --cacert /etc/ipa/ca.crt   -d  '{"method":"whoami","params":[[],{"version": "2.220"}],"id":0}'   -X POST    https://$IPASERVER/ipa/json
{"result": {"object": "user", "command": "user_show/1", "arguments": ["ayoung"]}, "version": "4.5.4", "error": null, "id": 0, "principal": "ayoung@YOUNGLOGIC.COM"}

This is handy if your system is not registered as an IPA client.

To fetch by username:

curl -k -H referer:https://$IPASERVER/ipa   -H "Content-Type:application/json"    -H "Accept:applicaton/json" --negotiate -u : --cacert /etc/ipa/ca.crt -d '{"method": "user_show", "params": [[ "ayoung" ], { "all": true, "rights": true }  ]}'  -X POST    https://$IPASERVER/ipa/json

Talking to FreeIPA with python-requests

The code that Rich M gave me a while back has bit rotted. At some point, I need to get an updated version, but until then, I can continue to talk to the FreeIPA server using Python and the Requests library. In the future, I can get a session cookie, but for now, python3-request-gssapi will work to authenticate me, provided I have a valid TGT.

I pulled the requests-gssapi library from Koji, as it does not currently ship in any of the RHEL8 repos. Here is the one I installed.

https://koji.fedoraproject.org/koji/buildinfo?buildID=1371255

Note that this quick-and-dirty code runs on the IPA server itself. A better approach would be to read the Server name out of /etc/ipa/default.conf.

#!/bin/python3
import requests
from requests_gssapi import HTTPSPNEGOAuth
import socket
hostname = socket.gethostname()
url = "https://%s/ipa/json" % hostname
referer =  "https://%s/ipa" % hostname
body = {"method":"user_find","params":[[""],{}],"id":0}
 
r = requests.post(url,
                  json = body,
                  auth=HTTPSPNEGOAuth(),
                  headers = {
                    'Content-Type': 'application/json',
                    'Accept': 'applicaton/json',
                    'referer': referer})
print(r.status_code)
if r.status_code  == 200:
    print(r.text)

Ansible and FreeIPA Part-1

Ansible is a workflow engine. I use it to do work on my behalf.

FreeIPA is an identity management system. It allows me to manage the identities of users in my organization

How do I get the two things to work together? The short answer is that it is trivial to do using Ansible Engine. It is harder to do using Ansible tower.

Edit: Second part is here. Third part is coming.

Continue reading

Recursive DNS and FreeIPA

DNS is essential to Kerberos. Kerberos Identity for servers is based around host names, and if you don’t have a common view between client and server, you will not be able to access your remote systems. Since DNS is an essential part of FreeIPA, BIND is one of the services integrated into the IPA server.

When a user wants to visit a public website, like this one, they click a link or type that URL into their browsers navigation bar. The browser then requests the IP address for the hostname inside the URL from the operating system via a library call. On a Linux based system, the operating system makes the DNS call to the server specified in /etc/resolv.conf. But what happens if the DNS server does not know the answer? It depends on how it is configured. In the simple case, where the server is not allowed to make additional calls, it returns a response that indicates the record is not found.

Since IPA is supposed to be the one-source-of-truth for a client system, it is common practice to register the IPA server as the sole DNS resolver. As such, it cannot just short-circuit the request. Instead, it performs a recursive search to the machines it has set up as Forwarders. For example, I often will set up a sample server that points to the google resolver at 8.8.8.8. Or, now CloudFlare has DNS privacy enabled, I might use that.

This is fine inside controlled environments, but is sub-optimal if the DNS portion of the IPA server is accessible on the public internet. It turns out that forwarding requests allows a DNS server to be used to attack these DNS servers via a distributed denial of service attack. In this attack, the attackers sends the request to all DNS servers that are acting as forwarders, and these forwarders hammer on the central DNS servers.

If you have set up a FreeIPA server on the public internet, you should plan on disabling Recursive DNS queries. You do this by editing the file /etc/named.conf and setting the values:

allow-recursion {"none";};
recursion no;

And restarting the named service.

And then everything breaks. All of your IPA clients can no longer resolve anything except the entries you have in your IPA server.

The fix for that is to add the (former) DNS forward address as a nameserver entry in /etc/resolv.conf on each machine, including your IPA server. Yes, it is a pain, but it limits the query capacity to only requests local to those machines. For example, if my IPA server is on 10.10.2.1 (yes I know this is not routable, just for example) my resolve.conf would look like.

search younglogic.com
nameserver 10.10.2.1
nameserver 1.1.1.1

If you wonder if your Nameserver has this problem, use this site to test it.

Different CloudForms Catalogs for Different Groups

One of the largest value propositions of DevOps is the concept of Self Service provisioning. If you can remove human interaction from resource allocation, you can reduce both the response time and the likelihood of error in configuration. Red Hat CloudForms has a self service feature that allows a user to select from predefined services. You may wish to show different users different catalog items. This might be for security reasons, such as the set of credentials required and provided, or merely to reduce clutter and focus the end user on specific catalog items. Perhaps some items are still undergoing testing and are not ready for general consumption.

Obviously, these predefined services may not match your entire user population.

I’ve been working on setting up a CloudForms instance where members of different groups see different service catalogs. Here is what I did.
Continue reading