1

first of all I need to say that I'm not a programmer, but I need to do something based on programming.... My problem is that I need to modify the DNS servers in almost 1000 nanostation equipments. I have access to them through ssh and I want to make a script to acomplish the task. I already made a file with the ip addresses of all CPE's (named client.txt). I think my script can begin like this:

#!/bin/bash
for host in $(cat client.txt);
do
  ssh Administrador@$host sameforall;
  sed 's/x.x.x.x/y.y.y.y /etc/resolve.conf;
  sed 's/w.w.w.w/z.z.z.z /etc/resolve.conf;

  # here I restart network service but I don't have the command yet
done

y.y.y.y and z.z.z.z are the new DNS servers and x.x.x.x and w.w.w.w the old ones

I know this is far away to be correct, but I need somebody help me. The first problem I'm going to find is that ssh prompts me to put the given servers ssh key to my known_hosts file, how can I solve this???

Can anybody please help me???

Jakuje
  • 9,145
  • 2
  • 40
  • 44
gasparmenendez
  • 63
  • 1
  • 2
  • 6
  • Possible duplicate of [Linux - Running The Same Command on Many Machines at Once](https://serverfault.com/questions/2533/linux-running-the-same-command-on-many-machines-at-once) – chicks Apr 22 '17 at 02:42

2 Answers2

3

First of all you need to set up a public/private ssh key pair, in order to connect to each host via ssh without password. You can check out this link and follow some easy steps.

AFAIK you have two alternatives. Yo can create a public/private key pair in each server and then import the public generated key of each host in your "master server" known hosts. The other alternative is the other way round: You can generate a public/private key pair in your master host. And then place that private key in each host.

Then you can run any command like this:

while read MY_HOST ; do ssh $MY_HOST "ANY_COMMAND" < /dev/null; done < client.txt

Both solutions are quite complicated in your case, because you have large number of hosts. A possible workaround (that would only work if all the nanostations have the same username/password) would be forcing the script to use a plain text uername/password. If this is a one shot change and you are not performing any changes like this in the future this may help:

while read MY_HOST ; do sshpass -p 'YourPassword' ssh user@$MY_HOST "ANY_COMMAND" < /dev/null; done < client.txt

Please refer to this link: SSH login with clear text password as a parameter

ADVICE

If you are performing some management tasks in such a large farm of devices you may consider using some IT automation tools such as Ansible or Puppet, or at least generate a ssh key pair when you deploy a new nanostation.

EDIT - Script example

This simple script will log the output to a text file, so you will know exactly which of the hosts did not work (maybe to connectivity or password error). You may want to improve the script by parsing the error and determining the cause.

#!/bin/bash

echo "" > connFailed.log

while read MY_HOST;
do  < /dev/null;

    sshpass -p 'YourPassword' ssh user@$MY_HOST "ANY_COMMAND" > /dev/null 2>&1
    if [ $? != 0 ] ; then
            echo "[ERROR] Unable to connect to: " $MY_HOST >> connFailed.log
    fi

done < client.txt
patan90
  • 141
  • 1
  • 5
  • thank you very much @patan90...for the workaround you suggest do I need to install sshpass, correct??? as far as I know all nanostations have the same user and password, but what happens if some nanostation hasn't?? in this case I need to implement something to close connection and see this ip address in some text file. Would be very difficult to do this??? – gasparmenendez Apr 18 '17 at 21:51
  • Hi @gasparmenendez ! Yes that's correct. It's just a tool that lets you provide ssh password non interactively (as a parameter in cmd). – patan90 Apr 20 '17 at 14:45
  • I edited the answer with a sample script. – patan90 Apr 20 '17 at 15:29
  • thanks @patan90 ! I'll try that sample script and post results!! – gasparmenendez Apr 21 '17 at 15:35
  • hi @patan90!! I already tried sshpass -p 'ubnt' ssh ubnt@192.168.1.20 "echo "nameserver x.x.x.x" > /etc/resolv.conf" ouside the script and worked perfect!!! I only have a doubt before running the script: how can I execute 2 commands??? ( I need to change server x.x.x.x and server y.y.y.y) – gasparmenendez Apr 21 '17 at 16:47
  • Hi! Adding "-e" parameter and a "\n" between the two nameservers will make the trick. It will be something like this: `sshpass -p 'ubnt' ssh ubnt@192.168.1.20 "echo -e "nameserver x.x.x.x\nnameserver y.y.y.y" > /etc/resolv.conf"` – patan90 Apr 21 '17 at 18:38
  • sorry @patan90 but "-e" and "\n" didn't make the trick...here's what my terminal show: me@me-Lenovo-ideapad-310-15ISK ~ $ sshpass -p 'ubnt' ssh ubnt@192.168.1.20 "echo -e "nameserver x.x.x.x \n nameserver y.y.y.y"> /etc/resolv.conf > > > > > > > > ^C me@me-Lenovo-ideapad-310-15ISK ~ $ and when I look into resolv.conf of nanostation it has only nameserver x.x.x.x....what I'm doing wrong??? – gasparmenendez Apr 22 '17 at 17:56
  • Hi @gasparmenendez . You can check in your nanostations (**echo $SHELL**) which shell you are using and then search how to print new lines with echo in that shell. You can also do **man echo** in the nanostation. That will provide precise details. This links may help: [link](http://stackoverflow.com/questions/8467424/echo-newline-in-bash-prints-literal-n) and [link](http://stackoverflow.com/questions/20536112/how-to-insert-a-new-line-in-linux-shell-script). Knowing the exact shell you are using will let you know how to do it. – patan90 Apr 24 '17 at 15:19
  • @gasparmenendez Each shell may have small differences so knowing the exact shell you are using or reading the **echo man page** will provide you with the needed information. – patan90 Apr 24 '17 at 15:22
  • hi @patan90, echo $SHELL returns this: /bin/sh and man echo returns: -sh: man: not found. I'll keep searching as you recommend. Thanks a lot!! – gasparmenendez Apr 24 '17 at 17:11
  • hi @patan90, when I do **echo -e "nameserver 209.244.0.3\nnameserver 209.244.0.4"** directly on the nanostation it displays: nameserver 209.244.0.3 nameserver 209.244.0.4 so I think the syntaxis is ok. The problem I think is in > /etc/resolv.conf – gasparmenendez Apr 24 '17 at 18:21
  • @gasparmenendez You are missing the last quotation marks (") in your command. That's why you need to keep pressing "^C". Please check that. I do not know if that will solve the problem, but give it a try. Furthermore **/bin/sh** is the most basic shell. Maybe the syntax is a bit different. Check if you have **/bin/bash** installed in your nanostation (ls /bin/bash). – patan90 Apr 24 '17 at 19:01
  • `sshpass -p 'ubnt' ssh ubnt@192.168.1.20 "echo -e "nameserver x.x.x.x\nnameserver y.y.y.y" > /etc/resolv.conf"` In your command you are missing the last **"**, after /etc/resolv.conf – patan90 Apr 24 '17 at 19:04
  • no my friend @patan90, I'm not missing the last ".... I think the problem then is the shell cause the nanostation show me this: **ls: /bin/bash: No such file or directory** so it hasn't the bash shell. As you say the syntax is a bit different so I could try to write yor script in **sh** – gasparmenendez Apr 24 '17 at 19:22
  • hi @patan90, I've been running some test and found something weird...when I run **echo -e "nameserver 209.244.0.3\nnameserver 209.244.0.4" > /etc/resolv.conf** directly on nanostation's CLI all is ok (the resolv.con file shows both namerservers in 2 lines) but when I run the syntaxis from a remote PC with **sshpass -p 'ubnt' ssh ubnt@192.168.1.20 "echo -e "nameserver 209.244.0.3\nnameserver 209.244.0.4" > /etc/resolv.conf"** the resolv.conf file shows the 2 nameservers in the same line along with the \n, like this **nameserver 209.244.0.3nnameserver 209.244.0.4** – gasparmenendez Apr 24 '17 at 21:53
  • the nanostation has a file called **shell** (/etc/shell) and inside it has 3 lines: **/bin/sh**, **/bin/ash** and **/bin/clish** that helps??? – gasparmenendez Apr 24 '17 at 22:05
  • Hi @gasparmenendez! Honestly I do not know the exact syntax of that shells and I have no access to machine with that shell now. But it's just a matter of figuring out how to print the "\n". There are many things to try (ie "\\n"). **A possible workaround would be to print each line separately, but in the second one using ">>" in order to append to the file**. I mean, run: `sshpass -p 'ubnt' ssh ubnt@192.168.1.20 "echo -e "nameserver x.x.x.x" > /etc/resolv.conf"` and then `sshpass -p 'ubnt' ssh ubnt@192.168.1.20 "echo -e "nameserver y.y.y.y" >> /etc/resolv.conf"`. – patan90 Apr 25 '17 at 18:28
  • yeap @patan90, that's a workaround...what I would like to understand is why directly on the nano the command works fine and when I send that very same command through ssh (not in a script) doesn't work??? it's driving me crazy... – gasparmenendez Apr 25 '17 at 20:32
  • hi @patan90, the workaround worked fine!!! but I just realized one thing: how do I save the changes?? because when I reboot the nanostaiton the resolv.conf file has the old DNS's.... – gasparmenendez Apr 25 '17 at 21:56
  • Hi @gasparmenendez. That has nothing to do with the script you are trying. **Which OS you are using in the nanostations?** You have to check the documentation to verify where you have to config the DNS entries. Surely your OS is using other config files and regenerates the resolv.conf when you reboot. You have to check your OS documentation/wiki. If you are using ubuntu/debian derivates you may change it in _"/etc/network/interfaces"_. This [link may be helpful] (https://askubuntu.com/questions/157154/how-do-i-include-lines-in-resolv-conf-that-wont-get-lost-on-reboot) – patan90 Apr 26 '17 at 14:43
  • Hi @patan90, already found this: **/tmp/system.cfg** inside nanostation. In that file are **resolv.nameserver.1.ip=192.168.61.5** and **resolv.nameserver.2.ip=192.168.61.6** among a **lot of other things**, so I think those are the values I need to modify but I understand that **echo** command overwrites or appends a content of/to a file....??? Sorry to ask you this, but there is another way to communicate us, I mean a fast one??? Thanks a lot!! – gasparmenendez Apr 26 '17 at 16:09
  • Hi @gasparmenendez. **It sounds strange to me having a config file located in /tmp, as it is a temporary folder.** Which distribution are you using? So we can check the exact documentation. By the way if you are sure that the config file is located there you can use **sed** command to search and replace (sed -i 's/OLD_IP/NEW_IP/g' /confg_path/file.cfg). In your case the command would be `sshpass -p 'ubnt' ssh ubnt@192.168.1.20 "echo -e "sed -i 's/192.168.61.5/x.x.x.x/g' /tmp/system.cfg"` and `sshpass -p 'ubnt' ssh ubnt@192.168.1.20 "echo -e "sed -i 's/192.168.61.6/y.y.y.y/g' /tmp/system.cfg"`. – patan90 Apr 26 '17 at 19:20
  • @gasparmenendez Please test the commands in only one station and with some temporary files first. Take into account that changing network settings of a nanostation could lead to a communication loss if something is not configured properly. I will try to answer ass soon as i can! – patan90 Apr 26 '17 at 19:25
  • thanks @patan90, I was thinking in **sed** command precisely. I have a nanostation for testing purposes only, so no problem. I was reading in wiki **(http://es.wiki.guifi.net/wiki/Nanostations:_Modificando_configuraci%C3%B3n_por_consola)** and after modify the values then I need to write the changes to mtd through **cfgmtd -f /tmp/system.cfg -w** and then reboot the nanostation... the question is: do I have to put all that with **sshpass...** ike the others??? – gasparmenendez Apr 26 '17 at 20:23
  • @gasparmenendez if you have to run more than just one command.. is better to put all the commands in another script and then run the script via ssh. This may help: (https://unix.stackexchange.com/questions/87405/how-can-i-execute-local-script-on-remote-machine-and-include-arguments) – patan90 Apr 27 '17 at 19:25
1

The first problem I'm going to find is that ssh prompts me to put the given servers ssh key to my known_hosts file, how can I solve this???

As with many things, by reading the manual. The man ssh manual will refer you to the manual man ssh_client for the ssh client settings configuration file ~/.ssh/config (but you can also adjust the client settings via command line switches) where you find among other the following setting:

StrictHostKeyChecking

If this flag is set to yes, ssh(1) will never automatically add host keys to the ~/.ssh/known_hosts file, and refuses to connect to hosts whose host key has changed. This provides maximum protection** against trojan horse attacks, though it can be annoying when the /etc/ssh/ssh_known_hosts file is poorly maintained or when connections to new hosts are frequently made. This option forces the user to manually add all new hosts. If this flag is set to no, ssh will automatically add new host keys to the user known hosts files.
If this flag is set to ask, new host keys will be added to the user known host files only after the user has confirmed that is what they really want to do, and ssh will refuse to connect to hosts whose host key has changed. The host keys of known hosts will be verified automatically in all cases. The argument must be yes, no, or ask. The default is ask.

HBruijn
  • 72,524
  • 21
  • 127
  • 192