简体   繁体   中英

Passing external shell script variable via ssh

When I stumble across an evil web site that I want blocked from corporate access, I edit my named.conf file on my bind server and then update my proxy server blacklist file. I'd like to automate this somewhat with a bash script. Say my script is called "evil-site-block.sh" and contains the following:

ssh root@192.168.0.1 'echo "#date added $(date +%m/%d/%Y)" >> /var/named/chroot/etc/named.conf; echo "zone \"$1\" { type master; file \"/etc/zone/dummy-block\"; };" >> /var/named/chroot/etc/named.conf'

It is then run as

$ evil-site-block.sh google.com

When I look at the contents of named.conf on the remote machine I see:

#date added 09/16/2014
zone "" { type master; file "/etc/zone/dummy-block"; };

What I can't figure out is how to pass "google.com" as $1.

First off, you don't want this to be two separately redirected echo statements -- doing that is both inefficient and means that the lines could end up not next to each other if something else is appending at the same time.

Second, and much more importantly, you don't want the remote command that's run to be something that could escape its quotes and run arbitrary commands on your server (think of if $1 is '$(rm -rf /)'.spammer.com ).

Instead, consider:

#!/bin/bash
# ^ above is mandatory, since we use features not found in #!/bin/sh

printf -v new_contents \
  '# date added %s\nzone "%s" { type master; file "/etc/zone/dummy-block"; };\n' \
  "$(date +%m/%d/%Y)" \
  "$1"
printf -v remote_command \
  'echo %q >>/var/named/chroot/etc/named.conf' \
  "$new_contents"
ssh root@192.168.0.1 bash <<<"$remote_command"

printf %q escapes data such that an evaluation pass in another bash shell will evaluate that content back to itself. Thus, the remote shell will be guaranteed (so long as it's bash) to interpret the content correctly, even if the content attempts to escape its surrounding quotes .

Your problem: Your entire command is put into single quotes – obviously so that bash expressions are expanded on the server and not locally.

But this also applies to your $1 .

Simple solution: “Interupt” the quotation by wrapping your local variable into single quotes.

ssh root@192.168.0.1 'echo "#date added $(date +%m/%d/%Y)" >> /var/named/chroot/etc/named.conf; echo "zone \"'$1'\" { type master; file \"/etc/zone/dummy-block\"; };" >> /var/named/chroot/etc/named.conf'

NB: \\"$1\\"\\"'$1'\\" .

NOTE: This solution is a simple fix for the one-liner as posted in the question above. If there's the slightest chance that this script is executed by other people, or it could process external output of any kind, please have a look at Charles Duffy's solution .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM