Running Process as Unprivileged User - linux

On Linux system, how does one run a process as a different, unprivileged user (like how lighttpd is run by www-data in the default setup)?
I've been using su $user; $command & over ssh, but those processes get killed when I logout.
If it makes any difference, I'm using a default Ubuntu setup on EC2.

su $other_user -c 'nohup sleep 600 &'

nohup $command </dev/null >/dev/null 2>/dev/null &
or
command </dev/null >/dev/null 2>/dev/null &; disown

Related

Why is Crontab not starting my tcpdump bash script capture?

I have created a simple bash script to start capturing traffic from all interfaces I have in my Linux machine (ubuntu 22), but this script should stop capturing traffic 2 hours after the machine has reboot. Below is my bash script
#!/bin/bash
cd /home/user/
tcpdump -U -i any -s 65535 -w output.pcap &
pid=$(ps -e | pgrep tcpdump)
echo $pid
sleep 7200
kill -2 $pid
The script works fine if I run it, but I need to have it running after every reboot.
Whenever I run the script, it works without problem
user#linux:~$ sudo ./startup.sh
[sudo] password for user:
tcpdump: data link type LINUX_SLL2
tcpdump: listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 65535 bytes
1202
35 packets captured
35 packets received by filter
0 packets dropped by kernel
but when I set it in the crontab as
#reboot /home/user/startup.sh
it does not start at reboot. I used ps -e | pgrep tcpdump to make sure if the script is running but there is not an output, it seems that it is not starting the script after the reboot. I don't know if I need to have root permissions for that. Also, I checked the file permission, and it has
-rwxrwxr-x 1 user user 142 Nov 4 10:11 startup.sh
Any suggestion on why it is not starting the script at the reboot?
Suggesting to update your script:
#!/bin/bash
source /home/user/.bash_profile
cd /home/user/
tcpdump -U -i any -s 65535 -w output.pcap &
pid=$(pgrep -f tcpdump)
echo $pid
sleep 7200
kill -2 $pid
Suggesting to inspect crontab execution log in /var/log/cron
The problem here was that even though the user has root permission, if an script needs to be run in crontab at #reboot, crontab needs to be modified by root. That was the only way I found to run the script. As long as I am running tcpdump, this will require root permission but crontab will not start it at the boot up if it is not modified by sudo.

SSH direct command execution with nohup

I can directly exec the command with this.
ssh ubuntu#myroot.com ls -la
However I want to use command like nohup sh heavytask.sh &
Even after quitting connection this task continues works.
So,what I try this
ssh ubuntu#myroot.com nohup sh heavytask.sh &
However it needs to wait task finished.
Is there any solution for this purpose?
I/O redirection should fix your issue, e.g.:
ssh ubuntu#myroot.com "nohup sh heavytask.sh > /dev/null 2> /dev/null < /dev/null &"

How to know PID of the process ran by remote ssh

If I run a process at the remote site by using ssh as follows:
nohup ssh remote sleep 100 &
Is there a way to know the PID of sleep at remote?
Trying echo $! just returns the PID of ssh at local.
And, greping won't work since there are multiple sleep processes at remote.
You could pass a string to ssh so try
nohup ssh remote 'sleep 100 &; echo $!'
Try the following
nohup ssh remote 'sleep 100 > out 2> err < /dev/null & echo $!'

Sudo - Waiting for child, and getting child PID

It seems that somewhere between sudo 1.7.2p2 and 1.7.4p5 the behaviour for waiting for executing processes has changed. It looks like in the older versions sudo would start the new process, and then quit. In the newer versions it starts the new process, and then waits for it. There is a bit of a discussion about it here: http://www.sudo.ws/pipermail/sudo-users/2010-August/004461.html which mentions that it is to stop it from breaking PAM session support.
This change is breaking one of my scripts which uses sudo to execute commands in the background, as with the older version sudo the command I want to execute would be backgrounded, and with the new version it is sudo itself that is backgrounded.
For example, the process returned by $! in this case is for sleep
user#localhost$ sudo -V
Sudo version 1.7.2p2
user#localhost$ sudo -u poweruser sleep 60 &
[1] 17491
user#localhost$ ps -fp $!
UID PID PPID C STIME TTY TIME CMD
poweruser 17491 17392 0 16:43 pts/0 00:00:00 sleep 60
Whereas in this case it is for sudo
user#localhost$ sudo -V
Sudo version 1.7.4p5
user#localhost$ sudo -u poweruser sleep 60 &
[1] 792
user#localhost$ ps -fp $!
UID PID PPID C STIME TTY TIME CMD
root 792 29257 0 16:42 pts/3 00:00:00 sudo -u poweruser sleep 60
Is it possible to get the process ID for a child process executed by sudo version 1.7.4p5? The $! variable returns the PID for sudo, and running sudo with the -b option doesn' seem to make the child PID available. Is it possible (without recompiling sudo) to revert the behaviour of sudo to stop it from waiting for child processes?
Thanks
This is certainly a hack, and it doesn't set $!, but you can echo the pid of the command:
$ sudo sh -c 'echo $$; exec sleep 60'
I'm guessing that your explanation of the old behavior is not quite right and that sudo simply exec'd the command rather than forking and exiting. Echoing the pid and then exec'ing the desired command might work for you, but you may need creative redirections. For example:
#!/bin/sh
exec 3>&1
pid=$( sudo sh -c 'echo $$; exec sh -c "{ sleep 1;
echo my pid is $$; }" >&3 &')
echo Child pid is $pid
In the above, you lose the pid of sudo...but it wouldn't be too hard to find it.

how to terminate a process which is run with sudo? Ctrl+C do it, but not kill

At my company, some commands are allowed to run with sudo, such as tcpdump. Others not.
I expect run tcpdump for a while, and then stop it.
When I run tcpdump, and I could abort that with Ctrl+C
I wrote a shell script like this -
#!/bin/sh
sudo tcpdump -ieth1 -w ~/dump.bin
sleep 5
kill -2 $!
it doesn't really work. The process of tcpdump is run as root, and current user is a normal account.
My question is: is there any way to do the equivalent of ctrl c in bash script?.
EDIT:
ps:As my company's security policy, I cannot run kill as root.
Try the -Z option to tcpdump. It instructs tcpdump to drop root privileges and run as the user specified in the argument.
sudo tcpdump -Z $USER -ieth1 -w ~/dump.bin
Now try killing that process.
Simply run kill through sudo as well:
sudo kill -2 $!
This way the kill process will have the privilege to send signals to a process that runs as root.
For programs that don't have special switches like -Z and in case you can alter sudoers file, this is a solution:
sudo myprogram &
sleep 5
sudo pkill myprogram
All I have to do is to allow to run pkill myprogram passwordless by using visudo and adding this line:
myuser ALL=(ALL) NOPASSWD:/bin/pkill myprogram
This is less dangerous that lo let sudo kill any program.
The timeout command also terminates a program after so long. sudo timeout 5 tcpdump -ieth1 -w ~/dump.bin should accomplish the same thing as the script.
sudo tcpdump -Z root -w ~/dump.bin -n -i eth0 -G 300 -W 1
G - Timeout Seconds (After timeout period the comman gets killed automatically)
Z - drop root and runs as user privilege
W - Number files to be saved (as a splitted file)
sudo tcpdump -ieth1 -w ~/dump.bin
will block your script, you need to put it into the background:
sudo tcpdump -ieth1 -w ~/dump.bin &
.
This and the answer from Blagovest should do it.

Resources