Get notifications for socket events in kernel - linux

I need to find for local tcp-connections/Unix-domain-connections the client process that starts the connection in the most effective way possible.
I currently have a solution for this implemented in a driver, that intercept both accept and connect syscalls, match them, and finds out the client process.
Now I try to achieve the same without my own driver.
Different approaches I tried:
Linux auditing system plugin that intercept the appropriate syscalls and resolve the client in a similar manner. This method has 3 problems:
Each intercepted event flows from the kernel to the auditd process to some other intermediate process and only than to my plugin.
The audit rules are applies for all the plugins and audit-log - I can't define my own set of filtering rules. - which may cause on machines that uses the audit system for extreme inefficiency.
It requires that audit to be installed on the machine (which is not default for many Linux distributions).
Imitate netstat/lsof - In order to find the process that holds a connection, they iterate the entire procfs mount - this makes sense, because after connection establishment, each connection could belongs to more than one process.
This approach is extremely not effective if I want to do so for each connection establishment.
I thought to try one of the LSM (Linux security modules) solutions - but I am currently unfamiliar with it - Is their a LSM that can pass the kernel events for a running application for a "decision"?
I will be happy to hear suggestions and other comments that could lead me to a reasonable solution for my original goal.

Found an option that suits my needs for Unix-domain-sockets only - if runnning code in the server side is a possability (as in my case) one can use getsockopt in the following manner:
getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cr, &len)
More details in http://welz.org.za/notes/on-peer-cred.html

Related

Is there a way to nullify SIGSTOP for a certain script?

I have created a script and I want it to be virtually "immune" to SIGSTOP.
I understand that both SIGKILL and SIGSTOP cannot be trapped or ignored.
I know that the init system for Linux cannot receive a "fatal" signal due to it having the SIGNAL_UNKILLABLE flag on its signal struct flags (although the latter half of that sentence flies over my head for the most part).
I'm willing to edit my kernel to grant this script immunity, the only problem is that I don't know how.
So, my question is, is there a way to nullify SIGSTOP for a certain script/process?
I was able to deal with SIGKILL thanks to the Restart parameter in the service file for my script (using systemd), and while I have scrolled through the manuals looking for something similar for suspended processes, I haven't found anything yet.
Is there anything similar to Restart=always for process suspension caused by SIGSTOP?
I would rather not have to go through the process of changing things in or related to the kernel, but if it's the only way I will.
Thanks.
Okay so the best solution I can come up with is SELinux.
SELinux is a kernel add-on created by the NSA that was later released to the public. It is commonly used on Linux systems and comes by default on Android devices. SELinux allows the creation of "contexts". Contexts are an additional label provided to files and processes that allow the subdivision of responsibility and permissions.
How does this solve your problem? Well, you can limit your SELinux permissions for your user processes (even for the root user) so that you're not even allowed to signal this other process at all. In fact, you can prevent any interaction with it whatsoever. If you'd like, you could go so far as to prevent yourself from even being able to turn SELinux off (although it's probably better that you don't if you can avoid it from an operational perspective). This is at some level probably the closest you'll get to a solution that is anywhere near the range of not-hackable. That being said, SELinux setup and configuration for this purpose is not exactly a walk in the park. Documentation is limited (but exists), distro-specific, and in some cases even esoteric. I do have some experience with SELinux myself.
Edit:
Doing some quick googling, it appears possible to install SELinux on Arch, but like most things on Arch, it requires some effort - more than should fit in a StackOverflow comment block. However I'll briefly describe your set of goals here once SELinux is installed:
Determine the context that you are currently in. Using the "id" command should provide this context.
Use a context process transition so that when you execute your script, that script runs in a new context. You will probably need to create a new context for your script to run in.
Create sepolicy rules allowing that script to interact with your processes however you need. Perhaps this includes the ability to kill other processes in a different context, or read from a tcp port using sniffing, etc. etc. You can use the audit2allow program to help you create these rules.
By default, SELinux denies anything it doesn't explicitly allow. Your goal now is to make sure that everything you might want to do on your system is allowed, and add policy rules to allow all those things. Looking at the SELinux audit logs is a great way to see everything SELinux is complaining about - it's your job to go through and convert all those audit failures into "allow" rules.
Once all that is done, just make sure not to "allow" whatever context your processes/shell start in from being able to kill or signal the context that your script runs in, and you should be done. Now trying to SIGSTOP or SIGKILL should generate a "Permission denied error".

File read(i.e. using vfs_read()) from LKM init_module()

I would like to read files from my LKM "initialization" function so that I can config the LKM from some configuration files.
I'm wondering if it is not a good practice to read files even from the initialization function of LKM; I heard that it is NOT recommended to read files from LKM after all kernel was initialized.
Please advice me.
Thank you.
Daum
Reading from/writing to files from the kernel is definitely not recommended.
The Kernel Newbies wiki page describes it quite nicely.
For several reasons:
Selecting where and in what format to read/write data is a policy and policy does not belong to kernel. A userland daemon is much
easier to replace with one that receives or sends the data over a
network, generates or converts them from/to different format etc.
Filesystem operations need a user context (i.e.: current != NULL). You can't be sure you're in user context so you can't write something
from (for example) an interrupt handler.
The kernel allows multiple filesystem namespaces for user processes. Which one should it use? How do you make sure it indeed
uses the one you want?
Kernel should not depend on particular layout of a filesystem nor on availability of writable filesystem. The location of the file is
a policy decision and policy decisions should be done in userspace.
Maybe you want to dump the kernel output in a remote MySQL server
tomorrow, that kind of policy is so much easier in userland.
Kernel code should be kept simple and stupid, because any bug in it is likely to have serious consequences. Working with files requires
being aware of various locking issues and would add unnecessary
complexity.
If you want to configure the behaviour of the kernel module you're writing, you can pass module parameters that configure it on start up. Alternatively, your module can expose interfaces to sysfs that can be used to configure it at run time.

Whats the easiest way to send messages to my linux daemon app?

Whats the easiest way to send messages to my linux daemon app? Is it possible that myapp foo bar can invoke a callback instead of starting a new process? Whats the standard way to communicate with a daemon? Is my most reasonable choice to stick the PID in /var/run and create a named pipe or a socket?
Whats is the standard way apps which run on the command line communicate to its daemon process? I'm assuming its impossible to ask linux to call a callback when I type in myapp foo bar?
Whats is the standard way apps which run on the command line communicate to its daemon process?
There are a number of ways to do this:
Dropboxes and Signals
A variety of locations are being used to store "pid files" containing a daemon's process ID number: /var/run/<app>/<app>.pid, /var/run/<app>.pid (thanks #Adam Katz for edit), /run/<app>/<app>.pid, /run/<app>.pid, (see Askubuntu: Why has /var/run been migrated to /run?).
When the pid of the daemon process is known, a command line program (which is running as a separate process) could communicate with the daemon in these ways:
Writing something into a prearranged place. This could be an ordinary file, a database table, or any convenient spot readable by the server.
Sending a signal to the daemon. The common way to do this locally is with the kill system call, int kill(pid_t pid, int sig);.
Old School Example: The server multiplexing daemon xinetd would reread its configuration file after receiving SIGHUP.
The send-a-signal methodology has been made redundant by the inotify API whereby a process can subscribe to file system events. Using signals is useful when you don't want the daemon to act on every file change, since not every change may leave the file in a valid state, as when modifying a system config file.
FIFO or Pipe
A fifo or pipe is simply a special file that blocks processes reading it until some other process has written to it. You can make a named pipe/fifo in the file system with mkfifo. The only tricky thing about this is that pipes should generally be opened unbuffered, e.g. with open() as opposed to fopen(). Scripting languages sometimes make a facility for pipe-friendly reading/writing: Perl had a line-buffered mode set with $|=1 that was useful for pipes.
More commonly, you see anonymous pipes all the time on the command line with the | symbol separating commands which are executed as separate processes.
Sockets
What about something newer, like mySQL? The mysql database system consists of a command line client mysql and a server mysqld and may also serve other clients either on the local machine or over the internet.
mySQL communicates using a socket. The server listens to a socket for connections, and forks new processes giving a socket descriptor to the child for processing. When the child is done processing, it can exit.
There are UNIX sockets and Internet sockets, with different namespaces. One guide to programming sockets in C on Linux would be the sockets chapter of the The GNU C Library manual.
No-wait I/O is an alternative to forking off processes. This is done in C with the select() system call, which allows having a process wait for an event on one or more files, including sockets, or a timeout. The GNU C Library docs includes a no-wait I/O socket server example
NodeJS is a server for the Javascript language, written as a single-threaded server using no-wait I/O, and shows that these techniques are still relevant in modern systems.
"Callbacks"
I'm assuming its impossible to ask linux to call a callback when I type in myapp foo bar?
Maybe. But it might be too much work to be worth the trouble.
When you type myapp foo bar into "Linux", that's not Linux, you are typing that into your command shell, which is a program running in its own process separate from everything else.
So, unless the functionality you want is built into the command shell, there is normally no way for that command shell to send messages to your other program without starting a new process.
The default command shell for many (but not all) Linux systems is /bin/bash. To communicate with a daemon that listens to sockets from bash we would need a socket opening procedure in bash. And, sure enough, it exists!
One can listen to a socket in bash. This is the basis for a daemon:
From: Simple Socket Server in Bash? answer by dtmilano:
Q: I have a simple debugging solution which writes things to 127.0.0.1:4444 and I'd like to be able to simply bind up a port from bash and print everything that comes across. Is there an easy way to do this?
A:
$ exec 3<>/dev/tcp/127.0.0.1/4444
$ cat <&3
One can also open a socket from bash to a remote process, i.e. communicate with a a daemon:
From: TCP connection, bash only
we learn exec 5<>"/dev/tcp/${SERVER}/${PORT}" redirects a TCP link to file descriptor 5 for both input and output.
Not all bash programs are compiled with TCP support. It is apparently Linux-distribution dependent. At least according to a comment on this answer by William Pursell
There are other shells besides bash. Many shells were developed back in the *nix days. ksh Korn shell. csh C-shell. Bourne shell sh. Ash shell. Wikipedia keeps a list of shells. And these shells each have their own advantages and disadvantages and are not entirely compatible with each other's formatting!
Fast forward about 30 years, and there aren't so many in common use now.
But an important feature exists here: each user can choose his own login shell. See the chsh command.
So where I am going here is that if bash doesn't support the communications you need to do, you could set up a command shell where special messages can be sent without opening a new process. This might save you a few milliseconds, and usually isn't worth it. But nothing is stopping you. You might even set up an ipython command shell, as suggested in https://stackoverflow.com/a/209670/103081, and python can import most anything you need to do socket communications with your specialized daemon.
There are too many inferior questions in your post, so they can't all be answered in a single compact response. Also, some questions are like taste compare request - I mean "what's the best way?" - and this kind of questions is usually disliked at SO. Despite this I'll try to provide at least basic references you can continue with.
Whats the easiest way to send messages to my linux daemon app?
There is no such way unless you are already using some framework which provide such way. Daemons are too different. Some require only a simple set of fixed messages, some require complex reconfiguration and on-the-fly modification of internal data. The main set of approaches is:
Unix signals are really the simplest way to provide protected (with minor simplification, only the same user or the superuser can send them), idempotent (repeat shall not change signal meaning), non-parameterized message; such message set is very limited (~50 freely used ones in Linux). They are delivered asynchronously but can be converted to internal message queue members in a target application. Their main usage is for simple messages as "stop gracefully", "reread your configs" or "turn on debug messages".
Unix domain sockets are the basic IPC transport for any interactions (except the most fast ones where shared memory is better). They allow datagrams (like UDP), byte streams (like TCP) and message streams (like SCTP or SPX). A listening socket shall be represented in file system with a path known to clients; Unix file access rights will regulate access to it or you can check credentials explicitly. Virtually any protocol can be built over such sockets, but only clients from the same running OS can connect it, such sockets aren't automatically visible even from host OS in virtualization case.
Non-pipe-style IPC: shared memory and semaphores can be used for high load interactions but they require strong usage discipline. There are two versions of such interfaces (SysV and Posix).
Internet domain sockets provide the same transports as Unix domain sockets, allow access from any remote client (not nessessarily on the same OS) but don't provide access checks automatically, so client authentication is needed. Also transport protection is often needed (SSL/TLS and so on).
Various frameworks are provided over socket interfaces which implement some parts of needed functionality such as registration, endpoint publishing, server search, and so on. For local interactions, this now starts with Dbus which is message-oriented and allows named servers and typed messages either in common OS space or user-local space.
Different netwide message transports are developed in last years (AMQP, ZeroMQ, Apache Kafka, etc.) They are designed for using in distributed network, but often without any authentication.
The main issue with self-made daemon is that you shall attach any of these interfaces explicitly and provide a framework to listen for, decode and process incoming messages. If your application has already to be message-driven, you can put it into an environment which is message-driven by design (Erlang, J2EE...), unless you are scared for rewriting to another language :)
Is it possible that myapp foo bar can invoke a callback instead of starting a new process?
It's more style related question than principal one. You can name a control tool in the same way as a long running one. There are such examples in practice: SysV init (telinit is only convenience name), firefox (without -no-remote it tries to connect to already running instance), but generally, separate names are preferred:
apachectl starts/stops/controls daemon but the daemon name is httpd;
rndc for named, gdc for gated, etc.
If a daemon binary is a very fat guy, cost to start it each time for a small control message is too high and shall be avoided. But if you really want to do this way, determine two things:
Do you want it to start automatically unless a running instance is found?
How will you distingiush daemon starting request from control request?
If you have strong answers to both questions, you needn't worry.
Whats the standard way to communicate with a daemon?
No, there is no a single standard way. There are a few standard ways, see above. One shall choose a way on determined pros and cons.
Is my most reasonable choice to stick the PID in /var/run and create a named pipe or a socket?
Again, see above, but you'd know that, unless the daemon has root rights, /run (/var/run) isn't writable. A non-root daemon shall use totally another directory (e.g. ~/run/ for its dedicated user home dir) or be provided with a writable subdirectory.
I'm assuming its impossible to ask linux to call a callback when I type in myapp foo bar?
You again asked for "callback" I don't understand exactly what it stands for. If your daemon is written in an imperative language out of event-driven environment, any message receiving from other processes shall be implemented explicitly. For Unix signals, you write signal receiving functions and configure process to start them on incoming signal. For sockets, you shall create socket, give it a known address, put it into listening mode and provide code to accept incoming connections, gather and decode messages, etc. Only for already event-driven environment, you can use standard methods.
For Erlang, such remote control is very often implemented as connect to daemon node and RPC request using gen_server:call() or analog. The called Erlang process processes this in generic code without any need to implement cases a requester was another process at the same node or from a separate one.
There are some frameworks which have already implemented some of this need in procedural environments; e.g. Dbus client libraries can be written in a way they
create a separate thread for Dbus socket listening;
accept incoming messages and call the callbacks you specify,
but this has its own disadvantages:
a callback is run in its own thread; you shall provide proper synchronization to avoid data spoiling;
with huge message rate, flow control is at least too rough, or even impossible, and a daemon could be overflowed early before it realises bus connect shall be stopped.
To summarize, your initial question was like "How I could reach my friend's home in an efficient way?" with minimum of details. You can simply step 20 meters if your friend resides next door, or you can ride a bike, or you need to call taxi, or you need to rent a space ship to reach back side of the Moon:) You should repeatedly narrow your requirements until a single variant remains.

Win32API/Win drivers: How to detect if file is accessed

I would like to create something like "file honeypot" on Windows OS.
The problem I would like to answer is this:
I need to detect that file is accessed (Malware wants to read file to send it over internet) so I can react to it. But I do not know how exacly tackle this thing.
I can periodically test file - Do not like this sollution. Would like some event driven without need to bother processor every few ms. But could work if file is huge enought so it cannot be read between checks.
I could exclusively open file myselve and somehow detect if file is accessed. But I have no idea how to do this thing.
Any idea about how to resolve this issue effectively? Maybe creating specialized driver could help but I have little experience in this.
Thanks
Tracking (and possibly preventing) filesystem access on Windows is accomplished using filesystem filter drivers. But you must be aware that kernel-mode code (rootkits etc) can bypass the filter driver stack and send the request directly to the filesystem. In this case only the filesystem driver itself can log or intercept access.
I'm going to assume that what you're writing is a relatively simple honeypot. The integrity of the system on which you're running has not been compromised, there is no rootkit or filter driver installation by malware and there is no process running that can implement avoidance or anti-avoidance measures.
The most likely scenario I can think of is that a server process running on the computer is subject to some kind of external control which would allow files containing sensitive data to be read remotely. It could be a web server, a mail server, an FTP server or something else but I assume nothing else on the computer has been compromised. And the task at hand is to watch particular files and see if anything is reading them.
With these assumptions a file system watcher will not help. It can monitor parts of the system for the creation of new files or modification or deletion of existing ones, but as far as I know it cannot monitor for read only access.
The only event-driven mechanism I am aware of is a filter driver. This is a specialised piece of driver software that can be inserted into the driver chain and monitor access to files. With the constraints above, it is a reliable solution to the problem at the cost of being quite hard to write.
If a polling mechanism is sufficient then I can see two avenues. One is to try to lock the file exclusively, which will fail if it is open. This is easy, but slow.
The other is to monitor the open file handles. I know it can be done because I know programs that do it, but I can't tell you how without some research.
If my assumptions are wrong, please edit your question and provide additional information.

Running external code in a restricted environment (linux)

For reasons beyond the scope of this post, I want to run external (user submitted) code similar to the computer language benchmark game. Obviously this needs to be done in a restricted environment. Here are my restriction requirements:
Can only read/write to current working directory (will be large tempdir)
No external access (internet, etc)
Anything else I probably don't care about (e.g., processor/memory usage, etc).
I myself have several restrictions. A solution which uses standard *nix functionality (specifically RHEL 5.x) would be preferred, as then I could use our cluster for the backend. It is also difficult to get software installed there, so something in the base distribution would be optimal.
Now, the questions:
Can this even be done with externally compiled binaries? It seems like it could be possible, but also like it could just be hopeless.
What about if we force the code itself to be submitted, and compile it ourselves. Does that make the problem easier or harder?
Should I just give up on home directory protection, and use a VM/rollback? What about blocking external communication (isn't the VM usually talked to over a bridged LAN connection?)
Something I missed?
Possibly useful ideas:
rssh. Doesn't help with compiled code though
Using a VM with rollback after code finishes (can network be configured so there is a local bridge but no WAN bridge?). Doesn't work on cluster.
I would examine and evaluate both a VM and a special SELinux context.
I don't think you'll be able to do what you need with simple file system protection because you won't be able to prevent access to syscalls which will allow access to the network etc. You can probably use AppArmor to do what you need though. That uses the kernel and virtualizes the foreign binary.

Resources