[HELP] Creating a script to record IP of a website
Red HatThis forum is for the discussion of Red Hat Linux.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
[HELP] Creating a script to record IP of a website
Hello all, this is my first post here at LinuxQuestions and to start it off I have a question that may be simple. I will provide as much information that I can to help explain what it is I am trying to accomplish.
Information:
My server is running CentOS latest version
I am booting to GRSEC
My problem is that my phone's IP address changes every 10-30 minutes, and my server is IP whitelisted. So in order for me to login to my server I need to somehow record my Phones IP address into the "/etc/hosts.allow file".
Getting the IP of my phone is simple, for this I set up an account at dyndns.org. My phone successfully updates it's ip to the site whenever it changes. For this example I will use "linuxquestions.dyndns.org" In order to get my phones IP I will run a "nslookup" on linuxquestions.dyndns.org every 10 minutes.
For this I will set a cron job to run every 10 minutes.
Code:
0,10,30,45 * * * * /scripts/dyndnslinuxquestions
Now all I need to do is write the script. This is where I am having some trouble. I know that I will somehow have to grep the IP from the nslookup command and manipulate the string.
Somehow I need to grab the "12.34.56.78" IP address and write it to the "/etc/hosts.allow" file and remove the last IP written in the file.
So lets say my hosts.allow file looks like such:
Code:
# hosts.allow This file describes the names of the hosts which are
# allowed to use the local INET services, as decided
# by the '/usr/sbin/tcpd' server.
#
#User 1
SSHD : 11.22.33.44/255.248.0.0 : ALLOW
# My Home IP
SSHD : 12.23.34.45 : ALLOW
# My Phone
SSHD : 13.24.35.46 : ALLOW
I need to delete the "SSHD : 13.24.35.46 : ALLOW" line every time the IP updates and then add the new IP that I gathered by using string manipulation on the "nslookup" command.
If someone could step me through the process and explain to me what each part of the script does instead of just handing it to me that would be awesome. I am here to learn not just copy and paste.
#!/bin/bash
usage() {
echo Usage:
echo -----
echo "$(basename $0) ip/address name"
}
if [ $# != 2 ]
then
usage
exit
fi
ip=$(dig +short $1 );
res=$?;
if [ -f /tmp/$1.record ]; then oldip=$(cat /tmp/$1.record); else oldip="0.0.0.0";fi
if [ $res = 0 -a "$ip" != "$oldip" -a "$ip" != "" ] ;
then
echo "$(date) $2 IP Changed from $oldip to $ip" | tee -a /var/log/dynipcheck.log;
echo $ip > /tmp/$1.record ;
fi
This doesn't do exactly what you want, but might give you some pointers. You might consider using sed to change the necessary line in hosts.allow.
I might also consider using iptables instead of hosts.allow, but I suspect that's just personal preference more than any real security advantage. Other opinions might differ.
#!/bin/sh
# Grep finds the Server line and sed uses a regular expression
# to cut out the IP address
NewIP=$(nslookup linuxquestions.dyndns.org | grep Server | sed -e "s/[^0-9]*\([0-9.]*\).*/\1/")
# The same happens here to get the old IP address. First I find
# the User 1 listing and following line. This isn't very pretty
OldIP=$(cat /etc/hosts.allow | grep "User 1" -A 1 | grep ALLOW | sed -e "s/[^0-9]*\([0-9.]*\).*/\1/")
echo "Changing $OldIP to $NewIP."
# Once we know the new and old IP addresses, we can use sed to
# replace them in a file. Actually, run this on any files
# that you want to replace the old with the new
sed -i "s@$OldIP@$NewIP@" /etc/hosts.allow
This isn't very elegant, but I think it does what you are looking for. Let me know how it works.
If you (your script) knows the old IP address then this one liner should work
Code:
sed -i "s/${old_IP//./\\.}/$(dig +short linuxquestions.org)/" hosts
Note: ${old_IP//./\\.} is bash parameter expansion, taking the value of $old_IP and globally changing every "." to "\." to make the "." stand for itself rather than "any character" in the sed substitution.
Test without the -i option!
Here it is demonstrated at the command line
Code:
c@CW8:/tmp$ cat hosts
# hosts.allow This file describes the names of the hosts which are
# allowed to use the local INET services, as decided
# by the /usr/sbin/tcpd server.
#
#User 1
SSHD : 11.22.33.44/255.248.0.0 : ALLOW
# My Home IP
SSHD : 12.23.34.45 : ALLOW
# My Phone
SSHD : 13.24.35.46 : ALLOW
c@CW8:/tmp$ old_IP=13.24.35.46
c@CW8:/tmp$ sed "s/${old_IP//./\\.}/$(dig +short linuxquestions.org)/" hosts
# hosts.allow This file describes the names of the hosts which are
# allowed to use the local INET services, as decided
# by the /usr/sbin/tcpd server.
#
#User 1
SSHD : 11.22.33.44/255.248.0.0 : ALLOW
# My Home IP
SSHD : 12.23.34.45 : ALLOW
# My Phone
SSHD : 75.126.162.205 : ALLOW
#!/bin/bash
usage() {
echo Usage:
echo -----
echo "$(basename $0) ip/address name"
}
if [ $# != 2 ]
then
usage
exit
fi
ip=$(dig +short $1 );
res=$?;
if [ -f /tmp/$1.record ]; then oldip=$(cat /tmp/$1.record); else oldip="0.0.0.0";fi
if [ $res = 0 -a "$ip" != "$oldip" -a "$ip" != "" ] ;
then
echo "$(date) $2 IP Changed from $oldip to $ip" | tee -a /var/log/dynipcheck.log;
echo $ip > /tmp/$1.record ;
fi
This doesn't do exactly what you want, but might give you some pointers. You might consider using sed to change the necessary line in hosts.allow.
I might also consider using iptables instead of hosts.allow, but I suspect that's just personal preference more than any real security advantage. Other opinions might differ.
Thanks for the response! Thanks for the tip on using sed I will research it somemore.
Quote:
Originally Posted by kainosnous
Were you looking for something like this:
Code:
#!/bin/sh
# Grep finds the Server line and sed uses a regular expression
# to cut out the IP address
NewIP=$(nslookup linuxquestions.dyndns.org | grep Server | sed -e "s/[^0-9]*\([0-9.]*\).*/\1/")
# The same happens here to get the old IP address. First I find
# the User 1 listing and following line. This isn't very pretty
OldIP=$(cat /etc/hosts.allow | grep "User 1" -A 1 | grep ALLOW | sed -e "s/[^0-9]*\([0-9.]*\).*/\1/")
echo "Changing $OldIP to $NewIP."
# Once we know the new and old IP addresses, we can use sed to
# replace them in a file. Actually, run this on any files
# that you want to replace the old with the new
sed -i "s@$OldIP@$NewIP@" /etc/hosts.allow
This isn't very elegant, but I think it does what you are looking for. Let me know how it works.
This appears to be exactly what I want but one thing. Since I am looking for the IP of second "Address:" not the first I will have to change the script a little . it would seem you are copying the text after the first "Server:" line which in this case is "66.45.228.250".
Just from reading a little bit about sed and looking at your examples I came up with this:
Code:
NewIP=$(nslookup linuxquestions.dyndns.org | grep "dyndns.org" -A 1 | grep "Address:" | sed -e "s/[^0-9]*\([0-9.]*\).*/\1/")
When I tested that, it successfully printed out JUST my phones IP.
Also, I see your looking up "User 1" IP. I believe I would need to change that to "My Phone"
Over all this is pretty much EXACTLY what I was wanting and I learned quite a bit.
I may extend this script to be more active and do more but for the time being I believe this will work. Thanks!
Quote:
Originally Posted by catkin
If you (your script) knows the old IP address then this one liner should work
Code:
sed -i "s/${old_IP//./\\.}/$(dig +short linuxquestions.org)/" hosts
Note: ${old_IP//./\\.} is bash parameter expansion, taking the value of $old_IP and globally changing every "." to "\." to make the "." stand for itself rather than "any character" in the sed substitution.
Test without the -i option!
Here it is demonstrated at the command line
Code:
c@CW8:/tmp$ cat hosts
# hosts.allow This file describes the names of the hosts which are
# allowed to use the local INET services, as decided
# by the /usr/sbin/tcpd server.
#
#User 1
SSHD : 11.22.33.44/255.248.0.0 : ALLOW
# My Home IP
SSHD : 12.23.34.45 : ALLOW
# My Phone
SSHD : 13.24.35.46 : ALLOW
c@CW8:/tmp$ old_IP=13.24.35.46
c@CW8:/tmp$ sed "s/${old_IP//./\\.}/$(dig +short linuxquestions.org)/" hosts
# hosts.allow This file describes the names of the hosts which are
# allowed to use the local INET services, as decided
# by the /usr/sbin/tcpd server.
#
#User 1
SSHD : 11.22.33.44/255.248.0.0 : ALLOW
# My Home IP
SSHD : 12.23.34.45 : ALLOW
# My Phone
SSHD : 75.126.162.205 : ALLOW
Not sure I quite understand what your doing here. Care to explain a bit?
--
I think my overall script would be something like:
Code:
#!/bin/sh
# Grep finds the Server line and sed uses a regular expression
# to cut out the IP address
NewIP=$(nslookup linuxquestions.dyndns.org | grep "dyndns.org" -A 1 | grep "Address:" | sed -e "s/[^0-9]*\([0-9.]*\).*/\1/")
# The same happens here to get the old IP address. First I find
# the User 1 listing and following line. This isn't very pretty
OldIP=$(cat /etc/hosts.allow | grep "My Phone" -A 1 | grep ALLOW | sed -e "s/[^0-9]*\([0-9.]*\).*/\1/")
echo "Changing $OldIP to $NewIP."
# Once we know the new and old IP addresses, we can use sed to
# replace them in a file. Actually, run this on any files
# that you want to replace the old with the new
sed -i "s@$OldIP@$NewIP@" /etc/hosts.allow
Tested and here is results:
Code:
root@LinuxQuestions [/]# sh /scripts/android_nslookup
Changing 12.34.56.78 to 97.41.50.57.
root@LinuxQuestions [/]#
Now I venture into the file and I see:
Code:
# My Phone
SSHD : 97.41.50.57 : ALLOW
Success!
Last edited by reneg4d3; 04-09-2010 at 03:42 PM.
Reason: typo
Bash substitutes the output (stdout) of command in place of $(command).
sed you know about. Its substitute command (s/<regular expression>/<replacement string>/) searches for a regular expression and replaces it with <replacement string>. In a regular expression, "." means any single character. Thus if you use an IP address as a regular expression, 192.168.1.1 will match 192.168.1.1 but it will also match 192a168Bm1z1. The special meaning of "." in a regular expression may be removed by "escaping" it with a backslash "\" thus regular expression 192\.168\.1\.1 will match only 192.168.1.1.
sed's -i option makes sed change a file "in place" -- it modifies the input file.
It is a very useful technique to try commands and parts of commands at the command line. You could have tried
Using safer code is recommended. Also, if you write to file, you are changing it's time stamp even when there is no change.
This code could and probably will be used by others also, maybe for larger number of IP's, so I would add write suppression just in case. Also, I would ADD BACKUP of hosts.allow, maybe even with time stamp in name (it does not have to be in /etc folder) so if you brake the file your system is not rendered totally useless while you re-create it by hand. If you create backup file, but without a stamp in filename, next run will overwrite the backup.
Adding smart code to view (less) backuped files from script, and option to revert to last good one would be my choice. Write once, saves you until the end of time. :-)
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.