Raw sockets need root priviliege - security

Why do we need root privileges when we use raw sockets ?

It's because you can spoof custom packets, which may interfere with inbound traffic. This too is also bad.

In short raw sockets is restricted to root because if it otherwise it would break other rules for networking that are in place.
A long standing rule is that you cannot bind on a port lower than 1024 without root's blessing. With raw sockets you can simulate a server on any port. (naturally being able to receive on this port is a different story you'd also have to sniff the network, but perhaps this could be done with a different machine.)

Opening a raw socket allows to read anything that is received in a given interface, so, basically, you can read any packet that is directed to any application - even if that application is owned by another user. That basically means that the user with this capability is able to read any and all communications of all users.

Related

Sending zeroMQ messages to/from localhost - secure?

I am trying to use zeroMQ for communicating between 2 processes. The message contains instructions from one process for the second to execute, so that from a security perspective it is quite important that only the proper messages are sent and received.
If I am worried about 3rd parties who may try to intercept or send malicious messages to the process, am I correct in assuming that as long as my messages are sent/received on IP 127.0.0.1 i am always safe? or is there any circumstance where this can be compromised?
Thanks for the help all!
Assumptions and security are usually two things you don't want to mix. The short answer to your question is that sending or receiving traffic to localhost (127.0.0.1) will not, under default conditions, send or receive traffic outside of the local host.
Of course if the machine itself is compromised then you are no longer secure at all.
You've applied the ipc tag, which I assume means that you're using the ipc:// protocol (if not, you should be if all of the communication is happening on one box). In this case, you shouldn't be using IPv4 addresses at all (or localhost), but ipc endpoint names. See here and here.
For ipc, you're not connecting or binding to an IP or DNS address, but something much more akin to a local file name. You just need to make sure both processes refer to the same filename, and that permissions are set so that both processes can appropriately access the directory (see the ZMQ docs for a little more info there, search for ipc). The only difference between an ipc endpoint name and a filename is that you don't need to create the file, ZMQ creates the resource so both processes can communicate with the same thing.
As S.Richmond says, if your machine is compromised, then all bets are off, but there's no way to publish ipc endpoints to the internet if you use them appropriately.

When using socket locally where the data go through?

Say the system is linux, I use TPC/IP protocol. When I send data to 127.0.0.1:1024 from A process, then B process get all the data.
How does the system handle these local data traffics?
Does the data go through the network interface card from A to B?
Or they are only manipulated in the memory (much faster than network interface card)?
It'll not be processed by your network card as 127.0.0.1 address is not set on any (it's on loopback device) but it'll go through whole ip stack. Benefits are that you can manipulate this traffic with iptables or iproute tools and whatever you made that way will be ready to work between remote hosts.
If you care more about performance and use only local communiaction consider AF_UNIX socket. You can find more in man socket and man unix.
Check man ipc as well.

Send binary data as HTTP and pass firewall

My game communicates with server through 4567 port using TCP custom binary protocol and some clients cannot play game. I think that is because of firewalls.
Later I will use 80 port and want to know: does firewall intruse into transmitting data and is there possibility that he will block non-HTTP data? If it is, how can I send my binary data within HTTP and will not firewall block even such data?
Thank you.
Depends whether you want to ACCEPT INCOMING connections or just want to use port 80 for OUTGOING connections. Most Firewalls block any incoming connections by default (plus most home-routers are configured to do so, too).
For outgoing connections, however, the default behavior of the most popular Firewalls is to block and ask the user for permission for the program, unless it is run with administrative privileges (in which case the user already had to grant the program almost full control over the computer anyway). But it depends on the Firewall in question.

Is there a way to test if a computer's connection is firewalled?

I'm writing a piece of P2P software, which requires a direct connection to the Internet. It is decentralized, so there is no always-on server that it can contact with a request for the server to attempt to connect back to it in order to observe if the connection attempt arrives.
Is there a way to test the connection for firewall status?
I'm thinking in my dream land where wishes were horses, there would be some sort of 3rd-party, public, already existent servers to whom I could send some sort of simple command, and they would send a special ping back. Then I could simply listen to see if that arrives and know whether I'm behind a firewall.
Even if such a thing does not exist, are there any alternative routes available?
Nantucket - does your service listen on UDP or TCP?
For UDP - what you are sort of describing is something the STUN protocol was designed for. It matches your definition of "some sort of simple command, and they would send a special ping back"
STUN is a very "ping like" (UDP) protocol for a server to echo back to a client what IP and port it sees the client as. The client can then use the response from the server and compare the result with what it thinks its locally enumerated IP address is. If the server's response matches the locally enumerated IP address, the client host can self determinte that it is directly connected to the Internet. Otherwise, the client must assume it is behind a NAT - but for the majority of routers, you have just created a port mapping that can be used for other P2P connection scenarios.
Further, you can you use the RESPONSE-PORT attribute in the STUN binding request for the server to respond back to a different port. This will effectively allow you to detect if you are firewalled or not.
TCP - this gets a little tricky. STUN can partially be used to determine if you are behind a NAT. Or simply making an http request to whatismyip.com and parsing the result to see if there's a NAT. But it gets tricky, as there's no service on the internet that I know of that will test a TCP connection back to you.
With all the above in mind, the vast majority of broadband users are likely behind a NAT that also acts as a firewall. Either given by their ISP or their own wireless router device. And even if they are not, most operating systems have some sort of minimal firewall to block unsolicited traffic. So it's very limiting to have a P2P client out there than can only work on direct connections.
With that said, on Windows (and likely others), you can program your app's install package can register with the Windows firewall so your it is not blocked. But if you aren't targeting Windows, you may have to ask the user to manually fix his firewall software.
Oh shameless plug. You can use this open source STUN server and client library which supports all of the semantics described above. Follow up with me offline if you need access to a stun service.
You might find this article useful
http://msdn.microsoft.com/en-us/library/aa364726%28v=VS.85%29.aspx
I would start with each os and ask if firewall services are turned on. Secondly, I would attempt the socket connections and determine from the error codes if connections are being reset or timeout. I'm only familiar with winsock coding, so I can't really say much for Linux or mac os.

NAT, P2P and Multiplayer

How can an application be designed such that two peers can communicate directly with each other (assuming both know each other's IPs), but without outgoing connections? That's, no ports will be opened. Bitorrent for example does it, but multiplayer games (as far as I know) require port forwarding.
I'm not sure what you mean by No Outgoing Connections, I'm going to assume like everyone else you meant no Incoming Connections (they are behind a NAT/FW/etc).
The most common one mentioned so far is UPNP, which in this context is a protocol that allows you as a computer to talk to the Gateway and say forward me this port because I want someone on the outside to be able to talk to me. UPNP is also designed for other things, but this is the common thing for home networking (Actually it's one of many definitions).
There are also more common and slightly more reliable ways if you don't own the network. The most common is called STUN but if I recall correctly there are a few variants. Basically you use a third party server that allows incoming connections to try and coordinate a communication channel. Basically, what you do is send a UDP packet to you're peer, which will open up you're NAT for a response, but gets dropped on you're peer's NAT (since no forwarding rule exists yet). Through the connection to the intermediary, they are then told to do the same, which now opens up their NAT, and matches the existing rule in you're NAT. Now the communications can proceed. Their is a variant of this which will allow a TCP/IP connection as well by sending SYN and SYN-ACK messages with some coordination.
The Wikipedia articles I've linked to has links to the relevant rfc's for these protocols on precisely how they work. Essentially it comes down to, there isn't an easy answer, as this is a very network centric problem.
You need a "meeting point" in the network somewhere: the participants "meet" at a "gateway" of some sort and the said "gateway function" takes care of the forwarding.
At least that's one way of doing it: I won't try to comment on the details of Bittorrent... I am sure you can google for links.
UPNP dealt with this mostly in the recent years, but the need to open ports is because the application has been coded to listen on a specific port for a response.
Ports beneath 1024 are called "registered" because they've been assigned a port number because a company paid for it. This doesn't mean you couldn't use port 53 for a webserver or SSH, just that most will assume when they see it that they are dealing with DNS. Ports above 1024 are unregistered, so there's no association - your web browser, be it Internet Explorer/Firefox/etc, is using an unregistered port to send the request to the StackOverflow webserver(s) on port 80. You can use:
netstat -a
..on windows hosts to see what network connections are currently established, including the port involved.
UPNP can be used to negotiate with the router to open and forward a port to your application. Even bit-torrent needs at least one of the peers to have an open port to enable p2p connections. There is no need for both peers to have an open port however, since they both communicate with the same server (tracker) that lets them negotiate and determine who has an open port.
An alternative is an echo-server / relay-server somewhere on the internet that both peers trust, and have that relay all the traffic.
The "problem" with this solution is that the echo-server needs to have lots of bandwidth to accomodate all connected peers since it relays all the traffic rather than establish p2p connections.
Check out EchoWare: http://www.echogent.com/tech.htm

Resources