DaemonForums  

Go Back   DaemonForums > Miscellaneous > Programming

Programming C, bash, Python, Perl, PHP, Java, you name it.

Reply
 
Thread Tools Display Modes
  #1   (View Single Post)  
Old 6th June 2008
splooge splooge is offline
New User
 
Join Date: May 2008
Posts: 5
Default Appending to file on remote host via SSH

Hey guys! I'm playing around with scripting for (basically) my first time. I found out most of what I needed through examples I found on google and have finished with about the first three-fourths of the script. Essentially, I am creating a script that makes my life easier when adding domains to my DNS servers. In one of our DNS farms we have 5 servers (1 master, not public facing, and 4 slaves which *are* public facing). In any case, creating the initial zone file and then modifying 5 instances of named.conf can get quite tedious when you're adding almost a new domain every day, so I'm trying to come up with a solution.

The script, when complete, will do this:

1) Create an initial zone file in /etc/namedb/master/
2) Add the zone to named.conf
3) Reload named, to read in the new named.conf
4) via SSH, append the new zone to named.conf on the slaves
5) via rndc, reload the slaves remotely

This part all works EXCEPT for #4 above:
Code:
if [ -z "$1" ] || [ -z "$2" ]
then
        echo "Proper usage of this script is `basename $0` [domain-name] [IP address]"
        exit
fi

#Let's do the zone file ...
echo "Creating initial zone file ..."

echo "\$TTL 300
$1.                     IN SOA  ns1.pwned.com. hostmaster.pwned.com. (
                                2008060401 ; serial
                                1H         ; refresh
                                10M        ; retry
                                1D         ; expire
                                1D         ; minimum
                                )

                        NS      ns1.pwned.com.
                        NS      ns2.pwned.com.

                        A       $2
www                     CNAME   @
" > /etc/namedb/master/db.$1

echo "Changing ownership on db.$1 ..."
chown bind:bind /etc/namedb/master/db.$1

# Let's update named.conf ...
echo "Updating named.conf ..."

echo zone \"$1\"" {
        type master;
        file \"master/db.$1\";
};
" >> /etc/namedb/named.conf

# Reload named for changes to take effect ...
echo "Reloading named ..."

rndc reload
What I *can't* get to work is appending to file on a remote host via SSH. I get errors at the curly braces and the $1 variable doesn't get carried over to the remote box. Here's basically what I am trying that is failing: (Note: ns1 is FreeBSD, ns2 is Gentoo)

Code:
ssh ns2 echo "zone \"test.com\" {
	type slave;
	file \"sec/db.test.com\";
	masters { 72.26.x.x; };
};
" >> /etc/namedb/named.conf
These are the error messages I get:
Code:
bash: line 1: type: slave: not found
bash: -c: line 3: syntax error near unexpected token `}'
bash: -c: line 3: `	masters { 72.26.x.x; };
Can anyone suggest the proper code to append multiple lines to a file on a remote machine via SSH that will ALSO carry the $1 variable over to the remote machine?

Thanks. I hope I was clear enough.

Last edited by splooge; 7th June 2008 at 02:37 AM.
Reply With Quote
  #2   (View Single Post)  
Old 6th June 2008
cajunman4life cajunman4life is offline
Real Name: Aaron Graves
Package Pilot
 
Join Date: May 2008
Location: Coolidge, Arizona
Posts: 203
Default

An alternative solution is you can put the data to a file locally, then SCP that file to the remote box.

Example:
I want to add today's date to file foo, and copy it to another box.

Code:
echo `date` >> /path/to/foo
scp /path/to/foo foouser@barserver:/path/to/foo
Don't know if that'll work for you, but it's a solution.
__________________
I just saved a bunch of money on my car insurance by fleeing the scene of the accident!
Reply With Quote
  #3   (View Single Post)  
Old 7th June 2008
corey_james corey_james is offline
Uber Geek
 
Join Date: Apr 2008
Location: Brisbane, Australia
Posts: 238
Default

i don't understand what you're trying to do - is this DNS replication?
Why don't you just force a zone transfer?
__________________
"No, that's wrong, Cartman. But don't worry, there are no stupid answers, just stupid people." -- Mr. Garrison

Forum Netiquette
Reply With Quote
  #4   (View Single Post)  
Old 7th June 2008
splooge splooge is offline
New User
 
Join Date: May 2008
Posts: 5
Default

Quote:
Originally Posted by cajunman4life View Post
An alternative solution is you can put the data to a file locally, then SCP that file to the remote box.

Example:
I want to add today's date to file foo, and copy it to another box.

Code:
echo `date` >> /path/to/foo
scp /path/to/foo foouser@barserver:/path/to/foo
Don't know if that'll work for you, but it's a solution.
Thanks for the reply, and thanks for the idea! This would certainly work, but I'm looking for something a little bit cleaner. I'd prefer to append to the file directly on the remote box, instead of appending to a local file then SCPing it over. I may be asking for too much, eh? =)
Reply With Quote
  #5   (View Single Post)  
Old 7th June 2008
splooge splooge is offline
New User
 
Join Date: May 2008
Posts: 5
Default

Quote:
Originally Posted by corey_james View Post
i don't understand what you're trying to do - is this DNS replication?
Why don't you just force a zone transfer?
No, not DNS replication. Replication works fine.

In my environment, with figuratively thousands of zones, I'm looking to simply automate the addition of new zones to all my name servers.

How does one add a new zone to name servers? (Rhetorical question there.) Here's the 5 steps I take to accomplish this task:

1) Create the new zone file in /etc/namedb/master. (db.zone.com)
2) Add the new zone to named.conf on the master dns server.
3) Reload the master name server, which reads in the new settings in named.conf
4) Add the new zones to the slaves servers' named.conf file.
5) Reload the slave name servers, again, to read in the changes in named.conf. Reloading the slaves at this point automagically initiates a zone transfer from the master.

This is what I am trying to automate. The only part I'm missing is for a clean way to append the new entries in named.conf on the slave servers without logging into them and doing it manually.

Sorry, I tend to add a lot of irrelevant information.
Reply With Quote
  #6   (View Single Post)  
Old 7th June 2008
TerryP's Avatar
TerryP TerryP is offline
Arp Constable
 
Join Date: May 2008
Location: USofA
Posts: 1,547
Default

Some thing like this?

Code:
Terry@dixie$ ssh2v 'echo "zone \"test.com\" {                              2:45
quote>        type slave;
quote>        file \"sec/db.test.com\";
quote>        masters { 72.26.x.x; };
quote>};
quote>">> /tmp/test.out'

#########################
#	WARNING		#
#########################

All activity is logged !


Terry@dixie$ ssh2v 'cat /tmp/test.out'                                     2:45
#########################
#	WARNING		#
#########################

All activity is logged !


zone "test.com" {
        type slave;
        file "sec/db.test.com";
        masters { 72.26.x.x; };
};

Terry@dixie$                                                               2:46
note: ssh2v is a personal shell alias that expands to "ssh -p MyPort user@host -i keyfile"

I find it is best to quote all arguments meant to be passed onto ssh to be run as a command on the server (and most similar situations comparable to sh -c 'commands'), helps remind me if I want things like >> redirections to files that I have to pass it to the servers shell, not my clients shell.


I can think of at least one other possible way of doing it, if I"m reading your right but it's just as cheesy I'm sure... (read only network shares) I'd rather hope that there is an appropriate program available to take care of such things as this without having to resort to ssh or nfs/friends.
__________________
My Journal

Thou shalt check the array bounds of all strings (indeed, all arrays), for surely where thou typest ``foo'' someone someday shall type ``supercalifragilisticexpialidocious''.
Reply With Quote
  #7   (View Single Post)  
Old 7th June 2008
splooge splooge is offline
New User
 
Join Date: May 2008
Posts: 5
Default

Thanks Terry! Using the ticks worked out really well! What I forgot to mention was that I am trying to pass a variable ("$1") that doesn't seem to work.

Code:
omni# cat terry.sh
ssh ns2 'echo "zone \"$1\" {
        type slave;
        file \"sec/db.$1\";
        masters { 72.26.x.x; };
};
" >> test'
omni# ./terry.sh test.com
Ends up looking like so:
Code:
zone "" {
        type slave;
        file "sec/db.";
        masters { 72.26.x.x; };
};
HOWEVER! I extrapolated and expanded your idea with the ticks (without really knowing what I was doing!) and "unticked" the variable:
Code:
omni# cat terry.sh
ssh ns2 'echo "zone \"'$1'\" {
        type slave;
        file \"sec/db.'$1'\";
        masters { 72.26.x.x; };
};
" >> test'
And it works flawlessly!!!
Code:
omni# ./terry.sh test.com
Resulted in:
Code:
zone "test.com" {
        type slave;
        file "sec/db.test.com";
        masters { 72.26.x.x; };
};
Thank you! I can't begin to say how much I appreciate all your guys' help. I can now move on with my life. =)

Here are the results:
Code:
omni# ./newdomain.sh test.com 1.1.1.1
Creating initial zone file ...
Changing ownership on db.test.com ...
Updating named.conf ...
Reloading named ...
server reload successful
Populating named.conf on ns2 ...
Reloading named on ns2 ...
server reload successful
Code:
omni# host www.test.com ns1
www.test.com is an alias for test.com.
test.com has address 1.1.1.1

omni# host www.test.com ns2
www.test.com is an alias for test.com.
test.com has address 1.1.1.1
Nice, clean, and all in one script!

splooge
Reply With Quote
  #8   (View Single Post)  
Old 7th June 2008
splooge splooge is offline
New User
 
Join Date: May 2008
Posts: 5
Default

Here's the final script, for completeness sake:

(NOTE: This required ssh keys and rndc keys for remote file access and remotely reloading named on the slave)

Code:
if [ -z "$1" ] || [ -z "$2" ]
then
        echo "Proper usage of this script is `basename $0` [domain-name] [IP address]"
        exit
fi

#Let's do the zone file ...
echo "Creating initial zone file ..."

echo "\$TTL 300
$1.                     IN SOA  ns1.pwned.com. hostmaster.pwned.com. (
                                2008060401 ; serial
                                1H         ; refresh
                                10M        ; retry
                                1D         ; expire
                                1D         ; minimum
                                )

                        NS      ns1.pwned.com.
                        NS      ns2.pwned.com.

                        A       $2
www                     CNAME   @
" > /etc/namedb/master/db.$1

echo "Changing ownership on db.$1 ..."
chown bind:bind /etc/namedb/master/db.$1

# Let's update named.conf ...
echo "Updating named.conf ..."

echo zone \"$1\"" {
        type master;
        file \"master/db.$1\";
};
" >> /etc/namedb/named.conf

# Reload named for changes to take effect ...
echo "Reloading named ..."

rndc reload

#Populate named.conf on ns2
echo "Populating named.conf on ns2 ..."

ssh ns2 'echo "zone \"'$1'\" {
        type slave;
        file \"sec/db.'$1'\";
        masters { 72.26.x.x; };
};
" >> /etc/bind/named.conf'

# Reload named on ns2
echo "Reloading named on ns2 ..."

rndc -s ns2 reload

Last edited by splooge; 7th June 2008 at 04:06 AM.
Reply With Quote
  #9   (View Single Post)  
Old 7th June 2008
cajunman4life cajunman4life is offline
Real Name: Aaron Graves
Package Pilot
 
Join Date: May 2008
Location: Coolidge, Arizona
Posts: 203
Default

Glad you got this worked out
__________________
I just saved a bunch of money on my car insurance by fleeing the scene of the accident!
Reply With Quote
Old 7th June 2008
TerryP's Avatar
TerryP TerryP is offline
Arp Constable
 
Join Date: May 2008
Location: USofA
Posts: 1,547
Default

The shells way of handling quoting can be a bit irksome at first but eventually you will love it (or curse it).

This awk tutorial gives a good overview of it when it talks about embedding awk programs within shell script.


Or for the programmer summery...

'' -- no interpolation
"" -- variable interpolation
`` -- execute shell commands and return output (as a scalar value I believe)

group of words within qoutes -- string
strings separated by white spaces are automatically concatenated (e.g. 'foo'$var'bar' is the same as foo${var}bar)
__________________
My Journal

Thou shalt check the array bounds of all strings (indeed, all arrays), for surely where thou typest ``foo'' someone someday shall type ``supercalifragilisticexpialidocious''.
Reply With Quote
Old 7th June 2008
J65nko J65nko is offline
Administrator
 
Join Date: May 2008
Location: Budel - the Netherlands
Posts: 4,125
Default

By using the "here" document construct of the shell will save you a lot of quoting or escaping
Code:
$ cat inline
#!/bin/sh

FILE=named.conf


cat <<END >${FILE}
zone $1 {
        type master;
        file "master/db.$1";
};
END
A sample run
Code:
$ sh inline xyz.com

$ cat named.conf
zone xyz.com {
        type master;
        file "master/db.xyz.com";
};
You even can redirect the output of a "here document" to a file
Code:
$ cat inline_redir
#!/bin/sh

FILE=$(mktemp)

echo ${FILE}
 
cat <<END > ${FILE} 
zone "$1" {
        type slave;
        file "sec/db.$1";
        masters { 72.26.x.x; };
};
END

$ sh inline_redir gorilla.com
/tmp/tmp.XwKYS14669

$ cat /tmp/tmp.XwKYS14669
zone "gorilla.com" {
        type slave;
        file "sec/db.gorilla.com";
        masters { 72.26.x.x; };
};
Now piping through ssh
Code:
$ cat ssh_append
#!/bin/sh

FILE=test.zone

ssh j65nko@parmenides "cat <<END > ${FILE} 
zone "$1" {
        type slave;
        file "sec/db.$1";
        masters { 72.26.x.x; };
};
END
"

$ sh ssh_append mickey_mouse.com

$ ssh j65nko@parmenides 'cat test.zone'
zone mickey_mouse.com {
        type slave;
        file sec/db.mickey_mouse.com;
        masters { 72.26.x.x; };
};
As you can see, the quotation marks are lost.
A fixed version
Code:
$ cat ssh_append                        
#!/bin/sh

FILE=test.zone

ssh j65nko@parmenides "cat <<END > ${FILE}
zone \"$1\" {
        type slave;
        file \"sec/db.$1\";
        masters { 72.26.x.x; };
};
END
"
$ sh ssh_append chimpansee.org 

$ ssh j65nko@parmenides 'cat test.zone' 
zone "chimpansee.org" {
        type slave;
        file "sec/db.chimpansee.org";
        masters { 72.26.x.x; };
};
__________________
You don't need to be a genius to debug a pf.conf firewall ruleset, you just need the guts to run tcpdump
Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
PHP read file contents - Maximum file size cksraj Programming 1 21st September 2009 11:38 AM
ssh/rdesktop into host behind NAT JMJ_coder General software and network 18 13th January 2009 08:19 PM
Print on remote WinXP from web host drhowarddrfine General software and network 5 13th October 2008 05:41 PM
Remote Access to File Server Oko OpenBSD Security 7 23rd June 2008 05:17 PM
Changing IP to host www, mail and etc in FreeBSSD neubie FreeBSD General 5 19th June 2008 07:34 AM


All times are GMT. The time now is 08:08 AM.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Content copyright © 2007-2010, the authors
Daemon image copyright ©1988, Marshall Kirk McKusick