-
Notifications
You must be signed in to change notification settings - Fork 4.8k
KDC setup for Linux #6158
KDC setup for Linux #6158
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| [kdcdefaults] | ||
| kdc_ports = 88 | ||
| kdc_tcp_ports = 88 | ||
|
|
||
| [realms] | ||
| TEST.COREFX.NET = { | ||
| acl_file = /var/kerberos/krb5kdc/kadm5.acl | ||
| dict_file = /usr/share/dict/words | ||
| admin_keytab = /var/kerberos/krb5kdc/kadm5.keytab | ||
| supported_enctypes = aes256-cts:normal aes128-cts:normal des3-hmac-sha1:normal arcfour-hmac:normal camellia256-cts:normal camellia128-cts:normal des-hmac-sha1:normal des-cbc-md5:normal des-cbc-crc:normal | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| [kdcdefaults] | ||
| kdc_ports = 750,88 | ||
|
|
||
| [realms] | ||
| TEST.COREFX.NET = { | ||
| database_name = /var/lib/krb5kdc/principal | ||
| admin_keytab = FILE:/etc/krb5kdc/kadm5.keytab | ||
| acl_file = /etc/krb5kdc/kadm5.acl | ||
| key_stash_file = /etc/krb5kdc/stash | ||
| kdc_ports = 750,88 | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this line required here? It feels like it should be just using the equivalent one from [kdcdefaults], no?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is default kdc.conf file generated with the KDC installation on Ubuntu/Debian (With required realm name changed). |
||
| max_life = 10h 0m 0s | ||
| max_renewable_life = 7d 0h 0m 0s | ||
| master_key_type = des3-hmac-sha1 | ||
| supported_enctypes = aes256-cts:normal arcfour-hmac:normal des3-hmac-sha1:normal des-cbc-crc:normal des:normal des:v4 des:norealm des:onlyrealm des:afs3 | ||
| default_principal_flags = +preauth | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A lot of lines that are present in the ubuntu file are missing from the centos one. Why?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These are default kdc.conf files generated by the MIT KDC installation. Yes, the file on CentOS/RHEL is significantly different than that in Ubuntu/Debian out of the box. |
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,11 +1,12 @@ | ||
| #!/bin/bash | ||
| #!/usr/bin/env bash | ||
|
|
||
| OS=`cat /etc/os-release | grep "PRETTY_NAME" | sed 's/PRETTY_NAME=//g' | sed 's/["]//g' | awk '{print $1}'` | ||
| OS=`cat /etc/os-release | grep "^ID=" | sed 's/ID=//g' | sed 's/["]//g' | awk '{print $1}'` | ||
| echo -e "Operating System: ${OS}\n" | ||
|
|
||
| realm="TEST.COREFX.NET" | ||
|
|
||
| principal1="HOST/host.test.corefx.net" | ||
| principal2="HTTP" | ||
| principal1="TESTHOST/testfqdn.test.corefx.net" | ||
| principal2="TESTHTTP" | ||
| krb_user="krb_user" | ||
| password="password" | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If someone runs this script, is there any danger that it'll open their machine up to any kind of attack? e.g. could it give someone with these fake creds access to anything on their machine? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. +1 on @stephentoub's question. I'm not convinced creating even low privilege accounts is a safe thing to do
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This will enable getting a Kerberos ticket for the TEST.COREFX.NET realm but there won't be any server that would trust that ticket.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @morganbr can also chime in if we have missed something
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Including this machine? My concern isn't that some other machine would trust these credentials, but rather than this machine would trust them, and that, for example, after I've run this script on my Linux machine that someone else can use these wide-open credentials to gain some kind of access, even limited access, to my Linux machine.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right.. I meant even this machine. @rahulkotecha there is no home directory etc for this user but you should verify if telnet, SSH etc are kerberized by default and can somehow allow a login
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Verified on Ubuntu, Debian, CentOS and RHEL.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for confirming, @rahulkotecha They probably all need passwd entry that maps to the Kerberos principal. One minor change we should make is to use non-standard service principal names. eg. change HTTP to TestHTTP etc. This will further reduce probability of a regular service using the service principals we are creating. cc: @joshfree
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I know steps have been taken to mitigate concerns related to this, but are there additional ones we can take? For example, do these credentials need to be hard coded, or could the setup script generate them randomly?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We couldn't think of a way to create a random password that the test case also would be aware of. @stephentoub, if the test case is always running elevated, we can store a random password in a well-known file which requires root access for reading. But if we expect the 3rd party dev experience running tests outside CI to run non-elevated, this would be an issue.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Right now the password is in a web page for the whole world to see. Even if a random one is written to a local file that doesn't require root access, isn't that still much better?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agreed :) @rahulkotecha I think we should make this change
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Filed #6329 for this to take care of in a followup PR |
||
|
|
||
|
|
@@ -15,83 +16,215 @@ kdb5_util="kdb5_util" | |
| add_principal_cmd="add_principal -pw ${password}" | ||
|
|
||
| krb_conf="krb5.conf" | ||
| kdc_conf="kdc.conf" | ||
| krb_conf_location="/etc/krb5.conf" | ||
| keytabfile="/etc/krb5.keytab" | ||
|
|
||
| # TODO: These locations varies for different distros, Set the values conditianally | ||
| krb_conf_location="/etc/" | ||
| kdc_conf_location="/etc/krb5kdc/" | ||
| database_file="/var/lib/krb5kdc/principal*" | ||
| PROGNAME=$(basename $0) | ||
| usage() | ||
| { | ||
| echo "This script must be run with super-user privileges." | ||
| echo "Usage: ${PROGNAME} [-h|--help] [-y|--yes] [-u|--uninstall]"; | ||
| } | ||
|
|
||
| kdc_setup() | ||
| # Cleanup config files and uninstall KDC | ||
| clean_up() | ||
| { | ||
| #Create/copy krb5.conf in /etc/ and kdc.conf in /etc/krb5kdc/ | ||
| echo "Stopping KDC.." | ||
| if pgrep krb5kdc 2> /dev/null; then killall krb5kdc ; fi | ||
|
|
||
| echo "Removing config files" | ||
| if [ -f ${krb_conf_location} ]; then | ||
| rm -f ${krb_conf_location} | ||
| fi | ||
|
|
||
| case ${OS} in | ||
| "ubuntu" | "debian") | ||
| kdc_conf_location="/etc/krb5kdc/kdc.conf" | ||
| dpkg -s krb5-kdc >/dev/null 2>&1 | ||
| if [ $? -eq 0 ]; then | ||
| echo "Uninstalling krb5-kdc" | ||
| apt-get -y purge krb5-kdc | ||
| fi | ||
| ;; | ||
|
|
||
| "centos" | "rhel") | ||
| kdc_conf_location="/var/kerberos/krb5kdc/kdc.conf" | ||
| yum list installed krb5-server >/dev/null 2>&1 | ||
| if [ $? -eq 0 ]; then | ||
| echo "Uninstalling krb5-server" | ||
| yum -y remove krb5-server | ||
| fi | ||
| ;; | ||
|
|
||
| *) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we print something out if the OS wasn't recognized?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, will add an echo statement. |
||
| echo "This is an unsupported operating system" | ||
| ;; | ||
| esac | ||
|
|
||
| if [ -f ${kdc_conf_location} ]; then | ||
| rm -f ${kdc_conf_location} | ||
| fi | ||
|
|
||
| echo "Cleanup completed" | ||
| } | ||
|
|
||
| error_exit() | ||
| { | ||
| echo "${1:-"Unknown Error"}" | ||
| echo "Aborting" | ||
| clean_up | ||
| exit 1 | ||
| } | ||
|
|
||
| # Common function across linux distros to configure KDC post installation | ||
| configure_kdc() | ||
| { | ||
| echo "Stopping KDC.." | ||
| if pgrep krb5kdc 2> /dev/null; then killall krb5kdc ; fi | ||
|
|
||
| # Remove database files if exist | ||
| rm -f ${database_files} | ||
|
|
||
| # Create/copy krb5.conf and kdc.conf | ||
| echo "Copying krb5.conf and kdc.conf.." | ||
| sudo /bin/cp ${krb_conf} ${krb_conf_location} | ||
| sudo /bin/cp ${kdc_conf} ${kdc_conf_location} | ||
| cp ${krb_conf} ${krb_conf_location} || \ | ||
| error_exit "Cannot copy ${krb_conf} to ${krb_conf_location}" | ||
|
|
||
| cp ${kdc_conf} ${kdc_conf_location} || \ | ||
| error_exit "Cannot copy ${kdc_conf} to ${kdc_conf_location}" | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What's the state of the machine if one of these errors out? Will uninstall successfully undo any changes made thus far, even if the install wasn't complete? I just want to make sure that a dev can get back to a clean state if something goes wrong part way through install.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, there is cleanup procedure in place which, upon occurrence of an error, will revert the changes made to the system thus far (config files, installation of kdc, etc.) |
||
|
|
||
| echo "Creating KDC database for realm ${realm}.." | ||
| sudo ${kdb5_util} create -r ${realm} -P ${password} -s | ||
| ${kdb5_util} create -r ${realm} -P ${password} -s || \ | ||
| error_exit "Cannot create KDC database for realm ${realm}" | ||
|
|
||
| echo "Adding principal ${principal1}.." | ||
| sudo ${kadmin} -q "${add_principal_cmd} ${principal1}@${realm}" | ||
| ${kadmin} -q "${add_principal_cmd} ${principal1}@${realm}" || \ | ||
| error_exit "Cannot add ${principal1}" | ||
|
|
||
| echo "Adding principal ${principal2}.." | ||
| sudo ${kadmin} -q "${add_principal_cmd} ${principal2}@${realm}" | ||
| ${kadmin} -q "${add_principal_cmd} ${principal2}@${realm}" || \ | ||
| error_exit "Cannot add ${principal2}" | ||
|
|
||
| echo "Adding user ${krb_user}.." | ||
| sudo ${kadmin} -q "${add_principal_cmd} ${krb_user}@${realm}" | ||
| ${kadmin} -q "${add_principal_cmd} ${krb_user}@${realm}" || \ | ||
| error_exit "Cannot add ${krb_user}" | ||
|
|
||
| echo "Exporting keytab for ${principal1}" | ||
| sudo ${kadmin} -q "ktadd ${principal1}@${realm}" | ||
| ${kadmin} -q "ktadd -norandkey ${principal1}@${realm}" || \ | ||
| error_exit "Cannot export kytab for ${principal1}" | ||
|
|
||
| echo "Exporting keytab for ${principal2}" | ||
| sudo ${kadmin} -q "ktadd ${principal2}@${realm}" | ||
| ${kadmin} -q "ktadd -norandkey ${principal2}@${realm}" || \ | ||
| error_exit "Cannot export kytab for ${principal2}" | ||
|
|
||
| echo "Exporting keytab for ${krb_user}" | ||
| sudo ${kadmin} -q "ktadd ${krb_user}@${realm}" | ||
| ${kadmin} -q "ktadd -norandkey ${krb_user}@${realm}" || \ | ||
| error_exit "Cannot export kytab for ${krb_user}" | ||
| } | ||
|
|
||
| # check the invoker of this script | ||
| if [ $EUID -ne 0 ]; then | ||
| usage | ||
| exit 1 | ||
| fi | ||
|
|
||
| # Parse command-line arguments | ||
| TEMP=`getopt -o hyu --long help,yes,uninstall -n 'test.sh' -- "$@"` | ||
| [ $? -eq 0 ] || { | ||
| usage | ||
| exit 1 | ||
| } | ||
| eval set -- "$TEMP" | ||
| uninstall=0 | ||
| force=0 | ||
| while true; do | ||
| case $1 in | ||
| -h|--help) usage; exit 0;; | ||
| -y|--yes) force=1; shift ;; | ||
| -u|--uninstall) uninstall=1; shift;; | ||
| --) shift; break;; | ||
| *) usage; exit 1;; | ||
| esac | ||
| done | ||
|
|
||
| # Uninstallation | ||
| if [ $uninstall -eq 1 ]; then | ||
| if [ $force -eq 0 ]; then | ||
| echo "This will uninstall KDC from your machine and cleanup the related config files." | ||
| read -p "Do you want to continue? ([Y]es/[N]o)? " choice | ||
| case $(echo $choice | tr '[A-Z]' '[a-z]') in | ||
| y|yes) clean_up;; | ||
| *) echo "Skipping uninstallation";; | ||
| esac | ||
| else | ||
| clean_up | ||
| fi | ||
| exit 0 | ||
| fi | ||
|
|
||
| echo "Removing existing database" | ||
| sudo rm -rf ${database_file} | ||
| # Installation | ||
| if [ $force -eq 0 ]; then | ||
| read -p "This will install KDC on your machine and create KDC principals. Do you want to continue? ([Y]es/[N]o)? " choice | ||
| case $(echo $choice | tr '[A-Z]' '[a-z]') in | ||
| y|yes) ;; | ||
| *) echo "Skipping installation"; exit 0;; | ||
| esac | ||
| fi | ||
|
|
||
| case ${OS} in | ||
| "Ubuntu") | ||
| "ubuntu" | "debian") | ||
| kdc_conf="kdc.conf.ubuntu" | ||
| kdc_conf_location="/etc/krb5kdc/kdc.conf" | ||
| database_files="/var/lib/krb5kdc/principal*" | ||
|
|
||
| dpkg -s krb5-kdc >/dev/null 2>&1 | ||
| if [ $? -ne 0 ] | ||
| then | ||
| if [ $? -ne 0 ]; then | ||
| echo "Installing krb5-kdc.." | ||
| sudo DEBIAN_FRONTEND=noninteractive apt-get -y install krb5-kdc krb5-admin-server | ||
| export DEBIAN_FRONTEND=noninteractive | ||
| apt-get -y install krb5-kdc krb5-admin-server | ||
| if [ $? -ne 0 ]; then | ||
| echo "Error occurred during installation, aborting" | ||
| exit 1 | ||
| fi | ||
| else | ||
| echo "krb5-kdc already installed.." | ||
| exit 2 | ||
| fi | ||
|
|
||
| echo "Stopping KDC.." | ||
| if pgrep krb5kdc 2> /dev/null; then killall krb5kdc ; fi | ||
| if pgrep kadmind 2> /dev/null; then killall kadmind ; fi | ||
|
|
||
| kdc_setup | ||
| configure_kdc | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If user already has krb5 installed this script will be a no-op. In such cases, the tests may fail (the user's krb5.conf may not contain the principals needed for the test)
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a way to prompt the user to overwrite their set up if that's actually what they want? What about an uninstall, that undoes all of the configuration done in the script?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Prompting will not be possible due to the automated nature. For uninstall, @stephentoub should we add an argument to the script? Then in #6139 should we also do an uninstall each time? (Note that always cleaning up will add to the time when devs run NegotiateStream tests locally)
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
That's not necessarily true. There are many utilities that prompt, for example, unless you pass a /force or /Y or some such flag that says "I know what I'm doing, I automatically say 'yes' to any prompt, so don't prompt me".
Yes, please.
If running the tests does an automatic install, then they should also automatically uninstall. Otherwise, running the tests leaves the box in a state different than it started. It should also be possible to run the uninstall manually and clean up any vestiges of the previous install.
We should make it so that it only uninstalls if it needed to install. That way, if a developer is working on this library and has manually run the install script, no extra install/uninstall time is taken in each run. If it's someone who's just running a full test pass or otherwise running the tests locally, and they don't have things set up appropriately, the tests will do the install and uninstall and their box will (hopefully) be left clean.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Makes sense. Thanks for the idea about force switch
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @stephentoub we are not actually overwriting user's setup. If the kdc is already installed, we are assuming that the machine is already setup with required users for the testing (through earlier runs of the script). If this assumption is indeed correct, then we might not require the force switch.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @rahulkotecha the force switch is also to let a dev running script outside CI to see some prompts before KDC config. Having the force switch allows the script to be run without prompts from test class setup |
||
|
|
||
| echo "Starting KDC.." | ||
| sudo ${krb5kdc} | ||
|
|
||
| ${krb5kdc} | ||
| ;; | ||
|
|
||
| "centos" | "rhel") | ||
| kdc_conf="kdc.conf.centos" | ||
| kdc_conf_location="/var/kerberos/krb5kdc/kdc.conf" | ||
| database_files="/var/kerberos/krb5kdc/principal*" | ||
|
|
||
| "Debian") | ||
| echo "This is a Debian system" | ||
| ;; | ||
|
|
||
| "CentOS") | ||
| echo "This is a CentOS system" | ||
| ;; | ||
|
|
||
| "Red Hat") | ||
| echo "This is a RedHat system" | ||
| yum list installed krb5-server >/dev/null 2>&1 | ||
| if [ $? -ne 0 ]; then | ||
| echo "Installing krb5-server.." | ||
| yum -y install krb5-server krb5-libs | ||
| if [ $? -ne 0 ]; then | ||
| echo "Error occurred during installation, aborting" | ||
| exit 1 | ||
| fi | ||
| else | ||
| echo "krb5-server already installed.." | ||
| exit 2 | ||
| fi | ||
|
|
||
| configure_kdc | ||
|
|
||
| echo "Starting KDC.." | ||
| systemctl start krb5kdc.service | ||
| systemctl enable krb5kdc.service | ||
| ;; | ||
|
|
||
| *) | ||
| echo "This is an Unknown system" | ||
| echo "This is an unsupported operating system" | ||
| ;; | ||
| esac | ||
| sudo chmod +r ${keytabfile} | ||
|
|
||
| chmod +r ${keytabfile} | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: indentation on all of this