Bash - Permission denied error when logging to /var/log/<file-name> - bash

For an application I want to store specific data on a data recovery server. On the application and DR server I created a user test1 and copied the public key from application server user test1 to DR user test1's authorized_keys file. User test1 is added to the wheel group.
I set permission on drwxr-xr-x /var/log
I then created a cron job to rsync the data from the application server to the DR server:
sudo rsync -avz -e "ssh -i /home/test1/.ssh/my-ssh-key" /var/nfsshare/ test1#10.10.10.10:/var/nfsshare > /var/log/nfs_cron-$(date +\%m-\%d-\%Y).log
When the cron executes I get the following error:
/bin/sh: /var/log/nfs_cron-08-26-2019.log: Permission denied
However, when I try to create a file manually it creates the file successfully.
sudo touch /var/log/test.txt
which creates the file as:
-rwxr-xr-x. 1 test1 test1 0 Aug 26 12:28 test.txt
Any thoughts?
Thanks!

You can create a directory and give permission to this user or you can use redirection/tee to write the log file.
For example using ACL:
mkdir -p /var/log/my_app/
setfacl -Rm g:MY_GROUP_ID:rwx /var/log/my_app/
The setfacl command is to setup ACL.
-R -> It's to be recursive and setup the ACL to all subfolder
-m -> It's to modify the ACL
goru -> It's to define the group or user
rwx -> It's the permission to setup for the group/user
http://tldp.org/LDP/abs/html/abs-guide.html#SETFACLREF
Another way is using redirection/tee. With redirection, you can "filter" what you want log into the file. For example:
Log and/or concatenate just in case of success
ls -lZ /tmp/myfile >> /var/log/mylog
Log everything (Sending stderr to stdout and writing into the same file)
ls -lZ /tmp/myfile >> /var/log/mylog 2>&1
or just use &>
ls -lZ /tmp/myfile &> /var/log/mylog
If you don't have permission to write on the destination file/directory, you can use tee to write. For example, appending (-a) and writing into the file /var/log/mylog.
ls -lZ /tmp/myfile | sudo tee -a /var/log/mylog
You can find some other examples and a better explanation in here:
https://www.tldp.org/LDP/abs/html/io-redirection.html
https://wiki.bash-hackers.org/howto/redirection_tutorial
https://wiki.bash-hackers.org/syntax/redirection

The problem is that the redirection is done by the user calling sudo, rather than by the sudo itself.
cmd > file
creates file before launching cmd, which means in your case that the regular user is trying to create the log, and then pass its filehandle to sudo to write to.
To confirm my theory, try this:
sudo echo test > /var/log/test.txt
and you should get the same error message.
You have to pass the filename to the command so that it is created by the program called by sudo. In your case, you could accomplish this by wrapping the whole thing into a script, for example.

Related

Commands without sudo in bash do not work

I am running a bash script and these commands in the script will not work without sudo in front of them. The script.sh is located in a folder such as /jobs/script.sh
Example of commands I am trying to run in the script.sh -
mv /var/app/myapp /var/app/myapp.old
rm file.tar.gz
tar -xzf /home/ubuntu/file.tar.gz -C /var/app/
All the above work if I add sudo in front of them.
I am trying to figure out what permissions are required for them to work without adding sudo in the script.
I have tried giving the script.sh rwx permissions and changing owner to root.
I'm learning permissions in linux, so I'm new to this. Basically what permission should the script.sh have so that I dont have to use sudo in the bash file? Any insight would greatly help.
When you run sudo <some command>, then <some command> is run by the root user (Super user do). The reason you might need to run any command using sudo is because the permissions on the files that command reads/writes/executes are such that only the "Super user" (root) has that permission.
When executing the command mv fileA fileB, the executing user would need:
Write permission to fileB if fileB already existed
Write permission to the directory containing fileB
From what you said it’s most likely you want read and write permissions you can achieve this with chmod
Chmod +[permission] filename
(+ is used to add permission you can also use - instead to remove it)
Where permissions can be:
r —> read
w—> write
x —>excecute
... and more
FOR EXAMPLE: it seems you write permissions for the first file so :
chmod +w /var/app/myapp
Will fix problem

Bash Script Cant Write To Log Files

I've created a simple bash script that grabs some data and then outputs it to a log file. When I run the script without sudo it fails to write to the logs and says they are write-protected. It then ask me if it should unwrite-protect them, but this fails (permission denied).
If I run the script as sudo it appears to work without issue. How can I set these log file to be available to the script?
cd /home/pi/scripts/powermonitor/
python /home/pi/powermonitor/plugpower.py > plug.log
echo -e "$(sed '1d' /home/pi/scripts/powermonitor/plug.log)\n" > plug.log
sed 's/^.\{139\}//' plug.log > plug1.log
rm plug.log
grep -o -E '[0-9]+' plug1.log > plug.log
rm plug1.log
sed -n '1p' plug.log > plug1.log
rm plug.log
perl -pe '
I was being dumb. I just needed to set the write permissions on the log files.
The ability to write a file depends on the file permissions that have been assigned to that file or, if the file does not exist but you want to create a new file, then the permissions on the directory in which you want to write the file. If you use sudo, then you are temporarily becoming the root user, and the root user can read/write/execute any file at all without restriction.
If you run your script first using sudo and the script ends up creating a file, that file is probably going to be owned by the root user and will not be writable by your typical user. If you run your script without using sudo, then it's going to run under the username you used to connect to the machine and that user will need to have permission to write the log files.
You can change the ownership and permissions of directories and files by using the chown, chmod, chgrp commands. If you want to always run your script as sudo, then you don't have much to worry about. If you want to run these commands without sudo, that means you're running them as some other user and you will need to grant write permission to that user, whoever it is, in order to write the files/folders where the log files get written.
For instance, if I wanted to run the script as user sneakyimp and wanted the files written to /home/sneakyimp/logs/ then I'd need to make sure that directory was writable by sneakyimp:
sudo chown -R sneakyimp:sneakyimp /home/sneakyimp/logs
This command changes ownership of that directory and its contents to the user sneakyimp. You might also need to run some chmod commands to make sure they are writable by owner.

Providing password using a variable to become a sudo user in Jenkins

I have a jenkins job, which has its own set of build servers. The process which i follow is building applications on the jenkins build server and then I use "send files or execute commands over ssh" to copy my build and deploy the same using a shell script.
As a part of the deployment commands, I have quite a few steps to be done, like mkdir, tar -xzvf etc.I want to execute these deployment steps with a specific user "K". But when i type the sudo su - k command, the jenkins job fails because i am unable to feed the password to it.
#!/bin/bash
sudo su - K << \EOF
cd /DIR1/DIR2;
cp ~/MY_APP.war .
mkdir DIR 3
tar -xzvf MY_APP.war
EOF
To handle that, I used a PASSWORD parameter and made the build as parameterized, so that i can use the same PASSWORD in the shell script.
I have tried to use Expect, but looks like commands like cd, tar -xzvf are not working inside it and even if they work they will not be executed with the K as a user since the terminal may expire(please correct if wrong).
export $PASSWORD
/usr/bin/expect << EOD
spawn sudo su - k
expect "password for K"
send -- "$PASSWORD"
cd /DIR1/DIR2;
cp ~/MY_APP.war .
mkdir DIR 3
tar -xzvf MY_APP.war
EOD
Note: I do not have the root access to the servers and hence cannot tweak the host key files. Is there a work around for this problem?
Even if you get it working, having passwords in scripts or on the command line probably is not ideal from a security standpoint. Two things I would suggest :
1) Use a public SSH key owned by the user on your initiating system as an authorized key on the remote system to allow logging as the intended user on the remote system without a password. You should have all you need to do that (no root access required, only to the users you already use on each system).
2) Set-up the "sudoers" file on the remote system so that the user you log in as is allowed to perform the commands you need as the required user. You would need the system administrator help for that.
Like so:
SUDO_PASSWORD=TheSudoPassword
...
ssh kilroy#somehost "echo $SUDO_PASSWORD | sudo -S some_root_command"
Later
How can i use this in the 1st snippet?
Write a file:
deploy.sh
#!/bin/sh
cd /DIR1/DIR2
cp ~/MY_APP.war .
mkdir DIR 3
tar -xzvf MY_APP.war
Then:
chmod +x deploy.sh
scp deploy.sh kilroy#somehost:~
ssh kilroy#somehost "echo $SUDO_PASSWORD | sudo -S ./deploy.sh"

Bash CLI: Is there a way to simultaneously create and set permissions on a file without repeating the filename?

Is there a way to simultaneously create and set permissions on a file without repeating the file name?
I tried:
touch text.txt && chmod u+x text.txt
This gives me permission denied when I run it and I want to know how to fix it and: How do I get rid of the repetition?
If you are getting a permissions error when you run your command, that suggests that you do not have permissions to create files where you're trying to create the file. Regarding the rest of your question:
As BroLow said, you can use umask to affect the default permissions of files created in your session. However, this can be inconvenient, particularly if you only want the new permissions in effect for a single command.
You can use the install command to create and set permissions on a file:
install -m <mode> -o <owner> -g <group> <srcfile> <destination>
If you want to create an empty file, you can use /dev/null as a source:
install -m 644 /dev/null <destination>

SCP File command as non-root user on the server

I have some files to upload. Usually to edit anything while logged in the server I must precede the command with sudo. That is known.
How do I send a file then as "admin" instead of "root" when I have disabled root login.
scp path\to\file admin#myaddress.com:/var/www/sitename/public/path/
PERMISSION DENIED
In my opinion, either you should give permissions to the admin user or scp your file to /tmp/ and then sudo mv /tmp/yourfile /var/www/sitename/public/path/.
There is no sudo option when we are using scp command from local to server.
Each user will have upload permission to its own folder in home directory ex. home/xxxxuser so use as below:
scp file_source_here xxxuser#yourserver:/home/xxxuser/
Now you can move file from this folder to your destination.
I suggest these two commands as it works in a bash script.
Move the file to tmp as suggested.
scp path\to\file admin#myaddress.com:/tmp
Assuming admin user can do sudo. The ssh option -t allow you to do sudo command.
ssh -t admin#myaddress.com 'sudo chown root:root /tmp/file && sudo mv /tmp/file /var/www/sitename/public/path/'

Resources