I have been trying to figure out a solution for a while now and finally stumbled on this post. The solution provided by @supersam654 did not work for me right away (was using https and python 3.8), but a few days of sleeping on got me this solution that works regardless of version (have not tested for too many versions, but naively hope that to be the case).
It should also work for ipv6 - though I have not tested that either.
The key to the solution was to use the default getaddrinfo() for all calls (no assumptions on its output) - simply replace the hostname with the ip address to override it with! Hence my grandiose statement on how well it works ;-)
import socket
dns_cache = {}
# Capture a dict of hostname and their IPs to override with
def override_dns(domain, ip):
dns_cache[domain] = ip
prv_getaddrinfo = socket.getaddrinfo
# Override default socket.getaddrinfo() and pass ip instead of host
# if override is detected
def new_getaddrinfo(*args):
if args[0] in dns_cache:
print("Forcing FQDN: {} to IP: {}".format(args[0], dns_cache[args[0]]))
return prv_getaddrinfo(dns_cache[args[0]], *args[1:])
else:
return prv_getaddrinfo(*args)
socket.getaddrinfo = new_getaddrinfo
To use the above logic - simply call the function like so before making requests (you can override with IP Address or another FQDN!):
override_dns('www.example.com', '192.168.1.100')
I believe this is a better solution than the ForcedIPHTTPSAdapter that I had used earlier.