Socketbox/Compatibility

Socketbox-inetd compatibility

Due to the nature of inetd, most programs should work without any modifications.

Name Works? Notes
OpenSSH yes Run with sshd -i. Tested with version 8.2p1.
Busybox httpd yes Run with httpd -i. Tested with versions 1.31.1 and 1.32.0.
Exim yes Run with exim4 -bs. Tested with version 4.93.

Socketbox-preload compatibility

Name Works? Notes
Apache2 yes Tested with version 2.4.41. Be sure to use a "Listen" statement that specifies a fe8f::/96 address to actually create a new socket. You can ignore the "Failed to enable APR_TCP_DEFER_ACCEPT" error message.
Nginx yes, with limitations Tested with version 1.18.0. Use listen [fe8f::(address)]:80 in your server block. Retrieval of $server_addr does not work (it returns the fe8f:: address instead of the real server IP address). Patch WIP. Please use HAProxy instead.
Postfix yes, with hacks Tested with version 3.4.13. Set inet_interfaces to [fe8f::(address)]. The fe8f::/96 address actually has to exist as an interface address in the network namespace that Postfix is running in; use ip addr add fe8f::1 dev eth0 preferred_lft 0. You will need to move /usr/lib/postfix/sbin/master to /usr/lib/postfix/sbin/master.distrib (with dpkg-divert, if using Debian/Ubuntu). Replace /usr/lib/postfix/sbin/master with a shell script:
#!/bin/sh
exec env SKBOX_DIRECTORY_ROOT=/run/socketbox-conf LD_PRELOAD=/path/to/libsocketbox-preload.so /usr/lib/postfix/sbin/master.distrib "$@"

Upon further testing, it appears that you might also need to do this on /usr/lib/postfix/sbin/smtpd.

Not yet tested:

  • Ports 465 or 587
  • Actually trying to send an email (only tested EHLO/MAIL FROM/RCPT TO)
  • chroot=y in master.cf
Python yes Tested with version 3.8.5. Use code like the following:
import socket
my_socket = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
my_socket.bind("/path/to/unix/domain/socket")
while True:
    a, addr = my_socket.accept()
    # do something with (a, addr)

(Note that this normally fails with OSError if socketbox-preload is not used.)

Not yet tested:

  • socket.create_server
Node.js no Tested with version 12.19.0. As an alternative, the core functionality of socketbox can be implemented in Node.js directly:
const net = require('net');
const http = require('http');
var appOne = http.createServer(/* (req, res) => ... */);
var appTwo = http.createServer(/* (req, res) => ... */);
var appDefault = http.createServer(/* (req, res) => ... */);

var mapping = {
    "@2001:db8::1": appOne,
    "@2001:db8::2": appTwo
};

var masterServer = net.createServer(s => {
    let key = "@" + s.localAddress;
    if (mapping.hasOwnProperty(key)) {
        mapping[key].emit("connection", s);
    } else {
        appDefault.emit("connection", s);
    }
});

masterServer.listen({host: "::", port: 80}); /* Alternatively call Node.js from Python using an inherited AF_INET[6] listening socket, perhaps using the IPV6_TRANSPARENT + TPROXY trick to arbitrarily select IPs and port numbers. */

See TCP Battleships.

Not yet tested:

  • Using fe8f:: with socketbox-preload (only tested server.listen({fd: Number(process.env.WHATEVER)})) where WHATEVER is the environment variable containing the file descriptor number of the socketbox dgram socket.
Apache Tomcat yes
Dovecot yes Tested with version 2.3.7.2. Only imap module currently tested. Set listen = fe8f::(address) in dovecot.conf. Needs the same hack described above with postfix for both the main binary and imap-login (or possibly pop3-login [untested]).

Other

Name Works? Notes
HAProxy yes Tested with version 2.4.0. I maintain my own private fork of HAProxy which relaxes the sockpair address mode, such that it will be fully compatible with the "A" protocol without requiring socketbox-preload or socketbox-inetd.

Run this modified version of HAProxy with the following Python script:

import socket, os

s = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
s.bind("/run/socketbox/haproxy_dgram.sock.tmp")

# os.chown("/run/socketbox/haproxy_dgram.sock.tmp", 0, [gid of socketbox group]) # only if /run/socketbox is not set-gid
os.chmod("/run/socketbox/haproxy_dgram.sock.tmp", 0o660)
os.rename("/run/socketbox/haproxy_dgram.sock.tmp", "/run/socketbox/haproxy_dgram.sock")

s.set_inheritable(True)
os.environ["SKBOX_HAPROXY_DGRAM_SOCK"] = str(s.fileno())

os.execv("/usr/local/bin/haproxy", ["haproxy", "--", "/etc/haproxy/haproxy.conf"])

and use bind sockpair@${SKBOX_HAPROXY_DGRAM_SOCK} in haproxy.conf.

Stuff that will likely work and not work

  • UDP servers will not work.
  • FTP servers will likely not work, because FTP requires an extra socket connection to be made when transferring data.

Servers to test

  • Squid
  • Traefik
  • Caddy
  • systemd-socket-proxyd Might work with ctrtool ns_open_file, however.