SSH to pfSense and run commands - shell

If I ssh to pfSense I have to select 8 to access the shell then I can run my commands as root.
If I create a new user I can ssh direct to the shell, but have no root access.
I'm trying to write a script that will log me in, select option 8 and then run my commands.
$rules="rules information is place in this var. 1n is used for new lines"
ssh admin#192.168.1.1 << EOF
printf "8\n"
printf $rules > /home/rules;
EOF
This fails and won't log me in or create my file.
If I change it to:
ssh -tt admin#192.168.1.1 << EOF
8
echo -e "$rules" > /home/rules;
exit
0
EOF
I get logged in but my $rules values are echoed to the screen not to the new rules file I want to create.
Any one advise how I can do this?
UPDATE
I've partially got this working by using:
printf "rules" > /home/rules the only issue with that is $rules contains a variable which isn't shown in the resulting file.
eg:
$rules="rules information is places in this var.\nis used for new lines\n$additional['rules']['local']";
is written to the file as:
rules information is places in this var.
is used for new lines
['rules']['local']
Note $additional is missing before ['rules']['local']
Any way I can include that correctly ?
I've tried adding \ before $additional, I've tried changing the var so it's not enclosed in " not ' and then updated the single quotes in the string.
Each time I end up with each line from $rules being echoed to the remote command line and not into the remote file.
Any ideas ?
Thanks

Here is what I've got:
bash-3.2$ A="coucou" B="a$Aa"; echo "${B}"
a
bash-3.2$ A="coucou" B="a${A}a"; echo "${B}"
acoucoua
bash-3.2$
So, could you try with braces {}?
more about this on this answer

Related

Bash - SSH to remote server and retrieve data

I have a bash script that needs to connect to another server for parts of it's execution. I have tried many of the standard instructions and syntaxes for executing ssh commands, but with little progress.
On the remote server, I need to source a shell script that contains several env parameters for some software. One of these parameters are then used in a filepath to point to an executable, which contains a function ' -lprojects ' that can list the projects for the software on that server.
I have verified that running the commands on the server itself works multiple times. My issue is when I try to run the same commands over SSH. If I use the approach where I use the env variable for the filepath, it shows that the variable is null in the filepath, giving a file/directory not found error. If I hard-code the filepath to point to the executable, it gives me an error saying that the shell script is not sourced (which I assume it needs for other functions and apis for the executable to reveal it's -lprojects function)
Here is how the code looks like somewhat:
ssh remote.server 'source /filepath/remotescript.sh'
filelist=$(ssh remote.server $REMOTEVARIABLE'/bin/executable -lprojects')
echo ${filelist[#]}
for file in $filelist
do
echo $file
ssh SERVER2 awk 'something' /filepath/"$file"/somefile.txt | sed 'something' >> filepath/values.csv;
done
As you can see, I then also need to loop through the contents of the -lprojects output in the remote.server, do some awk and sed on the files to extract the wanted text (this works), but then I need to write that back to the client (local server) values.csv file. This is more generic, as there will be several servers I have to do this for, but all of them have to write to the same .csv file. For simplicity, you can just regard this as a one remote server case, since it is vital I get it working for at least one now in the beginning.
Note that I also tried something like:
ssh remote.server << EOF
'source /filepath/remotescript.sh'
filelist=$(ssh remote.server $REMOTEVARIABLE'/bin/executable -lprojects')
EOF
But with similar results. Also placing the single-quotes in the filelist both before and after the remotevariable, etc.
How do I go about properly doing this?
To access the environment variable, you must source the script that defines the environment within the same SSH call as the one where you are using it, otherwise, you're running your commands in two different shells which are unrelated:
filelist=$(ssh remote.server 'source /filepath/remotescript.sh; $REMOTEVARIABLE/bin/executable -lprojects')
Assuming executable outputs one file name per line, you can use readarray to achieve the effect :
readarray -t filelist < <(ssh remote.server '
source /filepath/remotescript.sh
$REMOTEVARIABLE/bin/executable -lprojects
'
)
echo ${filelist[#]}
for file in $filelist
do
echo $file
ssh SERVER2 awk 'something' /filepath/"$file"/somefile.txt | sed 'something' >> filepath/values.csv;
done

bash- Redirection inside quotes after ssh

Still fairly new to bash and have a script that uses an ssh command. Following the ssh call, I have the code in single quotes. The example I am following did this, and I have found that it prevents being interrupted by the login to the server I am trying to get access to once I run the script (I only want to access information from the server, not interact with it). All of the code works, except for the redirection, as nothing is being written in the text file. I have added the code below...
while read h; do
ssh $h\
'for i in path/some/file; do
temp=$()
if [ $? == 1]; then
echo $i>>somefile.txt
echo "here"
fi
done'
done <serverlist.txt
Here gets echoed, however, the somefile.txt never gets populated.
Any help would be appreciated.

bash overriding a single line in a text file with another while using variables

Overview: I am trying to make a script that will take a list of machines and manually update their /etc/shadow files with a new root passwd. I know this isn't the best method but my boss wants this process automated. we are using a application called puppet for 90% of the update but some machines failed the update or can't have puppet installed, hence this dodgy fix.
(sorry for any stupid errors its only my 3rd week using any unix product, I have been a windows admin my whole life)
Issue:
I need to ssh into the PC's update the /etc/shadow file but only change the root user (not all systems have the same users and I don't want to remove any of those users in the process) I have gotten as far as being able to extract the current user in line 1 through ssh, then check if that user is indeed the root user but I am stuck on then updating the /etc/shadow file on the new machine as my boss has asked that the following standards happen.
I can't have any real user interaction in the script, so no manually typing the new passwd.
I am not allowed to have the new passwd displayed anywhere in clear text (inside the script or in another file)
Ok hopefully that's enough info onto the code.
root=user
unknown='unknown.txt'
filelines=`cat $unknown`
prod='new-shadow'
ohf='option-one-holding-file'
pel=prod-errorlog
for line in $filelines ; do
echo "Attempting to fix $line please wait"
ssh -oBatchMode=yes -l $user $line "awk '{if (NR==1) print \$0}' /etc/shadow" >> $ohf
if grep -q "root:" $ohf ; then
echo "root user located updating to produtcion password"
# ** This is the line that doesn't work **
ssh -oBatchMode=yes -l $user $line "sed -i '1s/.*/$prod/' /etc/shadow"
else
echo "unable to find root user this will require a manual fix this server will be listed in
the prod-errorlog file"
echo "$line" >> $pel
fi
done
The line in bold the sed line doesn't work I know why it doesn't work but I have no idea how to fix it at all, thank you to anyone who takes the time to look at this, I know the codes a bit of a mess, please forgive me.
To replace only the first line:
"echo '$prod' > /etc/shadow.new; tail -n +1 /etc/shadow >> /etc/shadow.new; mv -f /etc/shadow.new /etc/shadow"
Sorry for my previous wrong argument wrong: The '$prod' part in your script is correct, and is expanded OK. Yet $prod contains many reserved characters for regular expressions. Now this new version just create a new file (replacing the first line) and then move/overwrite on to the target one.

Want to read variable value from remote file

In one of my bash script I want to read and use the variable value from other script which is on remote machine.
How should I go ahead to resolve this. Any related info would be helpful.
Thanks in advance!
How about this (which is code I cannot currently test myself):
text=$(ssh yourname#yourmachine 'grep uploadRate= /root/yourscript')
It assumes that the value of the variable is contained in one line. The variable text now contains you variable assignment, presumably something like
uploadRate=1MB/s
There are several ways to convert the text/code into a real variable assignment in your current script, like evaluating the string or using grep. I would recommend
uploadRate=${text#*=}
to just remove the part up and including the =.
Edit: One more caveat to mention is that this only works if the original assignment does not contain variable references itself like in
uploadRate=1000*${kB}/s
ssh user#machine 'command'
will print the standard output of the remote command.
I would tell two ways at least:
1) You can simply redirect output to a file from remote server to your system with scp command...It would work for you.Then your script on your machine should read that file as an argument...
script on your machine:
read -t 50 -p "Waiting for argumet: " $1
It waits for output from remote machine,
Then you can
sshpass -p<password> scp user#host:/Path/to/file /path/to/script/
What you need to do:
You should tell the script from your machine, that the output from scp command is the argument($1)
2)Run script from your machine:
#!/bin/bash
script='
#Your commands
'
sshpass -p<password> ssh user#host $script
And you have also another ways to run script to do sth with remote machine.

bash and nohup capture

I have an scp script that looks like this:
#!/bin/bash
scp -r /usr/local/htdocs/$1 httpd#$2:/local/htdocs
I want to call it from the command line, and pass a directory, and destination server, similar to this:
move_site.sh website servername
However, I want to capture the output in a file containing the 2 parameters.
So I tried this, but it didn't print anything when calling using nohup
#!/bin/bash
scp -r /usr/local/htdocs/$1 httpd#$2:/local/htdocs > $1$1.out
How can I structure both the script and the calling command so that it runs in the background, and captures the output based on destination and site?
Your script should work, but maybe there is an error while trying to scp, that's why your output file is empty? To capture error messages to output file aswell, change > to >&:
#!/bin/bash
scp -r /usr/local/htdocs/$1 httpd#$2:/local/htdocs >& $1$2.out
To run your script in background, simply add & at the end of a command:
move_site.sh website servername &
P.S. website and servername should not include any characters, that are not allowed in a file name if you insist on using them in $1$2.out form.
If you want to pass two or more words as a single parameter, you have to wrap it with quotes:
$ cat s.sh
#!/bin/bash
echo "param1: $1, param2: $2"
So we get:
$ ./s.sh "a b" c
param1: a b, param2: c
Following this example, you have to adapt your script in consequence.

Resources