No, they don't have to tell you.
I'm pretty sure lying, by definition, is unethical (with the possible exception of some moral grey areas) (although maybe I'm confusing ethics and morality). But whether it's unethical or not doesn't really change whether they will or have to tell you.
Unsolicited contact from recruiters is unfortunately part of professional life for many. If the request isn't specifically directly towards you, and you're not interested, you could consider just ignoring them - such e-mails are probably sent in bulk, so they're not going to care much / notice if you don't reply.
You're presumably not connected to them (on LinkedIn) directly, but any of your contacts, or really anyone you know, could provide them with these details. Most of the unsolicited contact I get from recruiters involve them asking me if I know of anyone else who might be interested, which I always just respond "no" to, but possibly some people you know provided some of your details here.
It could be publicly available somewhere. Open a private browsing tab (Ctrl-Shift-P in IE, Ctrl-Shift-N in Chrome) look for yourself and see if you can find it.
Side note - I'm pretty sure LinkedIn doesn't make your email address available to anyone but your (possibly 1st degree) contacts (which is presumably optional as well). But you can hover over the icon in the top-right, go to Privacy & Settings, and look for the applicable setting there.
Or you could attribute it to recruiters providing these details to each other. If you've ever provided access to these details to a recruiter, this is possible.
One way to address this is the unique address idea (possibly a bit late now though) - provide a unique address each time you provide an address and then you can instantly know where your contact details originated from (you may not know where they got it, and it doesn't help you stop it, and it might not work if they just BCC you (TBC), and, depending how you do it, they can just modify the address if they know and care, but it might be better than nothing). With Gmail, I believe you could just add +
followed by anything to your email address and you'll still get the mail sent there, for example, if your address is [email protected]
, you'll also get mail sent to [email protected]
.