17

I want to make a script that will generate the a keytab using ktutil. When running the script I want to use [user]$ script.sh PASSWORD

#script.sh
echo "addent -password -p PRINCIPAL -k 1 -e aes256-cts-hmac-sha1-96" | ktutil

Ktutil than needs a password, here I want to use the PASSWORD argument from above. How would I pass the password arguement?

Cyrus
  • 84,225
  • 14
  • 89
  • 153
OrigamiEye
  • 864
  • 1
  • 12
  • 31

6 Answers6

24

With GNU bash:

user="PRINCIPAL"
pass="topsecret"

printf "%b" "addent -password -p $user -k 1 -e aes256-cts-hmac-sha1-96\n$pass\nwrite_kt $user.keytab" | ktutil

printf "%b" "read_kt $user.keytab\nlist" | ktutil

Output:

slot KVNO Principal
---- ---- ---------------------------------------------------------------------
   1    1                          PRINCIPAL@YOURDOMAIN
Cyrus
  • 84,225
  • 14
  • 89
  • 153
4

I followed the accepted answer by Cyrus but kept hitting

"Cannot read password while adding new entry" as mentioned by Arrow_Raider

I was able to overcome the error by using the slightly similar result using the below.

   {
    echo "addent -password -p ${user} -k 1 -e RC4-HMAC"
    sleep 1
    echo "${pass}"
    sleep 1
    echo "write_kt my.keytab"
    } |
    ktutil
BDarley
  • 697
  • 1
  • 10
  • 19
3

To create the multiple orgs keytabs and default hbase,pipe,hdfs keytab at the same time you can run the below script, which i have just created:

#!/bin/bash
read -p "Please enter space-delimited list of ORGS to create: " NEW_ORGS

clear
#echo "#################  CREATE KEYTABS  ############################"
#echo ""
kdestroy

for i in $NEW_ORGS
do
     printf "%b" "addent -password -p ${i} -k 1 -e aes256-cts-hmac-sha1-96\n${i}\nwrite_kt ${i}.keytab" | ktutil

     printf "%b" "read_kt ${i}.keytab\nlist" | ktutil

done
echo ""


if [ ! -e /home/eip/.keytabs/hbase.keytab ]
then
        printf "%b" "addent -password -p hbase -k 1 -e aes256-cts-hmac-sha1-96\nhbase\nwrite_kt hbase.keytab" | ktutil

        printf "%b" "read_kt hbase.keytab\nlist" | ktutil
fi

exit 0
Rahul Sharma
  • 2,867
  • 2
  • 27
  • 40
  • @Lokendra_Jain If there is `\n` in the environment variable (for example, in a password), the result will be incorrect. – Maxim Mandrik Oct 03 '21 at 12:32
2

A version in Python

https://github.com/Tagar/stuff/blob/master/keytab.py

piping password to ktutil in shell is not secure as password will be visible in list of processes.

Since this Python scripts just interacts with ktutil using pexpect library, it's possible to implement the same as a pure shell script using expect.

Hope this helps.

Tagar
  • 13,911
  • 6
  • 95
  • 110
2

Use expect to keep the password out of the process list:

expect << EOF
    set timeout 10
    spawn /usr/bin/ktutil
    expect {
       "ktutil: " { send "addent -password -p $PRINCIPAL -k 1 -e $METHOD\r" }
       timeout { puts "Timeout waiting for ktutil prompt."; exit 1; }
    }
    expect {
       -re "Password for \\\\S+: " { send "$PASSWORD\r" }
       timeout { puts "Timeout waiting for password prompt."; exit 1; }
    }
    expect {
       "ktutil: " { send "wkt $KEYTAB_TMP\r" }
    }
    expect {
       "ktutil: " { send "q\r" }
    }
EOF

Or use a <<HERE document to provide stdin, but if addent fails to prompt, you may end up with the password in your stdout:

/usr/bin/ktutil <<EOF
addent -password -p $PRINCIPAL -k 1 -e $METHOD
$PASSWORD
wkt $KEYTAB_TMP
q
EOF
rrauenza
  • 6,285
  • 4
  • 32
  • 57
  • Probably in the case of `expect send`: if there is `\r` in the environment variable (for example, in a password), the result will be incorrect. I like the second example, although also has its drawbacks if the `ktutil` program will change (but it is unlikely and the problem will be quickly detected, because it will be immediately visible). But in this example, it is possible to use `\r` and similar in passwords. – Maxim Mandrik Oct 03 '21 at 12:37
  • The expect approach doesn't work if kubernetes runs this. It results in a keytab file that is 0 bytes. Not sure about the second. – Arrow_Raider Jan 19 '22 at 23:58
1

enjoy

import os, getpass
from subprocess import run, PIPE
import sys
userndomain, passwd, enctype = 'username@DOMAIN', 'secret', 'arcfour-hmac-md5'
input_load = f"""add_entry -password -p {userndomain} -k 1 -e {enctype}
{passwd}
write_kt {user}.keytab
quit
"""
p = run(['ktutil'], stdout=PIPE, input=input_load, encoding='ascii')