Fossil SCM

Post-sleep edit pass on the new material in §3.2 of the containers doc.

wyoung 2023-03-28 00:02 trunk
Commit d21fb2678a02b56074fe46fadc90bfe9fca858159ecb0f7bbc3699b1a0eb92a3
1 file changed +21 -24
+21 -24
--- www/containers.md
+++ www/containers.md
@@ -269,20 +269,19 @@
269269
stage, since it’s written for the case where everything is in `/bin`.
270270
271271
Another useful case to consider is that you’ve installed a [server
272272
extension](./serverext.wiki) and you need an interpreter for that
273273
script. The first option above won’t work except in the unlikely case that
274
-it’s written in one of the bare-bones script interpreters that BusyBox
274
+it’s written for one of the bare-bones script interpreters that BusyBox
275275
ships.(^BusyBox’s `/bin/sh` is based on the old 4.4BSD Lite Almquist
276276
shell, implementing little more than what POSIX specified in 1989, plus
277277
equally stripped-down versions of AWK and `sed`.)
278278
279279
Let’s say the extension is written in Python. While you could handle it
280
-the same way we do with Tcl, because Python is more popular, we have
281
-more options. Let’s inject that into the stock container via a suitable
282
-“[distroless]” image instead. Because this will conflict with the
283
-bare-bones “`os`” layer we create, the method is more complicated:
280
+the same way we do with the Tcl example above, because Python is more
281
+popular, we have more options. Let’s inject a Python environment into
282
+the stock Fossil container via a suitable “[distroless]” image instead:
284283
285284
```
286285
## ---------------------------------------------------------------------
287286
## STAGE 2: Pare that back to the bare essentials, plus Python.
288287
## ---------------------------------------------------------------------
@@ -305,33 +304,31 @@
305304
$ make container-run &&
306305
docker exec -i $(make container-version) python --version
307306
3.11.2
308307
```
309308
310
-Relative to the Tcl example, the change from “`alpine`” to Chainguard’s
311
-Python image means we have no BusyBox environment to execute the `RUN`
312
-command with, so we have to copy the `busybox.static` binary in from
313
-STAGE 1 and install it in this new STAGE 2 for the same reason the stock
314
-container does.(^This is the main reason we change `USER` temporarily to
315
-`root` here.) The compensating bonus is huge: we don’t leave a package
316
-manager sitting around inside the image, waiting to be abused.
317
-
318
-Beware that there’s a limit to how much the über-jail nature of
319
-containers can save you when you go and provide a more capable OS layer
320
-like this. For instance, you might have enabled Fossil’s [risky TH1 docs
321
-feature][th1docrisk] along with the Tcl integration feature, which
322
-effectively gives anyone with check-in rights on your repo the ability
323
-to run arbitrary Tcl code on the host when that document is rendered.
324
-The container layer should stop that script from accessing any files out
325
-on the host that you haven’t explicitly mounted into the container’s
326
-namespace, but it *can* still make network connections, modify the repo
327
-DB inside the container, and who knows what else.
309
+Relative to the Tcl example, the change from “`alpine`” to [Chainguard’s
310
+Python image][cgimgs] means we have no BusyBox environment to execute
311
+the `RUN` command with, so we have to copy the `busybox.static` binary
312
+in from STAGE 1 and install it in this new STAGE 2 for the same reason
313
+the stock container does.(^This is the main reason we change `USER`
314
+temporarily to `root` here.) There are a few other steps required to
315
+avoid causing a conflict between our previously bare-bones “OS” layer
316
+and what the Chainguard image provides. The compensation for this hassle
317
+is huge: we no longer leave a package manager sitting around inside the
318
+container, waiting for some malefactor to figure out how to abuse it.
319
+
320
+Beware that there’s a limit to this über-jail’s ability to save you when
321
+you go and provide a more capable OS layer like this. The container
322
+layer should stop an attacker from accessing any files out on the host
323
+that you haven’t explicitly mounted into the container’s namespace, but
324
+it can’t stop them from making outbound network connections or modifying
325
+the repo DB inside the container.
328326
329327
[cgimgs]: https://github.com/chainguard-images/images/tree/main/images
330328
[distroless]: https://www.chainguard.dev/unchained/minimal-container-images-towards-a-more-secure-future
331329
[MTA]: https://en.wikipedia.org/wiki/Message_transfer_agent
332
-[th1docrisk]: https://fossil-scm.org/forum/forumpost/42e0c16544
333330
334331
335332
### 3.3 <a id="caps"></a>Dropping Unnecessary Capabilities
336333
337334
The example commands above create the container with [a default set of
338335
--- www/containers.md
+++ www/containers.md
@@ -269,20 +269,19 @@
269 stage, since it’s written for the case where everything is in `/bin`.
270
271 Another useful case to consider is that you’ve installed a [server
272 extension](./serverext.wiki) and you need an interpreter for that
273 script. The first option above won’t work except in the unlikely case that
274 it’s written in one of the bare-bones script interpreters that BusyBox
275 ships.(^BusyBox’s `/bin/sh` is based on the old 4.4BSD Lite Almquist
276 shell, implementing little more than what POSIX specified in 1989, plus
277 equally stripped-down versions of AWK and `sed`.)
278
279 Let’s say the extension is written in Python. While you could handle it
280 the same way we do with Tcl, because Python is more popular, we have
281 more options. Let’s inject that into the stock container via a suitable
282 “[distroless]” image instead. Because this will conflict with the
283 bare-bones “`os`” layer we create, the method is more complicated:
284
285 ```
286 ## ---------------------------------------------------------------------
287 ## STAGE 2: Pare that back to the bare essentials, plus Python.
288 ## ---------------------------------------------------------------------
@@ -305,33 +304,31 @@
305 $ make container-run &&
306 docker exec -i $(make container-version) python --version
307 3.11.2
308 ```
309
310 Relative to the Tcl example, the change from “`alpine`” to Chainguard’s
311 Python image means we have no BusyBox environment to execute the `RUN`
312 command with, so we have to copy the `busybox.static` binary in from
313 STAGE 1 and install it in this new STAGE 2 for the same reason the stock
314 container does.(^This is the main reason we change `USER` temporarily to
315 `root` here.) The compensating bonus is huge: we don’t leave a package
316 manager sitting around inside the image, waiting to be abused.
317
318 Beware that there’s a limit to how much the über-jail nature of
319 containers can save you when you go and provide a more capable OS layer
320 like this. For instance, you might have enabled Fossil’s [risky TH1 docs
321 feature][th1docrisk] along with the Tcl integration feature, which
322 effectively gives anyone with check-in rights on your repo the ability
323 to run arbitrary Tcl code on the host when that document is rendered.
324 The container layer should stop that script from accessing any files out
325 on the host that you haven’t explicitly mounted into the container’s
326 namespace, but it *can* still make network connections, modify the repo
327 DB inside the container, and who knows what else.
328
329 [cgimgs]: https://github.com/chainguard-images/images/tree/main/images
330 [distroless]: https://www.chainguard.dev/unchained/minimal-container-images-towards-a-more-secure-future
331 [MTA]: https://en.wikipedia.org/wiki/Message_transfer_agent
332 [th1docrisk]: https://fossil-scm.org/forum/forumpost/42e0c16544
333
334
335 ### 3.3 <a id="caps"></a>Dropping Unnecessary Capabilities
336
337 The example commands above create the container with [a default set of
338
--- www/containers.md
+++ www/containers.md
@@ -269,20 +269,19 @@
269 stage, since it’s written for the case where everything is in `/bin`.
270
271 Another useful case to consider is that you’ve installed a [server
272 extension](./serverext.wiki) and you need an interpreter for that
273 script. The first option above won’t work except in the unlikely case that
274 it’s written for one of the bare-bones script interpreters that BusyBox
275 ships.(^BusyBox’s `/bin/sh` is based on the old 4.4BSD Lite Almquist
276 shell, implementing little more than what POSIX specified in 1989, plus
277 equally stripped-down versions of AWK and `sed`.)
278
279 Let’s say the extension is written in Python. While you could handle it
280 the same way we do with the Tcl example above, because Python is more
281 popular, we have more options. Let’s inject a Python environment into
282 the stock Fossil container via a suitable “[distroless]” image instead:
 
283
284 ```
285 ## ---------------------------------------------------------------------
286 ## STAGE 2: Pare that back to the bare essentials, plus Python.
287 ## ---------------------------------------------------------------------
@@ -305,33 +304,31 @@
304 $ make container-run &&
305 docker exec -i $(make container-version) python --version
306 3.11.2
307 ```
308
309 Relative to the Tcl example, the change from “`alpine`” to [Chainguard’s
310 Python image][cgimgs] means we have no BusyBox environment to execute
311 the `RUN` command with, so we have to copy the `busybox.static` binary
312 in from STAGE 1 and install it in this new STAGE 2 for the same reason
313 the stock container does.(^This is the main reason we change `USER`
314 temporarily to `root` here.) There are a few other steps required to
315 avoid causing a conflict between our previously bare-bones “OS” layer
316 and what the Chainguard image provides. The compensation for this hassle
317 is huge: we no longer leave a package manager sitting around inside the
318 container, waiting for some malefactor to figure out how to abuse it.
319
320 Beware that there’s a limit to this über-jail’s ability to save you when
321 you go and provide a more capable OS layer like this. The container
322 layer should stop an attacker from accessing any files out on the host
323 that you haven’t explicitly mounted into the container’s namespace, but
324 it can’t stop them from making outbound network connections or modifying
325 the repo DB inside the container.
 
326
327 [cgimgs]: https://github.com/chainguard-images/images/tree/main/images
328 [distroless]: https://www.chainguard.dev/unchained/minimal-container-images-towards-a-more-secure-future
329 [MTA]: https://en.wikipedia.org/wiki/Message_transfer_agent
 
330
331
332 ### 3.3 <a id="caps"></a>Dropping Unnecessary Capabilities
333
334 The example commands above create the container with [a default set of
335

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button