I wrote a shell script to hook into a password protected database. A couple of others want to use the same shell script to share the database access, but I don't want to expose the password that is being used. Is there a way to lock the script so that no one can read it and only execute it? It'd also be ideal for them to enter their sudo password to run the script
Is there a way to lock the script so that no one can read it and only
execute it? It'd also be ideal for them to enter their sudo password
to run the script
Sure. Let's say the script containing the credentials is /usr/local/bin/myscript. Make this file owned by a privileged user. Let's say we have a user named "credentials":
# chown credentials /usr/local/bin/myscript
# chmod 700 /usr/local/bin/myscript
Now only the credentials user can read and execute this script.
Create another script /usr/local/bin/mywrapper that looks like this:
#!/bin/sh
exec sudo -u credentials /usr/local/bin/myscript
And create the appropriate /etc/sudoers entry:
auser ALL=(credentials) /usr/local/bin/myscript
So now, user auser runs "mywrapper". This in turn uses sudo to call the real script, which will prompt auser for their password.
I think this does everything you want. We use a mechanism very much like this at my office to protect credentials (in our case, ssh private keys).
In order to execute a shell script, you have to be able to read it. There are a couple of things you could do:
Who administers this database? Could the users get their own passwords for read only access? That would be ideal because it could limit their access to a small subset of the database.
If they have to have sudo access to run this script, maybe it's possible to remove the password out of the file and into a file that has 600 permissions set. The problem is that this could leak. For example, what if they run the script with set -xv? Then, they could see the password as the script executes.
Can you create a subset of data they might be interested in outside of the database? Then, have your script access that?
Or, you might want to take a look at several read-only modules in Perl. I'm thinking something like Acme::EyeDrops or Acme::Bleach which remove all those unsightly letters and numbers from your Perl script. (And I wonder why Python programmers say Perl is unreadable?)
Related
I have a post-commit hook in my subversion that will export a copy of my repo to a desired location for deployment. That part works fine, but it comes in with apache:apache. I need this to be changed to prod_user:prod_user. If I try to add a chown statement in my script, it will fail. If I try to use sudo, it will ask for a password that I cant give because this happening in a post-commit script. I'd like this to be as automated as possible.
My question is: How can I make this work? I need to export the contents of my repo to the production folder and convert the users/groups to match existing production users/groups.
Is there a way to pass my password as an argument to a sudo command?
Thank you for your help!
Is there a way to pass my password as an argument to a sudo command?
Don't do it, if at all possible. This will leak your password to anyone that can read the script.
But if you can't avoid it, use echo <password> | sudo -S <command> - -S makes sudo read from stdin so you can give it the password from there
Don't do any of sudo, chown, chgrp. It is not the responsibility of the uploader to fix permissions on the remote server.
Have the server administrator properly setup these, so that pushing production files from the repository works straight without messing with sudo permission at the server.
If you are the one same person, then take the time to fix the server side to avoid having a remote user elevate its privileges (even temporarily with sudo) for the sake of fixing uploaded files permissions.
Use crontab -e as root user, then you can change ownership without escalation of privileges.
Or run as prod_user and make it check out the code ...then it is already the owner of the files.
Keeping a file with the last deployment timestamp can be used to compare to HEAD timestamp.
Background
I have a long bash script which setup a large environment of interconnected software, taking several hours to complete. A few of the tasks it performs need to be run as root, for which I use sudo .... The whole process is then paused until the user notices and types in the root password. I seek some way for the user to type in the root password only at the beginning of the script, and then automatically supply it when required by sudo later.
My thoughts on possible (bad) solutions
I could store the password directly in a variable and then supply it using
echo "${root_password}" | sudo -S ...
but something tells me that this is bad practice.
Another workaround would be to force the user to run the entire script as root, but wouldn't that lead to different permissions for all of the files generated without the use of sudo?
You can prompt it at the start of your script, so it is not plain text hard saved.
Example:
#!/bin/bash
read -s -p "[sudo] sudo password for $(whoami): " pass
echo $pass | sudo -S apt-get update
help read:
-r do not allow backslashes to escape any characters
-s do not echo input coming from a terminal
I suggest you figure out all of the commands you need the script to run using SUDO, ensure the script is run by a special unprivileged user (e.g. scriptuser), and then edit /etc/sudoers to permit scriptuser to run those commands with NOPASSWD
As an example:
scriptuser ALL = NOPASSWD: /bin/kill, /usr/bin/othercommand, etc.
If you know the complete commands, including arguments, that's ideal (it means that an attacker that compromises the scriptuser account can only run those specific commands as root)
Sudo has a lot of options configurable in /etc/sudoers. If you man sudoers , you should see all of them. Forewarning: This man page is very hard to understand. Find examples. Test them. Ask on StackExchange.
I want to run the following sample bash script which needs sudo password for a command
#!/bin/bash
kinit #needs sudo password
vi hello.txt
while running the above script it is asking for password.
How can i pass the username and password in the command itself or is there any better way i can skip passing my password in the script ?
TL;DR
You can't—at least, not the way you think.
Longer Answer with Alternatives
You have a couple of options:
Authenticate interactively with sudo before running your script, e.g. sudo -v. The credentials will be temporarily cached, giving you time to run your script.
Add a specific command such as /usr/lib/klibc/bin/kinit to your sudoers file with the NOPASSWD option. See sudoers(5) and and visudo(8) for syntax.
Use gksudo(1) or kdesu(1) with the appropriate keyring to cache your credentials if you're using a desktop environment.
One or more of these will definitely get you where you want to go—just not the way you wanted to get there.
So if you have access to your full system, you can change your sudoers file to allow certain sudo commands to be run w/o a password.
On the command line run visudo
Find your user and change the line to look something like this:
pi ALL=(ALL) NOPASSWD: /path/to/kinit, /path/to/another/command
That should do it. Give it another shot!
Hope that helps
You shouldn't pass username and password. This is not secure and it is not going to work if the password is changed.
You can use this:
gksudo kinit # This is going to open a dialog asking for the password.
#sudo kinit # or this if you want to type your password in the terminal
vi hello.txt
Or you can run your script under root. But note that vi is going to be ran as root as well, which means that it will probably create files that belong to root, that might be not what you want.
I have to write a shell script to run some commands on unix. I have to switch several users.
How can I give passwords inside my script?
Note: I am not a root user. Also, security is not an issue in this case, so I could write passwords in my script.
Since you don't have root access, and assuming the programs you want to run aren't setuid, you have two basic choices:
Write an expect script to drive su - <username> and run your commands as child processes of expect.
Have someone with root access give you sudo access to the commands and users you need, and then run your commands with sudo -u <username> <command>.
Option 1 is best if you can't get administrative support, but option 2 is more flexible and easier to script from a Unix shell.
I'm trying to write a bash script that sets up my web development environment in ubuntu. As part of the process of setting up the script, it needs to edit files that are owned by root. It also needs to create fields in the public_html directory of the user that runs the script.
Should I therefore require that the script be run as the superuser? If it should, then how do I get it to access the current user's username? I would normally use the $USER variable, but I can't do that if the script is being run as the superuser. If I'm not the superuser, how can I get the script to request super user privileges for certain operations, while not requiring the user to type in a password for every operation that requires super user privileges.
Thanks
You can use the -E flag for sudo to preserve the environment variables, or, you can set up sudoers to preserve the environment on a per-command basis.
You can also set up the sudoers file to not ask for a password on a per-command basis, for example, to allow user xy to use smbmount without asking for a password:
xy ALL=NOPASSWD: /usr/bin/smbmount
In your case, it would be enough to just store the current user in a variable before invoking sudo, and use the already saved username:
CURRENT_USER=$USER
sudo yourscript.sh $CURRENT_USER
Then read the username from $1.
You can also use the SUDO_USER env variable, which is set to the user who is invoking sudo.
Insert a check at the top of the script:
# Make sure only root can run this script
if [[ $EUID -ne 0 ]]; then
echo "This script must be run as root" 1>&2
exit 1
fi
In this way when you run it without the root privileges you will be prompted, then you can simply rerun it the right way with:
sudo yourscript.sh
More infos at http://www.cyberciti.biz/tips/shell-root-user-check-script.html
There's a command named sudo for this purpose. It lets you specify that certain users can run certain commands as root (or another user).
If your users have root access anyway, you could just write a script that must be run as root and takes an username as parameter, instead of picking up the username.
Alternatively, one way of picking up the login username in an interactive shell is:
stat -Lc %U /proc/self/fd/0
This retrieves the ovner of the tty associated with stdin.
Just make it a setuid file. Or use sudo which is probably safer, since you can limit who gets to run it.
chmod 4755 script.sh
In Ubuntu, there's the SUDO_USER environment variable.
So, you can just run your script sudo somescript.sh and have it pull the invoking user's username $SUDO_USER.
Not sure on other dists, though.