Friday, February 20, 2009

NTP With Autokey Authentication

Recently I had to verify the functionality of NTP server with autokey authentication. Though I thought that it would be simple, it took me several days to find out how to configure the authentication. I found out dozens of different howtos, but none of them worked for me. So when I finally came to one that worked, I created several shell scripts that helped me to configure different kind of (unicast) NTP authentication.

The shell scripts are paired: setup_server_XYZ.sh and setup_client_XYZ.sh where XYZ is used identity scheme. MV identity scheme seems not to work on sles9.The usage of the scripts is:

  1. Edit PASS/SPASS/CPASS variables in both client and server script! These are password for generated keys
  2. Edit SERVER variable in setup_server_XYZ.sh - that is the server which will your server use for own synchronization.
  3. Copy setup_server_XYZ.sh to the ntp server.
  4. Run setup_server_XYZ.sh on the server. If XYZ is mv, script takes one argument N, which is number of client keys to generate + 1 (N-1 clients will be able to use the server).
  5. Copy setup_client_XYZ.sh to the client.
  6. Run setup_client_XYZ.sh . If XYZ is mv, script takes additional argument X which is client id - number between 1 and N-1 - which specifies which key client will use. The script will ask for server root's password twice - first time to identify the key to download from the server, and the second time to actually download the key.
  7. Make sure that both server and client are not configured to run in chroot (or copy/move /etc/ntp/ and /etc/ntp.conf to appropriate chroot directory).
  8. Start ntpd (manually or with initscript) on server and clients. It takes some time to establish the link between client and server (approximately 15 minutes).

When ntp is set up and running, the status can be checked with several commands:

  • ntpq -p - prints a list of server the host has configured as its NTP servers. If there's a star '*' before the server name, host uses the server for synchronization.
  • ntp -c as - print list of associations - including authentication status. Following output shows successfully authenticated association:
ind assID status  conf reach auth condition  last_event cnt
===========================================================
1 26132   f694   yes   yes   ok  sys.peer   reachable   9

The scripts have following limitations:

  • Server is configured to use one server - which is not a good idea - it should use more than one (same for clients). To fix this just add more server lines to /etc/ntp.conf.
  • Usage of /dev/urandom is not the best one as well, /dev/random (or file generated by command openssl rand) should probably be used for maximal security.
  • Configuration is saved to /etc but ntpd usually run in chroot.
  • The script setup_server_mv.sh always endlessly loops while generating client keys - seems to continuously reject duplicate keys - this is probably not problem in the script. So, try to use it but don't be surprised ;-)

setup_server_gq.sh:

#!/bin/bash

PASS=lala
SERVER=ntp2.suse.de

rm -fr /etc/ntp
mkdir -p /etc/ntp

cat <<> /etc/ntp.conf
server $SERVER
keysdir /etc/ntp
crypto pw $PASS randfile /dev/urandom
logfile /var/log/ntp
logconfig =all
EOF

cd /etc/ntp
RANDFILE=/dev/urandom ntp-keygen -T -G -p $PASS

echo server is set up. Start it with \'ntpd -u ntp [-d]\'

setup_client_gq.sh:

#!/bin/bash

PASS=lala
ping -c1 "$1" > /dev/null
if [ $? -ne 0 -o $# -ne 1 ] ; then
  echo "Needs one argument - ntp server address"
  exit 1
fi

rm -fr /etc/ntp
mkdir -p /etc/ntp

cat <<> /etc/ntp.conf
server $1 autokey
crypto pw $PASS randfile /dev/urandom
logfile /var/log/ntp
logconfig =all
keysdir /etc/ntp
EOF

cd /etc/ntp
RANDFILE=/dev/urandom ntp-keygen -H -p $PASS
KEY="`ssh root@$1 ls /etc/ntp/ntpkey_GQpar_\* | sed 's,.*/,,'`"

if [ "x$KEY" = "x" ] ; then
  echo Error while fetching key name
  exit 1
fi

scp root@$1:/etc/ntp/$KEY .
LINK="`echo $KEY | sed 's/^ntpkey_GQpar_\(.*\)\.[0-9]\+$/ntpkey_gp_\1/'`"
ln -s $KEY $LINK

echo client is set up. Start it with \'ntpd -u ntp [-d]\'

setup_server_iff.sh:

#!/bin/bash

SPASS=lala
CPASS=alal
SERVER=ntp2.suse.de

rm -fr /etc/ntp
mkdir -p /etc/ntp

cat <<> /etc/ntp.conf
server $SERVER
keysdir /etc/ntp
crypto pw $SPASS randfile /dev/urandom
logfile /var/log/ntp
logconfig =all
EOF

cd /etc/ntp
RANDFILE=/dev/urandom ntp-keygen -T -I -p $SPASS
RANDFILE=/dev/urandom ntp-keygen -e -q $SPASS -p $CPASS > tmp_key

echo keyname "'`head -n1 tmp_key | sed 's/^# *//'`'"
mv tmp_key `head -n1 tmp_key | sed 's/^# *//'`

echo server is set up. Start it with \'ntpd -u ntp [-d]\'

setup_client_iff.sh:

#!/bin/bash

CPASS=alal
ping -c1 "$1" > /dev/null
if [ $? -ne 0 -o $# -ne 1 ] ; then
  echo "Needs one argument - ntp server address"
  exit 1
fi

rm -fr /etc/ntp
mkdir -p /etc/ntp

cat <<> /etc/ntp.conf
server $1 autokey
crypto pw $CPASS randfile /dev/urandom
logfile /var/log/ntp
logconfig =all
keysdir /etc/ntp
EOF

cd /etc/ntp
RANDFILE=/dev/urandom ntp-keygen -H -p $CPASS
KEY="`ssh root@$1 ls /etc/ntp/ntpkey_IFFkey_\* | sed 's,.*/,,'`"

if [ "x$KEY" = "x" ] ; then
  echo Error while fetching key name
  exit 1
fi

scp root@$1:/etc/ntp/$KEY .
LINK="`echo $KEY | sed 's/^ntpkey_IFFkey_\(.*\)\.[0-9]\+$/ntpkey_iff_\1/'`"
ln -s $KEY $LINK

echo client is set up. Start it with \'ntpd -u ntp [-d]\'

setup_server_mv.sh (loops!!!):

#!/bin/bash

PASS=lala
SERVER=ntp2.suse.de

if [ "x`echo $1 | grep '^[1-9][0-9]*$'`" = "x" ] ; then
  echo Needs one argument n - number of client certificates to create + 1.
  exit 1
fi

rm -fr /etc/ntp
mkdir -p /etc/ntp

cat <<> /etc/ntp.conf
server $SERVER
keysdir /etc/ntp
crypto pw $PASS randfile /dev/urandom
logfile /var/log/ntp
logconfig =all
EOF

cd /etc/ntp
RANDFILE=/dev/urandom ntp-keygen -V $1 -p $PASS

echo server is set up. Start it with \'ntpd -u ntp [-d]\'

setup_client_mv.sh (untested, because setup_server_mv.sh loops!):

#!/bin/bash

PASS=lala
ping -c1 "$1" > /dev/null
if [ $? -ne 0 -o $# -ne 2 -o "x`echo $2 | grep '^[1-9][0-9]*$'`" = "x" ] ; then
  echo "Needs two arguments:"
  echo "  1. ntp server address"
  echo "  2. ntp client id 1..n-1 - which certificate to get."
  exit 1
fi

rm -fr /etc/ntp
mkdir -p /etc/ntp

cat <<> /etc/ntp.conf
server $1 autokey
crypto pw $PASS randfile /dev/urandom
logfile /var/log/ntp
logconfig =all
keysdir /etc/ntp
EOF

cd /etc/ntp
RANDFILE=/dev/urandom ntp-keygen -H -p $PASS
KEY="`ssh root@$1 ls /etc/ntp/ntpkey_MVkey$2_\* | sed 's,.*/,,'`"

if [ "x$KEY" = "x" ] ; then
  echo Error while fetching key name
  exit 1
fi

scp root@$1:/etc/ntp/$KEY .
LINK="`echo $KEY | sed 's/^ntpkey_MVkey[1-9][0-9]*_\(.*\)\.[0-9]\+$/ntpkey_mv_\1/'`"
ln -s $KEY $LINK

echo client is set up. Start it with \'ntpd -u ntp [-d]\'

That's all, I hope this can spare some time...

(This text has also been published on openSUSE wiki)

No comments:

Post a Comment