Using sed to change ip addresses in dhcpcd.conf file - bash

On a raspberry pi I am trying to write a simple script that will allow me to change the static ip settings in the dhcpcd.conf file. The below script works except for the dns-servers. It appears that the sed statement does not work for that line as it contains two ip addresses seperated by a space. The script is as follows:
#!/bin/bash
currip=$(cat /etc/dhcpcd.conf | grep -e '^static ip_address=' | cut -d= -
f2)
currgw=$(cat /etc/dhcpcd.conf | grep -e '^static routers=' | cut -d= -f2)
currdns=$(cat /etc/dhcpcd.conf | grep -e '^static domain_name_servers=' |
cut -d= -f2)
echo "current IP is $currip"
echo "current GW is $currgw"
echo "current DNS servers are $currdns"
echo "Enter new static ip in form of x.x.x.x/x: "
read newip
echo "Enter new GW in form of x.x.x.x: "
read newgw
echo "Enter new DNS servers in form of x.x.x.x x.x.x.x: "
read newdns
echo "currip is $currip"
echo "new ip will be $newip"
echo "new dns will be $newdns"
sed -i -e "s#$currip\b#$newip#g" /etc/dhcpcd.conf
sed -i -e "s#$currgw\b#$newgw#g" /etc/dhcpcd.conf
sed -i -e "s#$currdns\b#$newdns#g" /etc/dhcpcd.conf
chip=$(cat /etc/dhcpcd.conf | grep -e '^static ip_address=' | cut -d= -
f2)
chgw=$(cat /etc/dhcpcd.conf | grep -e '^static routers=' | cut -d= -f2)
chdns=$(cat /etc/dhcpcd.conf | grep -e '^static domain_name_servers=' |
cut -d= -f2)
echo "The ip has been changed to $chip"
echo "The GW has been changed to $chgw"
echo "The DNS server have been changed to $chdns"
The lines in the dhcpcd.conf file look like this:
static ip_address=192.168.126.7/24
static routers=192.168.126.1
static domain_name_servers=192.168.126.1 66.243.243.101
How do I need to tweak my sed statement for the domain_name_servers?

The problem is your static router "192.168.126.1" is also present in the static domain_name_servers. Therefore, when you overwrite the routers with
sed -i -e "s#$currgw\b#$newgw#g" /etc/dhcpcd.conf
the line in your conf file is changed to
static domain_name_servers={{what you entered}} 66.243.243.101
so it no longer it matched by the name servers sed.
I suggest changing the find and replace strings to include the keys as well as the values, such as in the following:
sed -i -e "s#^static ip_address=$currip\b#static ip_address=$newip#g" dhcpcd.conf
sed -i -e "s#^static routers=$currgw\b#static routers=$newgw#g" dhcpcd.conf
sed -i -e "s#^static domain_name_servers=$currdns\b#static domain_name_servers=$newdns#g" dhcpcd.conf**strong text**
This will make it so no other lines that happen to contain an earlier replaced-string will be changed

Related

Check ip is present within file & update iptables bash script

I want to check that the ip is present within the ccd folder and push the ip route to the FORWARDING chain in the iptables. Im new to bash scripting and need a little help finishing this script.
client file in /etc/openvpn/ccd :
ifconfig-push 10.8.0.45 255.255.255.0
push 'route 10.10.0.45'
I need to grep 10.8.0.45 & 10.10.0.45
and push those routes in the iptables.
e.g
iptables -A FORWARD -s 10.8.0.45 -d 10.10.0.45 -j ACCEPT
client-connect /etc/openvpn/on_connect.sh
script I need help with 'grep' or 'awk'
static_ip= cat $CCD_DIR/$common_name | grep -w "ifconfig-push" | awk -F ' ' {'print $2'}
ip_destination=cat $CCD_DIR/$common_name | grep -w "push 'route" | awk -F ' ' {'print $3'} | tr -d "'"
#!/usr/bin/env bash
#
# Add iptables rules based on CCD client config.
#
CCD_DIR="/etc/openvpn/ccd"
RULE_COMMENT="FORWARD"$common_name
static_ip=cat $CCD_DIR/$common_name | grep -w "ifconfig-push" | awk -F ' ' {'print $2'}.
ip_destination=cat $CCD_DIR/$common_name | grep -w "push 'route" | awk -F ' ' {'print $3'} | tr -d "'"
if [ -f $CCD_DIR/$common_name ]; then
sudo iptables -A FORWARD -s $static_ip -d ip_destination -j ACCEPT
fi
exit 0
Edit: I think my usage of cat is wrong .
Try like this.
static_ip=$( cat $CCD_DIR | grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b" | grep -E '(^|\s)10.8.0.45($|\s)' )
ip_destination=$( cat $CCD_DIR | grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b" | grep -E '(^|\s)10.10.0.45($|\s)' )
So first you grep all IP's address in file and then you search exactly what you need
Edited after your comment.
If I understand correctly,
"ifconfig-push" - Is only one peer ccd file ?
so you can use this :
static_ip=$( grep -w "ifconfig-push" | awk -F ' ' {'print $2'})
For the rest in "push route" you need to use loop to find all matching ip address and put them to the iptables.
if [ -f $CCD_DIR/$common_name ]
then
cat $CCD_DIR | awk -F 'route' {'print $2'} | awk -F ' ' {'print $1'} | sed '/^$/d' | grep -E "\b(10)\.(8)\.(0)\.|(10)\.(10)\.(0).\b" | while read ip_destination
do
sudo iptables -A FORWARD -s $static_ip -d ip_destination -j ACCEPT
done
fi

grep multiple pattern from read input

so i made a bash script the greps the name of the host on the redirected file. However, there are hosts that are named either with "-" or "_"
GTR_SRV123_EST
GTR-SRV123-EST
Right now, what i did was, grep just a portion of the FQDN, like SRV123
Is there a way i can grep the host even if i just put the FQDN GTR_SRV123_EST and it will still matched this GTR-SRV123-EST.
i have a prompt that ask for the hostname:
echo -n "Please enter the host: "
read $host
grep -i $host ${temp}/*
update:
so had it working with the help of Juan's command. However, the directory path is displayed on the output. How can i get rid of it.
/export/home/aa12s/GLB-TXU/temp/
Current output:
/export/home/aa12s/GLB-TXU/temp/GBL-ASA-A:100022FBC0D00038 gbl-asa-a-mode1 5005076801103673 active gbl-ac-wbg02
Desired output:
GBL-ASA-A:100022FBC0D00038 gbl-asa-a-mode1 5005076801103673 active gbl-ac-wbg02
Command:
grep -iE "$(echo $host| awk -F '/export/home/aa12s/GLB-TXU/temp/' '{$2=$1;a=gsub(/_/, "-",$2); print $1"|"$2}' 2>/dev/null)" ${temp}/*
Edit your pattern.
echo -n "Please enter the host: "
read host # Edit: not $host
host="${host//[_-]/\[_-\]}" # turn either into a *check* for either
grep -i "$host" ${temp}/*
Kind of hacky but give this a try:
grep -Ei "$(echo $host| awk '{$2=$1;gsub(/_/, "-",$2);print $1"|"$2}' 2>/dev/null)" ${temp}/*
To get rid of filepaths:
grep -iE "$(echo $host| awk '{$2=$1;gsub(/_/, "-",$2);print $1"|"$2}' 2>/dev/null)" ${temp}/* 2>/dev/null|awk -F \/ '{print $NF}'
NOTE: Slashes must NOT be present in the file content.
If there is no host name with both _ and - below will work.
Entered host contains only _
grep -iE $(echo $host | tr "_" "-")\|$host ${temp}/*
Entered host contains only -
grep -iE $(echo $host | tr "-" "_")\|$host ${temp}/*
Entered host contains both _ and -
grep -iE $(echo $host | tr "_" "-")\|$(echo $host | tr "-" "_")\|$host ${temp}/*
You can use backreference :
([_-]) : capture either _ ou - in group 1
\1 : reference group 1
try this command :
grep -iE "([_-])$host\1" ${temp}/*
https://regex101.com/r/uH5SHC/1/
Wiyh host=SRV123, you will capture :
GTR_SRV123_EST
GTR-SRV123-EST
and not
GTR_SRV123-EST

Email whois details on user login using mailx - whois output format not working using sed

I am using the below command in my .bash_profile to get email alerts on ssh user logins
I get the email alerts, the only problem is format of whois command output - its wrapped.
Output of whois in command line is neat. Even after using sed -r G it doesn't work.
echo -e 'ALERT - Shell Access on:' `date` `who` '\n\n' `whois $(who | cut -d'(' -f2 | cut -d')' -f1)` | sed -r G | mail -s "Alert: SSH Access from `who | cut -d'(' -f2 | cut -d')' -f1`" user#example.com
SOLUTION:
Paste the following in .bash_profile in the user/root directory to get email alerts
# Send email on user login - manually added
SSHLOGINIP=`who | cut -d'(' -f2 | cut -d')' -f1 | tail -n 1`
echo -e "ALERT - Shell Access on: `date` \n\n Active Sessions:\n `who` \n\n `whois $SSHLOGINIP`" | sed -r G | mail -s "Alert: SSH Access from $SSHLOGINIP" user#example.com
unset SSHLOGINIP
For whois to work on RHEL based systems like CentOS you would need to install jwhois
You need to double-quote the echo statement in its entirety:
echo -e "ALERT - Shell Access on:' `date` `who` '\n\n' `whois $(who | cut -d'(' -f2 | cut -d')' -f1)`"
That will prevent wrapping of the whois output before it is passed to sed -- preserving all the linebreaks. The remainder of your mailx line should be fine. One other thought. Why not just write all of the output to a tmp file following | sed -r G > tmpfile. Then just add the tmpfile as an attachment to mailx?
mail -s "Alert: SSH Access from `who | cut -d'(' -f2 | cut -d')' -f1`" -a tmpfile user#example.com

" echo" in bash script empty file

I have problem with echo command I need export data to csv but its empty file
#!/bin/bash
while read domain
do
ownname= whois $domain | grep -A 1 -i "Administrative Contact:" |cut -d ":" -f 2 | sed 's/ //' | sed -e :a -e '$!N;s/ \n/,/;ta'
echo -e "$ownname" >> test.csv
done < dom.txt
You need to use command substitution to store command's output in a shell variable:
#!/bin/bash
while read domain; do
ownname=$(whois $domain | grep -A 1 -i "Administrative Contact:" |cut -d ":" -f 2 | sed 's/ //' | sed -e :a -e '$!N;s/ \n/,/;ta')
echo -e "$ownname" >> test.csv
done
PS: I haven't tested all the piped commands.

Bash new variable with other variable

I get the ip address like that :
Ip=`ifconfig | grep inet | grep -v -E 'inet6|127.0.0.1' | \
tr -d [:alpha:] | tr -s [:space:] | cut -d: -f2`
I have an ip like this for instance : 10.1.0.76
I want to make a new variable with the Ip variable to have another ip, for instance my new variable will return : 10.1.0.178
Just the last number change, so I want to get just a part of Ip variable (10.1.0.) and add another number to the end.
I tried with sed but I always have mistakes like "there's no file call'd ..."
Can you help me ?
You can use parameter expansion: It's simply: ${Ip%.*}.178
${Ip%.*} is the ip with the last dot and everything after it removed. The .178 is what you want to append after that.
Here it is in context:
# Your original expression
Ip=`ifconfig | grep inet | grep -v -E 'inet6|127.0.0.1' | \
tr -d [:alpha:] | tr -s [:space:] | cut -d: -f2`
# assign a new variable with the ip with different end octet
newIp=${Ip%.*}.178
# Show new ip
echo "$newIp"
Well, given that you have IP in a format x.y.z.w, you can use perl regex:
$ echo "120.20.31.78" | perl -pe 's/(.*)\..*/$1\.123/'
120.20.31.123
This will repace last number ("78") with "123".
So, in your case (assuming your "Ip" variable is set correctly), it would be:
Ip=ifconfig | grep inet | grep -v -E 'inet6|127.0.0.1' | tr -d [:alpha:] | tr -s [:space:] | cut -d: -f2 | perl -pe 's/(.*)\..*/$1\.123/'
see this, I hope it is what you want:
kent$ echo $ip
10.1.0.76
kent$ echo $part
178
kent$ sed -r "s/(.*\.).*/\1$part/" <<< $ip
10.1.0.178
to set $ip with new value:
kent$ ip=$(sed -r "s/(.*\.).*/\1$part/" <<< $ip)
kent$ echo $ip
10.1.0.178

Resources