python fabric get public ip address - python

Try to get public ip address of host with python fabric
def publicip():
ip = local("curl -s 'http://checkip.dyndns.org' | sed 's/.*Current IP Address: \([0-9\.]*\).*/\'\1/g\'")
print (red(ip))
Error:
Fatal error: local() encountered an error (return code 2) while executing 'curl -s 'http://checkip.dyndns.org' | sed 's/.*Current IP Address: \([0-9\.]*\).*/'/g''

Curl is probably not installed on the host you're running on. You don't need it anyway as you can do this easily in Python like this:
import urllib2
u = urllib2.urlopen('http://checkip.dyndns.org')
line = u.next()
print line.split("<")[6].split().pop()

I'm not sure what local() (executes an external command?) is, but using the requests library and re.search this is fairly simple:
import requests, re
r = requests.get('http://checkip.dyndns.org')
myip = re.search(r'\d+\.\d+\.\d+\.\d+', r.text).group()

It seems local() doesn't support multiple commands to be executed. You can however split the execution into:
def publicip():
ip = local("curl -s 'http://checkip.dyndns.org'", capture=True)
and then ip will contain the desired html:
'<html><head><title>Current IP Check</title></head><body>Current IP Address: 1.2.3.4</body></html>'
Which you can parse using regex, e.g.:
r = re.compile(r'.*\<body>Current IP Address:\s(.*)\</body>.*')
final_ip = r.match(ip).group(1)

A pure python implementation is
import requests
r = requests.get('http://ipof.in/txt')
myip = r.text
Thats it. Do check out http://ipof.in if you need further information beyond just IP address

Related

How to get the IP address of incoming connection in custom PAM module

I am using PAM authentication to authenticate with my linux server. I have created a view on my website through Apache2 where I can use python to manually validate each login through a web shell with facial recognition and two factor authentication. This is working, but I can't seem to recover the IP address of the incoming connection. I need a way to find the IP address of my connection to the server before SSH is connected, in the PAM module which is running Python. I would like to use bash for this.
I am trying to execute commands to recover the IP address, I tried using "who" and other commands to see incoming SSH connections to no avail. I also tried using "echo $PAM_RHOST" and "$SSH_CLIENT" and "$SSH_CONNECTION" with no success.
I ended up using the auth.log which seems to work perfectly. All I had to do was reverse the log and get the last IP. The below code also collects unique IPs in order of the last login.
`
output = run_command('sudo tail -500 /var/log/auth.log')
op = output.split('\n')
op.reverse()
output = '\n'.join(op)
def unique(thelist):
u = []
for i in thelist:
if i not in u: u.append(i)
return u
ips = unique(re.findall('Accepted publickey for user from ([\d]+\.[\d]+\.[\d]+\.[\d]+)', output))
ip = ips[0]
print(ip) # The last IP
`

Python: How to print the local DNS Address ONLY?

when I type in nslookup in cmd I get this output:
Default Server: my server name.
Address: 192.168.2.1
I would like to use Python to output ONLY the DNS address. Just the number. How can I do that?
This is what I tried, but it opens up cmd again...
import os
print (os.system("nslookup"))
The output of print should be something like "192.168.2.1" ONLY.

Getting 127.0.1.1 instead of 192.168.1.* ip ubuntu python

I am new to python. I want to get the ipaddress of the system. I am connected in LAN. When i use the below code to get the ip, it shows 127.0.1.1 instead of 192.168.1.32. Why it is not showing the LAN ip. Then how can i get my LAN ip. Every tutorials shows this way only. I also checked via connecting with mobile hotspot. Eventhough, it shows the same.
import socket
hostname = socket.gethostname()
IPAddr = socket.gethostbyname(hostname)
print("Your Computer Name is:" + hostname)
print("Your Computer IP Address is:" + IPAddr)
Output:
Your Computer Name is:smackcoders
Your Computer IP Address is:127.0.1.1
Required Output:
Your Computer Name is:smackcoders
Your Computer IP Address is:192.168.1.32
I got this same problem with my raspi.
host_name = socket.gethostname()`
host_addr = socket.gethostbyname(host_name)
and now if i print host_addr, it will print 127.0.1.1.
So i foundthis: https://www.raspberrypi.org/forums/viewtopic.php?t=188615#p1187999
host_addr = socket.gethostbyname(host_name + ".local")
and it worked.
As per the above '/etc/hosts' file content, you have an IP address mapping with '127.0.1.1' to your hostname. This is causing the name resolution to get 127.0.1.1. You can try removing/commenting this line and rerun.
How can I get the IP address of eth0 in Python?
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(("8.8.8.8", 80))
print s.getsockname()[0]
This also worked for me:
gethostbyname(gethostname()+'.')
i get the same problem what your are facing. but I get the solution with help of my own idea, And don't worry it is simple to use.
if you familiar to linux you should heard the ifconfig command which return the informations about the network interfaces, and also you should understand about grep command which filter the lines which consist specified words
now just open the terminal and type
ifconfig | grep 255.255.255.0
and hit enter now you will get wlan inet address line alone like below
inet 192.168.43.248 netmask 255.255.255.0 broadcast 192.168.43.255
in your terminal
in your python script just insert
#!/usr/bin/env python
import subprocess
cmd = "ifconfig | grep 255.255.255.0"
inet = subprocess.check_output(cmd, shell = True)
inet = wlan.decode("utf-8")
inet = wlan.split(" ")
inet_addr = inet[inet.index("inet")+1]
print(inet_addr)
this script return your local ip address, this script works for me and I hope this will work for your linux machine
all the best
This solution works for me on Windows. If you're using Linux you could try this line of code instead:
IPAddr = socket.gethostbyname(socket.getfqdn())

How to query gateway for DNS adress by Python or Perl

The Linux/Windows can get DNS address from the router
I need to write a local dns proxy and how can I get the DNS server addresses like the OS does, are there any Perl or Python modules can do this?
Update
The question should be clear, I need some thing to simulate the interface start and the protocol talking with local router, I can not take a tcpdump before a interface starts. Not sure if there is an sample trace file on internet. Possiblely it's not IP protocol which I am not familiar with.
Update2
As I use local DNS proxy server, the TCP configuration is like showing in picture
If I query Net::DNS::Resolver, I get result: 127.0.0.1 which is not what I needed
Really long, formatted comment supporting Steffen's answer.
TLDR: Steffen is correct (+1 BTW). Net::DNS::Resolver should get you the information you need.
Example:
#!perl
use strict;
use warnings;
use Net::DNS::Resolver;
#configure a resolver object using your OS's current config.
my $resolver = Net::DNS::Resolver->new;
print join "\n", $resolver->nameservers;
Tested on Windows & OS X.
If you are serous in your quest for the rope to hang yourself, the protocol you're asking about is DHCP (Dynamic Host Configuration Protocol).
Using DHCP like your OS does, is not a mere "Query" for DNS servers, but a request for a (new/renewed) lease of an IP Address. The fact that things like Gateway, Time Servers & DNS Servers are included are also important, but secondary. If done incorrectly, you may either screw up the relationship between your OS and the DHCP server or convince your DHCP server that your program is another (false) machine on the network for which it should maintain lease information.
gethostbyname uses the resolver function of the underlying OS library. If you want to have more direct access to the DNS packets use Net::DNS::Resolver.
inspired by Steffen Ullrich
I got the issue resolved, by managed taking a DHCP trace and simulated by Net::DHCP::Packet, fortunately it's simple UDP protocol
You need to findout IP/Mac/GW address before using the script
#!/usr/bin/perl
use strict;
use warnings;
use IO::Socket::INET;
use Net::DHCP::Packet;
use Net::DHCP::Constants;
srand();
# creat DHCP Packet
my $discover = Net::DHCP::Packet->new(
Xid => int(rand(0xFFFFFFFF)), # random xid
Flags => 0x0000,
DHO_DHCP_MESSAGE_TYPE() => DHCPREQUEST(),
);
$discover->ciaddr('192.168.1.5');
$discover->chaddr('5cc5d43ca078');
my $handle = IO::Socket::INET->new(
Proto => 'udp',
ReuseAddr => 1,
PeerPort => '67',
LocalPort => '68',
PeerAddr => '192.168.1.1'
) or die "socket: $#";
$handle->send($discover->serialize());
my $newmsg;
if ($handle->recv($newmsg, 1024)) {
my $packet = Net::DHCP::Packet->new($newmsg);
print STDERR $packet->toString();
}
Execution result:
op = BOOTREPLY
htype = HTYPE_ETHER
hlen = 6
hops = 0
xid = eaba416c
secs = 0
flags = 0
ciaddr = 192.168.1.5
yiaddr = 192.168.1.5
siaddr = 0.0.0.0
giaddr = 0.0.0.0
chaddr = 5cc5d43ca078
sname =
file =
Options :
DHO_DHCP_MESSAGE_TYPE(53) = DHCPACK
DHO_SUBNET_MASK(1) = 255.255.255.0
DHO_ROUTERS(3) = 192.168.1.1
DHO_DOMAIN_NAME_SERVERS(6) = 192.168.1.1
DHO_DHCP_SERVER_IDENTIFIER(54) = 192.168.1.1
DHO_DHCP_LEASE_TIME(51) = 86400
DHO_VI_VENDOR_SPECIFIC_INFOMATION(125) = \x00\x00\x00\x00\x14\x02\x06HGW-CT\x0A\x02\x00\x00\x0B\x02\x00U\x0D\x02\x00.
padding [247] = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
We can see
DHO_DOMAIN_NAME_SERVERS(6) = 192.168.1.1
Is the DNS server address

dnsPython use IP on interface

I use dsnPython in a project.
I use many resolvers same as explained at Set specific DNS server using dns.resolver (pythondns).
In order to send several requests I need to dispatch my request on many IPs.
I have some IPs on my interface eth0.
Do you know a way to send a request through an specific IP ?
It's possible by using resolvers and source attribute :
import dns.resolver
my_resolver.nameservers = ['8.8.8.8']
answer = my_resolver.query(
qname = fqdn_port,
source = '1.2.3.4',
)
8.8.8.8 is the resolver IP
1.2.3.4 is an IP of server

Categories