How to connect ODP.Net through a firewall? - oracle

Apologies for a newbie question, but that's me - new to Oracle.
My client and oracle server are separated by a firewall. A limited set of IP addresses can be routed through this firewall. One routable IP is the address of a SCAN listener, which redirects to oracle servers that have non-routable IPs.
I am able to connect SQL Developer to my database, but not a simple ODP.Net client.
Using wireshark, I see that when SQL Developer connects to the SCAN listener, SCAN replies with a redirect to a random port on the SCAN IP, which it presumably then proxies to the actual Oracle server. Wireshark reveals that when ODP.Net tries to connect, SCAN replies with a redirect to the actual IP of the back-end server, which IP is not routable.
I'm looking for advice on how to get ODP.Net to enjoy the behavior that SCAN is offering SQL Developer.
I attempted to use the same connection string, completely bypassing tnsnames.ora for simplicity. In SQL Developer, I configured a connection using just IP address, port and service name. I then used wireshark to observe the connection string that SQL Developer sent to the server (yes, SQL Dev repeats the CID section):
(DESCRIPTION=
(ADDRESS=(PROTOCOL=TCP)(HOST=10.130.X.Y)(PORT=1521))
(CONNECT_DATA=
(CID=(PROGRAM=SQL Developer)(HOST=__jdbc__)(USER=myusername))
(SERVICE_NAME=myservice)
(CID=(PROGRAM=SQL Developer)(HOST=__jdbc__)(USER=myusername))))
I plugged this same connection string into an OracleConnection
var bldr = new Oracle.DataAccess.Client.OracleConnectionStringBuilder();
bldr.DataSource = #"(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=10.130.X.Y)(PORT=1521))(CONNECT_DATA=(CID=(PROGRAM=SQL Developer)(HOST=__jdbc__)(USER=myusername))(SERVICE_NAME=myservice)(CID=(PROGRAM=SQL Developer)(HOST=__jdbc__)(USER=myuser))))";
var connection = new Oracle.DataAccess.Client.OracleConnection(bldr.ConnectionString);
connection.Open();
connection.Close();
And instead of connecting I receive a timeout. Further examination of captured packets reveals the behavior detailed above: SCAN acts as a proxy for SQL Developer but not for ODP.

Related

How to get IP from a Connection object in Cx_Oracle

In cx_Oracle, I obtained a Connection object using tnsnames.ora
Example:
conn = cx_Oracle.connect ('scott', 'tiger', 'DBNAME')
I'm trying to get an IP from a connection object (= conn), but I can not figure out how to do it.
It is practically impossible. Even OCI does not support it. There was a trick in OCI to convert OCI Connection struct into the old Oracle7 connection context, and this structure contains "file handle" number for TCP socket to the database. From this file/socket descriptor you could get IP.
If you use tnsnames.ora you can easily parse it. But in case of Oracle RAC you 1st connect SCAN lister, this one will send you just redirect packet to some cluster node. TCP connection to scan listener is closed and a new TCP connection is opened, based on information received from SCAN listener.

SSH tunnel not working with JDBC while trying to route HTTPS traffic

I am trying to connect to Snowflake which only has port 443 open for communications using JDBC driver. Instead of directly connecting to the snowflake server I want to connect to it via tunnel server. So I've created a ssh tunnel from local machine to snowflake server. And I'm passing the forwarded local address and port as the host for the JDBC connection String. This is my final JDBC string.
jdbc:snowflake://127.0.0.1:21212/?db=TEST_DB&warehouse=LOAD_WH&user=<user>&password=<password>
but the JDBC driver is not able to establish connection and fails during SSL handshake. Since the host address in the JDBC connection string doesn't have the format of that of the CN and SAN present in snowflake's SSL certificate.
Adding the stacktrace along:-
javax.net.ssl.SSLPeerUnverifiedException: Certificate for <10.11.227.124> doesn't match any of the subject alternative names: [*.snowflakecomputing.com, snowflakecomputing.com]
at net.snowflake.client.jdbc.internal.apache.http.conn.ssl.SSLConnectionSocketFactory.verifyHostname(SSLConnectionSocketFactory.java:467)
at net.snowflake.client.jdbc.internal.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:397)
at net.snowflake.client.jdbc.internal.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:355)
at net.snowflake.client.jdbc.internal.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:142)
at net.snowflake.client.jdbc.internal.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:359)
at net.snowflake.client.jdbc.internal.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:381)
at net.snowflake.client.jdbc.internal.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:237)
at net.snowflake.client.jdbc.internal.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:185)
at net.snowflake.client.jdbc.internal.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
at net.snowflake.client.jdbc.internal.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:111)
at net.snowflake.client.jdbc.internal.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
at net.snowflake.client.jdbc.internal.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
at net.snowflake.client.jdbc.internal.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:108)
at net.snowflake.client.jdbc.internal.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:56)
at net.snowflake.client.jdbc.RestRequest.execute(RestRequest.java:141)
at net.snowflake.client.core.HttpUtil.executeRequestInternal(HttpUtil.java:280)
at net.snowflake.client.core.HttpUtil.executeRequest(HttpUtil.java:234)
at net.snowflake.client.core.SessionUtil.openSession(SessionUtil.java:906)
at net.snowflake.client.core.SFSession.open(SFSession.java:330)
at net.snowflake.client.jdbc.SnowflakeConnectionV1.<init>(SnowflakeConnectionV1.java:239)
at net.snowflake.client.jdbc.SnowflakeDriver.connect(SnowflakeDriver.java:344)
at java.sql.DriverManager.getConnection(DriverManager.java:664)
at java.sql.DriverManager.getConnection(DriverManager.java:270)
at org.apache.sqoop.manager.SqlManager.makeConnection(SqlManager.java:670)
at org.apache.sqoop.manager.GenericJdbcManager.getConnection(GenericJdbcManager.java:52)
at org.apache.sqoop.tool.EvalSqlTool.run(EvalSqlTool.java:70)
at org.apache.sqoop.Sqoop.run(Sqoop.java:175)
at org.apache.hadoop.util.ToolRunner.run(ToolRunner.java:65)
at org.apache.sqoop.Sqoop.runSqoop(Sqoop.java:211)
at org.apache.sqoop.Sqoop.runTool(Sqoop.java:250)
at org.apache.sqoop.Sqoop.runTool(Sqoop.java:259)
at org.apache.sqoop.Sqoop.main(Sqoop.java:268)
at com.cloudera.sqoop.Sqoop.main(Sqoop.java:57)
Anyone has done similar thing in past and can guide me on how to do that?
By default snowflake JDBC driver will use tls for communication since snowflake is on public cloud, we have to verify certificate to trust the connection. However, in your case, you are trying to connect to a local server (I guess no tls there), you can add turn ssl off in the connection property. You can try
Properties prop = new Properties();
prop.put("account", "testaccount");
...
prop.put("ssl", "off");
Connection conn = DriverManager.getConnection(url, prop);
I am not sure if this would work or not, but I think worth trying.

How to get the IP address of a connected WebSocket-client?

I'm currently working on a ABAP Push Channel server to WebSocket client connection and I need the IP-address of the client in order to identify whether this client is the one I want to send the message to. In my scenario there could be multiple WebSocket connections.
Now there is the ssi_websocket_table table and the ssi_websocket_table_row row with the the field caller_ip, however this gives me the IP address of the DNS-Server of the network I'm connected to, and I expected the IP address of my local PC since the WebSocket-client is running on this machine.
Is there any other way to get the clients IP address from an active WebSocket connection in ABAP?
P.S. Looking at all the table entries, it shows the correct IP when using a different server configuration, as soon as I know why that's the case I will report back.
As pointed out by vwegert it makes no sense to use the IP to tell the WebSockets apart, I think it would probably be better to use an ID for each WebSocket connection instead.
You could get the IP from the WebSocket server context which gets the IP header apparently from the opening HTTP handshake for the connection:
DATA(lo_context) = i_context. " IF_APC_WSP_SERVER_CONTEXT type
DATA(lo_request) = lo_context->get_initial_request( ).
" initialize G_CONTEXT_ID_FIELD for PCP_SET_CONTEXT_FIELDS
DATA(lv_id) = lo_request->get_header_field( if_http_header_fields_sap=>remote_addr ).
the sample is taken from the SAP standard class CL_APC_WS_EXT_ABAP_ONLINE_COMM, ON_MESSAGE method.

SMSC is having multiple connections with client But , Client has one connection with SMSC

I am having a strange issue. I am working on sms module for one of the client.
So, I am using Kannel to connect to SMSC server. At the very first attempt means after restarting both client and server applications . I am able to connect to SMSC with one active connections but, after some time server is having multiple connections for My IP although i am having only one connection at that time . Because , of this we are not able to receive MOs properly there is a huge MO drop. To overcome this problem we has to restart both client and server applications frequently. Which is not a proper solution So, server requested me to resolve our end as they have multiple partners and they are not facing this issue.
Background :
Before , they have provided us a ip(public ip) and port to connect to SMSC .Asked our IP(public ip) to make whitlist at their end. And they have provided VPN settings after VPN configured we are successfully connected to SMSC. They have masked our IP at their end to treat as local IP.
So, Please help me to resolve this multiple connections error as i am new to kannel and SMPP.
I had the same exact issue with another SMPP client app, it was NowSMS, and also, it was very strange as my NowSMS is connected to +15 SPs since 7 years ago, and I had no such issue with anyone of them. But, NowSMS told me that there's an understandable issue at SP's side and after a some investigations, we noticed that the SP deals with the first established connection only and ignores the other connections, although, I had one single connection only and all previous connections were closed from my side before establishing a new one.
So, please discuss the same with your SP, otherwise, share the full config here as you may have something incorrect.
BTW, did you try getting a live TCP trace from your side and SP's side at the same time?

Connecting to MySQL (on Google Cloud SQL) via JDBC and IPv6?

I would like to connect to Google Cloud SQL from an external application using JDBC and the instance's IPv6 address as shown on my Google Developers Console (here obfuscated):
String url = "jdbc:mysql://abcd:abcd:abcd:abcd:abcd:abcd:abcd:abcd";
String user = "root";
String password = "<also_obfuscated>";
connection = DriverManager.getConnection(url, user, password);
This leads to the following exception:
com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException:
Cannot load connection class because of underlying exception:
'java.lang.NumberFormatException:
For input string: "abcd:abcd:abcd:abcd:abcd:abcd:abcd:abcd"'.
I am using the latest JDBC driver for MySQL. Connection via JDBC and IPv4 works but requires an extra configuration step and incurs (small) extra cost.
So is it even possible to connect to MySQL via JDBC and IPv6 and if so how?
UPDATE According to the documentation, this URL should work for IPv6:
jdbc:mysql://address=(protocol=tcp)(host=abcd:abcd:abcd:abcd:abcd:abcd:abcd:abcd)(port=3306)
However, now I'm getting the following exception:
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException:
Communications link failure
The last packet sent successfully to the server was 0 milliseconds ago.
The driver has not received any packets from the server.
Besides the JDBC driver supporting IPv6 (which it does, according to the documentation), and the client OS supporting IPv6 (which mine should as it is OS X Yosemite), and the server OS supporting IPv6 (which the Google Cloud does because it reports an IPv6 server address) what other pieces need to be in place in order for IPv6 client-server connections to work?
E.g. does my ISP have to provide any particular support?
You need to register the IPV6 address from which you'll be coming into Google Cloud SQL, among the authorized addresses on the Cloud SQL console.
You can check that IPv6 address e.g by visiting sites such as whatismyv6.com .
Then, all your ISP has to do is to provide a stable IPV6 address (alas, even to these days, not all do -- alas, AT&T Uverse, my ISP at home, does not, for example).
Even from locations where I could reliably get a stable IPv6 address, I had exactly the same problem, originally -- until it dawned on me that, if I'm coming in with an IPv6 address and what I've authorized is an IPv4 one, Google Cloud SQL cannot "translate" one into the other to find out I'm in fact authorized!-)
Note that if you don't have and can't get an IPv6 address from which to connect (e.g. connecting from a home machine through an ISP that does not yet support IPv6) then you can hit the "Request IPv4 address" button under Google Developers Console / Storage / Cloud SQL / [Your Intance] / Access Control / IP Address and you will get one assigned (within a few seconds) which will cost $0.01 per hour, paid from your free $300 of credit if you still have that credit available. Once you move your app to, for example, one of Google's app servers, you will no doubt be able to get an IPv6 address. Release the IPv4 address when unused to save credit.
Try
String url = "jdbc:mysql://[abcd:abcd:abcd:abcd:abcd:abcd:abcd:abcd]";
In URLs literal IPv6 addresses have to be surrounded by [] so that the parser can see the difference between parts of the address and the optional port number which is also separated by a :.
It is often easier to use hostnames instead of literal IP addresses. It stays independent of the used IP protocol and changing addresses is easier as well.

Resources