[Maria-developers] [GSoC] Kerberize MariaDB -- some unclear point about the project
Hi Wlad and the community, I've developed a Kerberos plugin prototype with both raw API and GSSAPI supported on my own Linux box. The codes are pushed to my private repo already. It is just a prototype, which can handle only the normal case, without any tests in deployed environment. And I know there is a long way to go before accepted I now have a clear knowledge about the control flow of authentication plugin and Kerberos protocol. The working use case is like this: 1. login my computer as, for example, qiush; 2. create a user in MariaDB named qiush; 3. get the initial credential from Kerberos Key Distribution Center (KDC), i.e. tgt; 4. connect mysqld as qiush and now I can login DBMS passwordlessly before tgt expires. Correctly me if I miss something in this case. The exception case is how to get/renew tgt when the original expired. I have created a private repo based on 5.5 release version, which is available at https://launchpad.net/~qiush-summer. For those that concern about our project, you can track my progress. (The reason why I choose 5.5 release version instead of the latest development branch 10.x is that I cannot clone the repo lp:~maria-captains/maria/10.0-base from launchpad and I don't know why. I'll figure it out later if necessary). Some problems (three, exactly) when implementing the toy plugin. The first one is about the private repo and bazaar (I'm a git guy and have little experience working with bazaar). In order to make some demonstrated progress, I push my local update to the private repo each time I create a new commit. It seems the commit number is global (see the screen shot of my private repo history below). Recent revisions 3796. By Shuang Qiu 20 hours ago prototype with GSSAPI enabled 3795. By Shuang Qiu on 2013-06-15 Kerberos plugin prototype with raw krb5 API 3794. By Shuang Qiu on 2013-06-13 doodle 3793. By Michael Widenius on 2013-06-11 Fixed tests that failed on 32 bit because of my earlier fixes of 32 bit limits. 3792. By Sergei on 2013-06-07 MDEV-4468 Assertion `error != 0' fails or timeout occurs on select from a FEDERATED table which points at a non-existent table I'm afraid that my commits may pollute the code base. So the question is that will others (e.g. Sergei since commit 3792) see my changes next time he gets local branch updated. Is it the best practice to use bazaar like this (push after each commit)? If not, could you please give me some suggestion to use bazaar and launchpad correctly in our community? The other two are about the exception case. When get the initial credential from KDC, clients/services are asked for a password or asked to provide a keytab file to derive a long-term key that can be used encrypting messages between clients and KDC. On the server/service side, I think the keytab approach is better. Otherwise, each time we restart the service, a password will be asked. It may be annoying, I think :p. Then how to figure out the name of keytab file? I can come up with three approaches: 1. hard coded the filename and document the keytab file name clearly in the manual for users to follow (not the best choice, I think); 2. use the default Kerberos setting, which is /etc/krb5.keytab when properly configured; 3. make the filename an option in configuration file, e.g. ~/.my.cnf, with a default value /etc/krb5.keytab, since it is the default Kerberos setting. I prefer the third solution. As to the client side, I think both are OK. The problem of keytab choice is the same. Then I try to get some hints from similar password requesting authentication plugin. I read code in plugin/auth_dialog and plugin/auth_examples where server plugin and client plugin are implemented separately. In the client plugin, a external function of type mysql_authenticaton_dialog_ask_t static mysql_authentication_dialog_ask_t ask; can be provided as an alternative to command line input. Should I also implement them in two parts? And also provide the mysql_authentication_dialog_ask_t hook? The last problem. Kerberos requires user to provide a service name to resolve before requesting service ticket. How to name our service? Hard coded it as MYSQL or set in configuration file (I prefer the latter one)? Let me know your thoughts :). Thank you very much and best regards! Sincerely, Shuang
From: Maria-developers [mailto:maria-developers-bounces+wlad=montyprogram.com@lists.launchpad.net] On Behalf Of QIU Shuang Sent: Sonntag, 16. Juni 2013 16:07 To: Vladislav Vaintroub; maria-developers@lists.launchpad.net Subject: [Maria-developers] [GSoC] Kerberize MariaDB -- some unclear point about the project
Hi Wlad and the community,
I've developed a Kerberos plugin prototype with both raw API and GSSAPI supported on my own Linux box. The codes are pushed to my private repo already. It is just a prototype, which can handle only the normal case, without any tests in deployed environment. And I know there is a long way to go before accepted I now have a clear knowledge about the control flow of authentication
Hi Shuang, plugin and Kerberos protocol. Congratulations, that was fast! As we discussed, well probably need just GSSAPI more than raw Kerberos, on the interoperability reasons (Windows-SSPI, Java, everyone knows the GSSAPI blobs, but not the raw kerberos) . Also Kerberos Consortium recommends GSSAPI as portable solution ihttp://www.kerberos.org/software/appskerberos.pdf in Protocol Facilities for Integrating Kerberos, for the cross-platform compatibility, and language interoperability (e.g Java already has support for it)
The working use case is like this: 1. login my computer as, for example, qiush; 2. create a user in MariaDB named qiush; 3. get the initial credential from Kerberos Key Distribution Center (KDC), i.e. tgt; 4. connect mysqld as qiush and now I can login DBMS passwordlessly before tgt expires.
Yes. Details maybe tricky here. I think it is better to use the fully qualified Kerberos name when creating user in mariadb (that is returned by kinit on Linux, and e.g fully qualified domain name on Windows). Trying to make a nicer name, for example by removing domain part could introduce some ambiguity here and different Kerberos users to login as the same.
Correctly me if I miss something in this case. The exception case is how to get/renew tgt when the original expired.
You do not need to be concerned about TGT renewal, this is out of scope for the plugin. TGT needs to be valid at the moment when mysql client connects to mysql server, if something goes wrong, out best bet is to write an "actionable" error message, so user can understand and fix the problem.
I have created a private repo based on 5.5 release version, which is available at https://launchpad.net/~qiush-summer. For those that concern about our project, you can track my progress. (The reason why I choose 5.5 release version instead of the latest development branch 10.x is that I cannot clone the repo lp:~maria-captains/maria/10.0-base from launchpad and I don't know why. I'll figure it out later if necessary).
Some problems (three, exactly) when implementing the toy plugin.
The first one is about the private repo and bazaar (I'm a git guy and have
In order to make some demonstrated progress, I push my local update to the
It seems the commit number is global (see the screen shot of my private repo history below).
Recent revisions 3796. By Shuang Qiu 20 hours ago prototype with GSSAPI enabled 3795. By Shuang Qiu on 2013-06-15 Kerberos plugin prototype with raw krb5 API 3794. By Shuang Qiu on 2013-06-13 doodle 3793. By Michael Widenius on 2013-06-11 Fixed tests that failed on 32 bit because of my earlier fixes of 32 bit
Thanks! I will take a look. Working on 5.5 branch is perfectly fine little experience working with bazaar). private repo each time I create a new commit. limits.
3792. By Sergei on 2013-06-07 MDEV-4468 Assertion `error != 0' fails or timeout occurs on select from a FEDERATED table which points at a non-existent table
I'm afraid that my commits may pollute the code base. So the question is that will others (e.g. Sergei since commit 3792) see my changes next time he gets local branch updated. Is it the best practice to use bazaar like this (push after each commit)? If not, could you please give me some suggestion to use bazaar and launchpad correctly in our community?
The other two are about the exception case.
When get the initial credential from KDC, clients/services are asked for a
Dont be too concerned about it at this stage. It is common to make tens of small commits as long as you polish your patch. If you like to combine 3 patches into one bigger patch right now, you can do that too. For example shell> bzr uncommit -r3793 shell>bzr commit # write some comment shell>bzr push --overwrite This will do the trick. password or asked to provide a keytab file to derive a long-term key that can be used encrypting messages between clients and KDC.
On the server/service side, I think the keytab approach is better. Otherwise, each time we restart the service, a password will be asked. It may be annoying, I think :p.
Then how to figure out the name of keytab file? I can come up with three approaches: 1. hard coded the filename and document the keytab file name clearly in the manual for users to follow (not the best choice, I think); 2. use the default Kerberos setting, which is /etc/krb5.keytab when properly configured; 3. make the filename an option in configuration file, e.g. ~/.my.cnf, with a default value /etc/krb5.keytab, since it is the default Kerberos setting.
For the purpose of the task, user must be identifiable with Kerberos, when MySQL login happens. If there is a problem with that, user needs to fix it. So, I'd say it is outside of the scope, and we should only be concerned about informative error messages.
The last problem. Kerberos requires user to provide a service name to resolve before requesting service ticket. How to name our service? Hard coded it as MYSQL or set in configuration file (I prefer the latter one)?
I like the later one, too. I think the best we can do is this .-MySQL Server gets service principal name via new server variable for service principal name (we can think about good default..) . Server tells client its SPN, by sending (vio->write_packet) the first packet containing null-terminated SPN string. The client side reads this string, and puts it into the correct GSSAPI's function. This would be similar to how Oracle/MySQL Windows authentication works in case of domain authentication (which , is using Kerberos underneath) http://dev.mysql.com/doc/internals/en/authentication-method.html#windows-nat ive-authentication contains a diagram, and the last arrow in this diagram from server to client "auth-method switch to win-auth, may contain a UPN" means exactly that (server packet is sent with null terminated SPN) , even if it is hard to decipher ;) Thanks, Wlad
Hi wlad,
Congratulations, that was fast! Thank you. I know there are still many things to do.
As we discussed, we’ll probably need just GSSAPI more than raw Kerberos, No problem, I'll remove the raw Kerberos part in next iteration.
I think it is better to use the fully qualified Kerberos name when creating user in mariadb
Trying to make a nicer name, for example by removing domain part could introduce some ambiguity here and different Kerberos users to login as the same. I think so. But per my knowledge, the fully qualified name in MariaDB is username@hostname. What about the realm/domain part? I think this may be a gap between MariaDB and Kerberos. One solution I can come up is use username@hostname as MariaDB user and suffixed the realm name after query Kerberos with function `krb5_get_host_realm` (this is a raw API, I think GSSAPI has a correspondent, and will check it later).
TGT needs to be valid at the moment when mysql client connects to mysql server, if something goes wrong, out best bet is to write an "actionable" error message, so user can understand and fix the problem. That's fine.
Thanks! I will take a look. Working on 5.5 branch is perfectly fine No problem for this :).
Thank you very much for all your comments and hints! Sincerely, Shuang On Jun 18, 2013, at 5:48 AM, Vladislav Vaintroub <wlad@montyprogram.com> wrote:
From: Maria-developers [mailto:maria-developers-bounces+wlad=montyprogram.com@lists.launchpad.net] On Behalf Of QIU Shuang Sent: Sonntag, 16. Juni 2013 16:07 To: Vladislav Vaintroub; maria-developers@lists.launchpad.net Subject: [Maria-developers] [GSoC] Kerberize MariaDB -- some unclear point about the project
Hi Wlad and the community,
Hi Shuang,
I've developed a Kerberos plugin prototype with both raw API and GSSAPI supported on my own Linux box. The codes are pushed to my private repo already. It is just a prototype, which can handle only the normal case, without any tests in deployed environment. And I know there is a long way to go before accepted I now have a clear knowledge about the control flow of authentication plugin and Kerberos protocol.
Congratulations, that was fast! As we discussed, we’ll probably need just GSSAPI more than raw Kerberos, on the interoperability reasons (Windows-SSPI, Java, everyone knows the GSSAPI blobs, but not the raw kerberos) . Also Kerberos Consortium recommends GSSAPI as portable solution ihttp://www.kerberos.org/software/appskerberos.pdf in “Protocol Facilities for Integrating Kerberos”, for the cross-platform compatibility, and language interoperability (e.g Java already has support for it)
The working use case is like this: 1. login my computer as, for example, qiush; 2. create a user in MariaDB named qiush; 3. get the initial credential from Kerberos Key Distribution Center (KDC), i.e. tgt; 4. connect mysqld as qiush and now I can login DBMS passwordlessly before tgt expires.
Yes. Details maybe tricky here. I think it is better to use the fully qualified Kerberos name when creating user in mariadb (that is returned by kinit on Linux, and e.g fully qualified domain name on Windows). Trying to make a nicer name, for example by removing domain part could introduce some ambiguity here and different Kerberos users to login as the same.
Correctly me if I miss something in this case. The exception case is how to get/renew tgt when the original expired.
You do not need to be concerned about TGT renewal, this is out of scope for the plugin. TGT needs to be valid at the moment when mysql client connects to mysql server, if something goes wrong, out best bet is to write an "actionable" error message, so user can understand and fix the problem.
I have created a private repo based on 5.5 release version, which is available at https://launchpad.net/~qiush-summer. For those that concern about our project, you can track my progress. (The reason why I choose 5.5 release version instead of the latest development branch 10.x is that I cannot clone the repo lp:~maria-captains/maria/10.0-base from launchpad and I don't know why. I'll figure it out later if necessary).
Thanks! I will take a look. Working on 5.5 branch is perfectly fine
Some problems (three, exactly) when implementing the toy plugin.
The first one is about the private repo and bazaar (I'm a git guy and have little experience working with bazaar). In order to make some demonstrated progress, I push my local update to the private repo each time I create a new commit. It seems the commit number is global (see the screen shot of my private repo history below).
Recent revisions 3796. By Shuang Qiu 20 hours ago prototype with GSSAPI enabled 3795. By Shuang Qiu on 2013-06-15 Kerberos plugin prototype with raw krb5 API 3794. By Shuang Qiu on 2013-06-13 doodle 3793. By Michael Widenius on 2013-06-11 Fixed tests that failed on 32 bit because of my earlier fixes of 32 bit limits. 3792. By Sergei on 2013-06-07 MDEV-4468 Assertion `error != 0' fails or timeout occurs on select from a FEDERATED table which points at a non-existent table
I'm afraid that my commits may pollute the code base. So the question is that will others (e.g. Sergei since commit 3792) see my changes next time he gets local branch updated. Is it the best practice to use bazaar like this (push after each commit)? If not, could you please give me some suggestion to use bazaar and launchpad correctly in our community?
Don’t be too concerned about it at this stage. It is common to make tens of small commits as long as you polish your patch. If you like to combine 3 patches into one bigger patch right now, you can do that too. For example shell> bzr uncommit -r3793 shell>bzr commit # write some comment shell>bzr push --overwrite
This will do the trick.
The other two are about the exception case.
When get the initial credential from KDC, clients/services are asked for a password or asked to provide a keytab file to derive a long-term key that can be used encrypting messages between clients and KDC. On the server/service side, I think the keytab approach is better. Otherwise, each time we restart the service, a password will be asked. It may be annoying, I think :p.
Then how to figure out the name of keytab file? I can come up with three approaches: 1. hard coded the filename and document the keytab file name clearly in the manual for users to follow (not the best choice, I think); 2. use the default Kerberos setting, which is /etc/krb5.keytab when properly configured; 3. make the filename an option in configuration file, e.g. ~/.my.cnf, with a default value /etc/krb5.keytab, since it is the default Kerberos setting.
For the purpose of the task, user must be identifiable with Kerberos, when MySQL login happens. If there is a problem with that, user needs to fix it. So, I'd say it is outside of the scope, and we should only be concerned about informative error messages.
The last problem. Kerberos requires user to provide a service name to resolve before requesting service ticket. How to name our service? Hard coded it as MYSQL or set in configuration file (I prefer the latter one)?
I like the later one, too. I think the best we can do is this .-MySQL Server gets service principal name via new server variable for service principal name (we can think about good default..) . Server tells client its SPN, by sending (vio->write_packet) the first packet containing null-terminated SPN string. The client side reads this string, and puts it into the correct GSSAPI's function.
This would be similar to how Oracle/MySQL Windows authentication works in case of domain authentication (which , is using Kerberos underneath) http://dev.mysql.com/doc/internals/en/authentication-method.html#windows-nat ive-authentication contains a diagram, and the last arrow in this diagram from server to client "auth-method switch to win-auth, may contain a UPN" means exactly that (server packet is sent with null terminated SPN) , even if it is hard to decipher ;)
Thanks, Wlad
participants (2)
-
QIU Shuang
-
Vladislav Vaintroub