Saturday, 9 November 2019

Distro testing the easier way

Just been looking at a number of different Linux distributions and wondered how to install a number of them to try them out.

I came across two tools/websites that are fantastic for distrubtion hopping.

The first is Gnome Boxes. Boxes is an application that gives you access to virtual machines, running locally or remotely. It also allows you to connect to the display of a remote computer.

The other is Distro Test. There they allow you to test 857 versions with 252 operating systems. You can spin up a VM of your choice on their servers and play for 60 minutes, for free.


Tuesday, 27 August 2019

Oracle Primavera P6, forgotten password and locked accounts

Had a situation where we had forgotten the admin password on one of our EPPM instances and the account had been locked out due to too many login attempts.

If you have another admin account then you can login as that user and reset the password or unlock the account using the admin front-end. If you don't then read on...

Fix locked account

Unlocking the account was achieved by doing the following.

  1. Login to the P6 apps server.
  2. Run adminpv.cmd from P6_HOME\p6.
  3. Login as privuser.
  4. Navigate to Configuration->Custom->Primavera P6 Configuration->Database.
  5. Right-click on Instance and select Reset login failures.

Fix lost password

Login to the database either as admuser or sys and run the following update statement.
update admuser.users set passwd = null where user_name = 'admin';
commit;
You can now login as admin, leaving the password blank.

Now that we were logged in to P6 we were able to reset the admin password.

Monday, 19 August 2019

Check Java Security file for running java versions

I had an issue where a number of Java processes were taking a long time to start up.
I had read somewhere that altering the java.security file to use /dev/./urandom instead of /dev/random or /dev/urandom could speed things up.

So as is my way, I wrote a script to chech this setting for me.
for x in $(for i in $(pgrep -x -U $(id -ur) java); do readlink /proc/$i/exe; done | sort -u); do
  fn=${x/bin\/java/}
  echo $fn
  grep "^securerandom.source" ${fn}jre/lib/security/java.security
done
Breaking this down, firstly I wanted to find out the executable use by all of my running Java processes.
pgrep -x -U $(id -ur) java
This returns a list of process ID's for any java processes running as my user.

I then use readlink to get to the actual executable for each process.
readlink /proc/$i/exe
For example if I had a prcess id of 42474 and ran the above readlink e.g. readlink /proc/42474/exe I'd get something like the following.
/proc/42474/exe -> /u01/app/oracle/prod/jdk1.8/bin/java
I then ran the list through sort -u to produce a unique (-u) list of executables.

After I have my unique list of java executable I just grep the java.security file for a line that begins with securerandom.source. The ${x/bin\/java/} takes the full path provided in the loop and replaces the bin/java with nothing.
/u01/app/oracle/prod/jdk1.7/bin/java
securerandom.source=/dev/random
/u01/app/oracle/prod/jdk1.8/bin/java
securerandom.source=/dev/./urandom

Thursday, 1 August 2019

Heredoc for DOS/Powershell (multiple commands to SQL*Plus)

Hi, I do this all the time in Linux, sending multiple commands to a programme...
sqlplus / as sysdba <<!
shutdown immediate
startup
@?/rdbms/admin/utlrp
!
It's called heredoc but trying to do the same in DOS was slightly different and took a while to figure out...
( echo shutdown immediate
echo startup
echo @?/rdbms/admin/utlrp
) | sqlplus / as sysdba
To explain the () allows me to enter a number of lines before executing them and returning me to the command prompt.

I need these new lines as SQL*Plus expects them as delimiters to seperate commands.

So the above commands echo's a number of commands and pipes the results to SQL*Plus.

To embed brackets you need to escape the bracket using ^^^( and ^^^) like this...
( echo shutdown immediate
echo Starting database ^^^(normally^^^)
echo startup
echo @?/rdbms/admin/utlrp
) | sqlplus / as sysdba
To do the same in PowerShell do the following...
@' echo shutdown immediate
echo startup
echo @?/rdbms/admin/utlrp
'@ | sqlplus / as sysdba
The closing '@ must be at the beginning of the line with no preceeding spaces, otherwise it will fail.

Thursday, 14 March 2019

Check whether to patch Oracle OPatch

I was trying to figure out how to script if OPatch needed updating to the minimum required when patching Oracle software.

So I came up with the following.

Set my ORACLE_HOME to the software directory and add OPatch and bin to the PATH

export ORACLE_HOME=/u01/app/oracle/prod/mwwc12213
export PATH=$ORACLE_HOME/OPatch:$ORACLE_HOME/bin:$PATH

This is the minimum OPatch version required

export MIN_OP=13.9.4.0.0

This gets the installed OPatch version

opv=$(opatch version | head -1 | cut -f2 -d":" | sed 's/^ *//g') # Returns 13.9.3.0.0

And then converts the version number to an array of numbers, splitting on the period

op_ver=(${opv//./ }) # Returns an array - 13 9 3 0 0
op_min=(${MIN_OP//./ }) # Returns an array - 13 9 4 0 0

I then convert each member of the array to a zero padded number and combine to make a 10 digit number

min_total=$(printf "%02d%02d%02d%02d%02d" ${op_min[0]} ${op_min[1]} ${op_min[2]} ${op_min[3]} ${op_min[4]}) # Returns 1309040000
ver_total=$(printf "%02d%02d%02d%02d%02d" ${op_ver[0]} ${op_ver[1]} ${op_ver[2]} ${op_ver[3]} ${op_ver[4]}) # Returns 1309030000

Display a message, either success or failure

if (( $min_total > $ver_total )); then
  echo -e "\nOPatch Version\n~~~~~~~~~~~~~~\nMinimum   : $MIN_OP\nInstalled : $opv\nStatus    : \e[31mFailed - Patch OPatch and retest before continuing.\e[0m\n"
else
  echo -e "\nOPatch Version\n~~~~~~~~~~~~~~\nMinimum   : $MIN_OP\nInstalled : $opv\nStatus    : \e[32mSuccess - Continue patching.\e[0m\n"
fi

Success message example
OPatch Version
~~~~~~~~~~~~~~
Minimum   : 13.9.4.0.0
Installed : 13.9.4.0.0
Status    : Success - Continue patching.
Failure message example
OPatch Version
~~~~~~~~~~~~~~
Minimum   : 13.9.5.0.1
Installed : 13.9.4.0.0
Status    : Failed - Patch OPatch and retest before continuing.
This doesn't stop people ignoring this and continuing without patching but it's an easy way to calculate whether to patch OPatch or not.

Wednesday, 6 March 2019

SSH and sudo

Following on from my blog Fun with SSH here's a way to run sudo and pass the password on the command line in a script.

First you need to get the password from the user or set the password in a variable.

read -s -p "Enter remote user password: " usrpwd

This prompts the user to enter the password, without echoing to the screen and stores it in $usrpwd.

Now we can ssh to the remote server and run a command via sudo.
Here I'm just running date but you can do anything.

ssh raspberrypi sudo -S <<< $usrpwd date
james@raspberrypi's password:
[sudo] password for james: Wed  6 Mar 15:44:44 GMT 2019
If you incorporate this with my previous blog on SSH you can automate the logging into a remote server and running scripts.

As with all of this stuff the easier you make it for yourself the easier it is for somebody else to destroy your servers.

Fun with SSH

SSH to a remote host


This is the simplest way and will prompt for the remote users password every time.

ssh raspberrypi

If you need to login to the remote server under a different username then use:

ssh user@remote-host

If this is the first time you have used ssh to connect to this server you will see the below text.
The authenticity of host 'raspberrypi (xxx.xxx.xxx.xxx)' can't be established.
ECDSA key fingerprint is SHA256:??????????.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'raspberrypi,xxx.xxx.xxx.xxx' (ECDSA) to the list of known hosts.
Enter the remote users password and then you are in.

james@raspberrypi's password:
Linux raspberrypi 4.19.25-v7+ #1205 SMP Mon Feb 25 18:19:20 GMT 2019 armv7l
Last login: Wed Mar  6 10:55:48 2019 from yyy.yyy.yyy.yyy
Logout of the remote connection.

james@raspberrypi:~ $ logout
Connection to raspberrypi closed.

Automatic login to remote host (no password required)


You can set things up to allow you to ssh to a remote host without entering a password.
This is quick, but if you use a common account anybody will be able to login to the remote host without a password.

First you need to generate a key.

james@LAPTOP:~$ ssh-keygen

Accept the default file location and when prompted press enter rather than entering a password.
Generating public/private rsa key pair.
Enter file in which to save the key (/home/james/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/james/.ssh/id_rsa.
Your public key has been saved in /home/james/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:??????????. james@LAPTOP
The key's randomart image is:
+---[RSA 2048]----+
|                 |
+----[SHA256]-----+
Now we need to copy the key to the remote host.

james@LAPTOP:~$ ssh-copy-id raspberrypi
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/james/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
 james@raspberrypi's password:
Number of key(s) added: 1
Now try logging into the machine, with:   "ssh 'raspberrypi'" and check to make sure that only the key(s) you wanted were added.

james@LAPTOP:~$ ssh raspberrypi
Linux raspberrypi 4.19.25-v7+ #1205 SMP Mon Feb 25 18:19:20 GMT 2019 armv7l
Last login: Wed Mar  6 11:00:25 2019 from yyy.yyy.yyy.yyy
james@raspberrypi:~ $ logout
Connection to raspberrypi closed.

Automatic login to remote host (Key password required)


This time we are going to enter a passphrase when we run ssh-keygen to make connecting to the remote host a little more secure.

james@LAPTOP:~$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/james/.ssh/id_rsa):
/home/james/.ssh/id_rsa already exists.
Overwrite (y/n)? y
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/james/.ssh/id_rsa.
Your public key has been saved in /home/james/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:??????????. james@LAPTOP
The key's randomart image is:
+---[RSA 2048]----+
|                 |
+----[SHA256]-----+
james@LAPTOP:~$ ssh-copy-id raspberrypi
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/james/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
 james@raspberrypi's password:
Number of key(s) added: 1
Now try logging into the machine, with:   "ssh 'raspberrypi'" and check to make sure that only the key(s) you wanted were added.
This time connecting to the remote host prompts for the passphrase not the remote password.

james@LAPTOP:~$ ssh raspberrypi
Enter passphrase for key '/home/james/.ssh/id_rsa':
Linux raspberrypi 4.19.25-v7+ #1205 SMP Mon Feb 25 18:19:20 GMT 2019 armv7l
Last login: Wed Mar  6 11:05:14 2019 from yyy.yyy.yyy.yyy
james@raspberrypi:~ $ logout
Connection to raspberrypi closed.

Automatic login to remote host multiple times (Key password required once)


This is slightly different and will prompt for the passphrase once and allow multiple ssh login without prompting again.
It assume that you have already run ssh-keygen and entered a passphrase as in the above example.

Start running the ssh agent for your session.

james@LAPTOP:~$ eval $(ssh-agent -s)
Agent pid 382
Add you key to the agent.

james@LAPTOP:~$ ssh-add
Enter passphrase for /home/james/.ssh/id_rsa:
Identity added: /home/james/.ssh/id_rsa (/home/james/.ssh/id_rsa)
When you ssh to the remote host it will not prompt you for your passphrase.

james@LAPTOP:~$ ssh raspberrypi
Linux raspberrypi 4.19.25-v7+ #1205 SMP Mon Feb 25 18:19:20 GMT 2019 armv7l
Last login: Wed Mar  6 11:09:13 2019 from yyy.yyy.yyy.yyy
 james@raspberrypi:~ $ logout
Connection to raspberrypi closed.
Again, logging in for a second or subsequent times will also not require a password in this session.

james@LAPTOP:~$ ssh raspberrypi
Linux raspberrypi 4.19.25-v7+ #1205 SMP Mon Feb 25 18:19:20 GMT 2019 armv7l
Last login: Wed Mar  6 11:13:49 2019 from yyy.yyy.yyy.yyy
 james@raspberrypi:~ $ logout
Connection to raspberrypi closed.
Kill off the ssh agent.

james@LAPTOP:~$ eval $(ssh-agent -k)
Agent pid 382 killed
If you were now to attempt to ssh to the remote host again it will prompt for the passphrase.

Monday, 4 March 2019

Fix Linux time drift

Had a situation where two VM hosts had different times and the database/OIAM server (server1) was on one host and my Portal/UCM/etc. server (server2) was on the other host and wouldn't start because of the time difference.

Just ran the following on server 2 to get the time back in sync.

sudo date +%T --set $(ssh server1 date +%T)

This gets the time from server1 and uses it to set the time on server 2.

Bash brace expansion

Some examples of Bash's brace expansion.

The values inside the braces are repeated

echo a{b,c,d}e
abe ace ade
And you can embed braces within braces

echo a{b,c,d{e,f}}g
abg acg adeg adfg
Or it can be a sequence inside the braces

echo a{1..10}b
a1b a2b a3b a4b a5b a6b a7b a8b a9b a10b
Also includes an optional increment

echo a{1..10..2}
a1b a3b a5b a7b a9b
A simple real world example

mkdir -p james/{{logs,err}/{server1,server2},src,bin}

This makes the following directories:
james
james/logs
james/logs/server1
james/logs/server2
james/err
james/err/server1
james/err/server2
james/src
james/bin

Friday, 1 March 2019

Bash string and path manipulation

Just some notes on bash variable manipulation.

Sub stringing

name="James"
echo $name ${name} # Same result
James James
echo ${name:0:2} ${name::2} # Print first 2 characters, can omit the zero
Ja Ja
echo ${name::-2} # Remove n characters from the end
Jam
echo ${name:(-2):1} # Start 2 characters from the end and print 1 character
e
len=2
echo ${name:0:len} # Prints first 2 characters (note use of len not $len)
Ja
echo ${cake:-death} # Outputs $cake or the text death
death
cake="cakes"
echo ${cake:-death}
cakes
Moving on slightly to path maniplulation.

fName=/path/to/my/file.name
echo ${fName%.name} # Removes suffix .name
/path/to/my/file
echo ${fName#/path} # Removes prefix /path
/to/my/file.name
echo ${fName%.name}.type # Removes .name and replaces with .type
/path/to/my/file.type
echo ${fName##*.} # Prints the files extension
name
echo ${fName##*/} # Prints filename and extension, equivilent to basename
file.name
echo ${fName#*/} # Removes initial /
path/to/my/file.name
echo ${fName##*/} # Filename and extension
file.name
echo ${fName/a/A} # Replace first occurance of a with A
/pAth/to/my/file.name
echo ${fName//a/A} # Replace all occurances of a with A
/pAth/to/my/file.nAme
echo ${fName/%name/NAME} # Replace suffix
/path/to/my/file.NAME
echo ${#fName} # Print the length
21
a1=test
a3=${a2-$a1} # a3 = $a2 or $a1 if $a2 not set
a4=${a2-"this is a test"} # a3 = $a2 or "this is a test" if $a2 not set

echo "a1=$a1 : a2=$a2 : a3=$a3 : a4=$a4"
a1=test : a2= : a3=test : a4=this is a test
echo ${a5:=$a1} # Set a5 to $a1 if not set
test
echo ${a1:+$a4} # Prints $a4 id $a1 is set
this is a test
echo ${a2:?value is not set} # Prints error message is a2 not set
bash: a2: value is not set
: '
This is how
you print a
multi line
comment
'

Thursday, 28 February 2019

Oracle automatically start WebLogic 12c components

Short note on how to start Oracle WebLogic 12c components, e.g. OHS, automatically without prompting for a username and password.
export DOMAIN_HOME=/u01/app/oracle/domains/base_domain
$DOMAIN_HOME/bin/startComponent.sh ohs1 storeUserConfig
This will start ohs1 and prompt you for a username and password.

It will then store these credentials so subsequent starts/stops will not prompt you.

Wednesday, 27 February 2019

Linux - Store Oracle Transparent Encryption pass phrase remotely

I've setup Transparent Database Encryption (TDE) on one of my databases.
I don't want to use auto login or local auto login as that would defeat encrypting the database in the first place.
I do want to automatically open the wallet when I startup the database.

Here's how I fixed it.

First, as root, I need to mount a remote file system and add it to /etc/fstab.

As the Oracle user I need to generate my RSA private and public keys.
openssl genrsa -out ~/.rsa_key.pri 2048
openssl rsa -in ~/.rsa_key.pri -out ~/.rsa_key.pub -outform PEM -pubout
This creates two hidden files, the private key (.rsa_key.pri) and public key (.rsa_key.pub) in my home directory.

Now I need to pass my TDE pass phrase to openssl for it to encrypt and write to my remote file system.
echo "MyPassPhrase" | openssl rsautl -encrypt -inkey ~/.rsa_key.pub -pubin -out /remotefs/folder/file.name
Now I can use the following in a script to open the wallet without knowing or having to enter the TDE pass phrase.
passPhrase=$(openssl rsautl -decrypt -inkey ~/.rsa_key.pri -in /remotefs/folder/file.name)
sqlplus -s / as sysdba <<!
administer key management set keystore open identified by "$passPhrase";
!
You can easily wrap these commands in a script and use alongside dbstart in systemctl or manually.

Tuesday, 26 February 2019

Oracle Database Proxy Authenticated Connections

Not sure how long this has been available but we like this at work.

On an Oracle 12c database, login as sys as sysdba.

Create two users:
create user James identified by James;
create user Ben identified by Ben;
grant create session to James;
grant create session to Ben; 
Now grant Ben the ability to connect through to James:
alter user James grant connect through Ben;
Now you are able to connect as Ben without knowing his password.
connect Ben[James]/Ben
show user
USER is "JAMES"
So you can see that even though we are logging in as Ben, using the [] brackets we are actually logging in as James;

Oracle CPU downloader

Every quarter I have to go through and download numerous patches for the Oracle CPU (Critical Patch Update). You have to view the CPU docume...