This change allows you to have GSSAPI authentication and multiple hubs behind the same DNS name by making sessions "sticky".
The Problem
python-gssapi always resolves the hostname of the machine you're trying to talk to in order to obtain its kerberos ticket. With python-krbV this was controllable from the Koji client by using the krb_rdns = false and krb_canon_host = false options, but those options don't work for python-gssapi (see issue #2250). The only way I know of right now to control this behavior is by setting rdns = false in /etc/krb5.conf, but this would affect all kerberos requests on that machine and we can't do this on user's machines that have the Koji CLI installed.
If we can't set krb_rdns = false in the CLI, the Hubs need to have a keytab with their real hostnames (as opposed to the DNS alias) in order for the authentication to work. When the Koji CLI is used, a session is started with kojihub.example.com. This DNS name is resolved to one of the two Hubs (let's say kojihub01.example.com), and a kerberos ticket is obtained for it. When the CLI's actual request is sent, kojihub.example.com is resolved again and this time you might get a different Hub (kojihub02.example.com). When kojihub02.example.com gets the request, it will receive an authorization header for kojihub01.example.com, which it can't decrypt and therefore the request will fail. Sometimes you'll get lucky and all your requests will go to the same hub, but this is non-deterministic.
This means you can either have GSSAPI authentication or multiple Koji Hubs, but not both. I want both.
My Solution
The Koji code needs to be modified to only resolve the Hub's name once and use that resolution for the kerberos authentication and all subsequent requests withing the same session, guaranteeing that they all go to the same Hub. In lines 22-30 of koji/__init__.py , the hub's alias is extracted and resolved to all the IP addresses that are behind it. Those IPs are tested to see if they have a listening service, and the first one that does is chosen as the hub to talk to. In line 51, the Host header is set to the original hub alias so that SSL certificate validation will still work as expected. Note that for this to work, a new dependency (python-requests-toolbelt) has to be introduced. The original hub alias is preserved to be displayed for cosmetics purposes (line 6 of cli/koji_cli/commands.py) and also so that subsessions (created by Koji Builders) have the chance to get started on a different hub (line 42 of koji/__init__.py).
This change allows you to have GSSAPI authentication and multiple hubs behind the same DNS name by making sessions "sticky".
The Problem
python-gssapialways resolves the hostname of the machine you're trying to talk to in order to obtain its kerberos ticket. Withpython-krbVthis was controllable from the Koji client by using thekrb_rdns = falseandkrb_canon_host = falseoptions, but those options don't work forpython-gssapi(see issue #2250). The only way I know of right now to control this behavior is by settingrdns = falsein/etc/krb5.conf, but this would affect all kerberos requests on that machine and we can't do this on user's machines that have the Koji CLI installed.If we can't set
krb_rdns = falsein the CLI, the Hubs need to have a keytab with their real hostnames (as opposed to the DNS alias) in order for the authentication to work. When the Koji CLI is used, a session is started with kojihub.example.com. This DNS name is resolved to one of the two Hubs (let's say kojihub01.example.com), and a kerberos ticket is obtained for it. When the CLI's actual request is sent, kojihub.example.com is resolved again and this time you might get a different Hub (kojihub02.example.com). When kojihub02.example.com gets the request, it will receive an authorization header for kojihub01.example.com, which it can't decrypt and therefore the request will fail. Sometimes you'll get lucky and all your requests will go to the same hub, but this is non-deterministic.This means you can either have GSSAPI authentication or multiple Koji Hubs, but not both. I want both.
My Solution
The Koji code needs to be modified to only resolve the Hub's name once and use that resolution for the kerberos authentication and all subsequent requests withing the same session, guaranteeing that they all go to the same Hub. In lines 22-30 of
koji/__init__.py, the hub's alias is extracted and resolved to all the IP addresses that are behind it. Those IPs are tested to see if they have a listening service, and the first one that does is chosen as the hub to talk to. In line 51, the Host header is set to the original hub alias so that SSL certificate validation will still work as expected. Note that for this to work, a new dependency (python-requests-toolbelt) has to be introduced. The original hub alias is preserved to be displayed for cosmetics purposes (line 6 ofcli/koji_cli/commands.py) and also so that subsessions (created by Koji Builders) have the chance to get started on a different hub (line 42 ofkoji/__init__.py).