Firewalling¶
Tips for securing your application
Run kdb+ as a separate (non-root) user. If you need it to run on port 80, use authbind or iptables redirect.
Do not allow that user to write to any directory or files. If you need file access, arbitrate it via IPC with another kdb+ process. Pay attention to how that process will return values via .z.pg
or .z.ps
or similar.
Firewall all ports inbound and outbound except ones explicitly used.
For any backend kdb+ processes, restrict them to localhost
or a protected network (e.g. iptables --pol ipsec
)
Set process limits with ulimit no larger than you need them.
Restrict input by defining at least:
.z.pc:{}
.z.pg:{}
.z.ph:{}
.z.pi:{}
.z.pm:{}
.z.po:{}
.z.pp:{}
.z.pq:{}
.z.ps:{}
To allow certain IPC calls, implement only the ones you want. A denylist for functions is tricky because some otherwise useful functions may have a mode that accesses the disk which may cause information leak (e.g. key). It is much easier to use an allowlist.
As IPC functions either receive a parse tree or a string (that you could parse yourself), check the type of the input e.g. x:$[10h=type x;parse x;x]
If you use WebSockets, define:
.z.wc:{a[.z.a]-:1}
.z.wo:{$[2<;a[.z.a]+:1;hclose .z.w;1]}
When handling untrusted input, consider designing your application to wrap public entrypoints with reval
.
Pay attention to the fact that each WebSocket client can open up a lot of connections (200 on Mozilla, 256 for Chrome), so limit using .z.a
.
Log connections and consider using fail2ban to block suspicious traffic.
Callbacks,
Using .z
Permissions with kdb+
Q for Mortals:
ยง11.6 Interprocess Communication