I would like to know if there is anyway to send a mail as soon as someone tries su -, su or su root. I know the mail command and I am trying to write a script but I am very confused as to
where to write it - whether in .bashrc of root or in /etc/process
how to invoke the mail on the use of su
I've tried the usual Google search etc. but got links on usage of su, disabling it, securing ssh etc - none of which answered this question.
Thanks in advance
I guess that your underlying requirement is that you have a bunch of people you have given root privilege to but you don't completely trust them so you want to keep an eye on them. Your solution to this is to get yourself sent mail whenever they become root.
The problem with this solution is that the root user has unlimited privilege and so there's nothing to stop them from counteracting this mechanism. They could for instance, edit the /etc/login.defs file in one session, do the good thing that you want them to do and then later su to root and do the bad thing that you fear and at the end of that session they edit the /etc/login.defs file back to it's original state and you're none the wiser. Alternatively they could just make a copy of /usr/bin/bash and make the copy a suid file that will give them privilege whenever they run it.
You might be able to close any of the vulnerabilities I've just suggested but there will be many, many more. So you either trust them or else don't use su at all and give them sudo permission to run just those commands that they need to do the thing you want them to do.
There's a log file called /var/log/secure which receives an entry any time su is executed. It gets entries under other conditions as well. It's described in the Linux Administrator's Security Guide.
If user "fred" executes su -, an entry will appear which looks something like this:
Jul 27 08:57:41 MyPC su: pam_unix(su-l:session): session opened for user root by fred(uid=500)
A similar entry would appear with su or su root.
So you could set up a script which monitors /var/log/secure as follows:
#!/bin/sh
while inotifywait -e modify /var/log/secure; do
if tail -n1 /var/log/secure | grep " su: "; then
tail -n1 /var/log/secure | grep " su: " | mail -s "su occurred" you#email.com
fi
done
Note that you need to have the inotify-tool package installed to use inotifywait.
If this script is running in the background, it should send an email to you#email.com any time an su entry occurs.
Now where to run the script. One approach would be to put this into an executable script file (say, watchsu) and call it from your rc.local file:
nohup /path/to/watchsu 2>&1 &
I'm sure there are other ideas for where to start it. I'm not familiar with CentOS.
According to the man page for su, in /etc/login.defs you can set either SULOG_FILE file or SYSLOG_SU_ENABLE yes to log all su activity. Then you just need something like inotifywait to watch the log file for su events.
Related
Im currently logged in as admin and I want to edit the /etc/hosts file which required root access.
I'm not able to make the changes. The script gets executed sucessfully but the changes arent made.
My Script - Runs Sucessfully when executed from terminal
sudo -s
echo "127.0.0.1" >> /etc/hosts
su admin
sudo -s - switches to root without password when executed from terminal
su admin - switches back to admin user when run on terminal
My /etc/hosts file remains empty after running the script
There is no need to actually switch your user within the script.
Also, you can't echo something as root like that because the redirect (>>) is executed by the shell.
A possible workaround is using tee:
echo "127.0.0.1" | sudo tee -a /etc/hosts
Further explanation:
tee basically takes the data from the standard input and writes it either to the standard output, or to a file. For more information see the commands manual ($ man tee)
I have the following bash script to restart the network manager in Debian. The script works as is it should, but not as I would like it to. When the script asks for the sudo password I am able to pass it along using echo, but it displays the password in terminal while the script executes, making it less asthetically pleasing than I would like. Is there anyway to have the script enter the password, but not display the password text while the script calls for the sudo password?
I have tried as many suggestions on Stack Overflow as i could find, well as Stack Exchange before submitting this question.
Script is as follows:
#!/bin/bash
clear
echo "Restarting service Network Manager"
echo""
sleep 1
echo -e "\033[0;31m......................................\033[0m"
echo -e "\033[0;31m......................................\033[0m"
sleep 1
echo""
sudo service network-manager restart
sleep 2
echo <Password>
sleep 2
echo "Service Network Manager Restarted"
sleep 1
echo ""
echo "Relinquishing control of terminal to user..."
sleep 7
clear
Remove the echo <Password> line? I am pretty sure it does nothing other than display the password, as sudo apparently (through an appropriate entry in /etc/sudoers) works without you having to give a password. (What you write to terminal with echo does not get passed to any other process.)
Generally speaking, you can use sudo -S to make sudo expect the password on stdin. But also generally speaking, if you have to hardcode a password in a script, you're doing it wrong in some way.
Is there anyway to have the script enter the password
Putting password in script is not a good idea. First, from security point of view, password may be recovered from script from anyone with access to script. Second, from maintenance view, once you change your password, scripts suddenly stop working and you have to update them all.
Fortunately, as you are already using sudo there is better solution. You can configure sudo to allow running certain command without password, by using NOPASSWD rule in /etc/sudoers.
myuser ALL=(ALL) NOPASSWD: service network-manager restart
See:
How do I run specific sudo commands without a password?
How to run a specific program as root without a password prompt?
Warning: Always edit /etc/sudoers with visudo, never directly. It prevents you from breaking /etc/sudoers. Once you break your /etc/sudoers, you won't be able to use sudo, including using sudo to fix /etc/sudoers.
try this /bin/echo -e "password\n" | sudo apt-get update
or see this Use sudo with password as parameter
I noticed that when I typed sudo crontab -e I dont see my cron command, but when I do only crontab -e there is my command.
Is there a difference between the 2? If there is, where should I put my cron command, should it be in sudo or without the sudo?
Thanks!
Is there a difference between the 2?
Yes, indeed they are different.
The difference is that with sudo crontab -e the commands are schedule with root user's credentials. So that the commands in the sudo's cron table are executed as root user.
But with crontab -e, the commands are scheduled with the regular user who is logged in.
Where should I put my cron command, should it be in sudo or without the sudo?
Well, the answer to this depends on the type of command you want to run.
If the command required sudo access then sudo crontab -e should be used.
Else if the cron command doesn't require any special permission then use crontab -e.
Example:
If the ethernet network interface eth0 should be disabled or enabled at specific time then you would use the command
ifconfig eth0 up or ifconfig eth0 down
As the above commands require special permission (sudo), these commands are supposed to added to sudo's cron tab
Any other command which require minimal permission or no permission like removing a file from tmp directory like $ rm /tmp/somefile use the regular user's crontab.
Main part of the problem is to take care of the user with whom you wanna make your things done. Otherwise it will not trigger your cron job. And do make sure that you write output of your command in any file. It will help you to debug the problem which most probably might relate to your relative paths.
That's what I faced difficulties in. You can move forward following the below step:
identify your username with which you wanna go. Use whoami command.
Turn to your selected user mode and type crontab -e.
And append line < cron-schedule your-command >> output_filename.cron 2>&1 >
That's it.
Thanks!
I usually have to login in 20 to 50 times daily as a super user, typing the long password again and again..
i have just created a simple bash script
#!/bin/bash
sudo -s
echo password
./test
output root#localhost:
password
when i execute it, it works like charm... but it shows my password on the screen.....
do some one have any other best solution...... for this small problem.......
i hope this is not all the solution in security standard...... can we have any other solution with out exposing my password.....
You can pipe the echo'd password into a command. Try something like this:
echo myPassword | sudo -S
You can see come more info on this here.
Question is, do you REALLY want your password in a shell script file? (just emphasizing that its a terrible idea)
Is there a reason that you can't sudo su - to just become the root user instead of prepending all of your commands with sudo blah?
just change ownership of the script to root & set SUID-Bit in user the permissions
chmod u=rws g+x o+x script123
the script will run as root for every user
You can configure sudo to require a password only every so many minutes. The default is 5 minutes. Read the sudoers man page and scroll down to this:
timestamp_timeout
Number of minutes that can elapse before sudo will ask
for a passwd again. The timeout may include a
fractional component if minute granularity is
insufficient, for example 2.5. The default is 5. Set
this to 0 to always prompt for a password. If set to a
value less than 0 the user's timestamp will never
expire. This can be used to allow users to create or
delete their own timestamps via sudo -v and sudo -k
respectively.
simple solution is to use key base authentication
Use ssh-copy-id instead following from this tutorial which is secure
Services default to starting as root at boot time on my RHEL box. If I recall correctly, the same is true for other Linux distros which use the init scripts in /etc/init.d.
What do you think is the best way to instead have the processes run as a (static) user of my choosing?
The only method I'd arrived at was to use something like:
su my_user -c 'daemon my_cmd &>/dev/null &'
But this seems a bit untidy...
Is there some bit of magic tucked away that provides an easy mechanism to automatically start services as other, non-root users?
EDIT: I should have said that the processes I'm starting in this instance are either Python scripts or Java programs. I'd rather not write a native wrapper around them, so unfortunately I'm unable to call setuid() as Black suggests.
On Debian we use the start-stop-daemon utility, which handles pid-files, changing the user, putting the daemon into background and much more.
I'm not familiar with RedHat, but the daemon utility that you are already using (which is defined in /etc/init.d/functions, btw.) is mentioned everywhere as the equivalent to start-stop-daemon, so either it can also change the uid of your program, or the way you do it is already the correct one.
If you look around the net, there are several ready-made wrappers that you can use. Some may even be already packaged in RedHat. Have a look at daemonize, for example.
After looking at all the suggestions here, I've discovered a few things which I hope will be useful to others in my position:
hop is right to point me back
at /etc/init.d/functions: the
daemon function already allows you
to set an alternate user:
daemon --user=my_user my_cmd &>/dev/null &
This is implemented by wrapping the
process invocation with runuser -
more on this later.
Jonathan Leffler is right:
there is setuid in Python:
import os
os.setuid(501) # UID of my_user is 501
I still don't think you can setuid
from inside a JVM, however.
Neither su nor runuser
gracefully handle the case where you
ask to run a command as the user you
already are. E.g.:
[my_user#my_host]$ id
uid=500(my_user) gid=500(my_user) groups=500(my_user)
[my_user#my_host]$ su my_user -c "id"
Password: # don't want to be prompted!
uid=500(my_user) gid=500(my_user) groups=500(my_user)
To workaround that behaviour of su and runuser, I've changed my init script to something like:
if [[ "$USER" == "my_user" ]]
then
daemon my_cmd &>/dev/null &
else
daemon --user=my_user my_cmd &>/dev/null &
fi
Thanks all for your help!
Some daemons (e.g. apache) do this by themselves by calling setuid()
You could use the setuid-file flag to run the process as a different user.
Of course, the solution you mentioned works as well.
If you intend to write your own daemon, then I recommend calling setuid().
This way, your process can
Make use of its root privileges (e.g. open log files, create pid files).
Drop its root privileges at a certain point during startup.
Just to add some other things to watch out for:
Sudo in a init.d script is no good since it needs a tty ("sudo: sorry, you must have a tty to run sudo")
If you are daemonizing a java application, you might want to consider Java Service Wrapper (which provides a mechanism for setting the user id)
Another alternative could be su --session-command=[cmd] [user]
on a CENTOS (Red Hat) virtual machine for svn server:
edited /etc/init.d/svnserver
to change the pid to something that svn can write:
pidfile=${PIDFILE-/home/svn/run/svnserve.pid}
and added option --user=svn:
daemon --pidfile=${pidfile} --user=svn $exec $args
The original pidfile was /var/run/svnserve.pid. The daemon did not start becaseu only root could write there.
These all work:
/etc/init.d/svnserve start
/etc/init.d/svnserve stop
/etc/init.d/svnserve restart
Some things to watch out for:
As you mentioned, su will prompt for a password if you are already the target user
Similarly, setuid(2) will fail if you are already the target user (on some OSs)
setuid(2) does not install privileges or resource controls defined in /etc/limits.conf (Linux) or /etc/user_attr (Solaris)
If you go the setgid(2)/setuid(2) route, don't forget to call initgroups(3) -- more on this here
I generally use /sbin/su to switch to the appropriate user before starting daemons.
Why not try the following in the init script:
setuid $USER application_name
It worked for me.
I needed to run a Spring .jar application as a service, and found a simple way to run this as a specific user:
I changed the owner and group of my jar file to the user I wanted to run as.
Then symlinked this jar in init.d and started the service.
So:
#chown myuser:myuser /var/lib/jenkins/workspace/springApp/target/springApp-1.0.jar
#ln -s /var/lib/jenkins/workspace/springApp/target/springApp-1.0.jar /etc/init.d/springApp
#service springApp start
#ps aux | grep java
myuser 9970 5.0 9.9 4071348 386132 ? Sl 09:38 0:21 /bin/java -Dsun.misc.URLClassPath.disableJarChecking=true -jar /var/lib/jenkins/workspace/springApp/target/springApp-1.0.jar