Broken Pipe in RabbitMQ ConnectionFactory.newConnection() - rabbitmq

Rarely, when under more load than usual my RabbitMQ application starts returning SocketException: Broken pipe (and basically doesn't process any further messages).
The system is using the RPC pattern, with workers listening on a few predefined queues for jobs, clients submitting tasks on these jobs while opening a temporary auto-delete queues that they specify as replyTo queue where they listen for the replies on (and use a correlation ID as well to match the messages).
The code that actually leads to the Broken pipe is quite simple, it is in the client part and basically does:
factory = new ConnectionFactory();
factory.setUri(uri);
connection = factory.newConnection(); // this is when we get the exception
The exception is as follows:
2013-09-06 21:37:03,947 +0000 [http-bio-8080-exec-350] ERROR RabbitRpcClient:79 - IOException
java.net.SocketException: Broken pipe
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:109)
at java.net.SocketOutputStream.write(SocketOutputStream.java:153)
at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
at java.io.DataOutputStream.flush(DataOutputStream.java:123)
at com.rabbitmq.client.impl.SocketFrameHandler.flush(SocketFrameHandler.java:142)
at com.rabbitmq.client.impl.AMQConnection.flush(AMQConnection.java:488)
at com.rabbitmq.client.impl.AMQCommand.transmit(AMQCommand.java:125)
at com.rabbitmq.client.impl.AMQChannel.quiescingTransmit(AMQChannel.java:316)
at com.rabbitmq.client.impl.AMQChannel.transmit(AMQChannel.java:292)
at com.rabbitmq.client.impl.AMQChannel.transmit(AMQChannel.java:285)
at com.rabbitmq.client.impl.AMQConnection.start(AMQConnection.java:383)
at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:516)
at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:533)
...
I think this generally coincides with the workers taking longer than usual about their business, and thus more temporary client queues concurrently open (about 20-30 perhaps?), however as far as I know I'm not running into any of the usual watermarks (memory, disk - I could be running into some limit I don't know about).
I've reviewed the Rabbit logs and the only kind of errors I find there are:
=ERROR REPORT==== 6-Sep-2013::21:36:59 ===
closing AMQP connection <0.3105.1297> (10.118.69.132:42582 -> 10.12.111.134:5672):
{handshake_timeout,frame_header}
I checked both logs and the first "broken pipe" on the client appeared at 21:37:03, while the first ERROR of any kind in RabbitMQ logs on that date appeared at 21:36:59, with regular errors of the same kind appearing regularly thereafter until the systems were restarted. Thus I believe the ones published are corresponding log entries.
I'm using the Rabbit Java client 3.1.4 (latest on Maven central) with Rabbit server 3.1.4 running on Amazon Linux on AWS EC2.
Here is the rabbitmqctl status under normal situation (unfortunately not during the failure, I will try to get one when it appears next):
Status of node 'rabbit#ip-some-ip' ...
[{pid,2654},
{running_applications,
[{rabbitmq_management,"RabbitMQ Management Console","3.1.4"},
{rabbitmq_management_agent,"RabbitMQ Management Agent","3.1.4"},
{rabbit,"RabbitMQ","3.1.4"},
{os_mon,"CPO CXC 138 46","2.2.7"},
{rabbitmq_web_dispatch,"RabbitMQ Web Dispatcher","3.1.4"},
{webmachine,"webmachine","1.10.3-rmq3.1.4-gite9359c7"},
{mochiweb,"MochiMedia Web Server","2.7.0-rmq3.1.4-git680dba8"},
{xmerl,"XML parser","1.2.10"},
{inets,"INETS CXC 138 49","5.7.1"},
{mnesia,"MNESIA CXC 138 12","4.5"},
{amqp_client,"RabbitMQ AMQP Client","3.1.4"},
{sasl,"SASL CXC 138 11","2.1.10"},
{stdlib,"ERTS CXC 138 10","1.17.5"},
{kernel,"ERTS CXC 138 10","2.14.5"}]},
{os,{unix,linux}},
{erlang_version,
"Erlang R14B04 (erts-5.8.5) [source] [64-bit] [smp:2:2] [rq:2] [async-threads:30] [kernel-poll:true]\n"},
{memory,
[{total,331967824},
{connection_procs,5389784},
{queue_procs,2669016},
{plugins,654768},
{other_proc,10063336},
{mnesia,90352},
{mgmt_db,2706344},
{msg_index,7148168},
{other_ets,3495648},
{binary,1952040},
{code,17696200},
{atom,1567425},
{other_system,278534743}]},
{vm_memory_high_watermark,0.4},
{vm_memory_limit,3126832332},
{disk_free_limit,1000000000},
{disk_free,1487147008},
{file_descriptors,
[{total_limit,349900},
{total_used,71},
{sockets_limit,314908},
{sockets_used,66}]},
{processes,[{limit,1048576},{used,930}]},
{run_queue,0},
{uptime,5680}]
...done.
Any ideas what could be wrong or at least what I can do to debug this / get more clarity on what is happening?

I have changed my code to reuse Connection objects - actually even do that among multiple threads, and it seems the problem is not recurring (fingers crossed).

package com.rm.rabbitmq.tls;
import java.io.*;
import java.security.*;
import javax.net.ssl.*;
import com.rabbitmq.client.*;
public class Example2 {
public static void main(String[] args) throws Exception {
char[] keyPassphrase = "".toCharArray();
KeyStore ks = KeyStore.getInstance("PKCS12");
ks.load(new FileInputStream("/Users/global/Documents/tls-gen/basic/result/client_key.p12"), keyPassphrase);
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(ks, keyPassphrase);
char[] trustPassphrase = "welcome".toCharArray();
KeyStore tks = KeyStore.getInstance("JKS");
tks.load(new FileInputStream("/Users/global/Documents/tls-gen/basic/result/rabbitstore"), trustPassphrase);
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(tks);
SSLContext c = SSLContext.getInstance("TLSv1.3");
c.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
factory.setPort(5671);
factory.useSslProtocol(c);
//factory.enableHostnameVerification();
Connection conn = factory.newConnection();
Channel channel = conn.createChannel();
channel.queueDeclare("rabbitmq-java-test", false, true, true, null);
channel.basicPublish("", "rabbitmq-java-test", null, "Hello, World".getBytes());
GetResponse chResponse = channel.basicGet("rabbitmq-java-test", false);
if (chResponse == null) {
System.out.println("No message retrieved");
} else {
byte[] body = chResponse.getBody();
System.out.println("Received: " + new String(body));
}
channel.close();
conn.close();
}
}

Related

RabbitMQ TLS Authentication

There is a task to configure the operation of some web services using certificate authorization.
There is:
Erlang 22.3.3
RabbitMQ 3.8.3
It makes no sense to describe their installation.
What has been done next:
1. In accordance with the article (https://www.rabbitmq.com/ssl.html) we perform the following actions:
git clone https://github.com/michaelklishin/tls-gen tls-gen
cd tls-gen / basic
CN = client PASSWORD = 123 make
make verify
make info
Copy the created certificates, change the owner
mv testca/ /etc/rabbitmq/
mv server/ /etc/rabbitmq/
mv client/ /etc/rabbitmq/
chown -R rabbitmq: /etc/rabbitmq/testca
chown -R rabbitmq: /etc/rabbitmq/server
chown -R rabbitmq: /etc/rabbitmq/client
We bring the configuration file to the form (/etc/rabbitmq/rabbitmq.config):
[
{ssl, [{versions, ['tlsv1.2', 'tlsv1.1', tlsv1]}]},
{rabbit, [
{ssl_listeners, [5671]},
{auth_mechanisms, ['PLAIN', 'AMQPLAIN', 'EXTERNAL']},
{ssl_cert_login_from, 'client'},
{ssl_options, [{cacertfile, "/ etc / rabbitmq / testca / cacert.pem"},
{certfile, "/ etc / rabbitmq / server / cert.pem"},
{keyfile, "/ etc / rabbitmq / server / key.pem"},
{verify, verify_peer},
{fail_if_no_peer_cert, true}]}]}}
].
We start the server, try to connect from the client. We get the error:
2020-05-18 17: 21: 57.166 +03: 00 [ERR] Failed to connect to broker 10.10.11.16, port 5671, vhost dmz
RabbitMQ.Client.Exceptions.BrokerUnreachableException: None of the specified endpoints were reachable
---> RabbitMQ.Client.Exceptions.PossibleAuthenticationFailureException: Possibly caused by authentication failure
---> RabbitMQ.Client.Exceptions.OperationInterruptedException: The AMQP operation was interrupted: AMQP close-reason, initiated by Library, code = 0, text = 'End of stream', classId = 0, methodId = 0, cause = System .IO.EndOfStreamException: Reached the end of the stream. Possible authentication failure.
at RabbitMQ.Client.Impl.InboundFrame.ReadFrom (Stream reader)
at RabbitMQ.Client.Impl.SocketFrameHandler.ReadFrame ()
at RabbitMQ.Client.Framing.Impl.Connection.MainLoopIteration ()
at RabbitMQ.Client.Framing.Impl.Connection.MainLoop ()
at RabbitMQ.Client.Impl.SimpleBlockingRpcContinuation.GetReply (TimeSpan timeout)
at RabbitMQ.Client.Impl.ModelBase.ConnectionStartOk (IDictionary`2 clientProperties, String mechanism, Byte [] response, String locale)
at RabbitMQ.Client.Framing.Impl.Connection.StartAndTune ()
--- End of inner exception stack trace ---
at RabbitMQ.Client.Framing.Impl.Connection.StartAndTune ()
at RabbitMQ.Client.Framing.Impl.Connection.Open (Boolean insist)
at RabbitMQ.Client.Framing.Impl.Connection..ctor (IConnectionFactory factory, Boolean insist, IFrameHandler frameHandler, String clientProvidedName)
at RabbitMQ.Client.Framing.Impl.ProtocolBase.CreateConnection (IConnectionFactory factory, Boolean insist, IFrameHandler frameHandler, String clientProvidedName)
at RabbitMQ.Client.ConnectionFactory.CreateConnection (IEndpointResolver endpointResolver, String clientProvidedName)
--- End of inner exception stack trace ---
at RabbitMQ.Client.ConnectionFactory.CreateConnection (IEndpointResolver endpointResolver, String clientProvidedName)
at RabbitMQ.Client.ConnectionFactory.CreateConnection (String clientProvidedName)
at EasyNetQ.ConnectionFactoryWrapper.CreateConnection ()
at EasyNetQ.PersistentConnection.TryToConnect ()
In the rabbitmq log:
2020-05-18 17: 24: 59.880 [info] <0.3442.0> accepting AMQP connection <0.3442.0> (10/10/15/14/1561 -> 10/10/11/166767)
2020-05-18 17: 25: 02.887 [error] <0.3442.0> closing AMQP connection <0.3442.0> (10/10/15/14/1561 -> 10/10/11/1667671):
{handshake_error, starting, 0, {error, function_clause, 'connection.start_ok', [{rabbit_ssl, peer_cert_auth_name, [client, << 48,130,3,42,48,130,2,18,160,3,2,1,2,2 , 1,2,48,13,6,9,42,134,72,134,247,13,1,1,11,5,0,48,4,49,49,32,48,30,6,3,85,4,3 12,23,84,76,83,71,101,110,83,101,108,102,83,105,103,110,101,100,116,82,111,111,116,67,65,49,13,48,11,6,3,85,4,7,12,4,36,36,36 , 36.48,30,23,13,50,48,48,53,49,56,49,52,48,49,53,53,90,23,13,51,48,48,53,49 , 54,49,52,48,49,53,53,90,48,34,49,15,48,13,6,3,85,4,3,12,6,99,108,105,101,110,116,49,15,48 , 13,6,3,85,4,10,12,6,99,108,105,101,110,116,48,130,1,34,48,13,6,9,42,134,72,134,247,13,1,1,1,5,0,3,130 1,15,0,48,130,1,10,2,130,1,1,0,183,198,116,156,3,177,131,5,148,11,154,34,99,210,88,115,60,228,180,245,80,212,113,57,181,249,20,5,164,49,72,95,153,116,103,49 , 58,119,15,48,147,107,112,243,105,122,189,44,0,193,114,138,169,250,165,97,188,158,188,95,163,37,30,75,143,21,103,11,131,223,124,96,244,111,210,30,8,175,72,206,162,14,86,63,146,215,179,226,239,48,76,122,150,200,183,82,114,1 73,116,32,224,202,196,129,131,96,34,237,34,144,177,92,200,105,212,0,133,141,118,146,229,140,246,229,137,0,9,27,180,163,233,134,0,187,110,9,126,92,172,105,96,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,1,118,11,11,118,11,118,11,118,11,118,11,118,11,118,11,118,11,118,11,118,11,118,11,118,1,118,11,11,118,11,11,11,11,1,1,1,1,1,1,1,1,1,1,1,1,1,111,1'''1,11,11,1'''1,1''''N''O'', '' 92,181,68,172,135,15,90,152,209,242,31,138,135,34,95,29,162,226,175,253,176,14
UPDATE
New rabbitmq.config:
[
{rabbit,[
{auth_backends, [rabbit_auth_backend_internal]},
{auth_mechanisms, ['PLAIN', 'AMQPLAIN', 'EXTERNAL']},
{ssl_listeners,[5671]},
{ssl_options,[
{versions,['tlsv1.2', 'tlsv1.1']},
{cacertfile, "/etc/rabbitmq/testca/cacert.pem"},
{certfile, "/etc/rabbitmq/server/cert.pem"},
{keyfile, "/etc/rabbitmq/server/key.pem"},
{verify,verify_peer},
{fail_if_no_peer_cert,true}]}
]}
].
New error:
2020-05-18 18:48:56.681 [info] <0.1410.0> Connection <0.1410.0> (10.10.15.14:52744 -> 10.10.11.16:5671) has a client-provided name: Viber.CallbackService.dll
2020-05-18 18:48:56.682 [error] <0.1410.0> Error on AMQP connection <0.1410.0> (10.10.15.14:52744 -> 10.10.11.16:5671, state: starting):
EXTERNAL login refused: user 'O=client,CN=client' - invalid credentials
Have you enabled the ssl plugin and restarted the broker?
sudo rabbitmq-plugins enable rabbitmq_auth_mechanism_ssl
sudo systemctl restart rabbitmq-server
You may also try and set the following in rabbitmq.conf:
ssl_cert_login_from = common_name
ssl_options.password = 123
And create a user called client in the broker to match the CN name in your certificate.

BizTalk receiving from RabbitMQ

I'm new to RabbitMQ but I have now installed onto a Windows server and have a couple of demo console apps (C#) that happily write to a read from a queue.
The following code works to pull messages from a queue called "RabbitPoCQueue_2" on the local server:
string queueName = "RabbitPoCQueue_2";
var factory = new ConnectionFactory();
bool keepGoing = true;
factory.HostName = "127.0.0.1";
try
{
using (var connection = factory.CreateConnection())
using (var channel = connection.CreateModel())
{
const bool durable = false;
channel.QueueDeclare(queueName, durable, false, false, null);
System.Console.WriteLine(" [*] Waiting for messages.");
while (keepGoing)
{
var consumer = new EventingBasicConsumer(channel);
consumer.Received += (model, ea) =>
{
var body = ea.Body;
var message = Encoding.UTF8.GetString(body);
System.Console.WriteLine(" [x] Received {0}", message);
};
channel.BasicConsume(queue: queueName,
autoAck: true,
consumer: consumer);
channel.BasicGet(queue: queueName, autoAck: true);
System.Console.WriteLine("Press Y to continue or any other key to exit");
keepGoing = System.Console.ReadKey().Key == ConsoleKey.Y;
}
}
}
I now need to configure a BizTalk (2016 FP3 CU5) receive location to do the same. I have ensured I've stopped the console receiver and that I have messages sat on the queue for BizTalk to collect.
I followed the article https://social.technet.microsoft.com/wiki/contents/articles/7401.biztalk-server-and-rabbitmq.aspx
Problem is, when I start the receive location, I get no errors but nothing is received.
The config for the WCF receive location can be seen below:
and here:
and here's a pic from the RabbitMQ management console showing messages sat on the queue:
When I look in the RabbitMQ log file, I see 2 rows on starting the receive location. I see 3 rows when starting the .Net console app (using RabbitMQ API), as shown below - first 2 rows are from BizTalk, last 3 from the console app:
2019-08-28 16:17:45.693 [info] <0.13361.2> connection <0.13361.2> ([::1]:16807 -> [::1]:5672): user 'guest' authenticated and granted access to vhost '/' ** Start of Receive location
2019-08-28 16:19:57.958 [info] <0.13452.2> accepting AMQP connection <0.13452.2> (127.0.0.1:17173 -> 127.0.0.1:5672)
2019-08-28 16:19:58.026 [info] <0.13452.2> connection <0.13452.2> (127.0.0.1:17173 -> 127.0.0.1:5672): user 'guest' authenticated and granted access to vhost '/' ** Receive from command line
2019-08-28 18:56:26.267 [info] <0.13452.2> closing AMQP connection <0.13452.2> (127.0.0.1:17173 -> 127.0.0.1:5672, vhost: '/', user: 'guest')
2019-08-28 18:56:39.815 [info] <0.17923.2> accepting AMQP connection <0.17923.2> (127.0.0.1:41103 -> 127.0.0.1:5672)
Can anyone spot where I went wrong?

SSL issue on Android 9 Google Pixel One

I am trying to perform HTTPS requests to a host 10.10.10.1 from Android host with 10.10.10.2 in network without Internet connection - only WiFi 2 peers AP and Android 9 Google Pixel One device.
I've created network_security_config.xml with my cert that is self-signed and has CN=10.10.10.1 and SAN= DNS: 10.10.10.1 PI: 10.10.10.1.
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<certificates src="system" />
<certificates src="user" />
<certificates src="#raw/zone"/>
</trust-anchors>
</base-config>
</network-security-config>
I don't receive verification error and observe successful requests incoming to server - data are HTTP request, decrypted and shown on the server log. But the server can't send data back! It sends, but for some reason these data are not being accepted by the Android phone - just ignored.
I see packets are going from the server to the phone and the server repeatedly retries to shutdown SSL socket until error or success (I made such behavior intentionally during surveying) - here is Wireshark dump from WiFi air:
Here is my request from AsyncTask
protected String doInBackground(String... params) {
StringBuilder result = new StringBuilder();
try {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream caInput = new BufferedInputStream(MainActivity.this.getResources().openRawResource(R.raw.zone));
Certificate ca = cf.generateCertificate(caInput);
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(null, tmf.getTrustManagers(), null);
URL url = new URL("https://10.10.10.1/connect");
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setSSLSocketFactory(ctx.getSocketFactory());
conn.setRequestProperty("param1", params[0]);
conn.setRequestProperty("param2", params[1]);
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setDoInput(true);
mInputStream = conn.getInputStream();
byte[] buffer = new byte[1024];
ByteArrayOutputStream _buf = new ByteArrayOutputStream();
int l;
BufferedInputStream bufin = new BufferedInputStream(mInputStream);
while ((l = bufin.read(buffer,0,1024)) != -1) {
_buf.write(buffer, 0, l);
String rec = _buf.toString("UTF-8");
Log.d("MAIN", "Read: " + rec);
result.append(rec);
}
Log.d("MAIN", "Read finished: " + result.toString());
} catch (Exception e) {
e.printStackTrace();
}
return result.toString();
}
I suspect that Android 9 Network Security does block traffic somehow. I tried to use SSLSockets, change port from 443 to e.g. 1234 - no luck.
In fact my app is being created with Qt and firstly I used Qt stuff, but having no luck - I made fallback to Android Java code within my MainActivity, that I call via JNI from Qt code. Result is the same and I have no ideas more...
Where to dig?
UPD1
When the self-signed certificate is generated with SAN containing DNS:10.10.10.1 only (without IP:10.10.10.1) SSL fails with warnings:
W System.err: javax.net.ssl.SSLPeerUnverifiedException: Hostname 10.10.10.1 not verified:
W System.err: certificate: sha1/gyr2GOhy5lA+ZAHEzh0E2SBEgx0=
W System.err: DN: CN=10.10.10.1,O=Some ltd.,L=Knoxville,ST=TN,C=US
W System.err: subjectAltNames: [10.10.10.1]
W System.err: at com.android.okhttp.internal.io.RealConnection.connectTls(RealConnection.java:201)
W System.err: at com.android.okhttp.internal.io.RealConnection.connectSocket(RealConnection.java:149)
W ...
And conversely, with SAN IP:10.10.10.1 (without DNS: 10.10.10.1) - works as before - session established, data transferred to server and decrypted, but responses from server to client just ignored by client.
UPD2
I've also tried to use domain name some.device for the 10.10.10.1 device and issued certificate with CN and SAN DNS = some.device. It's resolved by Android 9 client, data is being sent successfully but response is still not being accepting.
Looks like Android bug.
After making additional surveying:
1. Some set of Android devices (builds), including Pixel 1, does not accept TCP session that was not finalized by mutual [FIN,ACK] and received data is not delivered to upper level of stack. Also data may not be accepted if TCP stream was not solid, with many retransmissions and Seq changing.
2. In case of using Qt - Android Network Security Configuration does not affect on communications.
3. This is not TLS related issue.

Specifying an outbound SSL configuration programmatically using JSSEHelper on Websphere 8.0. does not work

I am trying to create an SSL connection programmatically using a CUSTOM outbound ssl configuration configured in WAS 8.0.0.13 (IBM Websphere application server that uses java 1.6.0):
(Security->SSL certificate and key managemement->Related Items:SSL configurations).
The secure connection has been created successfully:a servlet that resides on the WAS server has connected to a server-side Socket listening on 127.0.0.1:1234.
The problem is that my preferred cipher suites defined in 'Quality of Protection (QoP) settings' within SSL configuration are ignored.
All the other properties (such as protocol or JSSE provider) are nicely regarded.
I have implemented a Servlet which was in the role of an SSL-client.
This Servlet used this custom SSL configuration which had the following cipher suites defined:
SSL_RSA_WITH_AES_128_CBC_SHA
SSL_DHE_RSA_WITH_AES_128_CBC_SHA
SSL_DHE_DSS_WITH_AES_128_CBC_
SHA SSL_RSA_WITH_AES_128_GCM_SHA256
SSL_RSA_WITH_AES_128_CBC_SHA256
SSL_DHE_RSA_WITH_AES_128_GCM_SHA256
SSL_DHE_RSA_WITH_AES_128_CBC_SHA256
SSL_DHE_DSS_WITH_AES_128_GCM_SHA256
SSL_DHE_DSS_WITH_AES_128_CBC_SHA256
Unfortunately, a different list of cipher suites has been provided in ClientHello request:
SSL_RSA_WITH_AES_128_CBC_SHA
SSL_DHE_RSA_WITH_AES_128_CBC_SHA
SSL_DHE_DSS_WITH_AES_128_CBC_SHA
SSL_RSA_WITH_3DES_EDE_CBC_SHA
SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA
SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA
SSL_RSA_WITH_DES_CBC_SHA
SSL_DHE_RSA_WITH_DES_CBC_SHA
SSL_DHE_DSS_WITH_DES_CBC_SHA
SSL_RENEGO_PROTECTION_REQUEST
(This custom SSL configuration contained TLSv1.1 protocol in its definition.)
I have also tried another protocol (TLSv1.2) with a smaller set of cipher suites:
SSL_RSA_WITH_AES_128_CBC_SHA
SSL_DHE_RSA_WITH_AES_128_CBC_SHA
SSL_DHE_DSS_WITH_AES_128_CBC_SHA
SSL_DHE_DSS_WITH_AES_128_CBC_SHA256
Once again, a different list of cipher suites was provided in ClientHello request:
SSL_RSA_WITH_AES_128_CBC_SHA
SSL_DHE_RSA_WITH_AES_128_CBC_SHA
SSL_DHE_DSS_WITH_AES_128_CBC_SHA
SSL_RSA_WITH_3DES_EDE_CBC_SHA
SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA
Moreover, I have also checked cell-default cipher suites and node-default-cipher-suites and there is no
match between them and those provided in the ClientHello:
Default Node Configuration/Default Cell Configuration:
SSL_RSA_WITH_AES_128_CBC_SHA
SSL_DHE_RSA_WITH_AES_128_CBC_SHA
SSL_DHE_DSS_WITH_AES_128_CBC_SHA
SSL_RSA_WITH_AES_128_GCM_SHA256
SSL_RSA_WITH_AES_128_CBC_SHA256
SSL_DHE_RSA_WITH_AES_128_GCM_SHA256
SSL_DHE_RSA_WITH_AES_128_CBC_SHA256
SSL_DHE_DSS_WITH_AES_128_GCM_SHA256
SSL_DHE_DSS_WITH_AES_128_CBC_SHA256
I have followed these instructions:
https://www.ibm.com/support/knowledgecenter/en/SSAW57_8.0.0/com.ibm.websphere.nd.doc/info/ae/ae/tsec_ssloutconfiguseJSSE.html
and have created the following implementation. 'doGet' method is an entry point:
public class TLSv1_1 extends HttpServlet {
private static final long serialVersionUID = 1L;
com.ibm.websphere.ssl.JSSEHelper jsseHelper;
public TLSv1_1() {
super();
jsseHelper = com.ibm.websphere.ssl.JSSEHelper.getInstance();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
Properties existing_sslProps = null;
try {
String existingAlias = "TLSv1.1";
existing_sslProps = jsseHelper.getProperties(existingAlias);
} catch (com.ibm.websphere.ssl.SSLException e) {
e.printStackTrace();
}
printSSLproperties(response, existing_sslProps);
SSLSocket socket = getSslSocket(existing_sslProps);
writeToSocket(socket, 1234);
}
public static void printSSLproperties(HttpServletResponse response, Properties sslProps) throws IOException {
if (sslProps != null) {
StringBuilder sb = new StringBuilder();
Set set = sslProps.entrySet();
Iterator it = set.iterator();
while (it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
Object value = entry.getValue();
sb.append("key: " + entry.getKey() + ", value: " + value + "\n");
}
System.out.println("sslProps: -----------\n" + sb.toString());
} else {
System.out.println("sslProps == null");
response.getWriter().append("sslProps == null");
}
}
public SSLSocket getSslSocket(Properties sslProps) {
Map<String, Object> sslMap = new HashMap<String, Object>();
sslMap.put("com.ibm.ssl.direction", "outbound");
sslMap.put("com.ibm.ssl.remoteHost", "127.0.0.1");
sslMap.put("com.ibm.ssl.remotePort", "1234");
sslMap.put("com.ibm.ssl.endPointName", "HTTP");
SSLSocketFactory sslSocketFactory = null;
try {
sslSocketFactory = jsseHelper.getSSLSocketFactory(sslMap, sslProps);
} catch (SSLException e) {
e.printStackTrace();
}
SSLSocket socket = null;
try {
socket = (SSLSocket) sslSocketFactory.createSocket();
} catch (IOException e) {
e.printStackTrace();
}
return socket;
}
public static void writeToSocket(Socket socket, int port) throws IOException, UnknownHostException {
InetAddress address = InetAddress.getByName("127.0.0.1");
socket.connect(new InetSocketAddress(address, port));
BufferedWriter stream = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
for (int i = 0; i < 3; i++) {
String lineX = UUID.randomUUID().toString();
stream.write(lineX);
stream.newLine();
stream.flush();
System.out.println("NEW LINE SUCCESSFULLY WRITTEN INTO SOCKET:" + lineX);
sleep();
}
}
private static void sleep() {
try {
Thread.sleep(1000 * 30);
} catch (InterruptedException e) {
}
}
}
The presence of the hash map sslMap seems to be of no importance.
It does not matter whether is set to null or contains no values.
I have also tried to enforce ssl properties on thread (this one has the highest preference among all the others):
This approach also dodn't worked:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String existingAlias = "TLSv1.1";
existing_sslProps = jsseHelper.getProperties(existingAlias);
jsseHelper.setSSLPropertiesOnThread(existing_sslProps);
CommonIO.printSSLproperties(response, existing_sslProps);
SSLSocket socket = getSslSocket(existing_sslProps);
CommonIO.writeToSocket(socket, 1234);
jsseHelper.setSSLPropertiesOnThread(null);
}
Finally, I have tried not to bind to any SSL configuration present in WAS server SSL configs, but only wire up a custom configuration with my java code:
sslProps.setProperty("com.ibm.ssl.protocol", "TLSv1.1");
sslProps.setProperty("com.ibm.ssl.enabledCipherSuites",
"SSL_DHE_DSS_WITH_AES_128_CBC_SHA SSL_DHE_DSS_WITH_AES_128_GCM_SHA256 SSL_DHE_DSS_WITH_AES_128_CBC_SHA256");
sslProps.setProperty("com.ibm.ssl.trustStore",
"/opt/IBM/Websphere/profiles/AppSrv01/config/cells/localhostCell01/nodes/localhostNode01/trust.p12");
sslProps.setProperty("com.ibm.ssl.trustStorePassword", "***");
sslProps.setProperty("com.ibm.ssl.trustStoreType", "PKCS12");
sslProps.setProperty("com.ibm.ssl.keyStore",
"/opt/IBM/Websphere/profiles/AppSrv01/config/cells/localhostCell01/key.p12");
sslProps.setProperty("com.ibm.ssl.keyStorePassword", "***");
sslProps.setProperty("com.ibm.ssl.keyStoreType", "PKCS12");
sslProps.setProperty("security.provider.1", "com.ibm.jsse2.IBMJSSEProvider2");
sslProps.setProperty("ssl.SocketFactory.provider", "com.ibm.jsse2.SSLSocketFactoryImpl");
But this approach also did not work.
Could you please help me? I suppose I missed something principal or custom SSL configuration does not exist in this product.
So due to my not looking at your code carefully initially. I see the problem. Because you get the Socket factory directly from the JSSEHelper, we are not getting the chance to put the ciphers on the socket.
In your case you should follow the WAS's programmatic SSL methods. Get the properties and put them on the thread. eg
try {
String existingAlias = "TLSv1.1";
existing_sslProps = jsseHelper.getProperties(existingAlias);
jsseHelper.setSSLPropertiesOnThread(existing_sslProps);
} catch (com.ibm.websphere.ssl.SSLException e) {
e.printStackTrace();
}
The later don't get the Socket factory from the JSSE, get the default. So in getSslSocket() do something like:
public SSLSocket getSslSocket(Properties sslProps) {
SSLSocketFactory factory = SSLSocketFactory.getDefault();
SSLSocket socket = null;
try {
socket = (SSLSocket) factory.createSocket();
} catch (IOException e) {
e.printStackTrace();
}
return socket;
}
This will get you a WAS socket factory. The create socket call should return you a socket with the ciphers set on the SSLSocket. When you are done you should clear the properties off the thread.
jsseHelper.setSSLPropertiesOnThread(null);
thank you for your tips! I followed these instructions:
https://www-01.ibm.com/support/docview.wss?uid=swg21162961
to increase log/trace level based on your tips.
If I had to make some other configuration changes, please let me know.
I gathered log files only from these subdirectories:
../logs/server1
../logs/nodeagent
../logs/ffdc
and placed them into ALL_LOGS/logs directory within these files:
https://drive.google.com/open?id=18TMYyjKx8L_pd8TxFG1uq1rOmikVyWeg
, so if there are also other log/trace files in different locations, please let me know.
(Only Delta is present in these files since I cleared all the log/trace files
before starting the server and retesting my scenario.)
I found only this in ffdc logs:
The client and server could not negotiate the desired level of security.Reason: Received fatal alert: handshake_failure vmcid: 0x49421000 minor code: 70 completed: No
I am not sure whether is the root cause of my problem, but no google results seemed to be relevant to my problem.
As far as google results are concerned, I meant these:
https://www.ibm.com/developerworks/community/forums/html/topic?id=a2910c33-8f55-4ef7-823d-7ae367682e35
http://www.dsxchange.com/viewtopic.php?t=134492&sid=f6e236a4f14a9d80fc51c0820e5f7ce7
None of them was helpful...
Along with logs-subdirectories, I am also attaching server-side socket stdout with stderr in TLSv1.1_enforce_OnThread.log.
Additionally, I am also attaching client-side configuration CONFIG_TLSv1.1._ENFORSE_SSL_ON_THREAD.png
Could you please check these log files?
Thank you honestly very much.
--
Michael
I'm looking at an error involving the use of a SSL configuration named "TLSv1.1". 2 of the 3 ciphers you have configured are not supported by TLSv1.1, you can find more info about cipher supported by IBM java 6 here https://www.ibm.com/support/knowledgecenter/es/SSYKE2_6.0.0/com.ibm.java.security.component.60.doc/security-component/jsse2Docs/ciphersuites.html?view=embed.
This is leaving you with one cipher, SSL_DHE_DSS_WITH_AES_128_CBC_SHA.
[12/17/17 6:16:19:524 EST] 00000000 SystemOut O Ignoring unsupported cipher suite: SSL_DHE_DSS_WITH_AES_128_GCM_SHA256
[12/17/17 6:16:19:524 EST] 00000000 SystemOut O Ignoring unsupported cipher suite: SSL_DHE_DSS_WITH_AES_128_CBC_SHA256
[12/17/17 6:16:19:527 EST] 00000000 SystemOut O %% No cached client session
[12/17/17 6:16:19:528 EST] 00000000 SystemOut O *** ClientHello, TLSv1.1
[12/17/17 6:16:19:528 EST] 00000000 SystemOut O RandomCookie: GMT: 1513509379 bytes = { 108, 16, 192, 144, 124, 116, 226, 48, 69, 61, 93, 187, 104, 67, 120, 166, 233, 194, 67, 244, 136, 159, 105, 130, 106, 175, 18, 251 }
[12/17/17 6:16:19:529 EST] 00000000 SystemOut O Session ID: {}
[12/17/17 6:16:19:529 EST] 00000000 SystemOut O Cipher Suites: [SSL_DHE_DSS_WITH_AES_128_CBC_SHA, SSL_RENEGO_PROTECTION_REQUEST]
This connection is going to port 9202 on the same host, 127.0.0.1. And ultimately ends in a error, javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure. I think your server is trying to talk to your nodeagent with the wrong SSL configuration. It seems to pick that configuration up from the dynamic outbound selection filter.
[12/17/17 6:16:19:440 EST] 00000000 SSLConfigMana 3 SSLConfig dynamic selection info: *,127.0.0.1,*
[12/17/17 6:16:19:440 EST] 00000000 SSLConfigMana 3 Parsing entry 0 of 1: *,127.0.0.1,*
[12/17/17 6:16:19:440 EST] 00000000 SSLConfigMana 3 This entry has 3 attributes.
[12/17/17 6:16:19:440 EST] 00000000 SSLConfigMana 3 Protocol: *, Host: 127.0.0.1, Port: *
[12/17/17 6:16:19:440 EST] 00000000 SSLConfigMana 3 Found a dynamic selection match!
[12/17/17 6:16:19:440 EST] 00000000 SSLConfigMana < getPropertiesFromDynamicSelectionInfo -> found. Exit
Your filter will match anything going to the 127.0.0.1, to use the SSL configuration called "TLSv1.1". What ever this connection is going to seems to be using TLSv1 protocol. So the connection fails because of protocol mismatch. It seems this SSL configuration is not intended to be used accessing 127.0.0.1 and port 9202. Could that be your local node agent or dmgr port? If so the connection needs to the the NodeDefaultSSLSettings.
It's not obvious to me in the trace what connection is talking to your server, localhost and port 1234. Perhaps if you fix your configuration so that the node will use the correct SSL configuration when going to port 9202 and 127.0.0.1 it may be easier to figure out.
thank you for your great support & swift reply!
based on your inputs, I removed all the dynamic outbound rules present in SSL configuration settings.
I have also modified the list of supported cipher suites
on WAS-side (client side) based on your great link you have provided!:-).
More precisely, I opted for only these suites
because they are supported by all TLS protocols (TLSv1.0,TLSv1.1, TLSv1.2):
SSL_RSA_WITH_AES_128_CBC_SHA
SSL_RSA_WITH_3DES_EDE_CBC_SHA
SSL_DHE_RSA_WITH_AES_128_CBC_SHA
SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA
SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA
Once again, I cleared all log files and then started application server.
After retesting my scenario, this delta in log-files has been generated:
https://drive.google.com/open?id=19KaDlsx2UVS_YfByaORQOf89mLlJke4e
Server side application that listens on 1234 port supports the same
cipher suites:
SSL_RSA_WITH_AES_128_CBC_SHA
SSL_RSA_WITH_3DES_EDE_CBC_SHA
SSL_DHE_RSA_WITH_AES_128_CBC_SHA
SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA
SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA
Of course, I didn't expect the issue will be resolved after these changes
but I expected that I find some errors in logs/traces to reduce the load imposed on you. Unfortunately, I wasn't successful. Could you please check these logs/traces? Thank you honestly very much!
(Please ignore this exception:
FFDC Exception:java.net.MalformedURLException SourceId:class com.ibm.wkplc.extensionregistry.PluginDescriptor.initFromDom ProbeId:1
present in server1_b7f67871_17.12.19_04.44.51.8551967663872103714940.txt file,
since I retested it once again (for the 3rd time) and this exception haven't been present after the 3rd re-test.)

RabbitMQ STOMP connection

I am working on a fun project which requires me to learn message queues and websockets. I am trying to connect browsers via websockets to an instance of rabbitmq using sockjs rather than pure websockets. On rabbit I have activated the plugins for stomp and web_stomp (web_stomp is required when using sockjs).
The problem I am running into is that while the call from the browser seems to be working properly because a very brief connection to Rabbit is made through the webstomp/stomp connection but after 2 or 3 seconds the connection is dropped by Rabbit.
This is confirmed by the rabbitmq logs:
=INFO REPORT==== 11-Jul-2016::23:01:54 ===
accepting STOMP connection (192.168.1.10:49746 -> 192.168.1.100:55674)
=INFO REPORT==== 11-Jul-2016::23:02:02 ===
closing STOMP connection (192.168.1.10:49746 -> 192.168.1.100:55674)
This is the browser code that connects to RabbitMQ via the webstomp plugin:
var url = "http://192.168.1.100:55674/stomp";
var ws = new SockJS(url);
var client = Stomp.over(ws);
var header = {
login: 'test',
passcode: 'test'
};
client.connect(header,
function(){
console.log('Hooray! Connected');
},
function(error){
console.log('Error connecting to WS via stomp:' + JSON.stringify(error));
}
);
Here is the Rabbit config:
[
{rabbitmq_stomp, [{default_user, [{login, "test"},
{passcode, "test"}
]
},
{tcp_listeners, [{"192.168.1.100", 55674}]},
{heartbeat, 0}
]
}
]
I have been over the Rabbit docs a million times but this feels like something simple that I am overlooking.
Resolved. After combing through the logs I realized that web_stomp was listening on port 15674 so I changed the config file to reflect that. I swear I had made that change at some point but it did not seem to make a difference.
One of the late changes I made before sending out my request was to turn off heartbeat. Everything I have read states that sockjs does not support heartbeat and that there were suggestions to turn it off rather than use the default. In addition to turning off heartbeat in the config file I also added this to the browser code:
client.heartbeat.outgoing=0;
client.heartbeat.incoming=0;