Archive

Archive for the ‘Bash’ Category

SSH private/public keys with passphrase and agent manager

2012-12-04 Leave a comment

Managing multiple systems that you only have access to by ssh can be annoying when you have to keep typing in ssh <HOST/IP>; then typing your password on each system.

This article explains how to use ssh pub/priv key pairs with a passphrase and ssh-agent.
The goal is to make logging in remotely more secure by using key pairs along with a passphrase but only having to use the passphrase once in a given time period.

First you’ll need to generate your own private/public key pair on the system you’ll be sshing FROM using the following command.

$ ssh-keygen -t rsa -b 4096 -f ~/.ssh/<ROLE>_rsa -C "Comment goes here"
Enter file in which to save the key (/home//.ssh/id_rsa):
Enter passphrase (empty for no passphrase):

NOTES:
You should never give your private key file or it’s contents to anyone. Think of it like a key to your house anyone that has it can access your “house”(server).

  • The comment just helps to let you know what the key is used for. I normally put the server(s) I’m going to push the public key too in the comments. This could be considered a minor security risk labeling where the key is used.
  • Some systems default to DSA, I recommend RSA 2048 bits or higher for the keys hence the keygen options -t rsa -b 4096. Two short write ups about DSA vs RSA can be found and .
  • Do not leave the passphrase empty as the worst case someone gets hold of your private key or gains access to your account they at least have to know the passphrase (back to the previous way of using just a password for security) to use it. An empty passphrase means anyone with the key can enter the server if they know which server the key is used on (hence the comment security risk).
  • If you generate more than one key pair and use the same passphrase, entering the passphrase will make all the key pairs that use that passphrase active at the same time.

Now that we have the keys generated the next step is to copy the .pub key text to the remote servers .ssh/authorized_keys file. I wrote this little bash script as a wrapper for the command used to publish the key. It prompts for what user to ssh with and the server host/ip then the ssh-copy-id command will prompt for the users password. It will automatically create the .ssh directory and append the key to the authorized_keys file. If your system doesn’t have ssh-copy-id I have included a bash 1 liner below the script that will check if the .ssh directory exists and create it then append the public key to the authorized_keys file.

if [[ -z "$sshusername" ]] && [[ -z "$serverIPaddress" ]] ; then
## Prompt for the user name to use
echo -en "\nIs $USER the account you want to use? \n" ;
select yn in "Yes" "No"; do
case "$yn" in
Yes ) sshusername="$USER" ; break ;;
No ) read -p "Type the username you want to use: " sshusername ; break;;
esac
done ;
echo -en "\n" ;

## Prompt for the server name or IP
read -p "Type the Hostname or IP address of the server: " serverIPaddress ;
echo -en "\n" ;

## The actual command to copy the key over
ssh-copy-id "$sshusername"@"$serverIPaddress" ;

## Clean up of the vars we used
unset sshusername ;
unset serverIPaddress ;
else
## The system uses the variables?!?
echo -en "Your system currently has the following variables set.\n sshusername AS $sshusername\n serverIPaddress AS $serverIPaddress\n\n";
fi ;

One way to push the new pub key to the server is by using the ssh-copy-id binary command. If you are using some other port besides 22 you’ll need to include the username/host and port option all in quotes.

#ssh-copy-id -i <path to pub key> "username@host/ip -p <port>"
ssh-copy-id -i .ssh/id_rsa.pub lifeforce4@example.com
ssh-copy-id -i .ssh/id_rsa.pub "lifeforce4@example.com -p 9999"

Bash one liner for pushing public key to remote system if youre unable to use ssh-copy-id. Be sure to put the correct and <HOST/IP> settings for the ssh command.

cat ~/.ssh/id_rsa.pub | ssh @<HOST/IP> 'if [[ -z "$HOME/.ssh" ]] ; then mkdir $HOME/.ssh ; fi ; cat - >> ~/.ssh/authorized_keys'

Now we should have a priv/pub key par in our .ssh folder and on the remote system our public key should be in the authorized_keys file. To test if it’s working ssh to the system. You should be prompted with the following instead of the @<HOST/IP>’s password:

$ssh server
Enter passphrase for key '/home//.ssh/id_rsa':

Upon entering the correct passphrase you will now be logged in to the remote system. Exit out of the system and try sshing again you’ll notice you get prompted again for the passphrase. Great all this seemed to do was add an extra layer of security but didn’t stop the annoying issue of each time having to enter a password/passphrase.

Now it’s time to use a key manager such as ssh-agent which allows us to enter the passphrase once and after that anytime we try to ssh to any server that has our public key we’ll get direct access (for a given amount of time before we have to reenter the passphrase).

On my systems I create two alias commands some people want to have their system prompt for the password when they open a session the first time I prefer to start start it when I need too that way if a day I don’t need to ssh to a server (it happens some times…) my shell doesn’t have access.

The two aliases I use are below.

## type agent once on the machine your are using unless the time elapses or the system was rebooted
## Removes the old hostname agent file
## starts the agent with 28800 seconds (8hrs) to be active in memory
##   and story the environment variables to access the keys in memory in the .agent file
## run the .agent file as a Tlc script and then add the private key identities to the authentication agent
alias agent='rm -f "$HOME"/.ssh/`hostname`.agent ; ssh-agent -t 28800 | grep -v echo > "$HOME"/.ssh/`hostname`.agent ; source "$HOME"/.ssh/`hostname`.agent ; ssh-add'

## Any new shells you just need to run this alias to have them use the agent in memory
alias sshagent='if [ -e "$HOME"/.ssh/`hostname`.agent ]; then source "$HOME"/.ssh/`hostname`.agent ; fi'

Now you have the generated keys with the remote system(s) having the public key in the auth file and you are able to use an agent so you only have to enter your passphrase once allowing you to ssh to any systems with the public key with out any prompts.

A system is only as secure as it’s user.

Categories: Bash, Computers, Linux, Security

Bash Color Logs

2012-05-17 Leave a comment

Simple little function that will tail a log and color the lines accordingly. With the option to exclude any lines with a given regex, currently does not work on active tails using the -f option. Copy it into your .bashrc or .bash_profile.

#####
## Program:
##    Log tail with color and option to remove lines
## Author:
##    Kyle Rizzo
##    lifeforce0 {at} gmail {dot} com
##    https://lifeforce4.wordpress.com
## Summary:
##    Simple little function that will tail a log and color
##    the lines accordingly. With the option to exclude any
##    lines with a given regex.
#####
ctail()
{
   if  [ $# -eq "3" ] ; then
      tail $1 $2 | eval "perl -pe 's/.*$3.*\n//g'" | perl -pe 's/^.*SEVERE.*$/\e[0;31;40m$&\e[0m/g; s/^.*FATAL.*$/\e[0;31;40m$&\e[0m/g; s/^.*ERROR.*$/\e[0;31;40m$&\e[0m/g; s/^.*CRIT.*$/\e[1;31;40m$&\e[0m/g; s/^.*WARN.*$/\e[1;33;40m$&\e[0m/g; s/^.*DEBUG.*$/\e[1;36;40m$&\e[0m/g; s/^.*INFO.*$/\e[0;32;40m$&\e[0m/g; s/^.*VERB.*$/\e[1;37;40m$&\e[0m/g';
   elif [ $# -eq "2" ]; then
      tail $1 $2 | perl -pe 's/^.*SEVERE.*$/\e[0;31;40m$&\e[0m/g; s/^.*FATAL.*$/\e[0;31;40m$&\e[0m/g; s/^.*ERROR.*$/\e[0;31;40m$&\e[0m/g; s/^.*CRIT.*$/\e[1;31;40m$&\e[0m/g; s/^.*WARN.*$/\e[1;33;40m$&\e[0m/g; s/^.*DEBUG.*$/\e[1;36;40m$&\e[0m/g; s/^.*INFO.*$/\e[0;32;40m$&\e[0m/g; s/^.*VERB.*$/\e[1;37;40m$&\e[0m/g';
   elif [ $# -eq "1" ]; then
      tail $1 | perl -pe 's/^.*SEVERE.*$/\e[0;31;40m$&\e[0m/g; s/^.*FATAL.*$/\e[0;31;40m$&\e[0m/g; s/^.*ERROR.*$/\e[0;31;40m$&\e[0m/g; s/^.*CRIT.*$/\e[1;31;40m$&\e[0m/g; s/^.*WARN.*$/\e[1;33;40m$&\e[0m/g; s/^.*DEBUG.*$/\e[1;36;40m$&\e[0m/g; s/^.*INFO.*$/\e[0;32;40m$&\e[0m/g; s/^.*VERB.*$/\e[1;37;40m$&\e[0m/g';
   else
      echo -en "Usage: \e[1;36;40mctail -f /Path/to/log/file\e[0m\n       \e[1;36;40mctail -f /Path/to/log/file excludeText\e[0m\n       \e[1;36;40mctail -100 mylog.txt '(SEVERE|FATAL|ERROR)'\e[0m\n       \e[0mNote: Removing lines will only work if you're not actively tailing a file with the \e[1;36;40m-f\e[0m option.\e[0m\n";
   fi
}

Create a temp log file to test each level.

for level in VERBOSE DEBUG INFO WARN CRITICAL ERROR CRIT FATAL WARNING VERB SEVERE;do tempdate=`date`; echo $tempdate $level Random text that is about the msg >> mylog.txt; tempnum=$RANDOM;sleep $((tempnum %= 9)); done
Categories: Bash, Computers, Linux, Perl, Programming

Basename Changer from listed text file

2012-04-18 Leave a comment
#!/bin/bash
#####
## Program:
##    Basename Changer from List
## Author:
##    Kyle Rizzo
##    lifeforce0 {at} gmail {dot} com
##    https://lifeforce4.wordpress.com
## Summary:
##    
##    
##    
#####

## Coloring Schemes
NC='\033[0;37m'
RED='\033[1;31m'
YELLOW='\033[1;33m'
BLUE='\033[1;34m'
CYAN='\033[1;36m'
WHITE='\033[1;37m'

files=($(ls *.mp3))
i=0
## read the file namelist.txt which has on each line
## a different file in the order that the users wishes
## the files located 
cat namelist.txt | while read j

## A loop to cycle though the 
do
    echo mv "${files[ $i ]}" "$j"
    (( i = i + 1 ))
done
Categories: Bash, Linux, Programming

Run perl command in bash script [complicated variables]

2011-08-17 Leave a comment

A simple little command that gets the epoch time of a file using perl and bash.

#!/bin/bash
f=/dir/struct/test.file
## Resolve the $f var before running the perl line by having the perl command in double quotes
## Double escape the perl var so the shell does not resolve it.
mtime=`perl -e "\\$t = (stat('$f'))[9]; print \\$t;"`
echo $mtime
Categories: Bash, Linux, Perl, Programming

List all users Crontab one liner

2011-08-01 Leave a comment

This grabs each user on the system from the passwd file and then checks to see if they have a crontab and prints out the results.

for u in $(cut -f1 -d: /etc/passwd); do sudo crontab -u $u -l; done
Categories: Bash, Linux, Programming

Dir/File space2score

2010-09-06 Leave a comment

I wrote this little script because I had to manage a task for creating a file naming scheme. It will replace all spaces in file names and subdirectories of a given directory with an underscore.

#!/bin/bash
#####
## Program:
##    File/Directory Formatter
## Author:
##    Kyle Rizzo
##    lifeforce0 {at} gmail {dot} com
##    https://lifeforce4.wordpress.com
## Summary:
##    This little script will search though all files and subdirs of a given
##    location then starting from the bottom up will replace ' '(spaces) with
##    '_' underscores.
#####

## Coloring Schemes
NC='\033[0;37m'
RED='\033[1;31m'
YELLOW='\033[1;33m'
BLUE='\033[1;34m'
CYAN='\033[1;36m'
WHITE='\033[1;37m'

## Find only Files with spaces and replace the spaces with underscores
#find $1 -depth -type f -name '* *' -print | while IFS= read -r file; do
## Find only Directories with spaces and replace the spaces with underscores
#find $1 -depth -type d -name '* *' -print | while IFS= read -r file; do
## Find any files/directories from the given path if none specified used ./
## and replace spaces with underscores in all names.
find $1 -depth -name '* *' -print | while IFS= read -r file; do
   file=$file
   basedir=${file%/*}
   filename=${file##*/}
   newfilename=$(echo "$filename" | tr -s ' ' _)

   echo -en "\n$WHITE"
   echo -en "Renaming $CYAN$filename$WHITE to $YELLOW$newfilename$WHITE \
in $BLUE$basedir/"

## Check if the file is a directory or a file with in a directory.
## Set newfile accordingly
   if [ ! "$basedir" = "$file" ]; then
      newfile="$basedir/$newfilename"
   else
      newfile="./$newfilename"
   fi

## Check to see if a file exists with that name
## Refuse to over wright the file if it does.
   if [ ! -e "$newfile" ]; then
      mv "$file" "$newfile"
   else
      echo "$RED\Refusing to overwrite $BLUE$newfile"
   fi
done
echo -en "$NC\n"
Categories: Bash, Computers, Linux, Programming

Bash color code selector.

2010-09-03 Leave a comment
#!/bin/bash
#####
## Program:
##    Linux Term Colors - bash script
## Author:
##    Kyle Rizzo
##    lifeforce0 {at} gmail {dot} com
##    https://lifeforce4.wordpress.com
## Summary:
##    This script will display all the different color combination's for a
##    terminal tested on Bash 3.2.25(1). Then prompt the user with a menu
##    that they can create their own color scheme. It will also display
##    the escape sequence required to make that scheme.
##    These special escape sequences can be used with any language for a
##    linux terminal.
##
##    "\E[" begins the escape sequence, you can also use "\033" or "\x1B".
##
##    Semicolon-separated numbers "HEW" "COLOR1" and "COLOR2".
##    Note: The foreground and background numbers do not overlap so order
##          does not matter, for formatting reasons I will have it always
##          be Foreground then Background.
##
##    "m" terminates the escape sequence, the text begins immediately after.
##
##    FG hew bit: 0/1 (dark/light)
##    Foreground Colors: 3x
##    Background Colors: 4x
##
##    x representing a different color
##       0 = Black   1 = Red
##       2 = Green   3 = Yellow
##       4 = Blue    5 = Magenta
##       6 = Cyan    7 = White
#####

NC="\e[0;37;40m" ## No Color (reset to default)
SELECTION=0 ## The user selection of the menu
FGBOLD=0 ## Default foreground bold/lightness
FGCOLOR=37 ## Default foreground color 'gray'
BGCOLOR=40 ## Default background color 'black'
ENDM="m" ## End the escape sequence

menu ()
{
   echo -en "Menu)\n\t\
1) Display color table\n\t\
2) Set foreground color \n\t\
3) Set background color \n\t\
4) Display selected colors \n\t\
5) Quit\n> ";
read -e SELECTION;
}

displayTable ()
{
   echo -en "B;FG;BG\t";
   for i in {40..47};
   do
      echo -en "  $i\t";
   done
   echo;
   for fg in {30..37};
   do
      for h in {0..1};
      do
         echo -en "$NC$h;$fg";
         for bg in {40..47};
         do
            echo -en "\t\e[$h$ENDM\e[$fg$ENDM\e[$bg$ENDM  RgB  ";
         done
         echo;
      done
   done
   ## Reset the console to no colors.
   echo -e $NC;
}

setFG ()
{
   displayTable
   echo -en "Set the foreground color number [3x]: ";
   read -e FGCOLOR;
   echo -en "Light|Bold text y/n: ";
   read -e FGBOLD;
   if [ "$FGBOLD" == "Y" ] || [ "$FGBOLD" == "y" ]; then
      FGBOLD=1
   else
      FGBOLD=0
   fi
}

setBG ()
{
   displayTable
   echo -en "Set the background color number [4x]: ";
   read -e BGCOLOR;
}

testColors ()
{
   echo -en " \e[$FGBOLD;$FGCOLOR;$BGCOLOR$ENDM";
   echo -en " This is a test of the colors you selected.";
   echo -en "$NC \\";
   echo -en "e[$FGBOLD;$FGCOLOR;$BGCOLOR$ENDM\n";
   echo -e "$NC========================================================\n\
Press enter if you can not read the text above the line.";

}

main ()
{
   while [ "$SELECTION" -ne 5 ]
   do
      menu
      case "$SELECTION" in
         1 )
            clear;
            displayTable
            ;;
         2 )
            clear;
            setFG
            ;;
         3 )
            clear;
            setBG
            ;;
         4 )
            clear;
            testColors
            ;;
         5 ) exit 0;;
         * )
            clear;
            menu
      esac
   done
}

displayTable
main
Categories: Bash, Computers, Linux, Programming