Add time and IP before bash cursor on Linux server SSH - linux

I was thinking about syntax looking like this:
IP: 123.123.123 | 28.10.2016 17:24 | root#vps:~$
Is it possible?
I wish log bash history with this data for debugging and backup.
I was try on it, but time is static and I don't know how write IP:
echo "force_color_prompt=yes" >> /root/.bashrc
echo "PS1='$(date +%T) | ${debian_chroot:+($debian_chroot)}\[\033[01;31m\]\u#\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '" >> /root/.bashrc
Maybe IP can be printed only first time after SSH login, is it possible?
Thanks

For IP getting printed out, add following lines to your .bashrc:
ip=`ip a | grep wlan0 | grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b" | head -1`
echo $ip
unset $ip
Now when ever you open a new terminal, your will get ip printed out for you. Same goes for ssh.
Please notice that Im using my wlan0 adapter to get the ip, you may need to change that to eth0 depending on your environment.

Set ip with Farhad's answer, then:
PS1='IP: $ip | \D{%d.%m.%G %H:%M} | \u#\h:\W$'
The time is dynamic.
References
Controlling the Prompt - Bash Reference Manual
STRFTIME(3) - Linux Programmer's Manual

Related

How to create an effective WHOIS Script in Linux

Disclaimer: I'm a noob to linux and scripting, please don't heckle me.
GOAL: Feed my linux system a .txt file full of IP Addresses and Perform a WHOIS look on each IP and show me specific fields (grep) such as the Organization Field. Bonus points if someone can help me figure out how to use my API key to check my IP list against abuseipdb.com
I've created an ip.txt file with my IP Addresses and I've tried using the following syntax. I'm using Kali Linux to perform this, but it worked on my friend's Fedora system.
sudo for ip in $(cat ip.txt); do whois $ip | echo "$ip $(grep -e 'Organization' | grep -v 'Verizon')"; done > whois.txt
My output is: -bash: syntax error near unexpected token 'do'. Remove "do" from my command and then I receive -bash: syntax error near unexpected token 'done'
Remove the "done" and the pipe out and then it's just pissed..
Please help a linux n00b :)
You are attempting to invoke sudo on the command for ip in $(cat ip.txt), and then running the syntactically invalid commands do whois .... (Note that for ip in $(cat ip.txt) is also syntactically invalid, but sudo is never invoked so no shell ever tries to parse that string as a command). You need to narrow the scope of sudo. eg
while read ip; do sudo whois "$ip" | ... ; done > whois.txt < ip.txt

Is it a good idea to add a bash code snippet into a bash conf file that is sourced by a bash script?

I have an executable bash script that picks up my external ip address from my modem and uploads it in a dynamic DNS service. The script is accompanied by a configuration file which I source from the script. The configuration file holds values for modem credentials, FQDN for my hostname, modem ip address and "status" website address.
In order to pick up my external IP address, I need to wget the "status" webpage from my modem and do some grep and sed operations to grab the external IP.
So the actual grep and sed code is also custom for every user.
The main question is: Canonically speaking, should such code be present in the conf file or in the script itself.
I am confused because I read this in 2 ways:
it is code so it should be in the script
it is variable so it should be in the config
I know this may sound like storm in a tea cup, but I would like to learn the right way.
Also, if you believe the right way is (2), I don't know how to declare the code in the configuration file. I tried the following and doesn't work. I've also not been able to find similar examples in the internet.
config:
grab_modem_ip='grep "[0-9]*\.[0-9]*\.[0-9]*\.[[0-9]*" |
grep tabdata | sed 's/\(.*\)<\/td>.*/\1/''
or
alias grab_modem_ip='grep "[0-9]*\.[0-9]*\.[0-9]*\.[[0-9]*" |
grep tabdata | sed 's/\(.*\)<\/td>.*/\1/''
(Notice that I have wrapped the whole command in '...' — single quotes.)
script
ipaddr=$( wget --user ${modemuser} --password ${modempass} "${modemsite}" -O - 2>/dev/null | "<grab_modem_ip>" )
I think that maybe 2 the correct solution. And I think that your command will solve using this:
ipaddr=$( wget --user ${modemuser} --password ${modempass} "${modemsite}" -O - 2>/dev/null | eval "grab_modem_ip" )
The answer I was looking for was "Variables hold data. Functions hold code. Don't put code inside variables!" as quoted from Greg's Wiki
so I rewrote grab_modem_ip as a function, that is defined in the conf file.
grab_modem_ip()
{
echo "${1}" | grep "[0-9]*\.[0-9]*\.[0-9]*\.[[0-9]*" | grep tabdata | sed 's/\(.*\)<\/td>.*/\1/'
}
Then invokation in the script is done as
modemstatuspage=$( wget --user ${modemuser} --password ${modempass} "${modemsite}" -O - 2>/dev/null )
ipaddr=$( grab_modem_ip "${modemstatuspage}")

My Ip changes Dynamically How can I get updated with the latest ip?

My isp provides dynamic ip addresses.I have forwarded my port to an raspberry pi and accessing it through ssh and also using it as web server.but the problem is that ip changes every 3-4 days is there any way or script so that i can be informed or updated with new ip address.
Thank You.
You can write a script like:
============
#!/bin/bash
OUT=$(wget http://checkip.dyndns.org/ -O - -o /dev/null | cut -d: -f 2 | cut -d\< -f 1)
echo $OUT > /root/ipfile
============
Set a cron to execute this every 3h or something and configure your mta to send the file /root/ipfile to your email address ( that too you can use a cron ). mutt can be a useful tool to attach the file and do the email delivery.

How to find a Linux namespace by network adapter?

I have a Linux server with multiple network namespaces defined:
# ip netns list
qdhcp-7dedbd4e-2265-4aa2-baac-add4e341dd18
qdhcp-851379ba-1d51-4e45-8e50-b756e81c0949
qdhcp-a19927c5-83b4-4bb4-a8b8-f21fdb5e004b
qdhcp-b94605ff-b0e2-4cfe-a95e-3dd10208a5fb
... ...
Each namespace contains one or more virtual network adapters - in this case, it's a TAP device:
# ip netns exec qdhcp-7dedbd4e-2265-4aa2-baac-add4e341dd18 ip route
192.168.168.0/24 dev tapda4018ab-b7 proto kernel scope link src 192.168.168.2
169.254.0.0/16 dev tapda4018ab-b7 proto kernel scope link src 169.254.169.254
default via 192.168.168.1 dev tapda4018ab-b7
Now let's say I know the name of the adapter - tapda4018ab-b7 - but I don't know the namespace it belongs to. Is there a way to look it up without checking namespaces one by one? Is there a generic Linux command to do this? Or at least OpenStack Neutron-specific command?
According to this man page http://man7.org/linux/man-pages/man8/ip-netns.8.html you could run the exec command on all namespaces but I tested it on an ubuntu trusty servers and it will not accept "-all" as an argument. So the only way I know to get such an information is via a small bash script. I made one that could certainly be improved as my scripting skills are rather basic, but it will do the work:
#!/bin/bash
i=$(ip netns list | wc -l)
counter=1
while [ $counter -le $i ]; do
ns=$(ip netns | head -$counter | tail -1)
ip netns exec $ns ip route | grep $1 | grep proto
let counter=counter+1
done
You can then launch the script using as sole argument your tap device as in the example bellow:
root#columbo:~# ./list_all_namespace tap8164117b-e3
5.5.5.0/25 dev tap8164117b-e3 proto kernel scope link src 5.5.5.3
If you do not provide an argument it will give you an error.
If I understand Neutron correctly (which is a big if - my only experience is with a fairly limited toy installation of Kilo/2015.1.2), you should be able to track through neutron's database to figure out the netns you're looking for
I believe your tap interface would be named using the first 5 octets (10 characters) of the port uuid that it's associated with, and the qdhcp netns uses the uuid of it's network, so you should be able to use the neutron CLI to track down the correct namespace.
You should be able to find the neutron port for your tap interface with:
$ neutron port-list | grep "da4018ab-b7"
| da4018ab-b7xx-xxxx-xxxx-xxxxxxxxxxxx | | fa:16:xx:xx:xx:xx | {"subnet_id": ...
where "da4018ab-b7" was pulled out of "tapda4018ab-b7". You can then use the full port uuid:
$ neutron port-show da4018ab-b7xx-xxxx-xxxx-xxxxxxxxxxxx
The network_id in the result from port-show should let you figure out the netns (qdhcp-network_id) containing tapda4018ab-b7.
You should be able to use similar logic to track down qg interfaces (which will probably show up on bridges in the default netns), but in that case it's the device_id that owns the port that gives you the qrouter-device_id netns you want.
You can use this script. Save this as get_dhcp_namespace.sh :-
ubuntu#ubuntu$ cat get_dhcp_namespace.sh
#!/bin/bash
interface=$1
id=${interface:3}
port_id=$(neutron port-list | grep $id | awk -F'|' '{print $2}' | tr -d ' ')
net_id=$(neutron port-show $port_id | grep network_id | awk -F'|' '{print $3}' | tr -d ' ')
echo "DHCP namespace is: qdhcp-$net_id"
Run this with the tap interface provided as argument. Don't forget to source the keystonerc/openstackrc/credentials file.
ubuntu#ubuntu$ ./get_dhcp_namespace.sh tapda4018ab-b7
qdhcp-bd39f45d-b45c-4e08-ab74-85c0b1180aea

Linux command for public ip address

I want command to get Linux machine(amazon) external/public IP Address.
I tried hostname -I and other commands from blogs and stackoverflow like
ifconfig | sed -En 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*/\2/p'
and many more. But they all are giving me internal IP Address.
Then I found some sites which provides API for this.
Example : curl http://ipecho.net/plain; echo
But I don't want to rely on third party website service. So, is there any command line tool available to get external IP Address?
simplest of all would be to do :
curl ifconfig.me
A cleaner output
ifconfig eth0 | awk '/inet / { print $2 }' | sed 's/addr://'
You could use this script
# !/bin/bash
#
echo 'Your external IP is: '
curl -4 icanhazip.com
But that is relying on a third party albeit a reliable one.
I don't know if you can get your external IP without asking someone/somesite i.e. some third party for it, but what do I know.
you can also just run:
curl -4 icanhazip.com
This is doing the same thing as a command the -4 is to get the output in Ipv4
You can use this command to get public ip and private ip(second line is private ip; third line is public ip.)
ip addr | awk '/inet / {sub(/\/.*/, "", $2); print $2}'
I would suggest you to use the command external-ip (sudo apt-get install miniupnpc) as it (I'm almost sure) uses upnp protocol to ask the router instead of asking an external website so it should be faster, but of course the router has to have upnp enabled.
You can simply do this :
curl https://ipinfo.io/ip
It might not work on amazon because you might be using NAT or something for the server to access the rest of the world (and for you to ssh into it also). If you are unable to ssh into the ip that is listed in ifconfig then you are either in a different network or dont have ssh enabled.
This is the best I can do (only relies on my ISP):
ISP=`traceroute -M 2 -m 2 -n -q 1 8.8.8.8 | grep -m 1 -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'`
extIP=`ping -R -c 1 -t 1 -s 1 -n $ISP | grep RR | grep -m 1 -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'`
echo $extIP
Or, the functionally same thing on one line:
ISP=`traceroute -M 2 -m 2 -n -q 1 8.8.8.8 | grep -m 1 -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'` | ping -R -c 1 -t 1 -s 1 -n $ISP | grep RR | grep -m 1 -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'
to save it to a temporary & hidden file add > .extIP to the end of the last line, then cat .extIP to see it.
If your ISP's address never changes (honestly i'm not sure if it would or not), then you could fetch it once, and then replace $ISP in line two with it
This has been tested on a mac with wonderful success.
the only adjustment on linux that I've found so far is the traceroute "-M" flag might need to be "-f" instead
and it relies heavily on the ping's "-R" flag, which tells it to send back the "Record Route" information, which isn't always supported by the host. But it's worth a try!
the only other way to do this without relying on any external servers is to get it from curl'ing your modem's status page... I've done this successfully with our frontier DSL modem, but it's dirty, slow, unreliable, and requires hard-coding your modem's password.
Here's the "process" for that:
curl http://[user]:[password]#[modem's LAN address]/[status.html] | grep 'WanIPAddress =' | grep -m 1 -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'
That fetches the raw html, searches for any lines containing "WanIpAddress =" (change that so it's appropriate for your modem's results), and then narrows down those results to an IPv4 style address.
Hope that helps!
As others suggested, we have to rely on third party service which I don't feel safe using it. So, I have found Amazon API on this answer :
$ curl http://169.254.169.254/latest/meta-data/public-ipv4
54.232.200.77
For more details, https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html#instancedata-data-retrieval
The super-easy way is using the glances tool. you can install it on Ubuntu using:
$ sudo apt install glances
then using it with:
$ glances
and at the top of the terminal, it highlights your public IP address, and so many other information about your system (like what htop does) and network status.
For a formatted output use :-
dig TXT +short o-o.myaddr.l.google.com #ns1.google.com
it'll give you formatted output like this
"30.60.10.11"
also FYI,
dig is more faster than curl and wget
The following works as long as you have ifconfig and curl.
curl ifconfig.me

Resources