Posts etiquetados ‘scripting’

How to define “hotkeys” in bash

Publicado: septiembre 20, 2010 en fast-tip, linux/unix, sysadmin, trick
Etiquetas:, , ,

For instance, I will define a hotkey to get manual page of current command without execute it (ideal for F1).

First, you get the code of the “hotkey” you want to use by pressing “Ctrl+U+<hotkey>”. For example:

* Ctrl+L: ^L
* Ctrl+J: ^J
* F1: ^[OP

This code may vary from terminal to terminal.

First you define an function, called single-man, to execute man of the first argument:

single-man() { man $1; }

Then, you add a line like this one in your .inputrc:

 "^[OP" "\C-A\C-K single-man \C-Y\C-M\C-Y"

What the hell does this? Well, when “F1” is pressed, in will simulate the press of “Ctrl+A”, that goes to the begining of the line, “Ctrl+K” that copies current line to clipboard, “Ctrl+Y” that pastes the clipboard, “Ctrl+M” that press Enter and Ctrl+Y that pastes the clipboard one more time.

I use this trick since several years ago.

The AIX service secldapclntd “Provides and manages connection between the AIX LDAP load module of the local host and LDAP Security Information Server, and handles transactions from the LDAP load module to the LDAP Security Information Server.”

This services fails too often. Each new version of AIX, brings new failures in this services. Failures appear more often if the LDAP server has a lot of users and groups.

When it fails:

  • sometimes does not reply, its hung
  • sometimes it consumes all CPU and lasts a lot to reply
  • sometimes it simply dies with a core.

This script will check and monitor it and restart it if necesary.

You can test this script stoping the service:

kill -STOP $(ps -fea| grep -v grep |grep /usr/sbin/secldapclntd| awk '{print $2}' )

You can add an entry to cron to execute it:

if crontab -l | grep /usr/local/bin/check-secldapclntd.sh; then
   echo "Already configured."
else
  crontab -l > /tmp/$$.crontab
  cat >> /tmp/$$.crontab <<EOF
# Check secldapclntd each 5 minutes
5,10,15,20,25,30,35,40,45,50,55 * * * * /usr/local/bin/check-secldapclntd.sh check-and-restart > /dev/null
EOF
  crontab /tmp/$$.crontab
  rm /tmp/$$.crontab
fi

And here goes the script (/usr/local/bin/check-secldapclntd.sh):

Sometimes we need to allow some users to remotelly execute commands in a server via ssh, but we want to restrict the commands to execute. There are some solutions around, like restricted shell or wrappers, but we can implement a simply solution using bash and sudo.

The idea is to use the restricted shell functionality in bash. We will simply:

  • Create a new user for this prupose
  • Asign it a script that will restrict the $PATH variable
  • Link there the needed commands (or create scripts that call sudo)
  • Set asymetric keys in ssh.

Here you have all commands for Linux or AIX, but it will work anyway (except the creation of the user).

# You have to set this variables before execute any command
# ---------------------------------------------------
# If we will use sudo for commands or only links
USE_SUDO=yes
# User restricted and commands to link or sudo
RESTRICTED_USER=jailuser
RESTRICTED_COMMANDS="
/somepath/somecommand1
/somepath/somecommand1
/somepath/somecommand1
"
# Remote host where execute commands
REMOTE_HOST=ahost
# final user to execute commands (sudo)
DEST_USER=arealuser
# ---------------------------------------------------



case `uname` in
AIX)
# Add shell script as new user
chsec -f /etc/security/login.cfg -s usw -a shells=$(lssec -f /etc/security/login.cfg -s usw -a shells | cut -f 2 -d =),/home/$RESTRICTED_USER/bin/rbash
mkdir /home/$RESTRICTED_USER/bin

# Create user
mkuser groups=sshcon maxexpired=-1 loginretries=-1 $RESTRICTED_USER

# Do not need to change password
pwdadm -c $RESTRICTED_USER
;;
# At this moment only debian
Linux)
adduser –shell /home/$RESTRICTED_USER/bin/rbash –disabled-password –no-create-home $RESTRICTED_USER
;;
esac

# Create shell script for restricted mode
cat >/home/$RESTRICTED_USER/bin/rbash <<EOF
#!/usr/bin/bash -e
export PATH=/home/$RESTRICTED_USER/bin
f=\$1
if [ “\$1” != “” ]; then
shift
exec /bin/bash \$f “\$*”
else
exec /bin/bash \$*
fi
EOF
chmod +x /home/$RESTRICTED_USER/bin/rbash

# Configure the commands
if [ “$USE_SUDO” == “yes” ]
# Sudoers
for i in $RESTRICTED_COMMANDS; do
[ “$sudocmd” ] || sudocmd=“NOPASSWD:$i” && sudocmd=“$sudocmd,NOPASSWD:$i”
done
sudocmd=“$RESTRICTED_USER ALL=($DEST_USER) $sudocmd”
echo “Add this line to /etc/sudoers: ‘$sudocmd'”

for i in $RESTRICTED_COMMANDS; do
cmdfile=$(basename $i)
cat > /home/$RESTRICTED_USER/bin/$cmdfile <<EOF
#!/bin/sh
exec sudo -u $DEST_USER $i \$@
EOF
chmod +x /home/$RESTRICTED_USER/bin/$cmdfile
done

else
# Link commands
ln -sf $RESTRICTED_COMMANDS /home/$RESTRICTED_USER/bin/
fi

Optionally, in origin server, we create a key and the adapters commands. We can create a common script and link to it the other commands.

# Create key
ssh-keygen -i rsa_id

# Define commands
cat > .$RESTRICTED_USER.$REMOTE_HOST.cmd <<EOF
#!/bin/sh
ssh -T -o IdentitiesOnly yes -o StrictHostKeyChecking=no -i id_rsa \
    $RESTRICTED_USER@$REMOTE_HOST \$(basename \$0) \$@
EOF
for i in $RESTRICTED_COMMANDS; do
    cmdfile=$(basename $i)
    ln -s .$RESTRICTED_USER.$REMOTE_HOST.cmd $cmdfile
done

Finally we add the public key in destination server

mkdir /home/$RESTRICTED_USER/.ssh
cat > /home/$RESTRICTED_USER/.ssh/authorized_keys <<EOF
<here goes your public key id_rsa.pub>
EOF
chown -R $RESTRICTED_USER /home/$RESTRICTED_USER/.ssh

Easy, isn’t it?