SSH Equivalence With Oracle RAC
Author: Andy Rivenes (andy@appsdba.com)
Copyright AppsDBA Consulting, All Rights Reserved.
Last Updated: February 8, 2008
Introduction
One of the Pre-Installation Tasks for installing Oracle RAC on Linux is to configure ssh. The gist of the configuration is to allow the installer to issue ssh and scp commands from the master node to the other nodes during the installation process without having to supply a password. The setup is well documented in the Oracle® Database Oracle Clusterware and Oracle Real Application Clusters Installation Guide
10g Release 2 (10.2) for Linux in the Pre-Installation Tasks section. The inconvenience with this setup is that several commands have to be run every time you log in to the system. Granted that this is only required when you run the installer or Opatch, but it's still a pain, especially since I usually forget to set it up, and then have to stop and go back and start over. The problem is that the commands that Oracle publishes, and that are repeated by most others writing about installing RAC are not easily put in a script.
The following offers a method to script SSH equivalency on Linux. It may not be as secure as forcing someone to enter a passphrase by hand every time it is set up, but it is convenient and I think secure enough to be a reasonable approach to the issue.
Enabling SSH Equivalency
The Oracle documentation describes running two commands for enabling SSH equivalency:
$ exec /usr/bin/ssh-agent $SHELL
$ /usr/bin/ssh-add
Without SSH equivalency the following command requires a passphrase:
/u01/app/oracle$ ssh racnode2 date
Enter passphrase for key '/u01/app/oracle/.ssh/id_rsa':
Fri Dec 21 14:34:22 PST 2007
/u01/app/oracle$
The following is an example of setting up SSH equivalency:
/u01/app/oracle$ exec /usr/bin/ssh-agent $SHELL
/u01/app/oracle$ /usr/bin/ssh-add
Enter passphrase for /u01/app/oracle/.ssh/id_rsa:
Identity added: /u01/app/oracle/.ssh/id_rsa
(/u01/app/oracle/.ssh/id_rsa)
Identity added: /u01/app/oracle/.ssh/id_dsa
(/u01/app/oracle/.ssh/id_dsa)
/u01/app/oracle$
Note that the prompt for a "passphrase" resulted in having to manually enter a passphrase. Once this has been run we can enter commands through SSH like the one in the example above without having to enter a passphrase:
/u01/app/oracle$ ssh racnode2 date
Fri Dec 21 14:32:35 PST 2007
/u01/app/oracle$
SSH Equivalence Script
The following shows how to script the above commands so that a passphrase does not have to be entered by hand. Three files are created. The first contains the actual passphrase, the second simply "cats" the passphrase, and the third runs the commands to invoke the ssh-agent and ssh-add commands. The trick to this method is the use of the SSH_ASKPASS environment variable. From the ssh man page:
"If ssh needs a passphrase, it will read the passphrase from the current terminal if it was run from a terminal. If ssh does not have a terminal associated with it but DISPLAY and SSH_ASKPASS are set, it will execute the program specified by SSH_ASKPASS and open an X11 window to read the passphrase. This is particularly useful when calling ssh from a .Xsession or related script. (Note that on some machines it may be necessary to redirect the input from /dev/null to make this work.)"
All three of these files will be placed in the $HOME/.ssh directory for the Oracle user. The permissions are set to only allow the owner to see the files, either 0600 or 0700. This is done with the chmod command. This makes access to the files relatively secure, allowing only the Oracle account to access the files.
The first step is to create a file for the passphrase. I called this file "key-passphrase". It has just one line in it for the passphrase.
/u01/app/oracle/.ssh$ cat key-passphrase
ora1pass
/u01/app/oracle/.ssh$
The second step is to create a script that can be run to echo the passphrase. I called this script "add-passphrase.sh":
/u01/app/oracle/.ssh$ cat add-passphrase.sh
#!/bin/sh
cat ~/.ssh/key-passphrase << EOF
/u01/app/oracle/.ssh$
And the third step is to create a file to invoke the passing of the passphrase to the authentication agent. This is done with the following script:
export DISPLAY=junk
export SSH_ASKPASS=~/.ssh/add-passphrase.sh
eval `/usr/bin/ssh-agent`
ssh-add < /dev/null
/u01/app/oracle$
I called this script "ssh_equiv". So the $HOME/.ssh directory now looks like the following:
/u01/app/oracle/.ssh$ ls -lart
total 36
-rw------- 1 oracle oinstall 951 May 30 2006 id_rsa
-rw-r--r-- 1 oracle oinstall 224 May 30 2006 id_rsa.pub
-rw------- 1 oracle oinstall 736 May 30 2006 id_dsa
-rw-r--r-- 1 oracle oinstall 604 May 30 2006 id_dsa.pub
-rw------- 1 oracle oinstall 1656 May 30 2006 authorized_keys
-rw-r--r-- 1 oracle oinstall 27 May 30 2006 config
-rw-r--r-- 1 oracle oinstall 3318 Dec 21 10:09 known_hosts
-rw------- 1 oracle oinstall 8 Dec 21 10:38 key-passphrase
-rwx------ 1 oracle oinstall 43 Dec 21 10:41 add-passphrase.sh
-rw------- 1 oracle oinstall 110 Dec 21 11:40 ssh_equiv
drwx------ 2 oracle oinstall 4096 Dec 21 14:38 .
drwxr-xr-x 19 oracle oinstall 4096 Dec 27 13:56 ..
/u01/app/oracle/.ssh$
The following shows an example of running the ssh_equiv script:
/u01/app/oracle/.ssh$ . ssh_equiv
Agent pid 882
Identity added: /u01/app/oracle/.ssh/id_rsa (/u01/app/oracle/.ssh/id_rsa)
Identity added: /u01/app/oracle/.ssh/id_dsa (/u01/app/oracle/.ssh/id_dsa)
/u01/app/oracle/.ssh$
orasetup
Now that we have the ssh_equiv script in our $HOME/.ssh directory it would be even nicer if it was run automatically when we set up our Oracle RAC environment. This is fairly easily done using the Open Source utility orasetup available at http://orautil.sourceforge.net.
orasetup allows the running of a local environment script. The directory is specified by the GBL_USERENV environment variable in the DEPVAR function, and would normally be set as part of the orasetup configuration. The environment file name is of the format $ENVFIL.env where ENVFIL is set to either the ORACLE_SID or TWO_TASK value for the environment being set up. This makes it fairly simple to now make the GBL_USERENV point to $HOME/.ssh and either rename our ssh_equiv script to ${ORACLE_SID}.env or make a link as in the following examples:
Define the orasetup GBL_USERENV variable
#
# Define the directory to search for a user defined environment script
#
#GBL_USERENV="$ORACLE_BASE/local/script"
GBL_USERENV="$HOME/.ssh"
Link or rename the ssh_equiv script:
/u01/app/oracle/.ssh$ ln -s ssh_equiv SID1.env
/u01/app/oracle/.ssh$ ls -lart
total 36
-rw------- 1 oracle oinstall 951 May 30 2006 id_rsa
-rw-r--r-- 1 oracle oinstall 224 May 30 2006 id_rsa.pub
-rw------- 1 oracle oinstall 736 May 30 2006 id_dsa
-rw-r--r-- 1 oracle oinstall 604 May 30 2006 id_dsa.pub
-rw------- 1 oracle oinstall 1656 May 30 2006 authorized_keys
-rw-r--r-- 1 oracle oinstall 27 May 30 2006 config
-rw-r--r-- 1 oracle oinstall 3318 Dec 21 10:09 known_hosts
-rw------- 1 oracle oinstall 8 Dec 21 10:38 key-passphrase
-rwx------ 1 oracle oinstall 43 Dec 21 10:41 add-passphrase.sh
-rw------- 1 oracle oinstall 110 Dec 21 11:40 ssh_equiv
lrwxrwxrwx 1 oracle oinstall 9 Dec 21 14:38 SID1.env -> ssh_equiv
drwx------ 2 oracle oinstall 4096 Dec 21 14:38 .
drwxr-xr-x 19 oracle oinstall 4096 Dec 27 13:56 ..
/u01/app/oracle/.ssh$
A trace of orasetup shows that it now picks up the script and can run it. The beauty of this approach is that it automates the setup of ssh equivalency for the oracle account, but will silently fail for other invokers of orasetup unless they have the same setup, which won't exist.
++ '[' /u01/app/oracle/.ssh '!=' '' ']'
++ '[' -r /u01/app/oracle/.ssh/SID1.env ']'
++ . /u01/app/oracle/.ssh/SID1.env
+++ export DISPLAY=junk
+++ DISPLAY=junk
+++ export SSH_ASKPASS=/u01/app/oracle/.ssh/add-passphrase.sh
+++ SSH_ASKPASS=/u01/app/oracle/.ssh/add-passphrase.sh
++++ /usr/bin/ssh-agent
+++ eval 'SSH_AUTH_SOCK=/tmp/ssh-PUaFw17875/agent.17875;' export 'SSH_AUTH_SOCK;' 'SSH_AGENT_PID=17876;' export 'SSH_AGENT_PID;' echo Agent pid '17876;'
++++ SSH_AUTH_SOCK=/tmp/ssh-PUaFw17875/agent.17875
++++ export SSH_AUTH_SOCK
++++ SSH_AGENT_PID=17876
++++ export SSH_AGENT_PID
++++ echo Agent pid 17876
Agent pid 17876
+++ ssh-add
Identity added: /u01/app/oracle/.ssh/id_rsa (/u01/app/oracle/.ssh/id_rsa)
Identity added: /u01/app/oracle/.ssh/id_dsa (/u01/app/oracle/.ssh/id_dsa)
++ '[' 0 -ne 0 ']'
This now enables the following:
/u01/app/oracle$ . orasetup SID1
Agent pid 31870
Identity added: /u01/app/oracle/.ssh/id_rsa (/u01/app/oracle/.ssh/id_rsa)
Identity added: /u01/app/oracle/.ssh/id_dsa (/u01/app/oracle/.ssh/id_dsa)
/u01/app/oracle$ ssh cpprac2 date
Fri Dec 21 12:04:32 PST 2007
/u01/app/oracle$ echo $ORACLE_HOME
/u01/app/oracle/product/10.2.0/db_1
/u01/app/oracle$ echo $ORACLE_SID
SID1
/u01/app/oracle$
Sources
The Complete FreeBSD: Documentation from the Source by Greg Lehey, O'Reilly Community Press, Pgs. 422-423.
A message found from Google by Patrice.Gonthier@alcatel.fr, at URL: http://marc.info/?l=openssh-unix-dev&m=109822418603321&w=2
ssh man page on Linux
|