Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
The community reviewed whether to reopen this question 12 months ago and left it closed:
Not suitable for this site This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Improve this question
I would like to block all connections to my server that use a VPN or Proxy. Is there anyway to detect that a VPN or proxy connection is being used? If not, is there anyway that I can check the likelihood that a VPN or proxy is being used? Lastly, is there anything that I can query or prompt the user with to check if they are using a VPN or Proxy so that if anyone does get through, I can try and perform additional verification? I do not need any information from the user such as location, true IP, or anything like that. I just want to entirely bar connections from VPNs or Proxies.
Edit: I've been thinking that I could potentially run a test to see if there is consistent discrepancies between ping to the VPN IP and the detectable latency of the client, but that sounds pretty unreliable.
Edit2: A proxy or VPN server would likely have many more ports open than a standard home connection so I could use the number of ports open to help gauge the likelihood of a connection coming from a VPN by running a port scan of the person connecting.
Unfortunately, there's is no proper technical way to get the information you want. You might invent some tests, but those will have a very low correlation with the reality. So either you'll not catch those you want, or you'll have a larger number of false positives. Neither can be considered to make sense.
Generating any kind of traffic backwards from an Internet server in response to an incoming client (a port scan, or even a simple ping) is generally frowned upon. Or, in the case of a port scan, it may be even worse for you, eg when the client lives behind a central corporate firewall, the worst of which is when the client comes from behind the central government network firewall pool...
Frankly, IP-based bans (or actually, any kind of limiting focusing on people who do not exclusively possess their public IP address: proxy servers, VPNs, NAT devices, etc) have been unrealistic for a long time, and as the IPv4 pools have been getting depleted in many parts of the world, ISPs are putting more and more clients behind large NAT pools (it's this week's news in my country that the largest ISP, a subsidiary of Deutsche Telekom, has started handing out private IPv4 addresses as a standard way of business to its customers, and people have to ask the provider explicitly to get a public IP address), so there's even less and less point in doing so. If you want to ban clients, you should ban them based on identity (account), and not based on IP address.
At IPinfo we offer a privacy detection API, which will let you know if a connection is coming from a VPN, an anonymous proxy, a tor exit node, or a hosting provider (which could be used to tunnel traffic). Here's an example:
$ curl ipinfo.io/43.241.71.120/privacy?token=$TOKEN
{
"vpn": true,
"proxy": false,
"tor": false,
"hosting": true
}
If you wanted to block connections to your site from VPNs then you could make an API request to get this information, and reply with an error if it's detected as a VPN. In PHP that would look something like this:
$ip = $_SERVER['REMOTE_ADDR'];
$url = "http://ipinfo.io/{$ip}/privacy?token={$IPINFO_API_TOKEN}";
$details = json_decode(file_get_contents($url));
// Just block VPNs
if($details->vpn) {
return echo "VPN Access Blocked!";
}
// Or we could block all the other types of private / anonymous connections...
if($details->vpn || $details->proxy || $details->tor || $details->hosting) {
return echo "Access Blocked!";
}
The simplest way to do this is to use an external service like an API to block VPN or proxy users.
MaxMind and GetIPIntel both offer it via API, you might want to give it a try. GetIPIntel provides free API service so I suggest you try that first.
For OpenVPN, someone used unique MSS values to identify VPN connections but the setup is complicated and it might be "patched" now.
The strategies you've mentioned in your edits don't seem like a very good idea because you'll run into many false positives. Sending out port scans whenever they connect to your service is going to take a lot of time and resources before you get the results.
List of Tor exit nodes is publicly available. You only want "exit nodes" and it's available as CSV. This should be 100% complete and accurate as it's generated directly from Tor directory.
A free list of open proxies is available from iblocklist.com. A free list that incorporates open proxies, Tor nodes and VPN endpoints from ip2location.com.
The last two have most likely limited coverage and accuracy, especially as it comes to VPN exit nodes - there's just too many of them. Some providers take another approach and consider all "hosted subnets" (subnets from which ISPs assign their clients IPs for hosted servers) as some kind of VPN or proxy, as end-users should be connecting from "consumer" subnets.
Yes, you can detect whether an IP belongs to a VPN/ proxy using Shodan. The following Python code shows how to do it:
import shodan
# Setup the API wrapper
api = shodan.Shodan('YOUR API KEY') # Free API key from https://account.shodan.io
# Lookup the list of services an IP runs
ipinfo = api.host(VISITOR_IP)
# Check whether the IP runs a VPN service by looking for the "vpn" tag
if 'tags' in ipinfo and 'vpn' in ipinfo['tags']:
print('{} is connecting from a VPN'.format(VISITOR_IP))
You can also look at the list of ports to determine the likelihood that the visitor is connecting from a HTTP proxy:
if 8080 in ipinfo['ports']:
print('{} is running a web server on a common proxy port'.format(VISITOR_IP))
Btw you can do this now using our new, free InternetDB API. For example:
import requests
VISITOR_IP = "5.45.38.184" # In production this would be the IP of your visitor
info = requests.get(f"https://internetdb.shodan.io/{VISITOR_IP}").json()
if "vpn" in info["tags"]:
print(f"{VISITOR_IP} is connecting from a VPN")
You can download a list of known proxy IP addresses and lookup locally to see if it is VPN, open proxy etcs.
There are several commercial products in the market. IP2Proxy LITE is a free one you can try immediately.
Get (somehow) list of IP of proxy servers.
Measure round trip ping time to user. Helps in online websocket games. Games are playable with ping under 50ms, so you can disconnect users with ping about 100ms and greater with a message "Sorry, too large ping".
Related
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 2 years ago.
Improve this question
For years I’ve used /etc/hosts to adjust IP address. Sometimes it’s for prototyping, or adding an address for development purposes that isn’t ready to go into public DNS. And sometimes I block certain domains that I don’t want to visit by redirecting them to incorrect IP addresses. Some are invasive tracking websites, e.g., connect.facebook.net. Others I keep blocked as an anti-procrastination measures, for example news sites such as politico.com which I might otherwise spend all day reading when I meant to be working.
But now on macOS 11 Big Sur, I notice that some /etc/hosts entries are ignored by Safari. DNS lookups with gethostbyname() correctly show the block/override address, but Safari displays the public site anyway.
What on earth is going on? What’s changed with /etc/hosts and can I keep using it to override DNS entries when doing development work?
macOS 11 added support for what is officially called “Service binding and parameter specification via the DNS (DNS SVCB and HTTPSSV)”.
Now, when you visit a website, it’s not just the typical DNS A host-to-ip-address record that’s consulted, but a brand-new HTTPS DNS record is checked too. It’s not just a name entry; it’s a brand-new record type (#65), to go along with the more familiar A and CNAME and MX.
These new HTTPS DNS records can indicate that the site supports HTTPS, including protocol versions and IP addresses. That way, typing in a bare domain name gives the https:// version of the site right away, maybe even on HTTP/2 or HTTP/3, skipping the old-fashioned HTTP redirect. There’s even a draft option for domain operators to tell your computer to bypass any local DNS settings and use a specific server for all future DNS queries involving their domain.
There are many pro-performance intentions here, and some pro-privacy ones too.
But there is a fatal privacy and security flaw in both the specification and implementation: it removes the ability for users to override domain name lookups in /etc/hosts, even when faced with actively malicious domain name operators.
To see how this is working in action:
The version of dig that comes with macOS doesn’t directly support these new records, but you can see whether they exist with
$ dig -t type65 www.politico.com
…
;; QUESTION SECTION:
;www.politico.com. IN TYPE65
;; ANSWER SECTION:
www.politico.com. 53806 IN CNAME www.politico.com.cdn.cloudflare.net.
www.politico.com.cdn.cloudflare.net. 300 IN TYPE65 \# 58 0001000001000302683200040008681210CA681211CA000600202606 47000000000000000000681210CA2606470000000000000000006812 11CA
…
I don’t know how to parse that, but wireshark does if I packet-capture it
Domain Name System (response)
Queries
www.politico.com.cdn.cloudflare.net: type HTTPS, class IN
Answers
www.politico.com.cdn.cloudflare.net: type HTTPS, class IN
Name: www.politico.com.cdn.cloudflare.net
Type: HTTPS (HTTPS Specific Service Endpoints) (65)
Class: IN (0x0001)
Time to live: 300 (5 minutes)
Data length: 58
SvcPriority: 1
TargetName: <Root>
SvcParams
SvcParam: ALPN
SvcParamKey: ALPN (1)
SvcParamValue length: 3
ALPN length: 2
ALPN: h2
SvcParam: IPv4 Hint
SvcParamKey: IPv4 Hint (4)
SvcParamValue length: 8
IP: 104.18.16.202
IP: 104.18.17.202
SvcParam: IPv6 Hint
SvcParamKey: IPv6 Hint (6)
SvcParamValue length: 32
IP: 2606:4700::6812:10ca
IP: 2606:4700::6812:11ca
So that’s what’s happening:
Safari on Big Sur can load some websites you’ve blocked in /etc/hosts, because it gets their IP addresses from these new HTTPS records
It can only do that for some sites, because most domain name operators haven’t set this up yet. It looks like Cloudflare has done this for everyone on their platform; fortunately most domain name operators, including the advertising/tracking/malware giants, haven’t caught on to this yet.
For now, you can keep using /etc/hosts for domain names that you fully control.
In the meantime, for other domains, you have some options:
you could run a local DNS server or firewall on your home network that blocks these requests
you could configure a local DNS resolver daemon on your mac, and use it to
block these requests
you could switch to a Linux distribution where a configurable local resolver daemon is the default
you could stop using Safari, although other apps using the default macOS networking stack may continue silently bypassing /etc/hosts
Chrome has run some trials for this but does not appear to have implemented it yet. Firefox has started implementing it but doesn’t seem to have gotten too far.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 9 years ago.
Improve this question
On Windows 7 I have an SSH tunnel running on my local 127.0.0.1:34567 address that I need to access so I can access 12.34.56.78:8080 with the help of SSH proxying for me as I cannot access that IP directly (due to not being on the whitelist).
My basic simple goal therefore is that on Windows whenever I request 12.34.56.78:8080 from anywhere (my browser for instance), I would like the request to instead be diverted to 127.0.0.1:34567 transparently, and I would like a software solution to this instead of a hardware one if possible. I think this is what's usually achieved in Linux by something called iptables, but I'm looking for something I can use on windows.
Does anyone know how this is possible? If I need to use any external Windows program for this, that is fine, but I prefer it to be free.
EDIT: please do not present me with reverse tunnel solutions. My goal is to request the same ip:port that I'm blocked from, but to be able to get to that ip:port successfully through the means of my existing SSH tunnel. Reverse tunnels involve requesting a different ip:port which is not what I'm looking for (I already have a forward tunnel I can use if I wanted to make requests to a different ip:port).
Example scenario: Pretend that you have an C-compiled .exe file whose source code you don't have access to that is hardcoded to request 12.34.56.78:8000 for SOAP webservices. The problem is, your IP is blocked from that ip:port, but you do have access to an SSH server which isn't blocked by 210.212.239.117:8080 and also have an SSH tunnel set up for that SSH server to access that ip:port... but your .exe has the original ip:port hardcoded, so you can't just tell it to request the SSH tunnel ip:port, as it's not possible to change the ip:port to be requested in any way due to it being hardcoded! You would have to have the request to 210.212.239.117:8080 on your computer somehow diverted to your SSH tunnel on the OS level. So how would you get that done?
EDIT 2: I'm not looking for routing tables either (I think). I don't want to modify the route my request goes through to reach target ip:port; I actually want to have the requested ip and port themselves silently changed. I kind of want to achieve something like the hosts file, except instead of resolving hostnames to ips, I want ip:ports to be reresolved to different ip:ports.
Bounty: Sorry, it appears this stackoverflow question of mine counts as Offtopic and isn't eligable for offering a bounty, so sorry to anyone who put in extra work and would have potentially received the bounty!
I haven't found a ready executable, but WFPSampler seems to be promising. It uses the new Windows Filtering Platform API (available since Windows Vista) to manipulate packets.
To use it for redirecting outgoing packets, give a look at Q&A section, there are many examples.
Check out BarbaTunnel: http://barbatunnel.codeplex.com/
TCP-Redirect mode is probably what you're looking for.
You can use a reverse shell. It can mirror a remote port. Use ssh to connect with -R option. For example ssh -R xxxx:localhost:xxxx user:pass#www.server.com. Check this out:http://www.debianadmin.com/howto-use-ssh-local-and-remote-port-forwarding.html.
Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 10 years ago.
Improve this question
Does anyone have a complete list of all IP addresses used by the Apple Push Notification Service?
I know that Apple uses a content delivery network to spread out these requests, and DNS lookups will return servers close to the requestor's location - the problem I have is in locating all of these servers that handle content for the United States.
For example:
$ nslookup gateway.push.apple.com
Non-authoritative answer:
canonical name = gateway.push-apple.com.akadns.net.
Address: 17.172.238.216
Address: 17.172.238.224
Address: 17.172.238.226
etc.
This list changes every time I query DNS - but all of the addresses seem to be in the same 17.172.238.x range - but there's no guarantee that tomorrow or next week I'll see a different range.
For the test push server, however, I already get results in different subnets. Sometimes I get one set of addresses:
$ nslookup gateway.sandbox.push.apple.com
Non-authoritative answer:
canonical name = gateway.sandbox.push-apple.com.akadns.net.
Address: 17.149.34.66
Address: 17.149.34.65
and other times, I'll get these addresses:
Address: 17.172.233.65
Address: 17.172.233.66
My server that will use the Apple Push Notification Service will be behind a corporate firewall, and I'll need to open up ports 2195 and 2196 for the production and test gateways -- however, my firewall team requires specific IP Addresses instead of host names.
I'm worried that if I just ask the firewall team to allow the IP Addresses I've seen so far, then my server will simply stop working a day or a week from now when the DNS server decides to serve up a different range.
If anyone has a comprehensive list for both the production and test environments, I'd appreciate it.
Update: I've tried asking the firewall team to open Apple's entire IP block (17.0.0.0/8), but they won't do that for me -- I need to narrow down the addresses a little bit.
Final update - 10/16/2016
Even though this question is closed, I thought I'd add a note explaining my final solution - and it is not what anyone looking for an answer wants to hear. I could never get ahead of the constantly changing addresses used by the CDN, so I finally gave up and leased an external server from Rackspace. I got the smallest server possible, and the only thing running on it is a port-forwarder that listens on 2195 and 2916 and sends the connections to Apple.
I used a simple iptables configuration on the Rackspace server to only allow connections on 2195/2916 from my corporate gateway, and then had my firewall team open a path to the static IP address on the external server. The firewall team is happy, with implementing a single path, and the external server can connect to the entire 17.0.0.0/8 range used by Apple.
From Apple's documentation (emphasis on the interesting bit added):
Push providers, iOS devices, and Mac computers are often behind firewalls. To send notifications, you will need to have TCP port 2195 open. To reach the feedback service, you will need to have TCP port 2196 open. Devices and computers connecting to the push service over Wi-Fi will need to have TCP port 5223 open.
The IP address range for the push service is subject to change; the expectation is that providers will connect by hostname rather than IP address. The push service uses a load balancing scheme that yields a different IP address for the same hostname. However, the entire 17.0.0.0/8 address block is assigned to Apple, so you can specify that range in your firewall rules.
17.0.0.0/8 is CIDR notation for 17.0.0.1 to 17.255.255.254.
The official answer is, unfortunately, that there is no official answer :) -- unless you consider Apple's rather sloppy approach of simply allowing all traffic to 17.0.0.0/8. Apple developer support provided the same link to the documentation as vcsjones in the first answer.
For my particular situation, I have narrowed the IP addresses down to these ranges after checking DNS regularly for the last couple of weeks. Keep in mind that these are only valid for the midwest portion of the United States, since Apple's CDN will return a set of addresses closest to the server making the query.
For gateway.push.apple.com, I'm opening ports 2195 and 2196 on my firewall for:
17.149.35.0 / 24
17.172.238.0 / 24
For gateway.sandbox.push.apple.com, I'm opening ports 2195 and 2196 on my firewall for:
17.149.34.66
17.149.34.65
17.172.233.65
17.172.233.66
Since these addresses are obviously subject to change, I've built in some monitoring for my application to detect when the APNS servers are no longer reachable (and fall back to these address ranges instead of using DNS). It's not the ideal solution, but it will have work for now until I can work out a solution with my corporate network / firewall teams...
To help users, I would like my code to discover Oracle databases on the LAN. I thought to do this by first detecting all hosts, then checking each host to see if it is listening on Oracle's default port.
Any ideas how to go about this? Preferably in Java, but any language or algorithm would do.
Are you using DHCP? If so, your DHCP server has a list of the leases it has passed out. That should do you for a list of hosts on the LAN. Then try opening a connection to the Oracle port on each of those hosts and see if it accepts the connection.
It should be pretty simple to implement as a shell script with half a dozen lines or so. Java seems like overkill for something like this. Loop through the leases file, grab the IP from each lease, and telnet to the Oracle port; if it connects, disconnect and print the IP to standard out.
If you want to stay platform-independant, and unless you have access to some kind of database that lists the hosts, the only way to get a list is to try each IP address in the local network - might as well try to connect to the Oracle port on each of them.
There are lots of problems with this approach:
Will only search through the local network, which may only be a small part of the LAN (in case of large companies with lots of subnets)
Can take a long time (you definitely want to reduce the timeout for the connection attempts, but if someone has configured his LAN as a class A network, it will still take forever)
Can trigger all kinds of alerts, such as desktop users' personal firewalls, and intrusion detection systems - because you're doing exactly the same thing someone trying to exploit a security hole in Oracle servers would do
As brazzy points out, scanning for hosts is likely to cause problems, especially if there is a bug in your scanner.
A better approach may be to get the owners of the databases to register them somewhere, for example in a local DNS service (or does Oracle have zeroconf support?), or simply on some intranet webpage or wiki.
You better register the SID names/addresses to some server with a fixed address(maybe with a simple web service), and then query the list from there. Another approach is the bruteforce one (explained by #brazzy) by scanning one or more subnets, but this isn't really a good thing to do.
In case you are looking for a tool Loo#Lan can do this for you. Unfortunately there's no source available...
All of these smart answers are the reasons why many companies do not use the default port. Using a different port for each database is entirely possible, you know.
Consider the following setup:
A windows PC with a LAN interface and a WiFi interface (the standard for any new laptop). Each of the interfaces might be connected or disconnected from a network. I need a way to determine which one of the adapters is the one connected to the internet - specifically, in case they are both connected to different networks, one with connection to the internet and one without.
My current solution involves using IPHelper's "GetBestInterface" function and supplying it with the IP address "0.0.0.0".
Do you have any other solutions you might suggest to this problem?
Following some of the answers, let me elaborate:
I need this because I have a product that has to choose which adapter to bind to. I have no way of controlling the setup of the network or the host where the product will run and so I need a solution that is as robust as possible, with as few assumptions as possible.
I need to do this in code, since this is part of a product.
#Chris Upchurch: This makes me dependent on google.com being up (usually not a problem) and on any personal firewall that might be installed to allow pinging.
#Till: Like Steve Moon said, relying on the adapter's address is kind of risky because you make a lot of assumptions on the internal network setup.
#Steve Moon: Looking at the routing table sounds like a good idea, but instead of applying the routing logic myself, I am trying to use "GetBestInterface" as described above. I believe what it should do is exactly what you outlined in your answer, but I am not really sure. The reason I'm reluctant to implement my own "routing logic" is that there's a better chance that I'll get it wrong than if I use a library/API written and tested by more "hard-core" network people.
Technically, there is no "connected to the Internet". The real question is, which interface is routeable to a desired address. Right now, you're querying for the "default route" - the one that applies if no specific route to destination exists. But, you're ignoring any specific routes.
Fortunately, for 99.9% of home users, that'll do the trick. They're not likely to have much of a routing table, and GetBestInterface will automatically prefer wired over wireless - so you should be good. Throw in an override option for the .1% of cases you screw up, and call it a day.
But, for corporate use, you should be using GetBestInterface for a specific destination - otherwise, you'll have issues if someone is on the same LAN as your destination (which means you should take the "internal" interface, not the "external") or has a specific route to your destination (my internal network could peer with your destination's network, for instance).
Then again, I'm not sure what you plan to do with this adapter "connected to the Internet", so it might not be a big deal.
Apparently, in Vista there are new interfaces that enable querying for internet connectivity and more. Take a look at the NLM Interfaces and specifically at INetworkConnection - you can specifically query if the network connection has internet connectivity using the GetConnectivity method.
See also: Network Awareness on Windows Vista
Unfortunately, this is only available on Vista, so for XP I'd have to keep my original heuristic.
I'd look at the routing table. Whichever NIC has an 0.0.0.0 route AND is enabled AND has the lowest metric, is the nic that's currently sending packets to the internet.
So in my case, the top one is the 'internet nic'.
IPv4 Route Table
===========================================================================
Active Routes:
Network Destination Netmask Gateway Interface Metric
0.0.0.0 0.0.0.0 10.0.0.10 10.0.0.51 20
0.0.0.0 0.0.0.0 10.0.0.10 10.0.0.50 25
(much other stuff deleted)
Another alternative is to ping or GetBestInterface 4.2.2.2 - this is an old and venerable DNS server, currently held by GTEI; formerly by Sprint if I remember right.
Start > Run > cmd.exe (this works in XP and Vista): ipconfig /all
This displays all info about the interfaces in your computer. The "public" facing interface should have a public IP address. For starters, it should not be 192.168.x.x or 10.x.x.x :)
running traceroute to some public site will show you. Of course, there may be more than one interface that would get you there.
Look at the routing table? Generally, unless you're routing between the networks in windows (which is possible, but unusual for a client computer these days) the interface that holds the default route is going to have the Internet connection.
Your question didn't detail why or what you're doing this with so I can't provide any specifics. The command line tool "route" may be of some help, but there are probably libraries for whatever programming language you're using to look at the routing table.
You can't rely on the IP address of the interface (e.g., assuming an RFC-1918 address [192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8] isn't the internet) since most sites have some kind of NATed firewall or proxy setup and the "internet" interface is really on a "private" lan that gets you out to the Internet.
UPDATE: Based on your further information, it sounds like you have a decent solution. I'm not so sure about the choice of 0.0.0.0 since that's a boundary case for IP address -- might be OK on your particular mix of platform/language. Sounds (from the API description) like you could just specify an address, so why not some address known to be on the Internet, e.g. the IP address of your web site, or something more random like 65.66.67.68? Just make sure not to pick one of the rfc-1918 addresses, or the localhost range (127.0.0.0/8), or multicast, any other reserved range, and any address that resolves to a .mil or .gov (while it doesn't sound like getbestinterface sends any traffic, it would suck to find out by having the feds break your door down... :)
Looking at the network point of view, either could be routing to the "internet" at any time. If things like spanning tree protocol are enabled on a switch then you may find that what may have been the routing card to begin with may not be anymore.
Ping google.com though each NIC.