简体   繁体   中英

Methods to detect public IP address in bash

As part of an installation script, I want to make an "educated guess" about the machines public IP address. It should be as robust as possible, working on a variety of hosts and platforms. Here is an example:

https://gist.github.com/4669037

This script uses 3 methods and then defaults to the value of /etc/hostname . I have only tested this on Ubuntu so far. Will this be likely to work on other distributions? And are there additional methods that I could add?

curl ipinfo.io/ip

Or

wget -q -O - ipinfo.io/ip

Or

lynx -source ipinfo.io/ip

get public ip address

curl ifconfig.me将是最佳选择,以防您没有 curl:

wget -qO- ifconfig.me/ip

How much public public IP are you looking for? What if the machine is behind NAT?

  • curl / wget / netcat ( nc ) <URL> which contains requester's address: should work most of the time, but may the site may be unreachable from the machine (be it firewall or temporary/permanent unavailability). You'll get the most public IP you can.

  • ifconfig : must run as root, otherwise you'd have to try /sbin/ifconfig or /usr/sbin/ifconfig as well. What if the machine has more NICs? How do you tell what IP is the right one? What if only IPv6 is used on the machine's LAN? In any case, you'll get the least public IP you can (and possibly a wrong one if more interfaces are configured on the machine - which often is the case these days with omnipresent virtualization using network tap devices and/or).

  • /etc/hostname : does not need to exist, on many systems it is /etc/HOSTNAME , and it does not contain IP address rather it should contain the hostname (usually the FQDN).

The point is, that the ways in which it can fail are numerous and you probably should consider either a) specifying more precisely what systems you are targeting or b) whether you really need to know the IP at all - is a solution that seems to work in simple cases worth using when it fails miserably in slightly more complicated setup? If you think you need the IP, prepare a way to handle failures gracefully in cases where you either don't get the IP at all or you get a wrong one.

试试这个命令:

wget -O - -q icanhazip.com

If on an AWS EC2 you can use:

curl checkip.amazonaws.com

NOTE: this service can be used from any web client.

I found my personal preferred method here:

  • dig +short myip.opendns.com @resolver1.opendns.com
  • dig +short txt ch whoami.cloudflare @1.0.0.1
  • dig +short txt oo.myaddr.l.google.com @ns1.google.com
    • dig +short txt oo.myaddr.l.google.com @ns1.google.com | awk -F'"' '{print $2}'

This solution doesn't work if you're behind nat or something. It helps without a 3rd party service. It works if the machine has the connection on it, like a server, or a ppp connection.

  • Not an exactly correct answer to question, but probably helps other people (like me)
  • Requires to be root in most (or all?) cases

You can get the (first) default route from route -n , find the interface it uses, and find the ip it has.

MAINIF=$( route -n | grep '^0\.0\.0\.0' | head -n 1 | awk '{print $NF}' )
IP=$( ifconfig $MAINIF | { IFS=' :';read r;read r r a r;echo $a; } )

Using only bash (with help from icanhazip.com ):

exec 3<>/dev/tcp/icanhazip.com/80 
echo -e 'GET / HTTP/1.0\r\nhost: icanhazip.com\r\n\r' >&3 
while read i
do
 [ "$i" ] && myip="$i" 
done <&3 
echo "$myip"

bash opens open a socket to icanhazip and sends an http request, the IP address is returned on the last non-empty line of the data returned. (previous lines are http headers)

This avoids the need for http client like wget or curl.

使用 curl 打shtuff.it IP 服务

curl http://shtuff.it/myip/short

Use ipify API:

curl 'https://api.ipify.org?format=json'

Bash script:

#!/bin/bash

ip=$(curl -s https://api.ipify.org)
echo "My public IP address is: $ip"

我使用 IPGrab 是因为它很容易让我记住。

curl http://ipgrab.io

I was getting whitespace characters at the end of other commands:

$ curl -s https://api.ipify.org
255.255.255.255%

I found that using jsonip.com combined with jq got rid of this. This way, parsing the IP address is as easy as a jq expression:

$ curl -s https://jsonip.com | jq -r '.ip'
255.255.255.255

See this jq play .

Donde: remote es un host al que tengas acceso y home es un host del que quieres averiguar su ip

Script bash:

 #!/bin/bash

 host_remote="sirio.fun"
 host_home="tutia.ovh"
      
 ip_home=$(ssh $host_remote ping -c 1 $host_home | awk '/bytes from/ {print $4}')
        
 echo $ip_home

Para cron:

#!/bin/bash

function alert() {
    echo "Old ip: "$ip_home_save
    echo "New ip: "$ip_home
    
    echo "Se guarda la nueva ip"
    ssh $host_remote ping -c 1 $host_home | awk '/bytes from/ {print $4}' > $host_remote_file
}

host_remote="sirio.fun"
host_home="cacadela.vaca"

host_remote_file=/tmp/${host_remote}.tmp

ip_home=$(ssh $host_remote ping -c 1 $host_home | awk '/bytes from/ {print $4}')

if [[ -f $host_remote_file ]]; then
    ip_home_save=$(cat $host_remote_file)
    echo $ip_home
    echo $ip_home_save
    [[ $ip_home == $ip_home_save ]] || error=1
else
    echo "No existen datos para comprobar, se generan ahora para futuras referencias"
    ssh $host_remote ping -c 1 $host_home | awk '/bytes from/ {print $4}' > $host_remote_file
    exit 1
fi

[[ $error ]] && alert || echo "No problem"

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