Serving applications as TCP sockets » History » Version 1
manawyrm, 05/01/2022 11:36 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 | <code>/etc/systemd/system/octoi-helloworld.socket</code> with the following content: |
||
13 | <pre><code class="ini"> |
||
14 | [Unit] |
||
15 | Description=OCTOI HelloWorld Socket for Per-Connection Servers |
||
16 | |||
17 | [Socket] |
||
18 | ListenStream=31337 |
||
19 | Accept=yes |
||
20 | |||
21 | [Install] |
||
22 | WantedBy=sockets.target |
||
23 | </code></pre> |
||
24 | <code class="ini">ListenStream=</code> is the TCP port on which the service should run. |
||
25 | <code class="ini">Accept=yes</code> causes systemd to accept() incoming connections directly. This could also be done by the service later on. |
||
26 | |||
27 | <code>/etc/systemd/system/octoi-helloworld@.service</code> with the following content: |
||
28 | <pre><code class="ini"> |
||
29 | [Unit] |
||
30 | Description=OCTOI HelloWorld Socket Per-Connection Server |
||
31 | |||
32 | [Service] |
||
33 | ExecStart=-/opt/octoi-helloworld.sh |
||
34 | StandardInput=socket |
||
35 | StandardError=null |
||
36 | DynamicUser=true |
||
37 | </code></pre> |
||
38 | |||
39 | <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. |
||
40 | <code class="ini">StandardInput=socket</code> will redirect any input from the socket to the program. |
||
41 | <code class="ini">StandardError=null</code> will redirect any error output to /dev/null. |
||
42 | <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. |
||
43 | If the application allows for this, it can be a powerful tool for security (by isolating the processes and minimizing permissions). |
||
44 | Warning: Applications with <code class="ini">DynamicUser</code> enabled run with their own private <code>/tmp</code> directories. Don't try to exchange files/sockets with other processes there. |
||
45 | |||
46 | systemd can also drop permissions in the usual way, by specifying a fixed user and group: |
||
47 | <pre><code class="ini"> |
||
48 | User=helloworld |
||
49 | Group=helloworld |
||
50 | </code></pre> |