Run a script from root and it calls another script that was in the sudo oracle. how to do that without asking the password of the oracle - linux

I'm logging into a linux machine with root and after login i have used su - oracle to connect my database. Now I've 2 shell scripts one at root home and one at home/oracle. In the home/oracle I've wrote a script for taking the backup of the database. The script available in the root is nohup ssh oracle#onprem-svcdb /home/oracle/test.sh while running the script its asking the password of the oracle, I don't need it to be like this while running the scripts It doesn't need to ask the password and it needs to run the script in oracle. What I need to do for that??? Can anyone help for this

If I understand corrently, you are getting a password prompt on using a script which connects to your database and executes something. If you dont need a password prompt , you would need to generate public and private keys for ssh for the logged in user , in your linux machine and get it configured in the database. Please have a look at the below link
http://docs.oracle.com/cd/E19253-01/816-4557/sshuser-33/index.html
You can try the below
Let this be you env variables.
---------VARIABLES --------------
export APP_USER=something
export APP_PASS=somepass
export APP_SID=sid
Here is the script with a execute permission.
--------------SCRIPT TO RUN SQL----------
#!/usr/ksh
sqlplus << END_OF_SQL
$APP_USER/$APP_PASS#APP_SID
select * from dual;
END_OF_SQL
exit $?
----------END SCRIPT----------
Source : https://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:142212348066

you could try expect tool:
You will start expect script below, that will start your main sql-script in return and will send oracle password if prompted:
content of /tmp/expect.exp script:
#!/usr/bin/expect -f
# set Variables
set password '***'
set timeout -1
# what to execute
spawn /usr/bin/su oracle -c "/tmp/main_script.sh"
match_max 100000
# Look for passwod prompt
while {1 > 0 } {
expect "*?assword:*"
# Send password aka $password
send -- "$password\r"
}
# send blank line (\r) to make sure we get back to gui
send -- "\r"
expect eof
than your main script will be stored in (or root home, whatever dir you need):
/tmp/main_script.sh content:
su - oracle
drop table; create table; other SQL commands
One disadvantage is - plain text password, stored inside the script
How to install: http://www.cyberciti.biz/tips/execute-commands-on-multiple-hosts-using-expect-tool-part-iii.html
Or you could try to modify visudo , like :
user1 ALL=(user2) NOPASSWD: /bin/bash
where : user1 will be granted "su to user2" without password prompt. You can replace also /bin/bash by ALL and then you could launch any command as user2

Related

How to ssh from one server to multiple server and switch to root and then change root password

From server A, i want to ssh multiple server using a non root user as direct root login is disabled to all server.
then i need to su - to switch to root
perform some normal operations, like changing directory, listing file etc.
and at the end change the root password using passwd command
I have expect installed on all servers and i am able to ssh from server A to any of the other servers but stuck in switching to root user and performing other operations as listed above.
#!/bin/bash
ssh user#ip<<'ENDSSH'
./su2root
#random operations
pwd
whoami
#random operations
./changepass
ENDSSH
su2root
#!/usr/bin/expect -f
spawn su -
set password "rootpass"
expect "assword:"
send "$password\r"
changepass
#!/usr/bin/expect -f
set newpassword "newrootpass"
spawn passwd
expect "*assword*"
send "$newpassword\r"
expect "*assword*"
send "$newpassword\r"
expect eof
exit 0
expecting to accomplish it using shell scripting only. Thanks in advance.
My initial comment on your question noted that you should be looking into running expect locally and spawning ssh sessions to the remote servers.
While not exactly answering your question, here is a simple expect script that logs into a remote system (one of my systems at home named valhalla), uses sudo -i to become root and executes the id command to show the user UID/GIDs. Note that I use ssh keys for logins which is why there is no expect for the initial login password.
The remote systems do not need expect in this example.
#!/usr/bin/expect
# vi: set ts=2 sw=2 noai ic showmode showmatch:
spawn ssh valhalla
expect "valhalla:"
send "sudo -i\r"
expect "assword for *"
send "XXXXXX\r"
expect "# "
send "id\r"
expect "(root)"
exit 0

Bash script not work fine

I need to write bash script to startup oracle DB
some command should run with user-root and some of them with user-oracle
How can I make these code as a bash script code
#!/bin/bash
su root
password
rm /var/tmp/.oracle/*
su oracle
lsnrctl start
sqlplus sys as sysdba
startup
But after i run this code ,It ask me root password and dont run other commend after su command.
Thanks.
Each line in a script is a command to execute. If a command reads input, it doesn't normally get it from the script file, it gets it from the script's standard input. If you want it to read from the script, you have to use a here-document:
#!/bin/bash
su root <<EOF
password
rm /var/tmp/.oracle/*
su oracle <<EOF1
lsnrctl start
sqlplus sys as sysdba
startup
EOF1
EOF
However, I'm not sure this will work with su. It probably doesn't read the password from standard input, but forces it to come from the terminal. You probably should be using sudo, which you can configure to not require a password for certain users and scripts.
Or if you use systemd, you should be able to configure a service startup script.

How can a BASH script automatically elevate to root on a remote server, without using sudoers nopasswd option?

o's!
Maybe you can help me with this. I can't find an answer to my specific questions, because there is an obvious solution which I'm not allowed to use. But first things first, the context:
In my company, which is a service provider, we administrate a bunch of
Linux servers. Some of my colleagues has for a long time been running
a BASH script from a source server, that then performs some tasks over
SSH on a number of remote Linux servers. The tasks it performs has to
be executed as root, so what the script does is it authorizes the
source server as root on the remote Linux servers via SSH (the remote
servers has the source servers public SSH key). Then what happened is
a new security policy was enforced and now root login over SSH is
denied. So the mentioned method no longer works.
The solution I keep finding, which we are by policy not allowed to do, is to create an entry in the sudoers file allowing sudo to root without password for the specific user.
This is the terms and they have to obey that. The only procedure that is allowed is to log on to the target server with your personal user, and then sudo su - to root WITH password.
Cocky as I apparently was, I said, "It should be possible to have the script do that automatically", and the management was like "Cool, you do it then!" and now I'm here at Stack Overflow,
because I know this is where bright minds are.
So this is exactly what I want to do with a BASH script, and I do not know if it's possible or how it's done, I really hope you can help me out:
Imagine Bob, he's logged into the source server, and he wants to
execute the script against a target server. Knowing that root over SSH
doesn't work, the authorization part of the script has been upgraded.
When Bob runs the script, it prompts him for his password. The
password is then stored in a variable (encrypted would be amazing) and
the script then logs on the target server as his user (which is
allowed) and then automatically elevates him to root on the target
server using the password he entered on the source server. Now the
script is root and it runs its tasks as usual.
Can it be done with BASH? and how?
UPDATE:
The Script:
## define code to be run on the remote system
remote_script='sudo -S hostname'
## local system
# on the local machine: prompt the user for the password
read -r -p "Enter password for $host: " password
# ...and write the password, followed by a NUL delimiter, to stdin of ssh
ssh -t 10.0.1.40 "$remote_script" < <(printf '%s\0' "$password")
The error:
[worker#source ~]$ sh elevate.sh
Enter password for : abc123
elevate.sh: line 10: syntax error near unexpected token `<'
elevate.sh: line 10: `ssh -t 10.0.1.40 "$remote_script" < <(printf '%s\0' "$password")'
First: Because it exposes plaintext passwords to the remote system (where they can be read by an attacker using diagnostic tools such as strace or sysdig), this is less secure than correctly using the NOPASSWD: flag in sudoers. If your security team aren't absolute idiots, they'll approve a policy exemption (perhaps with some appropriate controls, such as having a dedicated account with access to a setuid binary specific to the command being run, with authentication to that account being performed via public key authentication w/ the private key stored encrypted) rather than approving use of this hack.
Second: Here's your hack.
## define code to be run on the remote system
remote_script='sudo -S remote_command_here'
## local system
# on the local machine: prompt the user for the password
read -r -p "Enter password for $host: " password
# ...and write the password, followed by a NUL delimiter, to stdin of ssh
ssh "$host" "$remote_script" < <(printf '%s\0' "$password")
Allright, this is not the final answer, but I think I'm getting close, with the great help of CharlesDuffy.
So far I can run the script without errors on a remote server, that already has the publickey of my source server. However the command I execute doesn't create a file as I tell it to on the remote system.
However the script seems to run and the password seems to be accepted by the remote system.
Also I have to change in the sudoers on the remote host the line "Defaults requiretty" to "Defaults !requiretty", else it will tell me that I need a TTY to run sudo.
#!/bin/bash
## define code to be run on the remote system
remote_script='sudo -S touch /elevatedfile'
## local system
# on the local machine: prompt the user for the password
read -r -p "Enter password for $host: " password
# ...and write the password, followed by a NUL delimiter, to stdin of ssh
ssh -T 10.0.1.40 "$remote_script" < <(printf '%s\0' "$password")
UPDATE: When I tail /var/log/secure on the remote host I get the following after executing the script, which seems like the password is not being accepted.
May 11 20:15:20 target sudo: pam_unix(sudo:auth): conversation failed
May 11 20:15:20 target sudo: pam_unix(sudo:auth): auth could not identify password for [worker]
May 11 20:15:20 target sshd[3634]: Received disconnect from 10.0.1.39: 11: disconnected by user
May 11 20:15:20 target sshd[3631]: pam_unix(sshd:session): session closed for user worker
What I see on the source server, from where I launch the script:
[worker#source ~]$ bash elevate.sh
Enter password for : abc123
[sudo] password for worker:
[worker#source ~]$
Just make a daemon or cron script running as root, that in turn will check for any new scripts in specified secure location (ie. DB that it only has READ access to), and if they exist, it will download and execute them.

how to write expect script to login and run command on remote box

i wanted to execute commands on remote linux box from windows and also wanted to collect result of executed command. Basically i have to pass 2 boxes to execute that command here is flow.
Login to a box
ssh to another box
run command
collect output of command locally (in file)
I tried following
F:\xyz>plink xyz#a1.b1.com -i F:\x\y\PRIVATEKEY.ppk -pw xyz
ssh -f root#166.1.8.1 yum upgrade Cyberc
but this is asking for password. I can do it by adding id_rsa.pub value in to authorized_keys but we dont have permission to do. So instead of that i wanted to write EXPECT script to pass user/pass and commands to complete my job.
Any help on EXPECT script would be much appreciated.
Unless the program on the remote linux host is interactive (i.e. it has prompts that the user must respond to), then you probably don't need to use expect - you can simply use plink to connect to the remote Linux host from your windows machine and run the command. You can specify the username and password to authenticate with the remote host in the plink command. See the following links for more info:
http://the.earth.li/~sgtatham/putty/0.58/htmldoc/Chapter7.html
http://stackoverflow.com/questions/12844944/login-syntax-for-plink-using-ip-username-and-password

Crontab to send dump data to windows machine

I have mysql Database in Linux machine which should be dumped by using crontab and the data directly should have to store in a remote windows system. Is this possible? if yes, how?
You will need a script similar to the one below.
It would be best if you tested the script before running it from cron.
The scp command will prompt for the user's password on the destination machine - unless the ssh key setup on the scp destination machine contains public key authorization. For this to work with cron the scp command must be able to copy without user input of a password.
Once it works then set up the crontab entry. Specify the full path of the script in the entry.
export DB_DUMP_DIR=/home/database_dump
export DB_NAME=database_name_$(date '+%Y_%m_%d').sql
mysqldump -u root -p database_name > ${DB_DUMP_DIR}/${DB_NAME}
if [ $? -eq 0 ];then
scp ${DB_DUMP_DIR}/${DB_NAME} user#windows_machine:
else
echo "Error generating database dump"
fi

Resources