Proposal: automatic jailing of services (rc.d/*) [patch]
Alexander Leidinger
Alexander at leidinger.net
Sun Feb 24 10:00:32 UTC 2019
Hi,
Thanks to MWL for his upcoming jail book, it inspired me to come up with this.
Note, I'm not subscribed to freebsd-rc, please keep at least jail@ in
copy (I'm subscribed there).
I propose to extend the rc system to automatically jail services in a
light sense (off by default, can be enabled on individual service
level). The "light sense" means to inherit the entire host (subject to
options). All programs have still access to the entire filesystem
(subject to user access permissions). By default no network access.
Optional access to the hosts IPv4, IPv6, raw sockets or full access to
all network related parts (see below for "service jail options").
Similar optional access for sysvipc, mlock and vmm.
The benefit of this approach (aside of being able to prevent network
and other access if needed (without removing the network at all) when
it is not enabled) is to put a service and all its children into a
limited process namespace. A service and its children only see
themselves but no other processes (a rc script which uses some checks
in start_cmd to see if some other services/processes are started needs
to be modified to do the checks in start_precmd, only start_cmd (and
stop_cmd) is jailed in this design (so far), so that a service can
check a lot more than what is possible in a jail), and you can kill
all of those in one go (jail -r svcj-<svc>).
Note: this can not be used for services which require access to
/dev/(k)mem, as this is prohibited in a jail even if the dev-entry is
there (this means you can not enable this feature for services which
start X.org to access a graphic card without my patches for X.org in a
jail). Other hard-coded jail restrictions apply too off course.
As an example for a service which needs network access, it would have
to have in the rc script
: ${svcname_svcj_options:="net_basic")
to specify that it needs access to IPv4, IPv6 and access to reserved
ports (see below for more details).
This way the service comes with a default setting and an admin can
override what the service is allowed to do on his discretion in rc.conf.
There are off course drawbacks, depending on your point of view. If
you jail sshd, you can only see processes inside the sshd service jail
via ps/top/..., you can not use commands which require access to
/dev/(k)mem, you can not start ntpd from such a ssh session, and you
can not manage (stop/start via rc-means or kill) stuff which is
running in other service jails, or in short: all hard-coded jail
restrictions apply. If you stop such a service jail, the current
implementation removes the entire service jail (after running "service
stop" inside), so for sshd this would mean that any ssh connection to
the jailed sshd is killed instead of continuing like in the non
service jail case. So this is not something which can by enabled by
default and a careful review of what shall be handled in this way
needs to be done instead of enabling it blindly.
To enable jailing of a service, an admin has to specify
svcname_svcj="YES" in rc.conf and optionally options via
svcname_svcj_options="xxx" if it wants to override the settings/access
specified in the rc script (or set it if the rc script is not yet
modified to support service jails).
A rc script shall not enable a service jail by default, it's up to the
admin to enable that.
This also works in jails, but requires to set children.max to an
appropriate value for those jails (see jail(8) or MWLs upcoming book
for more info about hierarchical jails). As we expose
security.jail.param.children.* in jails, we could add a safetynet
inside the implementation to not use service jails even if configured,
when "jailed and cur = max".
RC settings:
<svc>_svcj="YES/NO"
<svc>_svcj_options="see_below"
service jails options translations:
netv4 -> ipv4=inherit allow.reserved_ports
netv6 -> ipv6=inherit allow.reserved_ports
net_basic -> ipv4=inherit ipv6=inherit allow.reserved_ports
net_raw -> allow.raw_sockets
net_all -> allow.socket_af allow.raw_sockets allow.reserved_ports
ipv4=inherit ipv6=inherit
sysvipc -> sysvmsg=inherit sysvsem=inherit sysvshm=inherit
mlock -> allow.mlock
vmm -> allow.vmm
Attached is a proof of concept (only lightly tested with
start/stop/status/restart) so that you can play around with it a
little bit. Please don't focus on the patch. This mail is to seek
feedback about the feature and the quick design so far. To make it
explicit, I do not ask (yet) if and which service to handle like this
by default. This is just the possibility to do something like this.
Bye,
Alexander.
--
http://www.Leidinger.net Alexander at Leidinger.net: PGP 0x8F31830F9F2772BF
http://www.FreeBSD.org netchild at FreeBSD.org : PGP 0x8F31830F9F2772BF
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 819 bytes
Desc: Digitale PGP-Signatur
URL: <http://lists.freebsd.org/pipermail/freebsd-rc/attachments/20190224/0ed00e09/attachment.sig>
More information about the freebsd-rc
mailing list