How to use Stored Password Protection with encrypted NFSv4


Preface

This document describes how to configure the Teradata JDBC Driver with Stored Password Protection feature on the Linux platform using Network File System (NFSv4) with Kerberos.

Stored Password Protection uses two Java properties files: a password-encryption-key file and an encrypted-password file to provide a password for logging onto a database. The properties files can be located on a network volume to prevent loss of the file in case the physical client machine is stolen. To protect their contents while in transit, an encrypted protocol is used.

An example will be described in this document where for a given user, a password-encryption-key file will be placed on one server and an encrypted-password file on another and then provide access to each file through NFSv4 using encrypted Kerberos.

The approach used to secure these files will be that the top level imported directories are only accessible to users with valid Kerberos credentials. Without such credentials, the directories are inaccessible. Below that level, for the actual files that hold the encryption information, the ownership will be that of the User ID that is mapped to that Kerberos principal. So, a valid user will be able to see their own files, but will not be able to access those of other users.


Prerequisites

This document is written using SUSE Linux Enterprise Server 11 & 12 systems. All of the systems need to be part of the same Kerberos domain. Our example will use the domain "mykerberos.com" with a realm of "MYKERBEROS.COM".

A total of five Linux systems will be used as shown in the table below.

System

Requirement

Description

Linux

Kerberos Distribution Server (KDC)

system1

JDK Contains:
  • Teradata JDBC Driver
  • password-encryption-key properties file
  • encrypted-password properties file

server1

Contains the password-encryption-key properties file

server2

Contains the encrypted-password properties file

client1

JDK Contains:
  • Teradata JDBC Driver
  • sample Java Program

The required packages for Kerberos and NFSv4 that are needed for "server1", "server2", and "client1" are listed in the table below.

System

Package

Description

server1

krb5 MIT Kerberos5 implementation - Libraries
krb5-client MIT Kerberos5 implementation - client programs
krb5-server MIT Kerberos5 implementation - server
pam_krb5 A Pluggable Authentication Module for Kerberos 5
nfs-kernel-server Support for Kernel nfsd

server2

krb5 MIT Kerberos5 implementation - Libraries
krb5-client MIT Kerberos5 implementation - client programs
krb5-server MIT Kerberos5 implementation - server
pam_krb5 A Pluggable Authentication Module for Kerberos 5
nfs-kernel-server Support for Kernel nfsd

client1

krb5 MIT Kerberos5 implementation - Libraries
krb5-client MIT Kerberos5 implementation - client programs
krb5-server MIT Kerberos5 implementation - server
pam_krb5 A Pluggable Authentication Module for Kerberos 5
sssd System Security Service Daemon

Start NFSv4

On "server1" and "server2", start NFSv4. Using the system adminstrator tool YaST, go to Network Services → NFS Server.

  1. Under "NFS Server" select "Start"
  2. Enter "MYKERBEROS.COM" for the NFSv4 domain name
  3. Select the "Enable GSS Security" field


These settings are shown below.


Click "Next" then "Finish".

NOTE: You may receive the errors in the screenshots below after clicking "Finish" if there are no entries in /etc/exports. The entries for /etc/exports will be configured in Modify /etc/exports later in this document and NFS & NFS server will be restarted in Restart the servers after the servers have been configured.



Click "OK" to continue.



Client/Server common setup

Set up users

Set up two users on each system. This would normally be done by setting up an LDAP server, but we will use two local users to simplify the example.

The users will be "nfsuser1" & "nfsuser2". Verify that the users with the UIDs shown below do not exist in /etc/passwd. If the users already exists, the UID values can be changes as long as they are the same across all systems.

Create "nfsuser1" and "nfsuser2" with the following commands:

NOTE: These users are created WITHOUT passwords which is NOT the same as null passwords. The actual password will be provided via a Kerberos principal.


Configuration changes for the new users

Now that the users have been created, the following changes are required for any system that you are planning to log into using ssh with "nfsuser1" and "nfsuser2". For our example, "client1" would need these changes.

Pluggable Authentication Modules (PAM) and (Secure Shell) SSH will be used so that these users have a default Kerberos principal when they log in. Make the following required configuration changes for both PAM and SSH as described in the table below:

File

Setting

Value

/etc/ssh/ssh_config

GSSAPIAuthentication yes
GSSAPIDelegateCredentials yes

/etc/ssh/sshd_config

KerberosAuthentication yes
KerberosOrLocalPasswd yes
KerberosTicketCleanup yes
GSSAPIAuthentication yes
GSSAPICleanupCredentials yes
GSSAPIKeyExchange yes
AllowAgentForwarding yes
ChallengeResponseAuthentication** yes
UsePAM** no

/etc/pam.d/common-auth

auth sufficient pam_krb5.so use_first_pass ignore_root forwardable
(***add this as the first entry)

/etc/shadow**

nfsuser1 - change the 1st field after the username which is "!" (an exclamation point) to "NP" (no password)
nfsuser2 - change the 1st field after the username which is "!" (an exclamation point) to "NP" (no password)

** needed on SLES 12 client system ONLY


After making changes to /etc/ssh/sshd_config, the sshd service need to be restarted for the changes to take effect.

Enter:
service sshd restart



Modify the /etc/hosts file

Modifications are needed in the /etc/hosts file.

The first two entries should be:

ipaddress     hostname.domainname hostname
127.0.0.1     localhost.localdomain localhost


As an example, for "server1" at mykerberos.com with an IP address of 10.25.30.13, the first two lines would be:

10.25.30.13   server1.mykerberos.com server1
127.0.0.1     localhost.localdomain localhost

NOTE: The 2nd line does NOT have any system specific values.


On the client system, it is important that the server hostnames resolve to the correct domain. When they do not, you are likely to see this error when trying to mount:

mount.nfs4:mount(2):Permission denied


For the client system "client1", in addition to modifying the first two lines as noted above, extra entries should be included to identify the two server systems "server1" and "server2". For "client1", the first four lines of the /etc/hosts file would be:

153.62.21.15  client1.mykerberos.com client1
127.0.0.1     localhost.localdomain localhost
10.25.30.13   server1.mykerberos.com server1
10.25.31.14   server2.mykerberos.com server2


Modify the /etc/idmapd.conf file

Modify the "Domain" variable to the system's domain name. For our example, it is set to:

Domain = MYKERBEROS.com


Kerberos setup

Generate principals & keytabs

Kerberos principals and keytabs need to be generated on the Linux Kerberos Distribution Server system in order to support NFSv4 with Kerberos. New principals must be added and keytab files are required on the client & server NFSv4 Kerberos systems. The specific entry we need on all systems is a "nfs/hostname.domain" credential on each system.

For our example, we will need the following principals:


Use the "kadmin" command to create the principals. An admin password is needed for "kadmin" and will need to be provided by the system administrator of your Kerberos environment. The principal and keytabs are written to the /etc/krb5.keytab file. This will be generated once and then distributed to all the affected systems.

Once you have successfully started "kadmin", use the "listprincs" subcommand to see which principals are present. If you see all of the above principals (i.e. nfs/client1.mykerberos.com@MYKERBEROS.COM, etc.) then you will not need to add them. Otherwise, they can be added via the "addprinc" subcommand as follows:


Kerberos principals are also needed for the local users "nfsuser1" & "nfsuser2". The following will create both the user principals and their passwords in the Kerberos database.


Now that the principals have been added to Kerberos database, they need to be put into the /etc/krb5.keytab file on each system. One entry will be added to each system.

NOTE: The actual value of the "-e encryption type/salt type" parameter may vary, so you should consult with your system administrator.


Run "kadmin" from the client and server systems and enter the following commands to update the keytab file on each system as shown in the table below.

System

Command

client1

ktadd -k /etc/krb5.keytab -e rc4-hmac:normal nfs/client1.mykerberos.com@MYKERBEROS.COM

server1

ktadd -k /etc/krb5.keytab -e rc4-hmac:normal nfs/server1.mykerberos.com@MYKERBEROS.COM

server2

ktadd -k /etc/krb5.keytab -e rc4-hmac:normal nfs/server2.mykerberos.com@MYKERBEROS.COM

After completing these "ktadd" commands, exit "kadmin" by entering "quit".

The contents of the keytab can be viewed using "klist -k /etc/krb5.keytab".



Validate the keytabs

To validate that the created keytab entries are useable, run the following commands which produce no output but will fail and produce an error if there are problems with the keytab.

System

Command

client1

kinit -k nfs/client1.mykerberos.com

server1

kinit -k nfs/server1.mykerberos.com

server2

kinit -k nfs/server2.mykerberos.com

The "klist" command can be run after any of the above commands to verify that the default principal has been changed.



Create the encrypted password properties files for Stored Password Protection

This section will create the encrypted password properties files needed for the Stored Password Protection example. The properties files will be created with the TJEncryptPassword.java sample program that is part of the Teradata JDBC Driver sample programs. Full documentation on how to run the program is included in the program file.

On "system1", the properties files that will be created are:


In a directory on the Linux system "system1" as listed in Prerequisites, compile TJEncryptPassword.java and run the program as follows:

javac TJEncryptPassword.java

java -cp .:terajdbc4.jar TJEncryptPassword AES/CBC/NoPadding -default HmacSHA1 PassKey.properties EncPass.properties dbs1 user1 password1


Older versions prior to Teradata JDBC Driver 16.20.00.11 require tdgssconfig.jar to be listed on the classpath as follows:

java -cp .:terajdbc4.jar:tdgssconfig.jar TJEncryptPassword AES/CBC/NoPadding -default HmacSHA1 PassKey.properties EncPass.properties dbs1 user1 password1


The command will encrypt the database password "password1" and generate two Stored Password Protection properties files. One file contains the password-encryption-key and the other contains the encrypted-password. These two files will be copied to the server systems in the next section.


Server setup

Setting up the Linux server(s) export directory

Set up the export directory structure as listed in the table below (logged in as root). The properties files created from the section above will be copied from "system1" to local directories on the servers.

The two directories that we'll be setting up are:

We will also change the ownership of these directories so they are owned by the local user that is mapped to a Kerberos principal.

System

Command

server1

mkdir -p /exports/JdbcKey/nfs1
chown nfsuser1/exports/JdbcKey/nfs1
chmod 700 /exports/JdbcKey/nfs1
cp PassKey.properties /exports/JdbcKey/nfs1 (copy this file from "system1")
chown nfsuser1 /exports/JdbcKey/nfs1/PassKey.properties
chmod 700 /exports/JdbcKey/nfs1/PassKey.properties
mkdir -p /exports/JdbcKey/nfs2
chown nfsuser2 /exports/JdbcKey/nfs2
chmod 700 /exports/JdbcKey/nfs2
touch /exports/JdbcKey/nfs2/testfile1
chown nfsuser2 /exports/JdbcKey/nfs2/testfile1
chmod 700 /exports/JdbcKey/nfs2/testfile1

server2

mkdir -p /exports/JdbcPass/nfs1
chown nfsuser1/exports/JdbcPass/nfs1
chmod 700 /exports/JdbcPass/nfs1
cp EncPass.properties /exports/JdbcPass/nfs1 (copy this file from "system1")
chown nfsuser1 /exports/JdbcPass/nfs1/EncPass.properties
chmod 700 /exports/JdbcPass/nfs1/EncPass.properties
mkdir -p /exports/JdbcPass/nfs2
chown nfsuser2 /exports/JdbcPass/nfs2
chmod 700 /exports/JdbcPass/nfs2
touch /exports/JdbcPass/nfs2/testfile2
chown nfsuser2 /exports/JdbcPass/nfs2/testfile2
chmod 700 /exports/JdbcPass/nfs2/testfile2

Modify /etc/sysconfig/nfs to support NFSv4

Make the following changes to /etc/sysconfig/nfs:


Modify /etc/exports

Add these lines to /etc/exports on "server1":


Add these lines to /etc/exports on "server2":


For both of these export files, we are using encrypted Kerberos (via sec=krb5p) and severely restricting who we export to by limiting the export to 153.62.21.15 (the IP address of the client system "client1"). Running "man exports" on Linux will provide details of the other options used along with alternative ways to configure this file.


Restart the servers

Run these commands on each server to export the NFSv4 filesystem, restart NFS, and restart the NFS server.

NOTE: These commands should be run whenever the /etc/exports file is modified.



Client setup

Create mount directories & mount remote file systems

On the client system "client1", we will restart the local NFS server, create mount directories for the Stored Password Protection files, and then mount the remote directories.

Run the following commands as root:


Logon to check access to mounted files

Logon to "client1" as a local user other than nfsuser1 and nfsuser2 and run these commands:

A "Permission denied" error message should be returned because the local user is not identified as being a Kerberos user. An example is shown below.



Now, using SSH, log in as "nfsuser1". For our test environment, this would be done as:

ssh nfsuser1@client1


You should be prompted for the password as:

Password for nfsuser1@MYKERBEROS.COM:


NOTE: On a SLES 12 client system, you may receive a different login prompt than a SUSE 11 client system. When logging in you may see:

nfsuser1@client1's password:


Next, run the "klist" command to ensure that you have a default principal and run the "ls" commands again. The output should show that you can see the "nfsuser1" files but not those of "nfsuser2". An example is shown below.




Access the encrypted password properties files for Stored Password Protection

The encrypted password properties files generated above in Create the encrypted password properties files for Stored Password Protection created by the TJEncryptPassword.java sample program are resources that will be accessed by the Teradata JDBC Driver. These resources are accessed via the classpath or direct files by specifying a prefix of either classpath: or file: in the ENCRYPTED_PASSWORD string.


Use Stored Password Protection with Classpath Access

To access the resource files using the classpath access, the following syntax is used:

"ENCRYPTED_PASSWORD(classpath:PassKey.properties,classpath:EncPass.properties)"


For security, classpath resources are required to have specific resource name prefixes. The PasswordEncryptionKeyResourceName (PassKey.properties is used in this document) must begin with "PassKey" and the EncryptedPasswordResourceName (EncPass.properties is used in this document) must begin with "EncPass".


Use Stored Password Protection with File Access

To access the resource files using the file access, the following syntax is used:

"ENCRYPTED_PASSWORD(file:PassKey.properties,file:EncPass.properties)"


There is no prefix requirement for the resource name when using file access.

For simplicity, the examples in this document use the same resource names "PassKey.properties" and "EncPass.properties" for both classpath and file access.

For futher examples of file access using the current directory, relative paths, and absolute paths refer to the documentation in the program file.



Comparison of Classpath Access Versus File Access

Teradata JDBC Driver Stored Password Protection offers flexibility for accessing the password-encryption-key file and the encrypted-password file.

In general, classpath access offers greater control and security, whereas file access offers greater flexibility.



Run a Java program using Stored Password Protection

In this section, we will run a sample Java program LogonTest.java using Stored Password Protection on the Linux client system "client1" using both classpath and file access.

On the Linux client system:

  1. Log in as the local user that has a generated Kerberos principal, "nfsuser1"
  2. Copy the Teradata JDBC Driver terajdbc4.jar from "system1" to a directory on "client1". Older versions prior to Teradata JDBC Driver 16.20.00.11 also require tdgssconfig.jar.
  3. Save LogonTest.java to the same directory used for step #2
  4. Compile the sample program LogonTest.java with the command: javac LogonTest.java
  5. Run the sample Java program using encrypted-password using either classpath or file access (see examples below)

Run the sample Java program with classpath access

(All on one line)

java -classpath .:./terajdbc4.jar:/importKey/JdbcKey/nfs1:/importPass/JdbcPass/nfs1 LogonTest jdbc:teradata://dbs1 user1 "ENCRYPTED_PASSWORD(classpath:PassKey.properties,classpath:EncPass.properties)"


Older versions prior to Teradata JDBC Driver 16.20.00.11 also require tdgssconfig.jar to be listed on the classpath.


The following results are returned:

Connecting to jdbc:teradata://dbs1 with user user1 and password ENCRYPTED_PASSWORD(classpath:PassKey.properties,classpath:EncPass.properties)
Successfully logged on
Closing Connection
Pass

Run the sample Java program with file access

(All on one line)

java -classpath .:./terajdbc4.jar LogonTest jdbc:teradata://dbs1 user1 "ENCRYPTED_PASSWORD(file:/importKey/JdbcKey/nfs1/PassKey.properties,file:/importPass/JdbcPass/nfs1/EncPass.properties)"


Older versions prior to Teradata JDBC Driver 16.20.00.11 also require tdgssconfig.jar to be listed on the classpath.


The folllowing results are returned:

Connecting to jdbc:teradata://dbs1 with user user1 and password ENCRYPTED_PASSWORD(file:/importKey/JdbcKey/nfs1/PassKey.properties,file:/importPass/JdbcPass/nfs1/EncPass.properties)
Successfully logged on
Closing Connection
Pass

These examples use the encrypted password properties files created in the previous section Create the encrypted password properties files for Stored Password Protection.