Adding a startup script to ubuntu

Its quite trivial but I have seen lot of people struggling for it including me. So here it goes -

write the startup script. say foo.sh in /etc/init.d folder. I dont need tell that it is to be done as root.

#!/bin/sh

start()
{
#launch your binary. For example if you want to lauch svnserver as a daemon at startup then

if ps -ef | grep "svnserve -d" | grep -v grep
then
echo svnserver is already running as a daemon
else
svnserve -d
fi
}
stop()
{
#stop your binary. You can do it by retrieving the PID and killing it
if ps -ef | grep "svnserve -d" | grep -v grep
then
var=`ps -ef | grep "svnserve -d" | grep -v grep | awk '{ print $2 }'
kill $var
else
echo svnserver is already stopped
fi
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
start
stop
;;
*)
echo "Usage - foo.sh start/stop/restart"
;;
esac



Once the script is done run -

update-rc.d foo.sh defaults

This will add the symbolic links for different run levels

Make the script executable
chmod +x foo.sh

Now whenever you will reboot, foo.sh will invoke your binary.

SSH

We use this every now n then, isnt it ?

I was recently looking into it, for setting up a secure remote login on an embedded device.

So, heres the picture that I see

installing an ssh server is as easy as everything else in ubuntu -
sudo apt-get install openssh-server

And of course, for any other device other than PC a cross compiled version will be required. Sometimes the X86 binaries work as they are on some of the devices, provided the device's arechitecture is X86 based too.

There are two steps in ssh authentication :
1. Host authentication
2. User authentication


1. Host authentication - This is the first step and it happens as soon as we try to set up a communication channel between two machines using SSH. Considering the two machines as an embedded device and a Linux box here, if we want to login onto the device from Linux box using SSH then we need to have the public key of device listed in ~/.ssh/known_hosts file of Linux box where '~' is the home of user who wants to log in, say 'root'. If the public key of device has not been listed in the 'known hosts' file before hand then instead of failing, the Linux box will issue a 'unverified key' warning which can be easily ignored and the public key of the device (sent by device to the machine for verification) can be added into the list right there. So, this step does not give a very strong stand for preventing an unauthorized access (unless strictly configured). But this is mandatory, so there can be two approaches -


i) Leave the job of adding public key of device into the list till the time of login when the warning can be ignored and key can be added forcibly, which does not sound very legal.


ii) Generate a public/private key pair for the device and copy private key on all other devices (if its required on multiple devices) . The public key should be added into the list of 'known hosts' in Linux box before login. The same public key will facilitate host authentication for all the devices.


2. User authentication - This is the second step and it happens only after successful host authentication. This happens as a series of requests sent by Linux box to the device. The request can be a key of a user or a password. So, if the first request fails then second request is sent and so on. To explain -


i) Key based authentication - For key based authentication of a user 'root' we need to copy the public key of 'root' in 'authorized_keys' file on the device at proper location. The location sometimes changes based on the server. For example, for openssh server it will be in the ~/.ssh/ folder however for "dropbear" server the location is '/etc/dropbear/authorized_keys'. At the time of authentication, the device encrypts a random string with the public key of 'root' and sends it to Linux box. If the box is able to decrypt it correctly with the private key of 'root' and send back the correct string to device then the user is considered authenticated. The keys can be protected using a passphrase at the time of generation for better security.


ii) Password based authentication - Password based authentication is equally secure since the password is sent over the channel in encrypted format. SSH authentication works like a fall back mechanism, so, if the key based authentication fails then it will automatically ask for password.


note: this division of host authentication and user authentication is not standard. I have just pictured them for better understanding.

setuid not working - Ubuntu

Ok, I am posting it here because I struggled a lot with this, sought/got lot of help and finally got this :-)

If you want to run any script as a root forever, I mean, no matter who starts the script, it should run as a root then lay back because Ubuntu wont let you do it easily.

Ideally, to run any script as root irrespective of who starts it, root should own it and the user id of script should be set to root. It goes like this -

on your root prompt i.e. sudo su - root
create your script, say foo.sh

and let root own it
chown root:root foo.sh

then set the UID
sudo chmod 4755 foo.sh

exit the root prompt and run your script as a normal user. It should run as root. BUT the sad part is that it does not.

The newer versions of ubuntu (I have tested on 9.04+) don't allow setting the uid for scripts. So even if you set it, it will automatically revert back or not work as expected.

But there is a ray of hope. You can still set the uid for binaries. So here it goes -

write a small c program which takes the name of your script as a parameter and runs it :-)

#include
int main(int argc, char* argv[])
{
system(argv[1]);
return 0;
}

compile it and set uid for its binary
gcc foo.c -o foo
sudo chown root:root foo
sudo chmod 4755 foo

Make your script executable
chmod 755 foo.sh

and you are done



execute the binary with name of your script as a parameter, something like this

./foo ./foo.sh

and the script will run under root :-)

To mention a use case - I was using Hudson CI tool which was supposed to invoke a shell script and the script required root privileges. This solution worked just perfect for me