Switch to root user within bash script - linux

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)

Related

Hide plaintext password from showing in bash script?

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

linux difference between "sudo crontab -e" and just "crontab -e"

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!

How to run Cron Job to creates files as User file instead of root file

Why the output file from this is owned by root and not w3svcsadm?
sudo -u w3svcsadm echo "TEST ran" > /home/your/emaildigest/TEST_$( date +%Y%m%d%H%M%S ).output
I'm running into some issues with cron, and I believe this is the key to my problems.
Using the -u flag with sudo executes the command 'echo "TEST ran"' as the user w3svcasadm, but that command isn't the thing doing the work of outputting to a file, which is done by the '>' operator. By the time bash is using that operator, it's already switched back to the user running the shell. If that user is root, then the file will be created under root. In your script, you could use "su w3svcsadm" to switch the shell user before executing that command, then you wouldn't have to use that -u flag at all.

Linux: how to change maximum number of files a process can open?

I have to execute a process on a cluster of machines. Size of cluster is of order 100. So I cannot execute processes manually, I have to execute them by script(which uses ssh, currently I am using python-paramiko for this). Number of tcp sockets these processes open is more than 1024(default limit of linux.) So I need to change that using {ulimit -n 10000}. This makes the changes for that shell session only. And this command works only with root user. So my script is not able to do that.
I tried to execute this command
sudo su && ulimit -n 10000 && <commandToExecuteMyProcess>
But this didn't work. The commands after "sudo su" didn't execute at all. They execute only when I logout of the su session.
This article shows way to make the changes permanently. But when I open limits.conf, I didn't find anything there. It only has some commented notes.
Please suggest me some way to increase the limit permanently or change it by script for each session.
That's not how it works: sudo su just opens a new shell so you can introduce commands as root, and after you exit that shell it executes the rest of the line as normal user.
Second: your this is a special case because ulimit is not actually a program, but a bash shell built-in command, so it must be used within bash, that is why something like sudo ulimit -n 10000 won't work: sudo can't find that program because it doesn't exist.
So, the only alternative is a bit ugly but works:
sudo bash -c 'ulimit -n 10000 && <command>'
Everything inside '...' will execute in a bash session of the root user.
Note that you can replace && with ; in this case: that's because it is being executed as root and ulimit -n 10000 will always complete successfully.

Detect use of su command in bash

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.

Resources