Use bash to change an IP address from dynamic to static on Linux


Changing the IP address of a Linux system from dynamic to static is not difficult, but requires a little care and a set of commands that you likely rarely use. This post provides a bash script that will run through the process, collect the needed information and then issue the commands required to make the changes while asking as little as possible from the person running it.

The bulk of the script focusses on making sure that the correct settings are used. For example, it collects the 36-charater universally unique identifier (UUID) from the system so that you never have to type it in or copy and paste it into place.

After asking only a question or two, the script runs a series of nmcli (Network Manager) commands that will change the IP address if requested and set the address to be static. Notice that a number of the fields in the commands that it will run 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 address requested and make sure that it is compatible with the current network.

Prior to running the commands shown above, the script collects the variables used to make sure the commands are set up correctly—largely by running commands that report on the current settings. The prominent UUID shown 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 that shown below so that it can be used in the nmcli commands shown earlier.

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

The command below pulls the subnet specification from an ip a command like that 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 nearly all the needed information from the system rather than asking the user to provide it makes the process a lot easier and, potentially, more reliable.

The script also gives you the option of changing the current IP address if you don’t like it. While this will leave you disconnected from the system by the time the script ends, you can immediately log back in using the new IP address.

Note that the script uses sudo for the final commands because those commands will change system settings.

Here is the script which 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 was tested on both Fedora 35 and Linux Mint. Notice that the command for fetching 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 an easy switch.

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 find command to look for very recently updated files and found this one that includes the “manual” (i.e., static) setting specified in the thrid command shown 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 very recently created or updated files, you can use a command like this that looks for files that have been changed in the last 14.4 minutes:

$ sudo find . -mtime -.01 -print

In case this isn’t clear, the -mtime variable when set to 1 means “1 day”. Since a day is 1440 minutes long, .1 would mean 144 minutes and .01 means 14.4 minutes.

Wrap-Up

Dynamic addressing is great except when it isn’t. It isn’t when the system in question is one you have to connect to fairly often rather than one you only connect from. Knowing how to change an IP address from dynamic to static can be a big deal when you need an IP address that doesn’t change.

Join the Network World communities on Facebook and LinkedIn to comment on topics that are top of mind.

Copyright © 2022 IDG Communications, Inc.



Source link