permission denied reading from file with <, even with sudo in use - bash

I need to run a script from server A in Server B. After ssh into server B, I ran the following command:
sudo ssh root#ip_A 'bash -s' < root/work/task.sh
I am getting the error below:
-bash: /root/work/task.sh: Permission denied.
On server A, I have done sudo chmod 777 task.sh.
Please thanks.

This is one of the few places where cat adds value even when not concatenating multiple files:
sudo cat /root/work/task.sh | ssh root#ip_A 'bash -s'
Because redirections such as < are run by the shell before the program being invoked is started, sudo can't change the permissions used for such redirections (it hasn't started yet!). By contrast, sudo cat somefile runs sudo first, then cat, which then opens somefile; since sudo runs first in that case, escalated permissions are available.

i test case 1:
sudo ssh root#ip_A 'bash -s < /root/work/task.sh'
which task.sh saved in ip_A, and works
and test case 2:
sudo ssh root#ip_A 'bash -s' < /root/work/task.sh
and it works too, no task.sh in ip_A, only has this file in local host.
do not know what your problem, can u show us your tash.sh?

Related

Prevent .bash_profile from executing when connecting via SSH

I have several servers running Ubuntu 18.04.3 LTS. Although it's considered bad practice to auto login, I understand the risks.
I've done the following to auto-login the user:
sudo mkdir /etc/systemd/system/getty#tty1.service.d
sudo nano /etc/systemd/system/getty#tty1.service.d/override.conf
Then I add the following to the file:
[Service]
ExecStart=
ExecStart=-/sbin/agetty --noissue --autologin my_user %I $TERM
Type=idle
Then, I edit the following file for the user to be able to automatically start a program:
sudo nano /home/my_user/.bash_profile
# Add this to the file:
cd /home/my_user/my_program
sudo ./program
This works great on the console when the server starts, however, when I SSH into the server, the same program is started and I don't want that.
The simplest solution is to SSH with a different user but is there a way to prevent the program from running when I SSH in using the same user?
The easy approach is to check the environment for variables ssh sets; there are several.
# only run my_program on login if not connecting via ssh
if [ -z "$SSH_CLIENT" ]; then
cd /home/my_user/my_program && sudo ./program
fi

Using sshpass to run a command on another server

I'm trying to run a single command on server X, to have that SSH into server Y and run another command
I'm doing this like the below:
sshpass -p 'my_password' ssh -t test-admin#my_ip "sudo su c command_must_be_run_root --arguments"
So to break it down:
I'm using "sshpass" to pass a password into my ssh command
I'm SSH'ing into the new server as the "test-admin" user
once in the server, I am running the command "sudo su command_must_be_run_root --arguments
This "command_must_be_run_root" is a command that has to be run as root only
It also has arguments I have to pass in. However I'm seeing that when I pass in the arguments, it is passing these arguments into the "su" command, and not passing them into the new command I want to run
Any ideas on how to fix this?
For what ever reason when you have a command with arguments you need to actually tell sudo su to login as root. Without logging in first it will run the first part of the command, even with all of it in single quotes, but not the args. (I guess it thinks that is the end of the command or it's only 1 command per sudo su -c, and that is why the persistent login works?). After adding sudo su -l root then you can continue with -c and everything that follows needs single quotes.
Should look like this:
sshpass -p 'my_password' ssh -t test-admin#my_ip "sudo su -l root -c 'command_ran_as_root --arguments'"
I don't think that su command is valid in any case. The syntax of su is su <someuser> [arguments...], so what you've written is going to try running command_must_be_run_root as user c.
I suspect that c is supposed to be -c, in which case you need to quote the arguments to -c, which would solve the problem you're asking about:
sshpass -p 'my_password' ssh -t test-admin#my_ip "sudo su -c 'command_must_be_run_root --arguments'"
But the next question is, if you already have sudo access, why are you bothering with su? You could just write instead:
sshpass -p 'my_password' ssh -t test-admin#my_ip sudo command_must_be_run_root --arguments

How to get the output of ssh when the command has a command to change user

When I use ssh to run command on a remote machine, I will get the output from shell. However, if I add
sudo su - user2
I will get no output. Now, I cannot do
ssh user2#host
Because of some permission issue.
Is there any way to get the output for the following command?
ssh user1#host 'sudo su - user2; wc -l tmp.txt'
Thanks to #laenkeio. Using sudo -u user2 can run some simple programs.
However, when I need to call a python script which needs some enviroment variable for user2, the script was not able to find those default path by using sudo -u user2.
If you have the appropriate sudo rights on host you should be able to do it with:
ssh -t user1#host 'sudo -u user2 wc -l tmp.txt'
Using sudo -u means "execute as user2", thus avoiding the extra su -. And -t forces ssh to allocate a tty so that sudo can ask for your password.
If you cannot do ssh user2#host for some permission issue, you'll not be able to run ssh user1#host 'sudo su - user2; ... for the same reason...
And, even with no permission issue, when doing su - user you'll be requested for a password...

"sudo su && somecommand" doesn't run somecommand

I have created a Jenkins job today, what it does is the Jenkins user should log into another server and run two commands seperated by &&:
ssh -i /creds/jenkins jenkins#servername.com "sh -c 'sudo su && df'"
The loging part works fine, then it runs the sudo su command and becomes root but it never runs the second command (i.e. df).
I even did this manually and from the Jenkins machine logged into the other server (servername). Then ran sh -c "sudo su && df" with no luck.
Can you please help?
Thanks in advance
If you are trying to run the df command as root, you should instead do sudo df.
This is because with sudo su && df, you are basically executing sudo su first and then df.
Also make sure, your jenkins user can be sudo without password.
The sudo su launches a second shell, and the command containing the && df is waiting to be executed in the non-root shell, just after the sudo su shell exits successfully.
This could be what you're looking for:
sh -c 'sudo su - root -c "df"'
Edit: please note that I don't normally use or advocate the use of sudo su - root -c type of constructions. However, I have seen rare cases in which a program doesn't work properly when called via sudo/gksudo, but does work properly when called via su/gksu -- in such cases, a given user should try to use sudo -i first, and if that does not work, one might have to resort to sudo su - root -c or similar, as a workaround of sorts to deal with a "misbehaving" program. Since the OP used some similar syntax on his post, I assumed that his case could be such a workaround case, so I maintained the sudo su - root -c type of structure on my answer.
when you did sudo su && df , sudo su will start a child process immediately without waiting for the && df part of the command to execute , when you hit Ctrl + D it exits the child process and enters the parent shell , that's when your && df will execute. You should do this using here strings, it might not be the best option but it works and it does not start a new child process
sh -c "sudo su" <<<df
note: don't surround <<< df with any quotes

Use sudo to change file in root directory [duplicate]

This question already has answers here:
How do I use sudo to redirect output to a location I don't have permission to write to? [closed]
(15 answers)
Closed 6 months ago.
I'm trying to write a script to configure resolv.conf and /etc/network/interfaces automatically. I'm running the commands as "sudo", but I'm getting "Permission denied" errors.
sudo apt-get --assume-yes install vsftpd
sudo "nameserver 8.8.8.8" >> /etc/resolv.conf
sudo python setinterfaces.py
sudo chattr +i /etc/network/interfaces
sudo apt-get --assume-yes install lamp-server^
Lines 2 and 3 get permission denied errors, but lines 1 and 5 did run. setinterfaces.py is supposed to overwrite /etc/network/interfaces'.setinterfaces.pyworks when pointed at the home folder but not theinterfaces` file.
Any idea? Do I have to be changing ownership? Ideally I'd like this to be a one command script, where I can just call it and it will run. I'm writing this script for people who are not experienced in *nix.
The sudo command executes the command you give it under the root account. In its simplest form, the syntax is:
sudo command args...
For example:
sudo whoami
prints root.
If you type, as you did in your question:
sudo "nameserver 8.8.8.8" >> /etc/resolv.conf
then it's not going to work; it will try to execute a command named "nameserver 8.8.8.8", which doesn't exist. The problem there is that you're missing the echo command.
This:
sudo "echo nameserver 8.8.8.8" >> /etc/resolv.conf
still won't work because there's no command called "echo nameserver 8.8.8.8". That entire string is passed to sudo as a single argument. It needs to see the command and each of its arguments as a separate argument.
So this:
sudo echo nameserver 8.8.8.8 >> /etc/resolv.conf
is getting closer -- but it still won't work. It executes the echo command as root -- but echo requires no special privileges, so there's no point in executing it as root. The >> /etc/resolv.conf redirection is executed by your shell, which is running as you, not as root. Since you don't have permission to write to /etc/resolv.conf, the command fails. The sudo command never sees the redirection.
You need the redirection to be executed under the root account, which means that you need a shell process running as root. So the solution is:
sudo sh -c 'echo nameserver 8.8.8.8 >> /etc/resolv.conf'
This launches a shell as a root process. That shell executes the command line echo nameserver 8.8.8.8 >> /etc/resolv.conf. Since you have a root shell executing both the echo and the output redirection, it should work.
(I suggest grabbing a copy of your /etc/resolv.conf file before doing this, just to make sure you can recover if you accidentally clobber it.)
Second line would be like this,
sudo sh -c "echo 'nameserver 8.8.8.8' >> /etc/resolv.conf"

Resources