Get IPv4 and IPv6 with one command - dig

I would like to know if it's possible to get IPv4 and IPv6 addresses with just one invocation of dig?
For example, this gives the IPv4 address:
dig hostname A
And this command will give me the IPv6 address:
dig hostname AAAA
How can I get both addresses, IPv4 and IPv6, with just one command?

It may be that this has been added to dig since the question was asked, but for completeness this can be accomplished through the following query:
dig hostname A hostname AAAA +short
Source: http://linux.die.net/man/1/dig -- under the 'Multiple Queries' section

If you're querying an authoritative server for the domain, you can get all the records for a name with an ANY query:
dig hostname ANY #servername
However, this won't work reliably if you're querying a caching server. When a caching server responds to an ANY query, it returns whatever records happen to be in cache at the time. If the name has both A and AAAA records, but the server has only looked up the A records recently, the AAAA records won't be in the cache, so it won't return them.
Furthermore, there is a proposal to allow DNS servers to refuse to answer ANY queries: Providing Minimal-Sized Responses to DNS Queries that have QTYPE=ANY. If you query a server that implements this, you may not be able to get both responses with a single query (although one of the suggestions in that draft is that an ANY query might just return all MX, A, and AAAA, since this is often what clients want). So for best reliability, you should just make two queries.

Now that IPv6 is a lot more common, I've found myself frequently needing to query both A and AAAA. I can never seem to remember the syntax, so I finally wrote a function for my ~/.bashrc called digall. I shared it with some friends and they loved it, so I threw it up on github in gist that anyone is welcome to use: https://gist.github.com/FreedomBen/23020c464779bb30cab754d92bdce6c6
Here's the current version which you can put in a file in your path and mark executable:
#!/usr/bin/env bash
#
# To use, simply run `digall <domain>` such as:
#
# digall example.com
# digall sub.example.com
#
# Place this file in your PATH. Suggest either /usr/local/bin/ or ~/bin
#
# Alternatively you can wrap it in a function called `digall` and put in ~/.bashrc
#
# License: MIT
declare -rx digall_color_restore='\033[0m'
declare -rx digall_color_red='\033[0;31m'
declare -rx digall_color_light_green='\033[1;32m'
declare -rx digall_color_light_blue='\033[1;34m'
declare -rx digall_color_light_cyan='\033[1;36m'
if [ -z "$1" ]; then
echo -e "${digall_color_red}Error: Please pass domain as first arg${digall_color_restore}"
else
echo -e "${digall_color_light_blue}Queries: (dig +noall +answer '$1' '<type>')...${digall_color_light_cyan}\n"
for t in SOA NS SPF TXT MX AAAA A; do
echo -e "${digall_color_light_green}Querying for $t records...${digall_color_restore}${digall_color_light_cyan}"
dig +noall +answer "$1" "${t}"
echo -e "${digall_color_restore}"
done
fi

Related

nslookup - return only the IP address of host

I'd like to be able to return only the IP from a nslookup command. Currently if I execute:
>nslookup foo21.bar.local
it will return something like:
Server: 11.13.5.134
Address: 11.13.5.134#53
Name: foo21.bar.local
Address: 11.13.35.312
I would like a command that returns just the:
11.13.35.312
Thanks for any answers.
dig has options to make that easy:
dig +short foo21.bar.local
will just give you the A records, one per line (a domain can have more than one A record). To only get the first one:
dig +short foo21.bar.local | head -n1
Using dig as #Marcus suggest is the most clean way.
To answer your question, we can use awk to get only the line with Address and then get the second col:
nslookup google.com | awk '/^Address: / { print $2 }'
Will output:
216.58.208.110

Why echo isn't able to access a variable in Ubuntu 20.04

I can't find anything that helps with this issue even if the answer may be very simple.
I'm trying to get squid to redirect traffic through a 3g dongle, therefore I need to table the IP and change it in the squid.conf every time it changes.
I'm using this code here on "/etc/ppp/ip-up.local" so it's launched every time a new IP connects (or reconnects) to the machine.
#!/bin/bash
if [[ "$PPP_IFACE" == "ppp0" ]] ; then
TABLE=uplink2
/bin/sed -i "s&\(tcp_outgoing_address\).*\(very1\)&\1 $PPP_LOCAL \2&" /etc/squid/squid.conf
fi
##generate ip subnet for route
baseip=`echo "$PPP_LOCAL" | cut -d"." -f1-3`
/usr/sbin/ip route add "$baseip".0/24 dev "$PPP_IFACE" src "$PPP_LOCAL" table "$TABLE"
/usr/sbin/ip route add default via "$PPP_REMOTE" table "$TABLE"
/usr/sbin/ip rule add from "$PPP_LOCAL" table "$TABLE"
/usr/sbin/squid/ -k reconfigure
/usr/bin/systemctl squid restart
exit 0
The problem is that baseip=echo "$PPP_LOCAL" | cut -d"." -f1-3 cannot use $PPP_LOCAL
I tried to add echo $PPP_LOCAL >> file.txt but it just adds an empty line.
It's awkward to me that sed instead accesses the variable and modify correctly the squid.conf file with the new address
How can I fix this??
I also have a "sub-question", I'm a complete newbie just starting to learn and I'm not sure whether or not I should add an ip-down code to remove the table rules
Thanks everyone for the help

Why this function in bashrc Dosnt work?

I am trying to get this function to file .bashrc
This is my function :
function my_ip() {
echo "internal or external?"
read -r choise
if [ "$choise" == "internal" ] ;then
echo "please enter the name of the card that youare using at";
read -r card ;
ifconfig "$card" | grep 'inet addr' |cut -d':' -f2|cut -d ' ' -f1;
else
wget -qO- http://noc.co.il |grep "var VisitorCountry" | awk '{print$4}'|cut -d '"' -f4;
fi
}
My goal is that the function will quickly give me my IP by choosing internal or external
if I want to automatically displays the network card ("without the need to ask Which network card do you use(The computer automatically detects which network card the user uses and will put the name as a variable at the right commend for internal IP , how can I get him to identify what card the user use(WLAN0 WLAN1 etc.) ?
A system can have more than one IP address. Which one of them is the one you are looking for? You did not specify that.
There are multiple questions related to finding IP addresses with bash:
Find internal IP address
The accepted answer uses a deprecated option for hostname; the second answer is the more correct one IMHO.
In bash, is there a way to find the IP address for all interfaces?
Find IP address for my system
Bash script to find all IP addresses
If none of those float your boat, consider closing this question and posting a new one with more precise phrasing what you are looking for.

Update all instances of IP address on a server

We currently have a dynamically provided IP address and are switching over to a static ip address. As such, I need to change the IP address on our 3 LAMP servers. These servers also run bind9 for DNS and postfix/dovecot for email. (MySQL is actually running as a Percona DB cluster which may be irrelevant.)
I think I have a good strategy, but want to check my logic with others who may have done this successfully before.
The concept is to stop all web, database, and mail services on each machine one at a time, pushing traffic to one of the two remaining servers, and run the following script to replace the old IP address with the new IP address, then reboot the server and attempt to push traffic back to it then proceed with the next server in the cluster if all goes well.
I used grep -r to find instances of the old ip address in the system and need to make sure that I'm not missing anything important that needs to be considered.
find /etc/bind -type f -print0 | xargs -0 sed -i 's/old.ip.address/new.ip.address/g'
find /etc/postfix -type f -print0 | xargs -0 sed -i 's/old.ip.address/new.ip.address/g'
find /etc/apache2 -type f -print0 | xargs -0 sed -i 's/old.ip.address/new.ip.address/g'
find /etc/postfix -type f -print0 | xargs -0 sed -i 's/old-ip-address/new-ip-address/g'
find /etc/bind -type f -print0 | xargs -0 sed -i 's/rev.address.ip.old/rev.address.ip.new/g'
As a point of clarification, grep -r found the IP address references in the /etc/bind/zones tables, the /etc/postfix configuration files, and the /etc/apache2 config file. The IP address separated by hyphens was also found in the postfix config files. The reverse IP address was also found in a /etc/bind/named.conf.local file and will also need to be replaced.
Can anyone see if I may be missing something here? I'm doing this in a production environment...not the most ideal of circumstances, of course.
Sorry all. Looks like I let this get stale after finding the solution. For posterity's sake, here's what seems to be working at this point:
$ORIGIN example.com.
$TTL 12H
; # symbol represents example.com.
# 12H IN SOA ns1.example.com. hostmaster#example.com. (
2015062954 ;serial
30M ;refresh
2M ;retry
2W ;expire
1D ;minimum TTL
)
NS ns1.example.com.
NS ns2.example.com.
MX 10 mail.example.com.
IN A 99.101.XXX.XXX
IN TXT "v=spf1 a mx ip4:99.101.XXX.XXX ~all"
IN SPF "v=spf1 a mx ip4:99.101.XXX.XXX -all"
ns1 IN A 99.101.XXX.XXX
ns2 IN A 99.101.XXX.XXX
mail IN A 99.101.XXX.XXX
IN TXT "v=spf1 a mx ip4:99.101.XXX.XXX ~all"
IN SPF "v=spf1 a mx ip4:99.101.XXX.XXX -all"
www IN A 99.101.XXX.XXX
dev IN A 99.101.XXX.XXX
demo IN A 99.101.XXX.XXX
webconf IN A 99.101.XXX.XXX
stats IN A 99.101.XXX.XXX
While the idea of using a find piped to an xargs sounds reasonable, I would take my 15 years of experience and tell you that is a bad idea. I would propose:
identify those services running on the boxes that are important (your find command works great here)
identify those files important to each of those services where address is defined
back up those files (cp to .orig works nicely)
create new files that contain your new addresses
This way you have a fast transition with:
cp somefile.new somefile
and a fast backout with:
cp somefile.orig somefile
Additionally, I would expect that the zones files contain actual DNS entries, so changing them is fine, but you'll probably need to reload named for those changes to take effect. Same goes for postfix, you'll want to postfix reload those as well.
EDIT (I haven't taken the time to actually load this zone, but it looks reasonably correct):
$ORIGIN example.com.
$TTL 12H # IN SOA ns1.example.com. hostmaster#example.com. (
2015062660 ;
30M ;refresh
2M ;retry
2W ;expire
1D ;minimum TTL
)
IN NS ns1.example.com.
IN NS ns2.example.com.
IN A 99.101.XXX.X
example.com. IN MX 10 mail.example.com.
mail IN A 99.101.XXX.X
IN TXT "v=spf1 a mx ip4:99.101.XXX.X ~all
ns1 IN A 99.101.XXX.X
ns2 IN A 99.101.XXX.X
www IN CNAME example.com.
dev IN CNAME example.com.
demo IN CNAME example.com.
webconf IN CNAME example.com.
stats IN CNAME example.com.
EDIT:
glue records

Domain foo.bar points 127.0.53.53 -- why?

I just noticed today that domain foo.bar resolves to 127.0.53.53 (http://foo.bar, http://whois.domaintools.com/foo.bar)
In my case this ends up on the localhost Apache, but I wonder why the registrant did not simply chose to point to 127.0.0.1? Is there any specific reason?
127.0.53.53 is a special IP addresses that is used by ICANN to prevent DNS name collisions with the new gTLDs.
In your case the .bar gTLD was delegated in February. So the 127.0.53.53 is a big hint for people using .bar in their internal setups that the .bar domain name will be used in the global DNS very soon.
If you look closer at the foo.bar record you see more information:
$ dig foo.bar A +short
127.0.53.53
$ dig foo.bar TXT +short
"Your DNS configuration needs immediate attention see https://icann.org/namecollision"
$ dig foo.bar MX +short
10 your-dns-needs-immediate-attention.bar.
$ dig foo.bar SRV +short
10 10 0 your-dns-needs-immediate-attention.bar.

Resources