How to run command in su mode in bash script? - linux

I need to run these two commands :
ulimit -s 1024
echo 120000 > /proc/sys/kernel/threads-max
The first one can be run just in user mode (not using sudo or su) and the second can only be run in su mode. I want to write a bash script that let me run these two commands. The first one is OK. For the second one, I need to su (change user to root), run the command, and then exit. Actually, I want to run the second command in su mode using a bash script. Any idea?

If your user has permission to use "sudo tee", then one solution is:
echo 120000 | sudo tee /proc/sys/kernel/threads-max

As a security measure, you cannot run scripts as a superuser without prepending sudo. If you want it to be passwordless, you need to run visudo and allow your (or the executing user) to run this command as a superuser without password confirmation.
The other way is to use the setuid bit on compiled code. Compile a simple program which will execute the echo 120000 > /proc/..., then change it to be owned by root: chown 0:0 executable_name, and chmod u+s executable_name to set the setuid bit on it. This will cause execution of this program to be ran with permissions of its owner, which is root.
This is the same way which allows passwd to modify a file which requires super-user privileges without actually being a super-user or sudoer.

Related

How to execute 'iftop' without sudo

I have a script that runs iftop in text mode, cuts down the output to what I'm concerned in, and saves it to a text file along with the output of the date command (I am monitoring network usage on various interfaces over time). Only problem I'm having is I'm trying to run my script every 15 minutes via the crontab, and in order to run the iftop command I need sudo permissions. Does anyone know some way to change the permissions of iftop to make it so I don't need sudo permissions?
Alternatively if I can give the script the ability to run the command with sudo that would be fine by me as well. I tried adding the script to the sudoers file via sudo visudo and adding the line:
user ALL=(ALL) NOPASSWD: /home/user/network_usage.sh
but that didn't work...perhaps a result of executing from the crontab?
Thanks,
-Eric
A more granular approach would be to use:
# setcap cap_net_raw=eip $(which iftop)
This lets iftop capture packets but does not give the process full root privileges. In case of a security problem or bug with "iftop" its side effects would be much more limited.
Related: https://unix.stackexchange.com/questions/189750/how-can-i-run-script-without-root-to-sniff-network-libpcap
If you have root access on the machine the quick and dirty way:
chmod +s $(which iftop)
This will make it run w/ root privileges no matter who invokes it.
But I still think your sudo like should work.
You may use root's crontab to run the script.
If instead of crontab -e you use sudo crontab -e you will edit root's crontab. Tasks specified in that file will run under root's account and privileges.
Alternatively, you can set the setuid access flag for your script file. To do so first change the owner of the file to root, then enable setuid like this:
sudo chown root /home/user/network_usage.sh
sudo chmod +s-w /home/user/network_usage.sh
The setuid bit makes an executable file run with the effective UID of its owner.
Regardless of what approach you take, be very careful.
Make your script owned by root and don't let any other user write to it, otherwise it could ease a privilege escalation.
Be aware of the side effects of your setuid programs. If the script has setuid and may create or modify files, it might be used by someone else to modify or create files they aren't supposed to. Always check the manual before giving setuid to any program you haven't written.

shell script to shutdown/restart Linux system

Is there any suitable shell script for shutting down or restarting a Linux machine? I have tried a shell script for shutdown, but when I enter sudo shutdown it will ask for the password. How we can enter the password using the script?
Another, in my opinion cleaner approach:
Create a new file in /etc/sudoers.d/ with content:
%users ALL=NOPASSWD: /sbin/shutdown
%users ALL=NOPASSWD: /sbin/reboot
This causes sudo to not ask for the password, if any user of group "users" tries to execute a shutdown or reboot. Of course you can also specify another group, maybe a newly created group for finer control of reboot permissions.
More information about the other possible settings for sudo can be found in the Manpage.
Yes, use the -S switch which reads the password from STDIN:
$echo <password> | sudo -S <command>
So to shut down the machine, your command would be like this (just replace <password> with your password):
$echo <password> | sudo -S poweroff
Exposing your password is generally bad idea search for something that can protect / hide it. In the past I've used Jenkins plugins to do this while executing the scripts regularly.
if you really want to achieve it, you should write a script containing the shutdown command; make root be its owner, then set the SUID bit with the chmod command and give to it executable permission for everybody. When executed, the owner of the script would become root and no password should be asked.

Shell script getting superuser privilege without being run as sudo

Here is my script:
script.sh:
sudo cat /etc/passwd-
If I am in a sudo session (e.g I ran an other command with sudo a few minutes ago), and now run
script.sh
The script will get sudo access. However if I run cat /etc/passwd-/, I will get a permission denied error.
As a user, I wouldn't expect script.sh to be able to get super user privileges so simply (e.g without me giving access to superuser privileges with sudo script.sh).
Is this expected behavior ?
Is it configurable ?
I see that behavior as being completely similar to sudo su, e,g potentially giving superuser access to any script you run in that session, but even worse, because you might not even be aware of it, and don't know when it ends (at least not without checking manually)
Is this expected behaviour ?
Yes, indeed, it is expected behavior. User's cached credential for sudo is responsible for it.
Is it configurable?
Yes, it is configurable.
And I think your security concern is a valid one. Running script.sh in a terminal where a sudo command is run before (within a certain timeout), will give the script superuser privilege if the script is written with explicit sudo commands.
You can avoid any script not prompting for a password when run as sudo by running it with:
sudo -k script.sh
It will ask for a password regardless of any previous sudo command/s or session.
And to run script.sh without sudo i.e with just script.sh and still prompt
for a password for the sudo command/s:
You can change the timeout value (the duration sudo maintains the session) permanently:
run sudo visudo
Then change the line:
Defaults env_reset
To
Defaults env_reset,timestamp_timeout=0
Save and exit (ctrl+X then Y)
This will ensure that sudo asks for a password every time it is run.
Or If you don't want to change it permanently and want your script to prompt for password at least once (while maintaining a session), then you can change your script like this:
sudo -k first-command-with-sudo
sudo second-command
sudo third
and so on
This script will prompt for password at least once regardless of any previous sudo command/s or session.
In case you are unaware of (or don't have access to) the content of the script script.sh (it can have sudo commands inside it or not)
And you want to be sure that any sudo command will surely prompt for password at least once, then run sudo -K (capital K) before running the script.
Now if you run script.sh and if it contains a sudo command, it will surely prompt for password.

Use sudo without password INSIDE a script

For some reason I need, as user, to run without sudo a script script.sh which needs root privileges to work.
I saw as the only solution to put sudo INSIDE script.sh. Let's take an example :
script.sh :
#!/bin/sh
sudo apt-get update
Of course, if I execute this script, I get a prompt asking me for a password. Then I added to my sudoers file (at the end to override everything else) :
user ALL=(ALL:ALL) NOPASSWD:/path/to/script.sh
By the way, I also tried the line :
user ALL=(ALL) NOPASSWD:/path/to/script.sh
(I think I didn't fully understand the difference)
But this doesn't solve my problem if I don't use sudo to execute this script :
# ./script.sh
[sudo] password for user:
# sudo ./script.sh
Starts updating...
Well, so I say to myself "Ok, that means that if I have a file refered in sudoers as I did, it will work without prompt only if I call him with sudo, what is not what I want".
So, ok, I create another script script2.sh as following :
script2.sh
#!/bin/sh
sudo /path/to/script.sh
In fact it works. But I am not truly satisfied of this solution, particularly by the fact that I have to use 2 scripts for every command.
This post is then for helping people having this problem and searching for the same solution (I didn't find a good post on it), and perhaps have better solutions coming from you guys.
Feel free to share your ideas !
EDIT 1 :
I want to insist on the fact that this "apt-get update" was just an example FAR from whhat my script actually is. My script has a lot of commands (with some cd to root-access-only config files), and the solution can't be "Well, just do it directly with apt-get".
The principle of an example is to help the understanding, not to be excuse to simplify the answer of the general problem.
From my blog: IDMRockstar.com:
The kicker is that sometimes, I need to run commands as root. Here's the quick and dirty way I accomplish that without divulging the passwords:
#! /bin/bash
read -s -p "Enter Password for sudo: " sudoPW
echo $sudoPW | sudo -S yum update
This way the user is prompted for the password (and hidden from terminal) and then passed into commands as needed, so I'm not running the entire script as root =)
If you have a better, way, I'd love to hear it! I'm not a shell scripting expert by any means.
Cheers!
.: Adam
If you want to run sudo /usr/bin/apt-get update without a password, you need to have the sudoers entry:
user ALL=(ALL:ALL) NOPASSWD:/usr/bin/apt-get update
For the larger issue of the script as a whole, there are two possible approaches:
Approach 1
For each command in the script that needs sudo, create a line in sudoers specifically for that command. In this case, the script can be called normally:
./script1.sh
Approach 2
Place a line in sudoers for the script as a whole. When this is done, the individual commands do not need sudo. However, sudo must be used to start the script as in:
sudo ./script.sh
If your password isn't something you want to be very secure about, (maybe some testing server in the company etc.) you can elevate to sudo in the script via echo like:
echo YourPasswordHere | sudo -S Command
The prompt still prints the "enter password" text to output though. So don't expect it to be neat.
See this Askubuntu post
As you noted, the file that must appear in the sudoers configuration is the one that is launched by sudo, and not the one that runs sudo.
That being said, what we often do, is having something like
user ALL=(ALL:ALL) NOPASSWD:/path/to/script.sh
in the sudo configuration, where script.sh has all the commands that the script has to do.
Then we define either a Bash function or an alias so that script.sh is actually
sudo /path/to/script.sh
The only issue is if some commands must not be run as root, you need to insert some su - user -c "command" commands in the script.
In new /etc/sudoers.d/apt-get file, put single line:
user ALL=(ALL:ALL) NOPASSWD:/usr/bin/apt-get update
Fully qualified path to executable is required here.
Then use following in your script:
sudo apt-get update
Here, fully specified name is not required. Sudo uses PATH environment variable for executable resolution.
While changing and checking sudoers configuration, be sure to keep another root session open for error recovery.
I suggest you look at the sudo environment variables - specifically you can use (and check for) $SUDO_USER. Call your script with sudo (1 entry in sudoers), then do user stuff as SUDO_USER and root stuff as root.
As mentioned by Basilevs you need to add your user to the sudoers file in order to avoid that sudo commands in the script get stuck awaiting the password.
On Ubuntu 16, there is a simpler way: just add the user to the sudo group, like this:
sudo usermod -aG sudo *username*
From then on, it should work like a charm.
Note:
This works only on the condition that the following line is in file /etc/sudoers:
%sudo ALL=NOPASSWD: ALL
(such line gives passwordless sudo privileges at group level, in this case to the sudo group)
(if this line is not present and you want to add it, make sure you use visudo)
Simply, in order to execute commands as root you must use su (even sudo uses su)
As long as you execute sudo ./script2.sh successfully just instead :
sudo su
"#" //commands as root here
"#" exit
//commands as use here
you can make it a shell function with the name sudo, but no other better way i think,however it's the case with scripts inti,rc android ..etc
must be tidy ;)
however this requires you to put NOPASSWD: su wich is totaly secure indeed
any way here just lacks POISX permissions principle which is filtering so dont enable something to all users or vice versa
simply, call sudo as much as you want with no additional thing then:
chown root script.sh
chmod 0755 script.sh
chgrp sudo script.sh
"make root owner of .sh"
"make it read only and exec for others"
"and put it in sudo group"
of course under sudo
that's it

How to supply sudo with password from script?

Please note: this is a guest VM (VBox) running on my local machine, and I'm not worried about security.
I am writing a script that will be executed on a Linux (Ubuntu) VM as the myuser user. This script will create a very large directory tree under /etc/myapp. Currently I have to do all this manually, and it starts with me giving myuser recrusive rwx permissions under /etc like so:
sudo chmod -R 777 /etc
[sudo] password for myuser: <now I enter the password and hit ENTER>
My question: how do I write a bash script that supplies the sudo command with my password so that I can just execute bash myscript.sh and it will make the necessary permission changes for me?
(BASH)
OK, if you've gotta do it, (keeping security warnings in mind):
$ sudo -S < <(echo "<your password>") <your sudo command>
If, as you say, you completely don't care about security...
Run visudo to edit /etc/sudoers with validation in place. Add the following line:
ALL ALL=(ALL) NOPASSWD: ALL
This will prevent sudo from ever asking for a password, for any user, for any command.
You can use expect or autoexpect. It's a bad idea, though.
Never put system passwords into writing. At least, not on a file on said system. Much less on an install script known to require root access. You're making yourself an easy target.
What you do instead, is configure sudo via /etc/sudoers/ to allow exactly that user to execute exactly that script without a password:
myuser ALL=(ALL) NOPASSWD : /path/to/script
Note:
If you remove the /path/to/script part, myuser will be able to sudo anything with no password.
If you change myuser for ALL, everyone will be able to run that script with no password.

Resources