I write script, that will create CentOS interfaces from file with list of IP addresses. In loop, i create file, next action, i add data for centos interfaces. Look:
from=/root/ip
inter=`cat /proc/net/dev | grep "eth0:\|venet0" | awk '{ print $1 }' | sed 's/://g'`
eth=`ifconfig | grep $inter | tail -1 | awk '{ print $1 }' | sed "s/$inter://g"`
echo "Last number of interface: $eth"
if [ "$eth" == "eth0" ]; then
eth_temp="-1"
else
eth_temp=$eth
fi
if [ "$inter" == "eth0" ]; then
echo "Name of interface: $inter"
echo "Add IP to interfaces"
if [ -f $from ]; then
for IP_TO_ETH in `grep -v ^# $from`; do
eth_temp=$(($eth_temp+1))
cent_int=`touch /etc/sysconfig/network-scripts/ifcfg-$inter:$eth_temp`
cat >> $cent_int <<END
DEVICE=eth0:$eth_temp
ONBOOT=yes
BOOTPROTO='static'
IPADDR=$IP_TO_ETH
NETMASK=255.255.255.0
END
done
else
echo "File does not exist"
fi
elif [ "$inter" == "venet0" ]; then
echo "Name of interface: $inter"
echo "This interface from OpenVZ. Not need to add"
else
echo "Other name of inteface"
fi
All ok. But it is not working. When i start bash/sh -x, i receive this:
cent.sh: line 28: $cent_int: ambiguous redirect
+ for IP_TO_ETH in '`grep -v ^# $from`'
+ eth_temp=61
++ touch /root/network-scripts/ifcfg-eth0:61
+ cent_int=
+ cat
cent.sh: line 28: $cent_int: ambiguous redirect
+ for IP_TO_ETH in '`grep -v ^# $from`'
+ eth_temp=62
++ touch /root/network-scripts/ifcfg-eth0:62
+ cent_int=
+ cat
Where i have error ? Please help. In ubuntu it is simply, because all will write in one file. But in CentOS, it is too difficult for me.
When you write:
variable=`command`
it sets the variable to the output of the command. But touch doesn't produce any output, so
cent_int=`touch /etc/sysconfig/network-scripts/ifcfg-$inter:$eth_temp`
assigns an empty string to cent_int. I think what you want is:
cent_int=/etc/sysconfig/network-scripts/ifcfg-$inter:$eth_temp
You don't need to use touch, since writing to the file with cat >> $cent_int will create the file if it doesn't already exist.
Related
I'm currently studying pen-testing and in the exercise book "Mastering kali linux for advanced penetration testing-second edition" and the script they give for Masscan & Nmap(combined) is this:
#!/bin/bash
function helptext {
echo "enter the massnmap with the file input with list of IP address ranges"
}
if [ "$#" -ne 1 ]; then
echo "Sorry cannot understand the command"
helptext>&2
exit 1
elif [ ! -s $1 ]; then
echo "ooops it is empty"
helptext>&2
exit 1
fi
if [ "$(id -u)" != "0" ]; then
echo "I assunme you are running as root"
helptext>&2
exit 1
fi
for range in $(cat $1); do
store=$(echo $range | sed -e 's/\//_g')
echo "I am trying to create a store to dump now hangon"
mkdir -p pwd/$store;
iptables -A INPUT -p tcp --dport 60000 -j DROP;
echo -e "\n alright lets fire masscan ****"
masscan --open --banners --source-port 60000 -p0-65535 --max-rate 15000 -oBpwd/$store/masscan.bin $range; masscan --read$
if [ ! -s ./results/$store/masscan-output.txt ]; then
echo "Thanks for wasting time"
else
awk'/open/ {print $4, $3, $2, $1}' ./results/$store/masscan-output.txt | awk'
/.+/{
if (! ($1 in Val)) { Key[++i] = $1; }
Val[$1] = Val[$1] $2 ",";
END{
for (j = 1; j <= i; j++) { printf("%s:%s\n%s", Key[j], Val[Key[j]], (j == i) ? "" : "\n"); }
}'>}./results/$store/hostsalive.csv
for ips found in $(cat ./results/$store/hostsalive.csv); do
IP=$(echo $TARGET | awk -F: '{print $1}');
PORT=$(echo $TARGET | awk -F: '{print$2}' | sed's/,$//');
FILENAME=$(echo $IP | awk'{print "nmap_"$1}');
nmap -vv -sV --version-intensity 5 -sT -O --max-rate 5000 -Pn -T3 -p $PORT -oA ./results/$store/$FILENAME $IP;
done
fi
done
I wrote it out by hand just to make sure it was done correctly and when i run after doing chmod +x (filename.sh) it i get:
(running ./filename.sh) i get "Sorry cannot understand the command
enter the massnmap with the file input with list of IP address ranges"
(running ./filename.sh ipran.txt) i get "./anyname.sh: line 37: syntax error near unexpected token found'
./anyname.sh: line 37:for ips found in $(cat ./results/$store/hostsalive.csv); do'"
i am meant to get "I am trying to create a store to dump now hangon" "alright lets fire masscan ****"
i have tried using different ips(in my ipran.txt file)
any help would be greatly appreciated
OS used -Kali linux
I have created a bash script that is used to modify the ulimit of open files in the RHEL server.
so i have reading the lines in the file /etc/security/limits.conf and if the soft/hard limit of the open files are less than 10000 for '*' domain i am commenting the line and adding a new line with soft/hard limit as 10000.
The Script is working as designed but the sed command to comment a line in the script is not working.
Please find the full script below :-
#!/bin/sh
#This script would be called by '' to set ulimit values for open files in unix servers.
#
configfile=/etc/security/limits.conf
help(){
echo "usage: $0 <LimitValue>"
echo -e "where\t--LimitValue= No of files you want all the users to open"
exit 1
}
modifyulimit()
{
grep '*\s*hard\s*nofile\s*' $configfile | while read -r line ; do
firstChar="$(echo $line | xargs | cut -c1-1)"
if [ "$firstChar" != "#" ];then
hardValue="$(echo $line | rev | cut -d ' ' -f1 | rev)"
if [[ "$hardValue" -ge "$1" ]]; then
echo ""
else
sed -i -e 's/$line/#$line/g' $configfile
echo "* hard nofile $1" >> $configfile
fi
else
echo ""
fi
done
grep '*\s*soft\s*nofile\s*' $configfile | while read -r line ; do
firstChar="$(echo $line | xargs | cut -c1-1)"
if [ "$firstChar" != "#" ];then
hardValue="$(echo $line | rev | cut -d ' ' -f1 | rev)"
if [[ "$hardValue" -ge "$1" ]]; then
echo ""
else
sed -i -e 's/$line/#$line/g' $configfile
echo "* hard nofile $1" >> $configfile
fi
else
echo ""
fi
done
}
deleteEofTag(){
sed -i "/\b\(End of file\)\b/d" $configfile
}
addEofTag()
{
echo "#################End of file###################" >> $configfile
}
#-------------Execution of the script starts here ----------------------
if [ $# -ne 1 ];
then
help
else
modifyulimit $1
deleteEofTag
addEofTag
fi
The command sed -i -e 's/$line/#$line/g' $configfile when executed from the terminal is working absolutely fine and it is commenting the line but it is not working when i am executing it from the unix shell script.
interpolation does not work in single quote
use double quote and try
sed -i -e 's/$line/#$line/g'
sed -i -e "s/$line/#$line/g"
also you might try:
sed -i -e s/${line}/#${line}/g
as this will tell the script to take the value of the variable instead of variable as such.
I was trying to make a script that would pretty much automate this process:
http://knowledgelayer.softlayer.com/procedure/add-additional-ips-redhat
Wasn't too sure how well it would work, but didn't get too far before I could get the script to one. Below is the content of the script:
Editing with updated code:
Edit#2: Got it mostly working, however now it runs the loop and skips over the read propmt to get the static IP
#!/bin/bash
path=/etc/sysconfig/network-scripts/
echo "Let's get your IP added :)"
echo""
getnewip()
{
echo read -p "Enter the new IP Address you wish to add: " staticip
}
getserverinfo()
{
gateway=$(netstat -rn | sed -n 3p | awk '{print $2}')
netmask=$(ifconfig eth1 | grep -i 'netmask' | grep -v '127.0.0.1' | awk '{print $4}')
clone=$( ifconfig | grep eth1 | awk '{print $1}' | cut -d: -f2 )
}
rangechecks()
{
cd /etc/sysconfig/network-scripts/
ls ifcfg-eth1-range*
filename==$1
if [[ ! -f $filename ]]; then
touch "$filename"
echo "Created \"$filename\""
fi
digit=1
while true; do
temp_name=$filename-$digit
if [[ ! -f temp_name ]]; then
touch "$temp_name"
echo "Created $path\"$temp_name\""
digit=$((digit + 1 ))
fi
done
}
writeinterfacefile()
{
cat >> "/etc/sysconfig/network-scripts/$1" << EOF
IPADDR_START=$staticip
IPADDR_END=$staticip
NETMASK=$netmask
CLONENUM_START=$((clone+1))
EOF
echo ""
echo "Your information was saved in the file '$1'."
echo ""
}
{
clear
getserverinfo
echo ""
echo "Please verify this information: "
echo "Gateway Address: " "$gateway"
echo "Netmask: " "$netmask"
echo "Your new IP: " "$staticip"
echo ''
while true; do
read -p "Is this information correct? [y/N]" yn
case $yn in
[Yy]* ) $writeinterfacefile;;
[Nn]* ) print "$getserverinfo" && exit ;;
* ) echo 'Please enter Y or n';;
esac
done
}
I'm fairly new at scripting, so excuse the horrid syntax. My eye is on that EOF but I have no clue.
rangecheckshas no }, your while has no done...
You should indent your code. I started doing that, and noticed the error right away.
Other things:
Single quotes don't expand variables, '/etc/sysconfig/network-scripts//$1 won't do what you want it to.
echo "" is equivalent to echo.
foo='bar'; echo "blah" echo -n $foo will output 'blah echo -n bar'.
exit exits the script, I'm not sure that's what you think it does.
[y/N] usually means N by default (the capital letter).
Also, you then ask to enter Y or n. Be consistent!
When using a variable as a parameter, double quote it. This ensures it stays the way it is (as one parameter, and not expanded by the shell).
I can't see the closing curly brace of function rangechecks
Also, don't indent the shebang in the first line.
I am looking for a bash script that reads a log and replaces IP addresses with a hostname. Does anyone have any idea of how to do this?
Following script should work. You can use it like this:
save it to ip_to_hostname.sh and then:
./ip_to_hostname.sh your_logfile > resolved_ip
#!/bin/bash
logFile=$1
while read line
do
for word in $line
do
# if word is ip address change to hostname
if [[ $word =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]
then
# check if ip address is correct
OIFS=$IFS
IFS="."
ip=($word)
IFS=$OIFS
if [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
then
echo -n `host $word | cut -d' ' -f 5`
echo -n " "
else
echo -n "$word"
echo -n " "
fi
# else print word
else
echo -n $word
echo -n " "
fi
done
# new line
echo
done < "$logFile"
Talking about IPv4: You may generate a list of sed-commands from your hosts file:
sed -rn 's/^(([0-9]{1,3}\.){3}([0-9]{1,3}))[ \t]([^ \t]+)[ \t].*/s#\1#\4#/p' /etc/hosts > hosts.sed
Then apply it on your logfile:
sed -f hosts.sed LOGFILE
Of course your hostsfilenames have to be listed in the hostfile.
Another, inverse approach would be to use logresolve.
From the manpage:
NAME
logresolve - Resolve IP-addresses to hostnames in Apache log files
SYNOPSIS
logresolve [ -s filename ] [ -c ] < access_log > access_log.new
SUMMARY
logresolve is a post-processing program to resolve IP-addresses in Apache's access logfiles. To minimize
impact on your nameserver, logresolve has its very own internal hash-table cache. This means that each
IP number will only be looked up the first time it is found in the log file.
Takes an Apache log file on standard input. The IP addresses must be the first thing on each line and
must be separated from the remainder of the line by a space.
So you could use REGEX's to extract all IPs, put them 2 times into a new file, once into the first column, and convert it with logresolve. Then use this table for generating such a sedfile as above.
The resolving can be done like this:
ip=72.30.38.140
hostname=nslookup $ip | grep name
hostname=${hostname#*name = }
hostname=${hostname%.}
This way IPs do not have to be in /etc/hosts.
The script itself depends on how your log looks like. Can you post an example?
This is the modified version of wisent's script I ended up using:
#!/bin/bash
logFile=$1
while read line
do
for word in $line
do
# if word is ip address change to hostname
if [[ $word =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\:[0-9]{1,5}$ ]]
then
port=$(echo "$word" | sed -e "s/.*://")
word=$(echo "$word" | sed -e "s/:.*//")
OIFS=$IFS
IFS="."
ip=($word)
IFS=$OIFS
# check if ip address is correct and not 192.168.*
if [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 && ${ip[2]} -le 255 && ${ip[3]} -le 255 && ${ip[0]}${ip[1]} -ne 192168 ]]
then
host=$(host $word | cut -d' ' -f 5)
if [[ $host =~ ^[0-9]{1,3}\(.*\)$ ]] # check for resolver errors
then
# if the resolver failed
echo -n "$word"
echo -n ":$port"
echo -n " "
else
# if the resolver worked
host=$(echo "$host'" | sed -e "s/\.'//" | sed ':a;N;$!ba;s/.*\n//g') # clean up cut's output
echo -n "$host"
echo -n ":$port"
echo -n " "
fi
else
# if the ip address isn't correct
echo -n "$word"
echo -n ":$port"
echo -n " "
fi
# else print word
else
echo -n $word
echo -n " "
fi
done
# new line
echo
done < "$logFile"
I added this to my .bashrc some time ago...
function resolve-hostname-from-ip()
{
if [ ! $1 ]
then
echo -e "${red}Please provide an ip address...${no_color}"
return 1
fi
echo "" | traceroute $1|grep " 1 "|cut -d ' ' -f4|cut -d '.' -f1
}
I have pre-defined terminal colors, so you can omit those if you like. =D
[root#somehostname ~ 08:50 AM] $ resolve-hostname-from-ip 111.22.33.444
someotherhostname
I have tested this on RHEL and SUSE successfully. I haven't tested it on IP's outside of my domain though, so I'm not 100% sure it will work in all cases...hope this helps =)
When you double-click a bash script, Ubuntu asks if the user wants to Display, Run, or Run In Terminal...
Is there a way within the script to determine if the user chose "Run In Terminal"?
Strictly speaking, you can't tell whether the user chose "Run In Terminal" after clicking on the script, or fired up a terminal and ran the script from there. But the commands below should help you, especially [ -t 2 ].
if [ -t 1 ]; then
echo "Standard output is a terminal."
echo "This means a terminal is available, and the user did not redirect the script's output."
fi
if [ -t 2 ]; then
echo "Standard error is a terminal." >&2
echo "If you're going to display things for the user's attention, standard error is normally the way to go." >&2
fi
if tty >/dev/null; then
echo "Standard input is a terminal." >$(tty)
echo "The tty command returns the name of the terminal device." >$(tty)
fi
echo "This message is going to the terminal if there is one." >/dev/tty
echo "/dev/tty is a sort of alias for the active terminal." >/dev/tty
if [ $? -ne 0 ]; then
: # Well, there wasn't one.
fi
if [ -n "$DISPLAY" ]; then
xmessage "A GUI is available."
fi
Here is an example:
#!/bin/bash
GRAND_PARENT_PID=$(ps -ef | awk '{ print $2 " " $3 " " $8 }' | \
grep -P "^$PPID " | awk '{ print $2 }')
GRAND_PARENT_NAME=$(ps -ef | awk '{ print $2 " " $3 " " $8 }' \
| grep -P "^$GRAND_PARENT_PID " | awk '{ print $3 }')
case "$GRAND_PARENT_NAME" in
gnome-terminal)
echo "I was invoked by gnome-terminal"
;;
xterm)
echo "I was invoked by xterm"
;;
*)
echo "I was invoked by someone else"
esac
Now, let me explain this in a little more details. In the case when script is executed by (in) a terminal, its parent process is always a shell itself. This is because terminal emulators run shell to invoke scripts. So the idea is to look at a grandparent process. If grandparent process is a terminal then you can assume that your script was invoked from a terminal. Otherwise, it was invoked by something else, for example, Nautilus, which is Ubuntu's default file browser.
The following command gives you a parent process ID.
ps -ef | awk '{ print $2 " " $3 " " $8 }' | grep -P "^$PPID " | awk '{ print $2 }'
And this command is giving you a name of your parent's parent process.
ps -ef | awk '{ print $2 " " $3 " " $8 }' | grep -P "^$GRAND_PARENT_PID " | awk '{ print $3 }'
And the final switch statement just compares grandparent process name with some known terminal emulators.
Never tried it, but probably this works:
if [ -t 1 ] ;
Although it would also be false if the output it piped...