Technology

How to find and replace ALL IP addresses with a new one

There is no greater hope in human life than survival. At the same time, it is important to live well. With that in mind, every content on the website is written so that a person can get all the information from here to start his life to make beautifully.

According to that, Technology is one of the topics. It is also a part of life. Read carefully Details of Technology related article

How to find and replace ALL IP addresses with a new one

At a certain point, I needed to change the VLAN IP address such as 172.0.0.2 with 172.0.0.1 for ease of use. As you know, Linux and Unix-like operating system stores all IP addresses and config in plain text files. This page explains my little adventure where I had to find and find and replace ALL IP addresses with a new one on Linux.

Tutorial details
Difficulty level Easy
Root privileges Yes
Requirements grep, sed, and Bash
Est. reading time 5 minutes

WARNING! I am dealing with system files stored at /etc/. Hence, root access is necessary. I also made snapshots option provided by Linode and backups before I decided to automate it. I am using Linode, but the procedure remains the same regardless of the home or cloud service provider. The important thing is to make a backup to recover in case something went wrong during mass editing.

Making Linode Server Backup

I made a manual backup of my Linode server by taking a snapshot

Step 1 – Finding a list of files for the old IP address

I decided to use the grep command as follows:
grep -R -w '172.0.0.2' /etc/
A truncated list of files that needs updating:

/etc/keepalived/keepalived.conf:    unicast_src_ip  172.0.0.2 # Private IP address of master (redis1)
/etc/ufw/user.rules:### tuple ### allow tcp 6379 172.0.0.2 any 172.0.0.0/24 in_eth1 comment=4f70656e2054435020526564697320504f5254206f6e2072656469733120686f737420666f7220636c7573746572
/etc/ufw/user.rules:-A ufw-user-input -i eth1 -p tcp -d 172.0.0.2 --dport 6379 -s 172.0.0.0/24 -j ACCEPT
/etc/ufw/user.rules:### tuple ### allow tcp 26379 172.0.0.2 any 172.0.0.0/24 in_eth1 comment=4f70656e205443502053454e5449454c20504f5254206f6e2072656469733120686f737420666f7220636c7573746572
/etc/ufw/user.rules:-A ufw-user-input -i eth1 -p tcp -d 172.0.0.2 --dport 26379 -s 172.0.0.0/24 -j ACCEPT
/etc/systemd/network/.05-eth1.network.linode-last:Address=172.0.0.2/24
/etc/systemd/network/.05-eth1.network.linode-orig:Address=172.0.0.2/24
/etc/haproxy/haproxy.cfg:# redis1 - 172.0.0.2
/etc/haproxy/haproxy.cfg:        server redis2 172.0.0.2:6379 check inter 3s
/etc/hosts:172.0.0.2	redis1 haproxy1 keepalived1
/etc/redis/sentinel.conf:bind 172.0.0.2
/etc/redis/sentinel.conf:sentinel known-replica mymaster 172.0.0.2 6379
/etc/redis/redis.conf:bind 172.0.0.2
.....
..
.....

I need to update services such as HAProxy, Nginx, Redis, MySQL, firewall rules, and more. The -R option read all files under each directory, recursively. It will also follow all symbolic links. The -w option will tell grep to select only those lines containing matches that form whole word.

Step 2 – Finding and replacing ip address with a new one using sed

This task is pretty simple, and the syntax for sed is as follows:
sed -i'.BACKUP' 's/OLD_IP_HERE/NEW_IP_HERE/g' input
For example:

OLD_IP='172.0.0.2'
NEW_IP='172.0.0.1'
INPUT_FILE='/etc/redis/redis.conf'
sed -i'.BACKUP' "s/${OLD_IP}/${NEW_IP}/g" "${INPUT_FILE}"

The -i option tells sed to make a backup before updating file. I can verify using the diff command:
diff /etc/redis/redis.conf /etc/redis/redis.conf.BACKUP
I compared updated file /etc/redis/redis.conf line-by-line with original backup file named /etc/redis/redis.conf.BACKUP:

70c70
< bind 172.0.0.1
---
> bind 172.0.0.2

Step 3 – Shell script to find and replace ALL IP addresses

First, we need to update the grep command as follows to get a list of files:
grep -l -H -R -w '172.0.0.2' /etc/
Outputs:

/etc/keepalived/keepalived.conf
/etc/ufw/user.rules
/etc/systemd/network/.05-eth1.network.linode-last
/etc/systemd/network/.05-eth1.network.linode-orig
/etc/haproxy/haproxy.cfg
/etc/hosts
/etc/redis/sentinel.conf
/etc/nginx/http.d/cyberciti.biz.conf
/etc/mysql/my.cnf

The -l option is most important for mass editing as it will suppress standard output. Instead, grep will print the name of each input file from which output would normally have been printed. The -H options ensure that grep displays each match’s file name. Then I am going to feed this list to sed using a while loop or bash for loop:

#!/bin/bash
set -euxo pipefail
OLD_IP='172.0.0.2'	# old server ip
NEW_IP='172.0.0.1'	# new server ip
DEST_DIR="/etc"		# search dir 
 
# Get file list
INPUT_FILES="$(grep -l -H -R -w ${OLD_IP} $DEST_DIR)"
 
# Ignore following dirs and files 
IGNORE_PATHS=(/etc/systemd/network/ /etc/network/ /etc/networks /etc/keepalived/keepalived.conf)
is_skip=0
 
# main
for f in $INPUT_FILES 
do
	for i in "${IGNORE_PATHS[@]}"
	do
		if [[ $f == *"${i}"* ]]
		then
			is_skip=1
			continue
		fi
	done
	[ $is_skip == 0  ] && sed -i'.BACKUP' "s/${OLD_IP}/${NEW_IP}/g" "$f"
	is_skip=0
done

After running the script, restart those services one by one using the systemctl command. For example:
sudo systemctl restart haproxy.service

 

Patreon supporters only guides 🤓

    • No ads and tracking

 

 

    • Join my Patreon to support independent content creators and start reading latest guides:

 

Join Patreon

Summing up

For Ansible, you need to edit the script to detect hostname and set correct OLD_IP and NEW_IP for each host. It can be done quickly using Bash array and case statement in the Bash script itself and left as an exercise to readers.

That was an easy and fun thing to do. For multiple servers, we can use Ansible to do our dirty work. The logic remains same or we can use above script:

---
- hosts: mylinodeservers
  tasks:

      - name: Copy IP update script
        ansible.builtin.copy:
          src: ip.updates.sh
          dest: ~/ip.updates.sh
          mode: 0700

      - name: Run ip.update.sh script
        command:~/ip.updates.sh

Update or edit the hosts file:

[mylinodeservers]
linode-01 ansible_user=admin ansible_python_interpreter='/usr/bin/python3'
linode-02 ansible_user=admin ansible_python_interpreter='/usr/bin/python3' 
linode-03 ansible_user=admin ansible_python_interpreter='/usr/bin/python3'

Then run it as follows:

ansible-playbook -i hosts --ask-vault-pass linode.yaml
# get other data from '@linode.data.yml' 
ansible-playbook -i hosts --ask-vault-pass --extra-vars '@linode.data.yml'  linode.yaml

See “How to find and replace text/IP address with Ansible” for other options. Make sure you read bash and other man pages for more information using the man command:
man bash
man sed
man grep

 


ADVERTISEMENT
 

 

Did you like this article?
Share it on any of the following social media channels below to give us your vote. Your feedback helps us improve.

Other related Technologies ideas you might enjoy

Related Articles

Leave a Reply

Your email address will not be published.