Change an IP address from dynamic to static with a bash script

0

Changing a Linux system’s IP address from dynamic to static isn’t difficult, but does require a bit of care and a set of commands that you probably rarely use. This post provides a bash script that will run the process, collect the necessary information, and then issue the necessary commands to make the changes while requiring as little as possible from the person running it.

Most of the scripting is about making sure the correct parameters are used. For example, it collects the system’s 36-character universally unique identifier (UUID) so you never have to type it in or copy and paste it in place.

After asking only a question or two, the script runs a series of nmcli (Network Manager) who will change the IP address if necessary and set the address as static. Note that a number of fields in the commands it will execute as shown below are variables derived from earlier commands in the script.

sudo nmcli connection modify $UUID IPv4.address $IP/$sz
sudo nmcli connection modify $UUID IPv4.gateway $router
sudo nmcli connection modify $UUID IPv4.method manual
sudo nmcli connection down $UUID
sudo nmcli connection up $UUID

If a new IP address is requested, the script will check the format of the requested address and ensure that it is compatible with the current network.

Before executing the commands shown above, the script collects variables used to ensure that the commands are configured correctly, primarily by executing commands that report the current settings. The prominent UUID displayed in each of them is collected from the output of this command:

$ nmcli connection show
NAME                UUID                                  TYPE      DEVICE
Wired connection 1  ec33e575-8059-3a20-b7a5-58393deb1783  ethernet  enp0s25

The UUID is saved in the script by the command like the one shown below so that it can be used in the nmcli commands presented above.

$ UUID=`nmcli connection show | tail -1 | awk ‘{print $4}’`
$ echo $UUID
ec33e575-8059-3a20-b7a5-58393deb1783

The command below extracts the subnet specification from a ip one command like the one shown below. The result will be something like “192.168.0.4/24” where the 24 (i.e. 24 bits) tells us that the first three bytes of the address (192.168.0) represent the network.

$ subnet=`ip a | grep “inet “ | tail -1 | awk ‘{print $2}’`
$ echo $subnet
192.168.0.11/24

Getting almost all the necessary information from the system rather than requiring the user to provide it makes the process much easier and, potentially, more reliable.

The script also gives you the option to change the current IP address if you don’t like it. Although this leaves you logged out of the system when the script completes, you can immediately log back in using the new IP address.

Note that the script uses sudo for final commands, as these commands will change system settings.

Here is the script I call “set_static_IP”:

#!/bin/bash

# get subnet
subnet=`ip a | grep “inet “ | tail -1 | awk ‘{print $2}’`

# get router/gateway
router=`ip route show | head -1 | awk ‘{print $3}’`

# get size of network portion of address in bytes
sz=`echo $subnet | awk -F / ‘{print $2}’`
bytes=`expr $sz / 8`
prefix=`echo $subnet | cut -d. -f1-$bytes`      # e.g., 192.168.0

# get IP address to be set
IP=`hostname -I | awk ‘{print $1}’` # current IP
echo -n “Keep IP address?—$IP [yn]> “
read ans if [ $ans =="n" ]; then echo -n “Enter new IP address: “ read IP # check if specified IP is properly formatted if [[ ! $IP =~ ^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$ ]]; then echo Invalid IP fi # check if specified IP works for local network if [[ ! $IP =~ ^$prefix ]]; then echo “ERROR: Specified IP not usable for local network” exit fi fi # check if specified IP is properly formatted if [[ ! $IP =~ ^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$ ]]; then echo Invalid IP fi # fetch the UUID UUID=`nmcli connection show | tail -1 | awk ‘{print $4}’` # UUID=`nmcli connection show | head -2 | tail -1 | awk ‘{print $3}’` # Mint # run commands to set up the permanent IP address sudo nmcli connection modify $UUID IPv4.address $IP/$sz sudo nmcli connection modify $UUID IPv4.gateway $router sudo nmcli connection modify $UUID IPv4.method manual sudo nmcli connection up $UUID

The script has been tested on Fedora 35 and Linux Mint. Note that the command to retrieve the UUID on Mint is different because the output of the “nmcli connection show” command is different. The command for Mint is included in the script but commented out for easy change.

The interaction with the script will look like this:

$ ./set_static_IP
Keep IP address?—192.168.0.18 [yn]> y
[sudo] password for yourid:
Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/24)

After running the script, I ran a to find to search for very recently updated files and found this one that includes the “manual” (i.e. static) parameter specified in the third command given above.

$ sudo cat “/etc/NetworkManager/system-connections/Wired connection 1.nmconnection”
[connection]
id=Wired connection 1
uuid=ec33e575-8059-3a20-b7a5-58393deb1783
type=ethernet
autoconnect-priority=-999
interface-name=enp0s25
permissions=
timestamp=1653746936

[ethernet]
mac-address-blacklist=

[ipv4]
address1=192.168.0.11/24,192.168.0.1
dns-search=
method=manual

[ipv6]
addr-gen-mode=stable-privacy
dns-search=
method=auto

[proxy]

To find only files created or updated very recently, you can use a command like this which finds files that have been modified within the last 14.4 minutes:

$ sudo find . -mtime -.01 -print

In case it’s not clear, the -mtime variable when set to 1 means “1 day”. Since a day is 1440 minutes long, .1 means 144 minutes and .01 means 14.4 minutes.

Wrap

Dynamic addressing is great except when it’s not. It’s not when the system in question is one you need to log in to quite often rather than the one you only log in from. Knowing how to change an IP address from dynamic to static can be a big problem when you need an IP address that doesn’t change.

Join the Network World communities on Facebook and LinkedIn to comment on the topics that matter to you.

Copyright © 2022 IDG Communications, Inc.

Share.

Comments are closed.