python get primary domain name from ip - python

I need to get primary domain name from ip. I have some doubts about how functions like gethostbyaddr and getfqdn work.
In the following example I'm going to reverse ip a random domain and then try to get the domain name back:
import socket
domain = 'heroku.com'
# get ip from domain
ip = socket.gethostbyname(domain)
print('ip =', ip)
# get domain from ip
print(socket.gethostbyaddr(ip))
print(socket.getfqdn(ip))
# OUTPUT
# ip = 50.19.85.154
# ('ec2-50-19-85-154.compute-1.amazonaws.com', ['154.85.19.50.in-addr.arpa'], ['50.19.85.154'])
# ec2-50-19-85-154.compute-1.amazonaws.com
It seems both gethostbyaddr and getfqdn are returning the public DNS of one of the load balanced ec2 on AWS. My question is why they don't return the domain heroku.com which is probably the domain registered on Route53?
Another example with google.com:
import socket
domain = 'google.com'
# get ip from domain
ip = socket.gethostbyname(domain)
print('ip =', ip)
# get domain from ip
print(socket.gethostbyaddr(ip))
print(socket.getfqdn(ip))
# OUTPUT
# ip = 216.58.208.174
# ('mil07s10-in-f14.1e100.net', ['174.208.58.216.in-addr.arpa', 'lhr25s09-in-f14.1e100.net', 'lhr25s09-in-f174.1e100.net'], ['216.58.208.174'])
# mil07s10-in-f14.1e100.net
Here again it seems they are returning the public DNS of some machine on GCP. How can I get the real primary domain name from an ip address (heroku.com and google.com in these examples)?

When we do a DNS lookup of a hostname, in the most of the cases we are returned with the CNAME. We take that CNAME, and further resolve it to get an IP. But multiple CNAME's in the (n-1)th stage can be mapped to the CNAME in the (n)th stage. Therefore getting back the CNAME from the CNAME of the later stages is a not a trivial task.
Another Possible Way
Well, now the discussion is moving away from the DNS, but I hope it helps you. Every router or node in the internet is mapped to a Autonomous System, and there are some organizations or sites which maintain this mapping database. So by having the IP, we can contact one such database to get its Autonomous System Number (ASN) and the organization to which the node belongs to. whois.cymru.com:43 is one such site. You can use simple network client like nc to query its database. Below I attached the screenshot of one such query.

Related

Redshift Not Connecting to Host via Python Script

I currently have a .csv file in an S3 bucket that I'd like to append to a table in a Redshift database using a Python script. I have a separate file parser and upload to S3 that work just fine.
The code I have for connecting to/copying into the table is below here. I get the following error message:
OperationalError: (psycopg2.OperationalError) could not connect to server: Connection timed out (0x0000274C/10060)
Is the server running on host "redshift_cluster_name.unique_here.region.redshift.amazonaws.com" (18.221.51.45) and accepting
TCP/IP connections on port 5439?
I can confirm the following:
Port is 5439
Not encrypted
Cluster name/DB name/username/password are all correct
Publicly accessible set to "Yes"
What should I be fixing to make sure I can connect my file in S3 to Redshift? Thank you all for any help you can provide.
Also I have looked around on Stack Overflow and ServerFault but these seem to either be for MySQL to Redshift or the solutions (like the linked ServerFault CIDR solution) did not work.
Thank you for any help!
DATABASE = "db"
USER = "user"
PASSWORD = "password"
HOST = "redshift_cluster_name.unique_here.region.redshift.amazonaws.com"
PORT = "5439"
SCHEMA = "public"
S3_FULL_PATH = 's3://bucket/file.csv'
#ARN_CREDENTIALS = 'arn:aws:iam::aws_id:role/myRedshiftRole'
REGION = 'region'
############ CONNECTING AND CREATING SESSIONS ############
connection_string = f"redshift+psycopg2://{USER}:{PASSWORD}#{HOST}:{PORT}/{DATABASE}"
engine = sa.create_engine(connection_string)
session = sessionmaker()
session.configure(bind=engine)
s = session()
SetPath = f"SET search_path TO {SCHEMA}"
s.execute(SetPath)
###########################################################
############ RUNNING COPY ############
copy_command = f
'''
copy category from '{S3_FULL_PATH}'
credentials 'aws_iam_role={ARN_CREDENTIALS}'
delimiter ',' region '{REGION}';
'''
s.execute(copy_command)
s.commit()
######################################
#################CLOSE SESSION################
s.close()
##############################################
Connecting via a Python program would require the same connectivity as connecting from an SQL Client.
I created a new cluster so I could document the process for you.
Here's the steps I took:
Created a VPC with CIDR of 10.0.0.0/16. I don't really need to create another VPC, but I want to avoid any problems with prior configurations.
Created a Subnet in the VPC with CIDR of 10.0.0.0/24.
Created an Internet Gateway and attached it to the VPC.
Edited the default Route Table to send 0.0.0.0/0 traffic to the Internet Gateway. (I'm only creating a public subnet, so don't need a route table for private subnet.)
Created a Redshift Cluster Subnet Group with the single subnet I created.
Launch a 1-node Redshift cluster into the Cluster Subnet Group. Publicly accessible = Yes, default Security Group.
Went back to the VPC console to edit the Default Security Group. Added an Inbound rule for Redshift from Anywhere.
Waited for the Cluster to become ready.
I then used DbVisualizer to login to the database. Success!
The above steps made a publicly-available Redshift cluster and I connected to it from my computer on the Internet.

Finding all the websites which are on a particular hostname

I did find this function on stackoverflow which extract hostname, aliaslist, and ipaddrlist,
but how can I make a function which take a hostname and search all the websites associated with it (hosted by it)?
>>> import socket
>>> def get_ips_for_host(host):
try:
ips = socket.gethostbyname_ex(host)
except socket.gaierror:
ips=[]
return ips
>>> ips = get_ips_for_host('www.slowtravelmagazine.com')
>>> print(repr(ips))
('ext-cust.squarespace.com', ['www.slowtravelmagazine.com'],
['198.185.159.144', '198.185.159.145', '198.49.23.144',
'198.49.23.145'])
You can't. At least not with a built in function. You would need a datasource that contains all websites with their associated IP addresses.
There are probably some providers out there that have an API for this.

Get IP from VM object using azure sdk in python

I am trying to get all the IPs (attached to VMs) from an azure subscription.
I have pulled all the VMs using
compute_client = ComputeManagementClient(credentials, subscription_id)
network_client = NetworkManagementClient(credentials,subscription_id)
for vm in compute_client.virtual_machines.list_all():
print(vm.network_profile.network_interface)
But the network_profile object seems to only be a pointer, I have read through the documentation and can not figure out how to link each vm to its attached IP addresses
I came across this: Is there any python API which can get the IP address (internal or external) of Virtual machine in Azure
But it seems that something has changed.
I am able to resolve the IPs of a machine only if I know the name of the Public_IP address object(Which not all of them have public IPs).
I need to be able to take this network_interface and resolve the IP on it
So It seems that in order to get the IPs, you need to parse the URI given in the vm.network_profile.network_interface. Then use the the subscription and the nic name to get the IP using network_client.network_interfaces.get().
The code I used is below:
compute_client = ComputeManagementClient(credentials, subscription_id)
network_client = NetworkManagementClient(credentials,subscription_id)
try:
get_private(compute_client, network_client)
except:
print("Auth failed on "+ subscription_id)
def get_private(compute_client, network_client):
for vm in compute_client.virtual_machines.list_all():
for interface in vm.network_profile.network_interfaces:
name=" ".join(interface.id.split('/')[-1:])
sub="".join(interface.id.split('/')[4])
try:
thing=network_client.network_interfaces.get(sub, name).ip_configurations
for x in thing:
print(x.private_ip_address)
except:
print("nope")
In this example you could also do x.public_ip_address to get the public IPs
As your said, indeed, something has changed, but not much.
First as below, NetworkManagementClientConfiguration has been remove, see the details in the link.
network_client = NetworkManagementClient(credentials,subscription_id)
Second, according to the source code, the parameter public_ip_address_name is the name of the subnet, cease to be the vm name.
# Resource Group
GROUP_NAME = 'azure-sample-group-virtual-machines'
# Network
SUBNET_NAME = 'azure-sample-subnet'
PUBLIC_IP_NAME = SUBNET_NAME
public_ip_address = network_client.public_ip_addresses.get(GROUP_NAME, PUBLIC_IP_NAME)
Then, you can also the private_ip_address & public_ip_address via the IPConfiguration from the PublicIPAddress
print(public_ip_address.ip_configuration.private_ip_address)
print(public_ip_address.ip_configuration.public_ip_address)

Have good way to python bottle web framework allow range of ip addresses?

I want let some IPs can access to site.
example :
bottle server IP : 192.168.0.1
and I want let 192.168.0.1/29 can access to site,
so 192.168.0.2 can access to site, 192.168.0.11 can't access to site.
my way is create a function to check client IP,
if out of range return status 403.
check IP function like this:
from netaddr import IPSet,IPAddress
def authIP(clientIP=None):
rules = IPSet(['192.168.0.1/29'])
if(IPAddress(clientIP) in rules):
return 'ok.'
else:
abort(403,'access denied.')
but, use this way,I will add this function to every route function to check it.
Like:
#route('/ip')
def tip():
cip = request.environ['REMOTE_ADDR']
return authIP(cip)
Have any other ideas ...?

Using django GeoIP and MaxMind database

I'm trying to setup geoip in Django to identify the source of a connection (to tailor content for different countries) but running into a problem.
First I execute:
from django.contrib.gis import geoip
geo = geoip.GeoIP('path to maxmind db')
Then geo.country('www.google.com') returns the US as you'd expect. Other popular websites also work fine.
However when I try it on my own client IP I get an empty record.
For example: geo.country('127.6.89.129')
returns {'country_name': None, 'country': None}
What am I missing here? Does the maxmind database only cover popular sites so can't be used if I want to identify the source of the connection?
I'm also using the browser locale settings to identify language but unfortunately I need geo-location to tailor some of the content independently of language.
The IP address you used in the example is a local IP address, you cannot use it outside your network, did you try with a real public IP address?
Your ip could be forwarded
def foo(request):
g = GeoIP()
country = g.country(get_client_ip(request))
country_code = country['country_code']
def get_client_ip(request):
x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
if x_forwarded_for:
ip = x_forwarded_for.split(',')[0]
else:
ip = request.META.get('REMOTE_ADDR')
return ip

Categories

Resources