The listener is the first contact we make in order to connect to the Oracle database. Therefore, as DBAs, it is also the front-end component we can secure. There are a few ways to secure the listener, and I’ll name some later.
When hackers look for an entry point to our database, any process that listens on the network and is related to Oracle is a target. The listener, in this scenario, is the first candidate, as it is the main process that listens to network connections, but is the listener the only one?
When we try to protect our database, there are several actions we can take. Some of them are network related, such as firewalls and network separations, while others are Oracle configurations. First, we can separate networks and listeners. If we have a server with many networks and databases, we can create a dedicated listener for each network so listeners that listen on specific networks won’t be able to connect clients to certain databases. Another thing we can do is to limit the rate of connections to the listener (by setting the RATE_LIMIT and CONNECTION_RATE_listener parameters in the listener.ora), so no one can overload the database. There are timeouts we can configure and more. Last thing we can do, is to configure which IP addresses are allowed to connect to the database, by setting the TCP.EXCLUDED_NODES and TCP.INVITED_NODES in the sqlnet.ora file.
How is a Connection Created?
Oracle manages connection differently on Windows and UNIX/Linux, and let’s focus on UNIX/Linux for now. When connecting to the database through the listener, the listener listens on the network, negotiates a TCP connection with the client, and then it spawns (using fork) a server process and hands off the open TCP socket to it. For the client that initiated the connection, this process is transparent and it uses the same open socket it negotiated with the listener. However, if the listener does not spawn a new process, but uses an existing one instead, it cannot hand off the socket, so it sends a redirect request to the client, which in turn creates a new connection with the existing process. In order to do this, this database process has to listen on the network as well, or it will not be able to respond to the client request. The process listens on a dynamic port (larger than 1024), cannot use a port that another process listens on (so it cannot be the same as the listener) and we don’t have control over the port number.
What Else is Listening?
In the past (if I remember correctly, 8i was the last version that had that), we had something called pre-spawned server processes. When we configured that, the listener started several server processes in advanced to reduce the amount of work when a new connection is coming. Once we initiated a connection, the listener simply redirected the client software to one of the existing server processes. As I explained above, these pre-spawned server processes were listening to the network waiting for the clients.
Today, we don’t have these pre-spawned server processes anymore, but we do have dispatchers. Dispatchers are used for the “shared server” architecture to allow connection pooling and multiplexing on the database side. Because the dispatchers start with the database, a client that wishes to connect using the shared server architecture will have to be redirected by the listener to one of the already started dispatchers. So the dispatchers have to listen on the network as well.
The last thing in this scenario is that most of us don’t use the “shared server” architecture, but if you use DBCA on Oracle 11.2 and up to create your database, it will configure a dispatcher for XDB, as XDB needs the “shared server” architecture.
Bypassing the Listener
Now that we know that processes that handle clients are listening to the network, let’s try to connect directly to one of them instead of going through the listener and see what happens.
First, we need to know which port the dispatcher is listening on, I guess port scanners can find that quite easily, we can also use netstat for that. Using “netstat -aptn” we can see the following line:
tcp 0 0 :::59806 :::* LISTEN 2203/ora_d000_ora12
The port in this case is 59806, and the process is ora_d000_ora12 which is the dispatcher.
I’ll simply go through the database and query v$dispatcher:
SQL> select name,network from v$dispatcher; NAME NETWORK ---- ----------------------------------------------------------- D000 (ADDRESS=(PROTOCOL=tcp)(HOST=liron-laptop)(PORT=59806))
In the NETWORK column we see the port the dispatcher is listening on. You also need to be aware that this is part of the databsae and it is not aware of services, so we can only connect to the instance by SID. I’ll create an entry in the tnsnames.ora for this port and SID:
disp = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(PORT=59806)(HOST = 10.230.14.120)) ) (CONNECT_DATA = (sid = ORA12) ) )
Then I’ll connect it:
C:\Users\liron>sqlplus system/password@disp SQL*Plus: Release 220.127.116.11.0 Production on Fri Oct 16 09:42:14 2015 Copyright (c) 1982, 2013, Oracle. All rights reserved. Last Successful login time: Fri Oct 16 2015 09:40:44 -07:00 Connected to: Oracle Database 12c Enterprise Edition Release 18.104.22.168.0 - 64bit Production With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options SQL>
And I’m in. The listener was DOWN at the time I connected.
What Else Does it Bypass?
Because we didn’t use the listener, then the obvious things are bypassed, such as any firewall configuration on the listener ports, the listener’s connection rate configuration, etc. Besides that, we need to remember that the sqlnet.ora file is loaded once at the start of a process. So if we add the TCP.EXCLUDED_NODES configuration, usually we just need to restart the listener. If there are dispatchers, we also need to restart the database itself so they will also reload the sqlnet.ora configuration. Until we restart the database, connections through the listener from the forbidden address will get the ORA-12537: TNS:connection closed error, but connections directly to the dispatcher will just work.
Another thing to remember is that the dispatchers use dynamic ports, we can’t control which port they will listen on, the OS allocates that. So every time you restrat the database, the dispatchers will listen on different ports.
Is There Anything Else?
I’m not aware of any other process that listens to the network, but if some features use such processes, I guess they would behave the same. Another thing to check is RAC, where there are many processes communicating between the nodes, and they are also potential processes to listen on the network. Last thing is that my examples are from 22.214.171.124 with no multitanent architecture, I don’t think 126.96.36.199 is any different, but because we can only connect to the SID, I guess there is no way to connect to a certain PDB using this method, but I haven’t tries that.