To Ask or Not to Ask?

Automation can save employee and customer time through reduced manual action and reduced errors. The less human interaction required the less likely errors are to occur because a reliable repeatable process has been created. Typing commands into a terminal can suffer from misspelling and commands entered in an improper order. Conversely, too much automation can also introduce errors in a process, however.

I have a shell script that has a section that requires the IPv4 address of the host network interface to create firewall rules as part of a software package installation that must be reliable in diverse environments. There are various ways that you can automate the collection of the IPv4 address as long as you’re sure that network interface names are constant and, in the event of multiple interfaces, the zero interface (ens192 for CentOS and eth0 or ens33 for Ubuntu, etc.) is used for internet access. Consistency isn’t always the case because companies or individuals can change the network interface name on operating system installation with scripts, have the name set in a standardized image, and change it manually.

The most popular way to capture the IPv4 address is to use the IP utility (command: ip) that is present in most Linux distributions by default. The issue is that the IP utility makes no guarantees which order the IPv4 addresses will be displayed. If you have a single interface, no problem. Multiple interfaces? Big problem. The examples below use a mix of ip, hostname, and ifconfig.

ip4=$(/sbin/ip -o -4 addr list eth0 | awk '{print $4}' | cut -d/ -f1)

As you can see, you must know the name of the interface. We know interface names can be changed.

ip="$(ifconfig | grep -A 1 'eth0' | tail -1 | cut -d ':' -f 2 | cut -d ' ' -f 1)"

We’re using “ifconfig” instead of “ip,” but we run into the same issue with needing to know the interface name.

ip=$(hostname -I)

Here we are using the hostname utility with the -I flag to query non-loopback addresses as a command for the variable “ip.” Any time $ip is called “hostname -I” is executed. Multiple interfaces make this method unusable.

ifdata -pa br0

“ifdata” is a utility that is part of the moreutils package. Do we need more software installed that forces us to track more vulnerabilities and install more updates to perform a single action once? I think not.

There are many more examples of how to capture the IPv4 address but they all run into the same environmental variables of multiple interfaces and interface name changes. If you’re lucky, you’ll find people arguing about these methods.

Capturing the IPv4 address with automation has too much variability to be captured reliably, thus, I ask the operator for the IP address. I perform some validation on the operator-supplied IP address to catch formatting and numerical issues. For example, if someone enters 123.123.123.1234 or 123.12l.123.123 a message is printed to the terminal telling the operator to check the IP address for format and numerical accuracy then presented with another opportunity to enter the IP address.

echo "$(tput setaf 3)What is the IP address assigned to the host network interface?$(tput setaf 9)"
read ip

while ! [[ "$ip" =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]
    do echo "$(tput setaf 3)Please check for IP address format and numerical accuracy.$(tput setaf 9)"

    sleep 5

    echo "$(tput setaf 3)What is the IP address assigned to the host network interface?$(tput setaf 9)"
    read ip
done

I have plans to mature the IPv4 validation that checks for a maximum of two bits in the first octet, eight bits in the second and third octet, and seven bits in the fourth octet for allowance of Class A through Class C IPv4 addresses.