I am trying to send and receive from a remote queue. I can get the send to work (I see the message in the queue), however, when I try to receive I get an access denied error. My computer is on a different domain than the remote queue's computer, so I'm pretty sure this has something to do with the issue. Here is the code snippet:
MessageQueue queue = new MessageQueue(#"FormatName:DIRECT=OS:DEVAPP002\private$\queuetest");
queue.Send("This is a test");
Message msg = queue.Receive(); // Kaboom
To test if permissions are your problem, check that the Anonymous User has read/write access to the queue.
The Everyone user means everyone logged in the domain, at least with respect to the queuing service.
Related
I have private queue created with Anonymous, Everyone, NetworkService full control on a server which is in workgroup mode. I can send a message using .net stub without any issue where as it throws exception while receiving the message. I tried to read the message using
Message.Receive() and Message.ReceiveByID() both throws exception. I tried to add the registry key as told in below link but it did not work
https://blogs.msdn.microsoft.com/johnbreakwell/2007/01/15/msmq-3-0-too-secure-for-you/
MessageQueue messageQueue = new MessageQueue(queueFormatPath);
var message = messageQueue.Receive();
MyMessageQueue.ReceiveById(e.Message.Id);
exception:
You're performing RPC communication so there are several areas to check, in addition to the one you've already found.
https://blogs.msdn.microsoft.com/johnbreakwell/2010/03/24/understanding-how-msmq-security-blocks-rpc-traffic/
https://blogs.msdn.microsoft.com/johnbreakwell/2009/05/17/failing-to-read-from-remote-msmq-queues/
https://blogs.msdn.microsoft.com/johnbreakwell/2008/07/10/getting-msmq-messages-out-of-windows-server-2008-remotely/
I have 3 machines, let's call them A, B (both servers) and Dev (my local machine).
I want to send a message queue item from A to B.
The actual C# code I have is rather simple and honestly, I really do not think it is problem here. (It's a webapi that takes a POSTed object and just shoves it down the queue).
I can send these messages just fine from Dev to B (while logged into a domain admin account) without a problem and I can inspect the body of the messages. However I cannot send messages from A to B. The private queue on B is set to allow "Everyone" the "Full Control" permissions.
If I pause the outbound queue on A and send the messages, they sit in the outbound queue and the body is exactly as I would expect it to be, but when I resume that outbound queue again, they are never received on the other end at B.
I can't figure out what's going on for the life of me. I tried the 'TCP' method but I need to refer to my queues by machine name not IP.
For reference, the code used to send the message is:
using (var queue = new MessageQueue($"FormatName:Direct=OS:MachineB\\private$\\Queue"))
{
var queueItem = new QueueItem();
queueItem.Object = this.postedObject;
var message = new System.Messaging.Message(queueItem);
queue.Send(message);
}
For reference and anyone else who comes across this:
The project sending the messages to the queue was a webapi. It was running under the AppPoolIdentity account in IIS and despite the receiving queue allowing Everyone access, it was denying these messages, but gracefully. So the webapi would fire the message and wouldn't throw any exceptions, it'd hit the outbound, but then never arrive.
We switched the account to NetworkService and it worked just fine.
So...this one's got me baffled.
The target queue lives on ServerA where MSMQ is running in Workgroup mode. The queue is a non-transactional, private queue, with Full rights on pretty much the world (including NETWORK SERVICE, but EXCLUDING ANONYMOUS LOGON).
I'm specifying the queue address as such: FormatName:DIRECT=OS:ServerA\private$\targetqueue.
If I'm interested in sending "fire-and-forget"-style (no need for transaction as there is no other persistence going on), I would assume it would be fine to simply call:
Message message = ConstructMessageWithObjectPayload(serializableObject);
using (MessageQueue queue = new MessageQueue(queueAddress))
{
queue.Send(message);
}
But strangely, the message never arrives in the target queue and enabling negative source journaling (which interestingly enough causes the message to be sent to the Dead-letter messages queue on the target server) tells me that it is a "Nontransactional message".
Consequently, using
queue.Send(message, MessageQueueTransactionType.Single);
works! Having a hard time wrapping my head around this. What am I missing?
Also, I've seen a good number of posts by others where their similar problem was solved by giving ANONYMOUS LOGIN Full rights. In what scenario is this necessary? Giving NETWORK SERVICE access somewhat made sense because that is the account that MSMQ itself runs under. If running in Workgroup mode like I am, is it necessary at all to assign rights to Everyone or even the account that my process runs under?
Appreciate the help!
I have the following setup and problem with MSMQ. Based on previous experience with MSMQ I'm betting that it is something simple I'm missing but I just don't know what it is.
The Setup
I have 3 load-balanced web servers (lets call them Servers W1, W2 and W3) and 1 server which processes certain events/data away from web requests (which I'll call P). All 3 of the web servers, once a particular event occurs within the web application, will send a message to a remote private queue on Server P, which will then process each message from the queue and carry out some task.
The Problem
For the most part - at a guess 95% of the time - everything runs fine, but occasionally Server P does not receive messages from the web servers. This is either because W1, W2 or W3 are not sending them or they are not being received by P, I just can't tell. This means I'm missing vital events happening from the users on the web application but I cannot find any errors listed in my own logs.
The Details
Here are all the details I can think of which may help explain my setup and what I've figured out so far:
The private queue on Server P is non-transactional.
The private queue has permissions setup for Everyone to both Send and Receive Messages.
This is the code I use (C#) to send the message to the remote private queue:
var queue = new MessageQueue(#"FormatName:DIRECT=OS:ServerP\PRIVATE$\MyMessageQueue");
var defaultProperties = queue.DefaultPropertiesToSend;
defaultProperties.AcknowledgeType = AcknowledgeTypes.FullReachQueue | AcknowledgeTypes.FullReceive;
defaultProperties.Recoverable = true;
defaultProperties.UseDeadLetterQueue = true;
defaultProperties.UseJournalQueue = true;
queue.Send(requestData);
Sending the message using the code above does not appear to throw an exception - if it did my error handler in the web application would have caught and logged it, so I'm assuming it is sent.
There are outgoing queues on W1, W2 and W3 all pointing to the private queue on P - all these are empty.
On W1, W2 and W3 I cannot see any "dead-letter" messages.
On P the private queue is empty so messages are being processed (which I can verify from my database).
On P there are no "dead-letter" messages. There are journal messages but they don't seem to correspond to any recent date/times.
All servers are running Windows Server 2012.
Most of the time messages are sent, received and processed just fine but, without any pattern visible to me, sometimes they are not. Can anyone see what is going wrong? Or explain to me how I can try and figure out what is happening?
Are you sure that the receiver on P does not crash/lose the message somehow? Because your queue is not transactional, if somehow processing fails then that's one lost message.
Anyway, there are many possible causes why this could fail.
What kind of logging do you have (DEBUG/INFO levels)?
I think the following will help tracking down the issue:
When an event is generated in the web app.
Right before you send an event from the web app, via MSMQ.
In the receiver when you get a message from the queue.
This way you could at least match sent messages to received messages and to processed messages.
As a side note, when you check for dead-letter messages you do so on the source computer and on any intermediary hops, not on the destination one. If you don't have any hops, then they will be relayed to the non-transactional dead-letter queue on the web servers.
I have a private queue on a remote machine that everyone and the anonymous login have full access to. The following code produces and error when trying to receive:
var qpath = #"FormatName:DIRECT=TCP:xx.xx.xx.xx\PRIVATE$\QueueName";
var q = new MessageQueue(qpath);
var msg = new Message();
msg.AttachSenderId = false;
msg.Recoverable = true;
msg.Body = "hello";
q.Send(msg); // <-- this works!
var recMsg = q.Receive(TimeSpan.Zero); // <-- this breaks! :|
The Error message is: Message Queue service is not available.
The sent message are ending up in the queue on the remote machine
The same happens when using OS:MachineName instead of TCP:xx.xx.xx.xx
The queue server is not part of the domain.
Any ideas?
If the remote machine is part of a different domain then:
MSMQ 3.0 applications running on cross-forest computers running a member of the family in non-trusted domains will use the secured remote read API. By default, the MSMQ 3.0 server hosting the queue containing the message to be read requires other domain computers making read requests to establish an encrypted channel, but such a channel cannot be established between non-trusted domains. Thus, remote read requests from cross-forest computers will be rejected. To modify this default behavior and allow the Message Queuing server to accept requests from domain computers that do not establish an encrypted channel, add the
HKLM\SOFTWARE\Microsoft
\MSMQ\Parameters\Security\NewRemoteReadServerAllowNoneSecurityClient
registry entry (a DWORD) and set it to 1.
This is form: Reading Messages from Remote Queues.