is it possible to pass parameters between services runtime? What I've already found is how to start services with variables and how to pass them parameters using an external file at run-time. However, I could not find information about exchanging data between services.
You're looking for an IPC mechanism. Systemd does not provide one because Linux already has quite a few.
The most common method is for a service to listen on a socket (usually an AF_UNIX socket in /run, but TCP is also an option, e.g. if you're writing in Java) and for other services to connect to it and submit or receive data. You can invent your own protocol, but practically any RPC system (such as gRPC or SunRPC or REST) that's built for network use will also work for local use, both across TCP and across AF_UNIX sockets.
D-Bus is one specific IPC system that systemd itself uses (which is also built on top of AF_UNIX sockets, but with a central "message bus" daemon), but it is not part of systemd. It will likely be available on any systemd-based distribution, however. D-Bus bindings are available for most programming languages.
Aside from AF_UNIX sockets, Linux also has several forms of "shared memory" and "message queue" systems (POSIX IPC and SysV IPC variants of each).
Related
I'm breaking a big application into several processes and I want each process to communicate with each other.
for now it's gonna be on the same server, but later several servers on same local network will have several processes that will need to communicate between each other. (means service on one server, with service on other server on same vpc)
so.. my raw options are tcp or unix sockets. I know that with Unix sockets can be useful only if you're on the same server. but we're thinking about writing our own implementation that on same server processes will communicate on unix sockets, and between servers that will communicate using tcp.
is it worth it ? of course tcp sockets are slower then unix sockets.. cause it doesn't go through the network and doesn't get wrapped with tcp related data. the question is by how much ? I couldn't find online proof of benchmarking between tcp and unix sockets. if tcp adds 3%-5% overhead that's cool, but can it be more then that ? I'd like to learn from experience of big projects.. of other people over the years, but didn't find anything relevant.
next...
our project is a NodejS project.
some people may say that I can use a broker for messages, so I tried using nats.io compared to node-ipc (https://www.npmjs.com/package/node-ipc) and I found out that node-ipc is 4 times faster but nats has the cool publish-subscribe feature... but performance is important.
so I have tons of options, no concrete decision.
any information regarding the issue would be greatly appreciated.
The question is actually too broad to answer, but one answer for TCP vs unix domain sockets:
Architect your code, so that you can easily move between those if necessary. The programming model for these is basically the same (both are bidirectional streams of data), and the read/write APIs on OS level as well as in most frameworks is the same. This means e.g. in node both will inherit from the Readable/WriteableStream interfaces. That means the only code that you need to change for switching between those is the listener on the server side where you call the TCP accept APIs instead of the unix domain socket accept APIs and the other way around. You can even have your application accept both types of connections and later on handle them the same internally.
TCP support is always nice because it gives you some flexibility. With my last measurement the overhead was a little bit more (I think 30% versus TCP over loopback) but these are all micro benchmarks and it won't matter for most applications. Unix domain sockets might have an advantage if require some of their special functions, e.g. the ability to send file descriptors across them.
And regarding TCP vs NATS & Co:
If you are not that experienced with network programming and protocol design it makes sense to use readymade IPC systems. That could be anything from HTTP to gRPC to Thrift. These are all point-to-point systems. NATS is different, since its a message broker and not RPC. It also requires an extra component in the middle. Whether this makes sense totally depends on the application.
On Linux a fairly common method for IPC between userland processes and services is, for example, a socket interface (either Unix domain or netlink).
Simply -- What is the Windows analog of this and how do userland processes communicate with services?
To set the stage: Assume I have a background service running that monitors devices on a network. If I wanted to write a program to utilize the services provided by this service, what would be the common "Windows-way" of doing this?
If I am completely off-base here, what is the common way a Windows service may extend itself on the Windows OS so other processes may know it is actively listening for connections?
Windows has named pipes,
"A named pipe is a named, one-way or duplex pipe for communication
between the pipe server and one or more pipe clients. All instances of
a named pipe share the same pipe name, but each instance has its own
buffers and handles, and provides a separate conduit for client/server
communication. The use of instances enables multiple pipe clients to
use the same named pipe simultaneously."
https://msdn.microsoft.com/en-us/library/windows/desktop/aa365590%28v=vs.85%29.aspx
libpcap is used for package capturing. As I understand, it can capture the network packages from all ports. And it can capture the package data in link layer (such as ethernet frame).
This looks a little confusing to me, because it seems impossible to intercept all network traffic (from all ports) by just using the socket API in Unix-like system. Moreover, socket API seems unable to get the information in link layer (such as the header of Ethernet frame).
Is it true that libpcap is implemented by socket API? If not, which OS-level API is used to implement it?
libpcap is not part of the sockets API. On Linux PF_PACKET is used, which is an evolution of the BSD mechanism. On other operating systems there are other mechanisms (DLPI, Windows requires a DLL).
The capture on any interface mechanism is a Linux specific mechanism, and the capture mechanism occurs above the layer of the network interface.
The capture mechanism inside the kernel either has an explicit call out to a kernel packet filter, or is inserted by adjusting the plumbing (SVR4).
Is it true that libpcap is implemented by socket API?
If you're on Linux or IRIX, it is true. If you're on another flavor of UN*X, it is not true.
If not, which OS-level API is used to implement it?
On *BSD, OS X, AIX, and Solaris 11 and later: BPF.
On earlier versions of Solaris, and on HP-UX: STREAMS+DLPI.
it seems impossible to intercept all network traffic (from all ports) by just using the socket API in Unix-like system
On Linux, if you open a PF_PACKET socket, and don't bind it to a particular interface, packets from all interfaces are delivered to the socket.
socket API seems unable to get the information in link layer
You have to use the right type of socket, namely a PF_PACKET socket on Linux or a PF_RAW socket with a protocol of RAWPROTO_SNOOP on IRIX. Other UN*Xes don't have socket types for packet capture, and use other mechanisms.
On Linux, access to the raw packets needed by libpcap is done using a PF_PACKET socket.
See http://man7.org/linux/man-pages/man7/packet.7.html
It's implemented by inserting a driver into the network stack.
Normally, applications use kernel-level TCP stack. Instead of using default kernel-level implementation, by using your own implementation of TCP/IP stack processing in user-space, you can be bypass the kernel.
more readings
"zero copy networking" vs "kernel bypass"?
according to that StackOverflow post pcap is also doing kernel Bypass
I have doubt in using Linux Pipes for IPC. My question is
Can Linux pipes can be used to communicate between the processes running on different machines?.
Thanks,
No, you can't use only pipe to communicate between different machines, because pipe is defined as local machine communication method (IEEE standard says that it creates two file descriptors in current process. Descriptors usually can't be send to other machine, only inherited from parent or passed via local machine sockets).
But you can try to use pipe to some external socket program, like netcat, which will resend all data over tcp socket, and remote netcat will replay it back into the program.
And if you are developing some application, it can be better to use tcp sockets directly.
PS: The IPC - Inter-process communication - AFAIK means communications between different processes on one (same) machine (linux IPC from Linux Programmer's Guide 1995).
PPS: If sockets are hard to work with them directly, you may choose some Message Passing library or standard. For example MPI standard (OpenMPI, MPICH libraries) is often used to communicate between many machines in tightly-coupled computing clusters, and there are some popular interfaces like RPC (Remote procedure call, several implementations) or ZeroMQ
Pipe is only used for communication between related process on the same host (eg. parent and child process).
My goal is to monitor sockets and relate them to the applications that created them.
I am aware of netstat, ss, lsof and so on and that they can list all sockets with their application.
And I also know that I can parse /proc/net/tcp to get the sockets and relate them to the applications with /proc/(PID), which is exactly what these tools do or they use netlink sockets.
My researches brought me to an article which explains how to get all sockets from the kernel with netlink via the inet_diag protocol. The user space program sets up a netlink socket of the inet_diag type and sends a request to the kernel. The response consists of several messages which contain the sockets and additional related information.
This is really neat, but unfortunately the kernel sends this information only once per request. So I have to "poll" continuously.
Further researches brought me to another article which monitors IP changes of interfaces with netlink route sockets continuously. The socket is bound to a multicast group and then messages are read from it in an endless loop.
So I investigated if there is the same possibility with the inet_diag sockets. Unfortunately I am not really able to understand kernel code. But as far as I can tell there are no multicast groups for this socket family.
At this point I am stuck and I need to know if this approach is somehow feasible or somebody knows any other hints.
You can try dtrace if every tools you mentioned can't meet your requirement.
You can use kprobe kernel module to hook all connect system call,whichi monitor sockets and relate them to the applications that created them
just like Elkeid,Elkeid Driver hooks kernel functions via Kprobe, providing rich and accurate data collection capabilities, including kernel-level process execve probing, privilege escalation monitoring, network audition, and much more. The Driver treats Container-based monitoring as a first-class citizen as Host-based data collection by supporting Linux Namespace. Compare to User Space agents on the market, Elkeid provides more comprehensive information with massive performance improvement.