Project

General

Profile

Serving applications as TCP sockets » History » Version 2

manawyrm, 05/01/2022 11:44 PM

1 1 manawyrm
h1. Serving applications as TCP sockets
2
3
systemd has become the standard init system on most Linux machines. 
4
One lesser known feature is ability to serve TCP sockets and launch arbitrary services on connection.
5
This was usually done using inetd/xinetd in the past.
6
7
More information about inetd-replacement of systemd can be found at: 
8
http://0pointer.de/blog/projects/inetd.html
9
10
h2. Hello World example
11
12 2 manawyrm
Create <code>/etc/systemd/system/octoi-helloworld.socket</code> with the following content:<pre><code class="ini">
13 1 manawyrm
[Unit]
14
Description=OCTOI HelloWorld Socket for Per-Connection Servers
15
16
[Socket]
17
ListenStream=31337
18
Accept=yes
19
20
[Install]
21
WantedBy=sockets.target
22
</code></pre>
23
<code class="ini">ListenStream=</code> is the TCP port on which the service should run.
24
<code class="ini">Accept=yes</code> causes systemd to accept() incoming connections directly. This could also be done by the service later on.  
25 2 manawyrm
  
26
Create <code>/etc/systemd/system/octoi-helloworld@.service</code> with the following content:<pre><code class="ini">
27 1 manawyrm
[Unit]
28
Description=OCTOI HelloWorld Socket Per-Connection Server
29
30
[Service]
31
ExecStart=-/opt/octoi-helloworld.sh
32
StandardInput=socket
33
StandardError=null
34
DynamicUser=true
35
</code></pre>
36
37
<code class="ini">ExecStart=</code> is the program that will be executed. Notice the - at the beginning, which will get systemd to ignore any non-zero return codes.
38
<code class="ini">StandardInput=socket</code> will redirect any input from the socket to the program.
39
<code class="ini">StandardError=null</code> will redirect any error output to /dev/null.
40 2 manawyrm
<code class="ini">DynamicUser=true</code> is a very useful feature that will _dynamically create a new system user and group_ , with a new PID/GID for each incoming connection. This is done internally without touching the /etc/passwd file. 
41 1 manawyrm
If the application allows for this, it can be a powerful tool for security (by isolating the processes and minimizing permissions).
42 2 manawyrm
+Warning: Applications with <code>DynamicUser</code> enabled run with their own private <code>/tmp</code> directories. Don't try to exchange files/sockets with other processes there.+
43 1 manawyrm
44
systemd can also drop permissions in the usual way, by specifying a fixed user and group:
45
<pre><code class="ini">
46
User=helloworld
47
Group=helloworld
48
</code></pre>
49 2 manawyrm
50
Create <code>/opt/octoi-helloworld.sh</code>:
51
<pre><code class="shell">
52
#!/bin/bash
53
echo "Hello World"
54
55
# Sleep before closing the session to give PortMaster time to flush
56
# all data onto the connection.
57
sleep 5
58
</code></pre>
59
60
Don't forget to set +x permissions on the shell script.
61
62
Reload systemds configuration, then enable and start the socket:
63
<pre><code class="shell">
64
systemctl daemon-reload
65
systemctl enable --now octoi-phonebook.socket
66
</code></pre>
67
68
systemd is now listening to the TCP port:
69
<pre><code class="shell">
70
# netstat -tulpen
71
Active Internet connections (only servers)
72
Proto Recv-Q Send-Q Local Address           Foreign Address         State       User       Inode      PID/Program name    
73
tcp6       0      0 :::13063                :::*                    LISTEN      0          2674600    1/systemd           
74
</code></pre>
75
76
You can check the status (and the number of past connections) with:
77
<pre><code class="shell">
78
# systemctl status octoi-phonebook.socket
79
● octoi-helloworld.socket - OCTOI HelloWorld Socket for Per-Connection Servers
80
     Loaded: loaded (/etc/systemd/system/octoi-helloworld.socket; enabled; vendor preset: enabled)
81
     Active: active (listening) since Mon 2022-05-02 01:11:11 CEST; 29min ago
82
   Triggers: ● octoi-phonebook@8-123.123.123.85:31337-123.123.123.123:1091.service
83
     Listen: [::]:31337 (Stream)
84
   Accepted: 8; Connected: 1;
85
      Tasks: 0 (limit: 1131)
86
     Memory: 4.0K
87
        CPU: 4ms
88
     CGroup: /system.slice/octoi-helloworld.socket
89
90
Mai 02 01:11:11 communityisdn systemd[1]: Listening on OCTOI HelloWorld Socket for Per-Connection Servers.
91
</code></pre>
92
93
For each open connection, you can see the "Triggers:" line, with the service which has been started for that connection.
Add picture from clipboard (Maximum size: 48.8 MB)