This question already has answers here:
sudo echo "something" >> /etc/privilegedFile doesn't work [duplicate]
(15 answers)
bash alias using sudo returning command not found
(2 answers)
Closed 1 year ago.
I have the following alias in my .bashrc file,
alias genpass="tr -dc A-Za-z0-9 </dev/urandom | head -c 13 ; echo ''"
alias savepass='echo "$1: $(genpass)" >> .secret'
alias getlastpass='tail .secret -n 1
the intention of this alias is to generate a password and later being able to retrieve the last one. I'm storing the passwords in a file called .secret with the following permissions,
-rw------- 1 root root 92 Sep 17 12:48 .secret
so in a way that only root user can read and write the file.
So the problem that I'm facing here is the following one, when I try to run
sudo savepass
is returning me
bash: .secret: Permission denied
Which I assume is because when this alias is not been executed as root, which is the owner of this file.
I don't know how to solve this, so any help is welcome, and any criticism related to this form of storing password is also welcome. My final goal is to be able to store password from the terminal and be able to retrieve it later, in a save way. If you know a better way to do this, just let me know, it will also be a valid answer. Just keep in mind that I want to do this from the terminal without installing any fancy program, just bash script.
If your unprivileged user can alter the file, why do you store it with root permissions? This does not give you any benefit. Store the file with the user id of the user who needs to read and write it and stop using sudo.
The problem in your solution is, that echo is run with root permissions. But the redirection is still done by the shell running the sudo. And that shell does not have root permissions.
If you still want to keep your approach, you have to run tee -a by sudo. For this you have to put the sudo in the alias. But now it might be better to write a function instead of an alias.
savepass () {
echo "$1: $(genpass)" | sudo tee -a .secret
}
Btw: if you want to store your passwords in clear text files, use the netrc syntax, used by other tools, too.
Related
This question already has answers here:
Bash script runs one command before previous. I want them one after the other
(2 answers)
Closed 3 years ago.
I tried to use the following bash to access the content of a folder;
test_dir="/some_dir/dir_test"
ssh -t -t user#remote-host "
if [ -d '$test_dir' ]; then
sudo chown -R user:admin '$test_dir'
echo '$test_dir'/*
if [ '$(ls -A $test_dir)' ]; then
sudo rm -rf '$test_dir'/*
echo '$test_dir'/*
fi"
the script tried to check if /some_dir/dir_test is empty or not, if not, delete all files in that folder; but I got the following error;
ls: cannot access '/some_dir/dir_test': No such file or directory
/some_dir/dir_test
drwxr-xr-x. 3 sys admin 16 Sep 23 15:03 dir_test
However, I can ssh to remote-host and ls -A /some_dir/dir_test.
I am wondering how to fix it.
$(ls -A $test_dir) is being executed locally on the client, not the server. You need to escape the $. You'll also need to use " around it, otherwise the command substitution won't be executed.
if [ \"\$(ls -A $test_dir)\" ]; then
Often the best way to execute multiline commands is to use scp to copy a script to the remote machine, then use ssh to execute the script. Mixing local and remote expansion of variables and command substitutions gets complicated, especially when you need to quote them.
Premise
I couldn't find a tool or script that would rename multiple files (100+) in the manner I needed it to. So I tried to write a Bash Script utilizing the 'mv' command.
Problem
The script does it's job and renames most of the files but then randomly outputs the 'Operation Not Permitted' error while renaming the files.
Error Output
mv: cannot move 'filename.extension' to 'newFilename.extension': Operation not permitted
The Script
a=1
for i in *.<extension>; do
newName=$(printf "%03d <filename>.<extension>" "$a") #03 = Amount of 0 Padding you want to add
sudo mv -i -- "$i" "$newName"
let a=a+1
done
Thank You in advance for any possible help.
It is rarely a good idea to have sudo inside scripts. Instead, remove the sudo from the script and run the script itself with sudo:
sudo myscript.sh
That way, all commands within the script will be run with root privileges and you only need to give the password once when launching the script.
Instead of putting sudo in the script remove it and run the script using sudo.
sudo script.sh
If that still doesn't work make sure your user id is in the sudoers file so you will have the necessary root privileges.
I am trying to create a bash script that starts with the user executing a sudo -s command.
This is my script:
#!/bin/bash
SSH_USER=testuser
SUDO_PASSWD=secretpassword
FILE=/www/a/logs/service.log
MACHINES=( 'machine1' );
for HOST in ${MACHINES[#]}; do
ssh -t -l "$SSH_USER" "$HOST" "echo '$SUDO_PASSWD' | sudo -Ss chmod 777 $FILE"
done
I feel like this script should not prompt me for the password but it does. I do not want to have to input the password 30 different times. I have tried multiple versions where I hard code the password into the script but I still get prompted to enter in a password. HELP ME PLEASE. I'm VERY new at creating bash scripts and need some serious guidance.
The idea you have there will never work as sudo(1) does not read passwords from standard input unless it's a terminal. Hardcoding passwords into a script is also very bad idea, as pointed out repeatedly in comments.
If you really want to make this happen (I recommend against it), you should do edit /etc/sudoers in your target machine to let you run sudo(1) without it asking a password for things you need to be done without a password. For that you should not let yourself run any chmod command lines without a password, but instead create a script in target machine (for example ยด/usr/local/bin/do-my-promiscuous-chmod`) then tell sudo to let you run just that script without asking a password.
For example adding the following to /etc/sudoers will let user "foo" run /usr/local/sbin/do-unsafe without a password and with root privileges:
foo ALL = (root) NOPASSWD: /usr/local/sbin/do-unsafe
Agree with Sami, no hardcoding password in scripts.
more suggestions.
If the script needn't run as root, and can be run by some other application admin account, such as DBA, you should nominate to that user only to limit the permissions, such as:
foo ALL = (dba) NOPASSWD: /usr/local/sbin/do-unsafe
Secondly, don't give any files with 777 permissions, it is unsafe. Think some others way, such as ACL permission set.
chmod 777 $FILE
I'm writing a UNIX shell function that is going to execute a command that will prompt the user for a password. I want to hard-code the password into the script and provide it to the command. I've tried piping the password into the command like this:
function() {
echo "password" | command
}
This may not work for some commands as the command may flush the input buffer before prompting for the password.
I've also tried redirecting standard input to a file containing the password like this, but that doesn't work either:
function() {
echo "password" > pass.tmp
command < pass.tmp
rm pass.tmp
}
I know that some commands allow for the password to be provided as an argument, but I'd rather go through standard input.
I'm looking for a quick and dirty way of piping a password into a command in bash.
How to use autoexpect to pipe a password into a command:
These steps are illustrated with an Ubuntu 12.10 desktop. The exact commands for your distribution may be slightly different.
This is dangerous because you risk exposing whatever password you use to anyone who can read the autoexpect script file.
DO NOT expose your root password or power user passwords by piping them through expect like this. Root kits WILL find this in an instant and your box is owned.
EXPECT spawns a process, reads text that comes in then sends text predefined in the script file.
Make sure you have expect and autoexpect installed:
sudo apt-get install expect
sudo apt-get install expect-dev
Read up on it:
man expect
man autoexpect
Go to your home directory:
cd /home/el
User el cannot chown a file to root and must enter a password:
touch testfile.txt
sudo chown root:root testfile.txt
[enter password to authorize the changing of the owner]
This is the password entry we want to automate. Restart the terminal to ensure that sudo asks us for the password again. Go to /home/el again and do this:
touch myfile.txt
autoexpect -f my_test_expect.exp sudo chown root:root myfile.txt
[enter password which authorizes the chown to root]
autoexpect done, file is my_test_expect.exp
You have created my_test_expect.exp file. Your super secret password is stored plaintext in this file. This should make you VERY uncomfortable. Mitigate some discomfort by restricting permissions and ownership as much as possible:
sudo chown el my_test_expect.exp //make el the owner.
sudo chmod 700 my_test_expect.exp //make file only readable by el.
You see these sorts of commands at the bottom of my_test_expect.exp:
set timeout -1
spawn sudo chown root:root myfile.txt
match_max 100000
expect -exact "\[sudo\] password for el: "
send -- "YourPasswordStoredInPlaintext\r"
expect eof
You will need to verify that the above expect commands are appropriate. If the autoexpect script is being overly sensitive or not sensitive enough then it will hang. In this case it's acceptable because the expect is waiting for text that will always arrive.
Run the expect script as user el:
expect my_test_expect.exp
spawn sudo chown root:root myfile.txt
[sudo] password for el:
The password contained in my_test_expect.exp was piped into a chown to root by user el. To see if the password was accepted, look at myfile.txt:
ls -l
-rw-r--r-- 1 root root 0 Dec 2 14:48 myfile.txt
It worked because it is root, and el never entered a password. If you expose your root, sudo, or power user password with this script, then acquiring root on your box will be easy. Such is the penalty for a security system that lets everybody in no questions asked.
Take a look at autoexpect (decent tutorial HERE). It's about as quick-and-dirty as you can get without resorting to trickery.
You can use the -S flag to read from std input. Find below an example:
function shutd()
{
echo "mySuperSecurePassword" | sudo -S shutdown -h now
}
Secure commands will not allow this, and rightly so, I'm afraid - it's a security hole you could drive a truck through.
If your command does not allow it using input redirection, or a command-line parameter, or a configuration file, then you're going to have to resort to serious trickery.
Some applications will actually open up /dev/tty to ensure you will have a hard time defeating security. You can get around them by temporarily taking over /dev/tty (creating your own as a pipe, for example) but this requires serious privileges and even it can be defeated.
with read
Here's an example that uses read to get the password and store it in the variable pass. Then, 7z uses the password to create an encrypted archive:
read -s -p "Enter password: " pass && 7z a archive.zip a_file -p"$pass"; unset pass
But be aware that the password can easily be sniffed.
Programs that prompt for passwords usually set the tty into "raw" mode, and read input directly from the tty. If you spawn the subprocess in a pty you can make that work. That is what Expect does...
Simply use :
echo "password" | sudo -S mount -t vfat /dev/sda1 /media/usb/;
if [ $? -eq 0 ]; then
echo -e '[ ok ] Usb key mounted'
else
echo -e '[warn] The USB key is not mounted'
fi
This code is working for me, and its in /etc/init.d/myscriptbash.sh
That's a really insecure idea, but:
Using the passwd command from within a shell script
Please [1] consider this command: sudo incrontab ~/incron-config where ~/incron-config contains:
/home/zetah/doc IN_CREATE,IN_MOVED_TO /home/zetah/scripts/do_something.sh $#/$#
and do_something.sh consists of [2]:
#! /bin/bash
python /home/zetah/scripts/py_something.py "$1"
Python script accesses some online services and produces 3 new files. They are owned by root.
Why is that and how can I change this behavior. I want to be the owner of those product files
Thanks
[1] Posted on Ask Ubuntu previous - thought to try my chances here, will interlink in any result
[2] Seems lame to wrap Python script in Bash script, but I couldn't do it otherwise
created files are owned by root probably because you run incrontab as root and then python inherit from it through bash
You can run incrontab from your own user, simply add your username in /etc/incron.allow (to allow you to use incron) and then recreate the incron table with your account with "incrontab -e" (don't forget to remove the entry from root)
Second option (if you can't modify incron.allow) is to call python with your username.
In your bash script, modify :
python /home/zetah/scripts/py_something.py "$1"
in
su <username> -c"python /home/zetah/scripts/py_something.py '$1'"
Hope it's help
ericc