Get IP addresses of established connections to Oracle 11 - oracle

During development I found that database have large number of lived connections by:
SELECT username, COUNT(*) FROM v$session GROUP BY username;
In order to find who actually hold connection I want to get a list of IP addresses.
During general web search and reading official docs I build query:
SELECT username, seconds_in_wait, machine, port, terminal, program, module, service_name
FROM v$session
WHERE type = 'USER';
where machine is most important part of select. But unfortunately machine field shows host name known by client OS.
Internet full of recommendation to use UTL_INADDR.GET_HOST_ADDRESS which is not applicable in my case. Firstly because of ORA-24247: network access denied by access control list (ACL) and secondly because client OS host name usually defined in /etc/hostname and doesn't available to DNS server in our intranet...
Any other way to retrieve IP of open session to Oracle DB (DB instance hold information about its sockets in any case...).
UPDATE
I under trusted intranet but with unknown network hierarchy.
And I try to find which applications use my tables (several app-servers, I don't know all of them). Some of them overuse connections and need to be fixed. But firstly they should be identified...

Bear in mind that the Oracle session doesn't need to know, and certainly doesn't need to trust, the client name/IP address you're coming from; it's sitting above the network transport layer, and doesn't really care if you're connected over TCP/IP or something else. (I'm not even sure if the listener has to pass the info across, or if it effectively passes a ready-made socket). As you've seen the machine is just what the client declared, like program and other fields in the v$session view; it may not bear any resemblance to anything that DNS or your server's /etc/hosts can resolve, particularly if the client is a Windows box.
What you could do is, at Unix/Linux level (since you refer to /etc/hosts, I assume you aren't on Windows), look for the port and see what address that shows; for example v$session shows my port as 50527, so if I do netstat -an | grep 50527 I see:
tcp 0 0 192.168.1.1:1521 192.168.1.23:50527 ESTABLISHED
So I can see I'm connected from 192.168.1.23. You can do that with a host command if you're running SQL*Plus on the server, but it's still a bit inconvenient. If you needed to do this regularly, and adding a logon trigger to capture it to an audit table isn't an option, and you really had to do it from within the database you could probably write a Java stored procedure to do the lookup from that port for you. But it's probably easier to write a shell script to query the port numbers from v$session and do the lookup that way round.

Thanks to all for digging into my question (which is still general purpose, not exactly mine!!).
Just short answer: you can't get real IP from Oracle system tables.
For this tasks you can use general purpose utilities like netstat or lsof -p <pid-of-oracle> but only on server side!
Some help can come from v$session.port values...
One good suggestion from helpers - use good names from DB clients. They are populated to v$session table rows:
machine, terminal, program, module, service_name
so they can help to identify clients...

The IP address of an incoming connection can usually be found in your Listener log. That is how I track such information when I need to.

I've found my auditing script from 2001 when logon triggers didn't exist AFAIK. It parses the COMMENT$TEXT column of SYS.AUD$ where ACTION#=100 to get the IP address of the client. That column still contains Authenticated by: DATABASE; Client address: (ADDRESS=(PROTOCOL=tcp)(HOST=a.a.a.a)(PORT=p)) in our environments.

Try this in your select statements (i.e., from v$session):
utl_inaddr.get_host_address(substr(machine,instr(machine,'\')+1)) ip
Sorry, I don't have the source, but it worked for me.

Related

How to simulate external TCP traffic in Windows?

I don't have any code yet, so please feel free to move this to a sister site, if you think it belongs there :)
I have a Program A ( I don't have it's source code, so I can't modify it's behavior ) running on my machine which keeps listening to a particular port on the system for TCP data. It's a Peer to Peer application.
System 1 running A ====================== System 2 sunning A
The program A is supposed to run on systems where I may not be allowed to modify Firewall settings to allow incoming connections on the port the program listens to. I have an EC2 linux server running Ubuntu 16.
So I thought I can use an existing tool or create a program that would connect to the server on port X, and fetch the data from the server, and locally throw that data to the port A is listening to.
System 1 running A ========= SERVER =========== System 2 sunning A
What kind of configuration should I have on the server ? And is there any program I can use for this, or an idea of how to make one ?
I did something similar to bypass firewalls and hotspots.
Check this out https://github.com/yarrick/iodine, with a proper configuration your would be able to send\receive packets as DNS queries which is I know is always allowed, I used my server to get usual internet access with any hotspot I found.
You would lose some time, higher latency but you will have access.
Hope I helped.

Socket.Bind and IP source routing, with multiple local network interfaces

I wrote a tool running on a system (Win7) with two network interfaces, each linked to a different subnet, each with its own gateway which is then linked to two separate distant networks (there are outgoing firewalls after each gateway). I’m initiating outgoing TCP connections via both NICs by using Socket.Bind (before doing Connect) to each relevant NIC’s IP address. First NIC is working fine, but for the second NIC, I’m getting SocketException: “A socket operation was attempted to an unreachable network”.
My original understanding was that since sockets are bound to concrete NIC’s local endpoint, which has its gateway defined, the connection should be routed to this gateway and therefore should work. However, it seems that source IP address is ignored and the routing is working according to local routing table (i.e. second NIC’s connect request goes to first, default, network and being rejected because it has wrong subnet).
Adjusting local routing tables helps, but it makes me wonder about the whole reasoning behind ability of the socket to bind to specific local IP.
Doing some extra reading, I found out that, indeed, there’s such thing as “source IP routing”, but it is disabled in Windows by default (via DisableIPSourceRouting registry setting), due to security reasons, as described, e.g. here:
http://msdn.microsoft.com/en-us/library/ff648853.aspx
http://www.bloggersbase.com/disableipsourcerouting/
Questions:
If my original understanding was correct (i.e. Socket.Bind should be enough) – why it is not working without modifying routing tables?
If my understand was NOT correct (i.e. Socket.Bind is ignored and routing is used) – what’s the point of having Socket.Bind? Why doing it at all?
Also, I’d like to understand better, what is the actual risk of having source IP routing enabled (preferably with example of a possible exploit)?
Any ideas of solving the requirement without manually modifying local routing table will be greatly appreciated.
Many thanks.
OK, after some reading, here are some high-level explanations on what's happening. I still need to verify the below conclusions in my system. Apparently, local binding is typically ignored when selecting network interface. Instead, routing table is used for this. However, in Strong Host Model (default for Vista and newer, non-existant in XP), source IP is used as a 'constraint' in the routing table lookup.
Brief explanation about strong host model vs. weak host model:
http://technet.microsoft.com/en-us/magazine/2007.09.cableguy.aspx
Explanation on what's different in XP vs newer Windows versions in respect to the above:
http://blogs.technet.com/b/networking/archive/2009/04/24/source-ip-address-selection-on-a-multi-homed-windows-computer.aspx

How do you use telnet to check a connection to Oracle?

I've been trying to get sqlplus to connect to Oracle from my OS X machine. I asked another question about it here.
One person suggested that I try telnet. Consulting the man page, I tried:
[ ethan#gir ~ ]$ telnet DBHOST:1521
Trying xxx.xxx.xxx.xxx...
telnet: connect to address xxx.xxx.xxx.xxx: Operation timed out
telnet: Unable to connect to remote host
Also...
[ ethan#gir ~ ]$ telnet DBHOST 1521
...with same result.
I'm not sure how to interpret these results. Seems like what you'd expect in any case. You wouldn't do this...
$ ssh some_mysql_host:3306
How is telnet to Oracle different?
Or maybe I didn't understand what they meant.
If anyone could help me understand how one uses telnet to test a connection to Oracle I would be grateful.
They're proposing use of telnet simply because it's one of the simplest TCP/IP clients and because it's installed almost everywhere. It's just an easy way to check from the command line whether you're actually able to make a TCP/IP connection to any particular service.
Also, on many of the ASCII based IP protocols it's straight forward to actually interact with the server to check its working by typing in commands and looking at the responses - I've done this numerous times myself with SMTP servers.
In your case, as you're getting a timeout, either the whole host is down, or the access to that particular host or service is being blocked by a firewall. If you can reach the server with a ping then the latter is more likely.
There's also an outside chance that your name resolution is actually taking you to the wrong host, but you should be able to confirm that by looking at the IP address that telnet said it was trying to connect to.
Another common response is "connection refused". That means that the host is up, but that there's no service running on the specified port.
Basically when you specify a port number e.g
Telnet myserver 1521
It will try to connect to the machine on that port. If you see any data returned or even a blank console then it has connected. If you receive an unable to connect message then the machine is not listening on that port or a firewall is blocking the connection.
Your attempt to telnet to dbhost 1521 getting 'unable to connect' with a timeout suggests that either your hostname resolution for 'dbhost' is giving you the wrong answer, or that host is offline, down or you have network problems.
If oracle was working, you'd get a connection. You wouldn't really be able to do anything with it, but it would confirm that oracle was up and listening.
Oracle instance is not connected from other systems, while it is connected from localhost, I think port is not opened and it is showing problem to telnet 1521 port from other system.
Why not do it the 'right' way? Telnetting to some arbitrary network port will not give you correct information, if the database and it's listener is working correctly.
Just install the oracle instantclient software and use the configuration wizard.

How do I detect hosts on my LAN?

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.

How do you find out which NIC is connected to the internet?

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.

Resources