<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.alpinelinux.org/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Darkfader</id>
	<title>Alpine Linux - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.alpinelinux.org/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Darkfader"/>
	<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/wiki/Special:Contributions/Darkfader"/>
	<updated>2026-04-28T02:04:28Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.40.0</generator>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32262</id>
		<title>User:Darkfader/distcc</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32262"/>
		<updated>2026-04-01T00:36:15Z</updated>

		<summary type="html">&lt;p&gt;Darkfader: /* ccache and memcached */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi,&lt;br /&gt;
&lt;br /&gt;
I&#039;m preparing this page. It can take a long time till I finish.&lt;br /&gt;
If you are also wishing to write on this topic, feel free to integrate the content.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Document overview ==&lt;br /&gt;
&lt;br /&gt;
I noticed that almost every distro has one partially complete, partially helpful document on how to use distcc on the distro.&lt;br /&gt;
Usually they also have one for ccache.&lt;br /&gt;
In either case, they&#039;re enough to get started, but not really a reliable watertight thing.&lt;br /&gt;
We definitely needed one of our own.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== goal ===&lt;br /&gt;
&lt;br /&gt;
to describe a working setup for building aports in easiest/fastests fashion&lt;br /&gt;
not planning to add versatility or features where it would make the setup more errorprone.&lt;br /&gt;
the page should describe enough of the steps to successfully compile an LTS kernel via aports and have that job be distributed over multiple nodes.&lt;br /&gt;
Logs should be set up and able to display errors, but not show any errors during the test compile.&lt;br /&gt;
&lt;br /&gt;
To include a path for analysis via testing components.&lt;br /&gt;
&lt;br /&gt;
distcc can greatly improve compile speeds for large software, it comes with a different set of features than ccache; it focusses not avoiding unneccessary compile work, but on a way to speed up the necessary one.&lt;br /&gt;
&lt;br /&gt;
There&#039;s valuable info in the docs of other distros, it should be referenced here (i.e. the arch wiki troubleshooting), when it makes sense, add a TOC for their content.&lt;br /&gt;
&lt;br /&gt;
=== audience ===&lt;br /&gt;
people running software builds on alpine and have multiple computers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This page will show a specific installation, specific configuration, and specific tests, resulting in a specific set of functionality that can be tested to be working.&lt;br /&gt;
&lt;br /&gt;
== installation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Packages ===&lt;br /&gt;
&lt;br /&gt;
you need, on each host&lt;br /&gt;
* distcc&lt;br /&gt;
* distccd-openrc&lt;br /&gt;
* distcc-pump&lt;br /&gt;
* distcc-pump-pyc&lt;br /&gt;
&lt;br /&gt;
the .pyc will speed up the invocations, without it &lt;br /&gt;
idk if one or both should be installed in that case. but it appears to be also automatically be precompiled in /usr/lib/python3.12/site-packages/include_server/__pycache__/ so what does the package do exactly?&lt;br /&gt;
&lt;br /&gt;
There&#039;s some references to cpython-312, so maybe it actually still uses classy python-c conversion or matbe that&#039;s just a component for reading C source code. I have zero idea.&lt;br /&gt;
&lt;br /&gt;
you also need stuff to do compiles&lt;br /&gt;
* alpine sdk&lt;br /&gt;
* clang&lt;br /&gt;
* binutils&lt;br /&gt;
...&lt;br /&gt;
* elfutils(-dev)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Settings ===&lt;br /&gt;
==== settings for distcc ====&lt;br /&gt;
&lt;br /&gt;
* there&#039;s /etc/default/distcc&lt;br /&gt;
* there&#039;s /etc/conf.d/distcc &lt;br /&gt;
&lt;br /&gt;
make all your settings here&lt;br /&gt;
take care with the listen address, if you specify an IP it&#039;ll not be on 127.0.0.1 in case you would have localhost in your list...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* command_whitelist.sh &lt;br /&gt;
&lt;br /&gt;
this is half functional, you need to set things here but you also need to maintain the symlinks that are collected under /usr/lib/distcc (for your compilers) and /usr/lib/distcc/bin (for itself)&lt;br /&gt;
&lt;br /&gt;
you MUST run the script to update the compilers!&lt;br /&gt;
Info for script and what files it will create&lt;br /&gt;
&lt;br /&gt;
/usr/sbin/update-distcc-symlinks&lt;br /&gt;
&lt;br /&gt;
tschike:/usr/bin# ls -l /usr/lib/distcc/&lt;br /&gt;
total 4&lt;br /&gt;
drwxr-xr-x 2 root root 4096 Mar  2 18:14 bin&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c89 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c99 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 cc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc-15.2.0 -&amp;gt; ../../bin/distcc&lt;br /&gt;
&lt;br /&gt;
distcc itself is in bin&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cpp -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 g++ -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 06:49 x86_64-alpine-linux-musl-gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
&lt;br /&gt;
the last symplink here is wrong, made by me and would not work...&lt;br /&gt;
BAD symlink.&lt;br /&gt;
&lt;br /&gt;
=== distcc hosts file ===&lt;br /&gt;
&lt;br /&gt;
idk about that thing it&#039;s odd&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== abuild.conf ===&lt;br /&gt;
&lt;br /&gt;
settings for aports&lt;br /&gt;
* cc=&lt;br /&gt;
* cxx=&lt;br /&gt;
* cpp=&lt;br /&gt;
* cflags=&lt;br /&gt;
* njobs&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== detail infos ==&lt;br /&gt;
&lt;br /&gt;
???&lt;br /&gt;
&lt;br /&gt;
=== hosts syntax ===&lt;br /&gt;
&lt;br /&gt;
* myhost otherhost&lt;br /&gt;
* myhost,cpp,lzo myotherhost,cpp,lzo&lt;br /&gt;
&lt;br /&gt;
==== the host ====&lt;br /&gt;
&lt;br /&gt;
hostname/ip&lt;br /&gt;
localhost&lt;br /&gt;
127.0.0.1&lt;br /&gt;
::1 - does not work&lt;br /&gt;
&lt;br /&gt;
==== protocol ====&lt;br /&gt;
&lt;br /&gt;
* no protocol given&lt;br /&gt;
* ,cpp,lzo protocol&lt;br /&gt;
&lt;br /&gt;
cpp implies lzo, it requires compression, even if you have 10gbit/s or more, it&#039;s just hardcoded&lt;br /&gt;
&lt;br /&gt;
=== threads ===&lt;br /&gt;
/number of workers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== architecture ==&lt;br /&gt;
it can handle C, C++, ObjC, maybe some other stuff&lt;br /&gt;
&lt;br /&gt;
* what happens with normal xmit&lt;br /&gt;
* what happens with pump mode&lt;br /&gt;
* at which step the include server is used and how it collects the includes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== distribution algorithm ===&lt;br /&gt;
honestly I simply don&#039;t get it&lt;br /&gt;
&lt;br /&gt;
* The order matters&lt;br /&gt;
* The number of threads matters&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== localhost ====&lt;br /&gt;
&lt;br /&gt;
* localhost precedence&lt;br /&gt;
* localhost fallback&lt;br /&gt;
&lt;br /&gt;
variable: DISTCC_FALLBACK&lt;br /&gt;
&lt;br /&gt;
0 = Fail to compile if it would need to fallback to a normal local gcc call&lt;br /&gt;
1 = If remote compile fails, just do it yourself&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Operation ==&lt;br /&gt;
&lt;br /&gt;
=== startup and shutdown ===&lt;br /&gt;
service distcc stop is not entirely reliable (it can take a minute after the stop until the processes are gone and sometimes it will never stop&lt;br /&gt;
this is very bad with openrc, the openrc script returns after a second and only relies on its service flags, not the process status.&lt;br /&gt;
manually check after stopping, wait a min, if needed, kill it all.&lt;br /&gt;
at some point the rc file needs to be rewritten, it can&#039;t stay like it is.&lt;br /&gt;
&lt;br /&gt;
if you used a pump mode session, that also needs a logout (pump --shutdown)&lt;br /&gt;
avoid running multiple startups without shutdown in one session. it&#039;s safe as far as I can tell but nothing cleans up these processes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== ccache and distributed caches ===&lt;br /&gt;
CCACHE is said to be conflicting with pump mode unless when you call them in the backend&lt;br /&gt;
so, where you start the compile, you don&#039;t use it&lt;br /&gt;
where the compile happens, you use it&lt;br /&gt;
they can share the cache via memcached, this is a nice trick for consistency&lt;br /&gt;
Upon looking at the ccache website, it seems the correct mechanism is not memcached but Redis. This would work just as well. Generally a cache shared in this way would be optimal for performance.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This patch is described to be solving the interactions between ccache and distcc to work much better&lt;br /&gt;
https://patch-diff.githubusercontent.com/raw/ccache/ccache/pull/301.diff&lt;br /&gt;
&lt;br /&gt;
patch status is, unclear&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
zephyrOS runs KeyDB backend for distcc at scale since a while.&lt;br /&gt;
They picked this software to not need a large ram redis server.&lt;br /&gt;
One could alternatively use one system if it has enough ram (rumor has it DDR3 ECC is cheap)&lt;br /&gt;
&lt;br /&gt;
=== dockerized / native ===&lt;br /&gt;
&lt;br /&gt;
it remains mostly the same, a container needs to make sure it monitors the right services (distccd, nginx, include_server)&lt;br /&gt;
if you&#039;re using zeroconf, you need to somehow expose the mdns service broadcasts &amp;amp; receptio&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== untested build container system ====&lt;br /&gt;
&lt;br /&gt;
See this one https://github.com/bensuperpc/docker-distcc&lt;br /&gt;
not yet tested, but this could be a good basis for a &#039;best practice&#039; container.&lt;br /&gt;
There&#039;s others, especially for crossbuilds, but those are also very complex to modify.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Processs list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
Workdir list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
=== alpine-chroot ===&lt;br /&gt;
&lt;br /&gt;
when using the &#039;official&#039; script there&#039;s still some odd pieces, seemed to be the processes died on logout. but not all of them.&lt;br /&gt;
&lt;br /&gt;
==== manual launch ====&lt;br /&gt;
&lt;br /&gt;
Starting the daemon would be using&lt;br /&gt;
/usr/bin/distccd --pid-file /var/run/distccd/distccd.pid -N 15 --user distcc --port 3632 --log-level=debug --log-file=/var/log/distccd.log --allow my-sub-net/24&lt;br /&gt;
&lt;br /&gt;
==== localhost? =====&lt;br /&gt;
unclear if you need to use --allow for 127.0.0.1/32 or something to allow the remote preproccesor.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Gitlab integration ===&lt;br /&gt;
&lt;br /&gt;
TBA&lt;br /&gt;
&lt;br /&gt;
Maybe work from this k8s howto, it&#039;s a bit more prod-grade than most:&lt;br /&gt;
&lt;br /&gt;
https://cinaq.com/blog/2020/05/10/speed-up-docker-builds-with-distcc-ccache-and-kubernetes/&lt;br /&gt;
&lt;br /&gt;
== Kernel specific settings ==&lt;br /&gt;
&lt;br /&gt;
currently (distcc 3.4-r9 on Alpine) you need a patch to build the kernel.&lt;br /&gt;
See &lt;br /&gt;
&lt;br /&gt;
=== Include server Settings ===&lt;br /&gt;
&lt;br /&gt;
cache reset triggers&lt;br /&gt;
This ought to be set before enabling pump mode.&lt;br /&gt;
&lt;br /&gt;
export INCLUDE_SERVER_ARGS=&amp;quot;--stat_reset_triggers=include/linux/compile.h:include/asm/asm-offsets.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
link to explanation TBA&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Disabling GCC Plugins ===&lt;br /&gt;
&lt;br /&gt;
KConfig unselect HAVE_GCC_PLUGINS&lt;br /&gt;
&lt;br /&gt;
Some info is here in the troubleshooting part of the Arch Wiki&lt;br /&gt;
https://wiki.archlinux.org/title/Distcc#Troubleshooting&lt;br /&gt;
&lt;br /&gt;
=== Patches ===&lt;br /&gt;
&lt;br /&gt;
Other things (for 6.6LTS)&lt;br /&gt;
PCIe Stub patch&lt;br /&gt;
&lt;br /&gt;
=== Autoconf === &lt;br /&gt;
&lt;br /&gt;
No known setup examples&lt;br /&gt;
Add whatever it publishes in mdns&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== troubleshooting / analysis ==&lt;br /&gt;
&lt;br /&gt;
=== testing ===&lt;br /&gt;
&lt;br /&gt;
# turn off fallback DISTCC_FALLBACK=1&lt;br /&gt;
# set distcc up to point at specific system under test DISTCC_HOSTS=&amp;quot;mytestbox,cpp,lzo&amp;quot;&lt;br /&gt;
# GCC example compiles&lt;br /&gt;
## code example C&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example C++&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example ObjC&lt;br /&gt;
## same with included header&lt;br /&gt;
# Cmake example compiles&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docoument the thing with compile launcher ccache;distcc&lt;br /&gt;
there&#039;s some blog post, point to that&lt;br /&gt;
no ccache here yet&lt;br /&gt;
show $CC differences distcc vs gcc, what configure scripts see&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Latency ===&lt;br /&gt;
&lt;br /&gt;
Latency of pump mode startups and fallbacks needs to be investigated.&lt;br /&gt;
LZO is enforced even if you have faster network&lt;br /&gt;
DNS Requests, very old bug report from Gcode, one request per call, is it true? how to get rid of it?&lt;br /&gt;
TMPDIR is respected, make sure it&#039;s on ramdisk even on the remote nodes.&lt;br /&gt;
Compile ideally never goes to disk when it doesn&#039;t have to.&lt;br /&gt;
How efficient is the include server collection and unpacking?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== failed to distribute, running locally instead ===&lt;br /&gt;
&lt;br /&gt;
the curse of the ancient, wise bulgarian witch compildora nottherea has befallen people all over the world. only strict and mindless adherence to rituals passed down from generation to generation has given hope to those who are under her ages old spell. again and again it reemerges to prey on idealistic young men and women who spend so much time at their unholy computers that they try to spend less time there by spending a lot of time trying to optimize what the computer does, slowly, instead of reflecting on why they are there, while the computer is busy working, and why they try to solve this by adding a component that makes the computer be more error-prone at that same work, increasing the need of their presense at this idolized thinking machine to oversee and often repair, or worse, mindlessly restart its doing.&lt;br /&gt;
if the curse is not lifted, despair may befall them and all they see is the need to investigate and ruminate further on the workings of this tool, ignoring thereby the obivous flaws that stem from of its alchemic origins.&lt;br /&gt;
&lt;br /&gt;
just wait till you find out it has a backoff alghoritm deciding whether to call out to a remote server independent of that server functioning. graceful performance degradation is the goal, and degrading it is while we try to figure this out.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Node Selection algorithm ====&lt;br /&gt;
&lt;br /&gt;
as per my understanding, a flowchart goes here:&lt;br /&gt;
&lt;br /&gt;
# compile task&lt;br /&gt;
# evaluate whether to run locally by job nature&lt;br /&gt;
# determine if local host&#039;s load is notable&lt;br /&gt;
# look at distcc hosts list&lt;br /&gt;
# do something based off localhost entry if first&lt;br /&gt;
# filter for nodes with cpp flag&lt;br /&gt;
# do something based off localhost entry if not first&lt;br /&gt;
# further prioritize by server order, first is handled in some way&lt;br /&gt;
# skip nodes in backoff prisons&lt;br /&gt;
# balance and priotize by server thread number, if given&lt;br /&gt;
# send to suitable host&lt;br /&gt;
# if compile not successful, proceed on other node&lt;br /&gt;
# if nodes depleted, proceed on localhost&lt;br /&gt;
&lt;br /&gt;
== security ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== tcpwrapper style ip range filter ===&lt;br /&gt;
&lt;br /&gt;
the original security model consists of ip restrictions.&lt;br /&gt;
there seems to also be some GSSAPI user auth.&lt;br /&gt;
further, commands that can be called are restricted by name and location.&lt;br /&gt;
this appears to be a runtime whitelist lookup, meaning it&#039;s done and authorized by the same parts of the daemon as processes the compile request along with the intended compiler.&lt;br /&gt;
so the main weaknesses against malicious clients seem to be in sending things to compile, and in overriding the remote compiler to use.&lt;br /&gt;
it can be assumed that a malicious client able to exploit the compiler handshake can then run arbitrary stuff.&lt;br /&gt;
There&#039;s at least a github issue regarding this (link lost, but see here: https://gitlab.com/postmarketOS/pmbootstrap/-/work_items/1619) suggesting running over ssh. That does only partitally alleviate this risk with regard  to a key based verfication of a client versus a the standard ip restrictions which always include some parsing.&lt;br /&gt;
So this protects against someone directly exploiting the TCP code of distcc.&lt;br /&gt;
It does not protect against malicious clients.&lt;br /&gt;
(ssh force command can&#039;t be used or you&#039;ll not compile anything)&lt;br /&gt;
&lt;br /&gt;
The basic step for protecting access should be filtering who can access the distcc server, so use nftables etc. to restrict access to port 3262 (??) set up the internal filter the same way.&lt;br /&gt;
&lt;br /&gt;
=== seccomp ===&lt;br /&gt;
&lt;br /&gt;
The next thing is to confine the compiler calls to only write in their temp directory and that they can only run compilers (using nsjail, apparmor, selinux etc)&lt;br /&gt;
&lt;br /&gt;
the above issue also references the second bit of security, namely a seccomp filter which will already cover a good bit of the above&lt;br /&gt;
https://github.com/distcc/distcc/pull/235&lt;br /&gt;
the commit got closed without merge, from what I see.&lt;br /&gt;
&lt;br /&gt;
I will update the entry once it&#039;s clear if the patch was later added or instead nothing was done.&lt;br /&gt;
&lt;br /&gt;
=== privs ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The other internal security bit is that they do some priviledge dropping. it runs as a dedicated user (distcc), so you can also have an audit policy, and can/could use something like iptables&#039; to ensure it can only connect to the other distcc/memcached hosts, but nothing else.&lt;br /&gt;
&lt;br /&gt;
=== compiler list ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
One needs to investigate when compiler_whitelist.sh is exactly called. as far as I recall it doesn&#039;t close stdin/stdout.&lt;br /&gt;
&lt;br /&gt;
=== distcc-hardened ===&lt;br /&gt;
&lt;br /&gt;
Alpine adds some hardening patch, idk what nature/origina that has.&lt;br /&gt;
&lt;br /&gt;
=== selinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
there&#039;s also a selinux policy for distcc from gentoo or liguros if one is so inclined.  &lt;br /&gt;
links for further review:&lt;br /&gt;
&lt;br /&gt;
- https://repology.org/project/selinux-distcc/versions  &lt;br /&gt;
- https://gitlab.com/liguros/liguros-repo/-/tree/stable/sec-policy/selinux-distcc&lt;br /&gt;
&lt;br /&gt;
=== general posture ===&lt;br /&gt;
&lt;br /&gt;
Some security measures like the above should definitely be used since the project at its core relies on accepting foreign input over the network, has only a few part-time maintainers that cannot easily drive the project forward or do large refactors.&lt;br /&gt;
But the seccomp changes were done almost 10 years ago, so, if they were actually upstreamed, I&#039;d say they came through.&lt;br /&gt;
&lt;br /&gt;
A kind of overengineered solulion would be to use netlabel to ensure application integrity across hosts, meaning only a valid process would be able to send packets to the distcc nodes :-)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Alternatives ==&lt;br /&gt;
&lt;br /&gt;
Arch wiki refers to a fork by SUSE&lt;br /&gt;
https://github.com/icecc/icecream&lt;br /&gt;
&lt;br /&gt;
It appears &#039;maybe better&#039; but hard to tell. There&#039;s no mention if maybe SUSE&#039;s OBS uses it or something. Without more knowledge of their use I don&#039;t know how big a benefit will come from switching. At least you&#039;d wanna know they have a higher commitment to maintenance than the understaffed distcc &#039;team&#039; of current.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A commercial alternative (incredibuild https://www.incredibuild.com/) exists, but I have not tried it.&lt;br /&gt;
There are references to some &#039;forever free&#039; tier, also, but I could not yet find the terms and conditions for having a &#039;forever free thing&#039;. it also seems you need a windows-based &#039;coordinator&#039; host.&lt;br /&gt;
opinion: generally if there&#039;s some professional context with high (business) pressure for faster builds I would check that out, and then without time pressure build a great distcc setup for the long-term.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Architecturally it seems to be taking the ccache approach with a shared cache and smarter redistribution.&lt;br /&gt;
So anything that can call ccache is something they can scale out. I&#039;ll add a link later, for those whom it helps.&lt;br /&gt;
Naturally it is out of scope for this article.&lt;br /&gt;
Nonetheless it&#039;s interesting since the ordering of how to run ccache and how to run distcc is an issue that also exists in the OSS world. Not just that we don&#039;t have an automatic setup and integration of the tools (ccache, redis, distccd, distcc-pump) but we also don&#039;t have collected sufficient data to aid in deciding which aproach is the best.&lt;br /&gt;
Integrating into CIs (gitlab-runner specifically) is another item where cache persistence becomes very fragile.&lt;br /&gt;
Having an alpine build container that knows how to use ccache with redis and distcc-pump would be a possible step forward.&lt;br /&gt;
&lt;br /&gt;
== Other sources ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://retroflux.net/blog/distcc-adventures/&lt;/div&gt;</summary>
		<author><name>Darkfader</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32261</id>
		<title>User:Darkfader/distcc</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32261"/>
		<updated>2026-04-01T00:34:32Z</updated>

		<summary type="html">&lt;p&gt;Darkfader: /* ccache and memcached */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi,&lt;br /&gt;
&lt;br /&gt;
I&#039;m preparing this page. It can take a long time till I finish.&lt;br /&gt;
If you are also wishing to write on this topic, feel free to integrate the content.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Document overview ==&lt;br /&gt;
&lt;br /&gt;
I noticed that almost every distro has one partially complete, partially helpful document on how to use distcc on the distro.&lt;br /&gt;
Usually they also have one for ccache.&lt;br /&gt;
In either case, they&#039;re enough to get started, but not really a reliable watertight thing.&lt;br /&gt;
We definitely needed one of our own.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== goal ===&lt;br /&gt;
&lt;br /&gt;
to describe a working setup for building aports in easiest/fastests fashion&lt;br /&gt;
not planning to add versatility or features where it would make the setup more errorprone.&lt;br /&gt;
the page should describe enough of the steps to successfully compile an LTS kernel via aports and have that job be distributed over multiple nodes.&lt;br /&gt;
Logs should be set up and able to display errors, but not show any errors during the test compile.&lt;br /&gt;
&lt;br /&gt;
To include a path for analysis via testing components.&lt;br /&gt;
&lt;br /&gt;
distcc can greatly improve compile speeds for large software, it comes with a different set of features than ccache; it focusses not avoiding unneccessary compile work, but on a way to speed up the necessary one.&lt;br /&gt;
&lt;br /&gt;
There&#039;s valuable info in the docs of other distros, it should be referenced here (i.e. the arch wiki troubleshooting), when it makes sense, add a TOC for their content.&lt;br /&gt;
&lt;br /&gt;
=== audience ===&lt;br /&gt;
people running software builds on alpine and have multiple computers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This page will show a specific installation, specific configuration, and specific tests, resulting in a specific set of functionality that can be tested to be working.&lt;br /&gt;
&lt;br /&gt;
== installation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Packages ===&lt;br /&gt;
&lt;br /&gt;
you need, on each host&lt;br /&gt;
* distcc&lt;br /&gt;
* distccd-openrc&lt;br /&gt;
* distcc-pump&lt;br /&gt;
* distcc-pump-pyc&lt;br /&gt;
&lt;br /&gt;
the .pyc will speed up the invocations, without it &lt;br /&gt;
idk if one or both should be installed in that case. but it appears to be also automatically be precompiled in /usr/lib/python3.12/site-packages/include_server/__pycache__/ so what does the package do exactly?&lt;br /&gt;
&lt;br /&gt;
There&#039;s some references to cpython-312, so maybe it actually still uses classy python-c conversion or matbe that&#039;s just a component for reading C source code. I have zero idea.&lt;br /&gt;
&lt;br /&gt;
you also need stuff to do compiles&lt;br /&gt;
* alpine sdk&lt;br /&gt;
* clang&lt;br /&gt;
* binutils&lt;br /&gt;
...&lt;br /&gt;
* elfutils(-dev)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Settings ===&lt;br /&gt;
==== settings for distcc ====&lt;br /&gt;
&lt;br /&gt;
* there&#039;s /etc/default/distcc&lt;br /&gt;
* there&#039;s /etc/conf.d/distcc &lt;br /&gt;
&lt;br /&gt;
make all your settings here&lt;br /&gt;
take care with the listen address, if you specify an IP it&#039;ll not be on 127.0.0.1 in case you would have localhost in your list...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* command_whitelist.sh &lt;br /&gt;
&lt;br /&gt;
this is half functional, you need to set things here but you also need to maintain the symlinks that are collected under /usr/lib/distcc (for your compilers) and /usr/lib/distcc/bin (for itself)&lt;br /&gt;
&lt;br /&gt;
you MUST run the script to update the compilers!&lt;br /&gt;
Info for script and what files it will create&lt;br /&gt;
&lt;br /&gt;
/usr/sbin/update-distcc-symlinks&lt;br /&gt;
&lt;br /&gt;
tschike:/usr/bin# ls -l /usr/lib/distcc/&lt;br /&gt;
total 4&lt;br /&gt;
drwxr-xr-x 2 root root 4096 Mar  2 18:14 bin&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c89 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c99 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 cc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc-15.2.0 -&amp;gt; ../../bin/distcc&lt;br /&gt;
&lt;br /&gt;
distcc itself is in bin&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cpp -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 g++ -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 06:49 x86_64-alpine-linux-musl-gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
&lt;br /&gt;
the last symplink here is wrong, made by me and would not work...&lt;br /&gt;
BAD symlink.&lt;br /&gt;
&lt;br /&gt;
=== distcc hosts file ===&lt;br /&gt;
&lt;br /&gt;
idk about that thing it&#039;s odd&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== abuild.conf ===&lt;br /&gt;
&lt;br /&gt;
settings for aports&lt;br /&gt;
* cc=&lt;br /&gt;
* cxx=&lt;br /&gt;
* cpp=&lt;br /&gt;
* cflags=&lt;br /&gt;
* njobs&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== detail infos ==&lt;br /&gt;
&lt;br /&gt;
???&lt;br /&gt;
&lt;br /&gt;
=== hosts syntax ===&lt;br /&gt;
&lt;br /&gt;
* myhost otherhost&lt;br /&gt;
* myhost,cpp,lzo myotherhost,cpp,lzo&lt;br /&gt;
&lt;br /&gt;
==== the host ====&lt;br /&gt;
&lt;br /&gt;
hostname/ip&lt;br /&gt;
localhost&lt;br /&gt;
127.0.0.1&lt;br /&gt;
::1 - does not work&lt;br /&gt;
&lt;br /&gt;
==== protocol ====&lt;br /&gt;
&lt;br /&gt;
* no protocol given&lt;br /&gt;
* ,cpp,lzo protocol&lt;br /&gt;
&lt;br /&gt;
cpp implies lzo, it requires compression, even if you have 10gbit/s or more, it&#039;s just hardcoded&lt;br /&gt;
&lt;br /&gt;
=== threads ===&lt;br /&gt;
/number of workers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== architecture ==&lt;br /&gt;
it can handle C, C++, ObjC, maybe some other stuff&lt;br /&gt;
&lt;br /&gt;
* what happens with normal xmit&lt;br /&gt;
* what happens with pump mode&lt;br /&gt;
* at which step the include server is used and how it collects the includes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== distribution algorithm ===&lt;br /&gt;
honestly I simply don&#039;t get it&lt;br /&gt;
&lt;br /&gt;
* The order matters&lt;br /&gt;
* The number of threads matters&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== localhost ====&lt;br /&gt;
&lt;br /&gt;
* localhost precedence&lt;br /&gt;
* localhost fallback&lt;br /&gt;
&lt;br /&gt;
variable: DISTCC_FALLBACK&lt;br /&gt;
&lt;br /&gt;
0 = Fail to compile if it would need to fallback to a normal local gcc call&lt;br /&gt;
1 = If remote compile fails, just do it yourself&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Operation ==&lt;br /&gt;
&lt;br /&gt;
=== startup and shutdown ===&lt;br /&gt;
service distcc stop is not entirely reliable (it can take a minute after the stop until the processes are gone and sometimes it will never stop&lt;br /&gt;
this is very bad with openrc, the openrc script returns after a second and only relies on its service flags, not the process status.&lt;br /&gt;
manually check after stopping, wait a min, if needed, kill it all.&lt;br /&gt;
at some point the rc file needs to be rewritten, it can&#039;t stay like it is.&lt;br /&gt;
&lt;br /&gt;
if you used a pump mode session, that also needs a logout (pump --shutdown)&lt;br /&gt;
avoid running multiple startups without shutdown in one session. it&#039;s safe as far as I can tell but nothing cleans up these processes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== ccache and memcached ===&lt;br /&gt;
CCACHE is said to be conflicting with pump mode unless when you call them in the backend&lt;br /&gt;
so, where you start the compile, you don&#039;t use it&lt;br /&gt;
where the compile happens, you use it&lt;br /&gt;
they can share the cache via memcached, this is a nice trick for consistency&lt;br /&gt;
Upon looking at the ccache website, it seems the correct mechanism is not memcached but Redis. This would work just as well. Generally a cache shared in this way would be optimal for performance.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This patch is described to be solving the interactions between ccache and distcc to work much better&lt;br /&gt;
https://patch-diff.githubusercontent.com/raw/ccache/ccache/pull/301.diff&lt;br /&gt;
&lt;br /&gt;
patch status is, unclear&lt;br /&gt;
&lt;br /&gt;
=== dockerized / native ===&lt;br /&gt;
&lt;br /&gt;
it remains mostly the same, a container needs to make sure it monitors the right services (distccd, nginx, include_server)&lt;br /&gt;
if you&#039;re using zeroconf, you need to somehow expose the mdns service broadcasts &amp;amp; receptio&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== untested build container system ====&lt;br /&gt;
&lt;br /&gt;
See this one https://github.com/bensuperpc/docker-distcc&lt;br /&gt;
not yet tested, but this could be a good basis for a &#039;best practice&#039; container.&lt;br /&gt;
There&#039;s others, especially for crossbuilds, but those are also very complex to modify.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Processs list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
Workdir list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
=== alpine-chroot ===&lt;br /&gt;
&lt;br /&gt;
when using the &#039;official&#039; script there&#039;s still some odd pieces, seemed to be the processes died on logout. but not all of them.&lt;br /&gt;
&lt;br /&gt;
==== manual launch ====&lt;br /&gt;
&lt;br /&gt;
Starting the daemon would be using&lt;br /&gt;
/usr/bin/distccd --pid-file /var/run/distccd/distccd.pid -N 15 --user distcc --port 3632 --log-level=debug --log-file=/var/log/distccd.log --allow my-sub-net/24&lt;br /&gt;
&lt;br /&gt;
==== localhost? =====&lt;br /&gt;
unclear if you need to use --allow for 127.0.0.1/32 or something to allow the remote preproccesor.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Gitlab integration ===&lt;br /&gt;
&lt;br /&gt;
TBA&lt;br /&gt;
&lt;br /&gt;
Maybe work from this k8s howto, it&#039;s a bit more prod-grade than most:&lt;br /&gt;
&lt;br /&gt;
https://cinaq.com/blog/2020/05/10/speed-up-docker-builds-with-distcc-ccache-and-kubernetes/&lt;br /&gt;
&lt;br /&gt;
== Kernel specific settings ==&lt;br /&gt;
&lt;br /&gt;
currently (distcc 3.4-r9 on Alpine) you need a patch to build the kernel.&lt;br /&gt;
See &lt;br /&gt;
&lt;br /&gt;
=== Include server Settings ===&lt;br /&gt;
&lt;br /&gt;
cache reset triggers&lt;br /&gt;
This ought to be set before enabling pump mode.&lt;br /&gt;
&lt;br /&gt;
export INCLUDE_SERVER_ARGS=&amp;quot;--stat_reset_triggers=include/linux/compile.h:include/asm/asm-offsets.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
link to explanation TBA&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Disabling GCC Plugins ===&lt;br /&gt;
&lt;br /&gt;
KConfig unselect HAVE_GCC_PLUGINS&lt;br /&gt;
&lt;br /&gt;
Some info is here in the troubleshooting part of the Arch Wiki&lt;br /&gt;
https://wiki.archlinux.org/title/Distcc#Troubleshooting&lt;br /&gt;
&lt;br /&gt;
=== Patches ===&lt;br /&gt;
&lt;br /&gt;
Other things (for 6.6LTS)&lt;br /&gt;
PCIe Stub patch&lt;br /&gt;
&lt;br /&gt;
=== Autoconf === &lt;br /&gt;
&lt;br /&gt;
No known setup examples&lt;br /&gt;
Add whatever it publishes in mdns&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== troubleshooting / analysis ==&lt;br /&gt;
&lt;br /&gt;
=== testing ===&lt;br /&gt;
&lt;br /&gt;
# turn off fallback DISTCC_FALLBACK=1&lt;br /&gt;
# set distcc up to point at specific system under test DISTCC_HOSTS=&amp;quot;mytestbox,cpp,lzo&amp;quot;&lt;br /&gt;
# GCC example compiles&lt;br /&gt;
## code example C&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example C++&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example ObjC&lt;br /&gt;
## same with included header&lt;br /&gt;
# Cmake example compiles&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docoument the thing with compile launcher ccache;distcc&lt;br /&gt;
there&#039;s some blog post, point to that&lt;br /&gt;
no ccache here yet&lt;br /&gt;
show $CC differences distcc vs gcc, what configure scripts see&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Latency ===&lt;br /&gt;
&lt;br /&gt;
Latency of pump mode startups and fallbacks needs to be investigated.&lt;br /&gt;
LZO is enforced even if you have faster network&lt;br /&gt;
DNS Requests, very old bug report from Gcode, one request per call, is it true? how to get rid of it?&lt;br /&gt;
TMPDIR is respected, make sure it&#039;s on ramdisk even on the remote nodes.&lt;br /&gt;
Compile ideally never goes to disk when it doesn&#039;t have to.&lt;br /&gt;
How efficient is the include server collection and unpacking?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== failed to distribute, running locally instead ===&lt;br /&gt;
&lt;br /&gt;
the curse of the ancient, wise bulgarian witch compildora nottherea has befallen people all over the world. only strict and mindless adherence to rituals passed down from generation to generation has given hope to those who are under her ages old spell. again and again it reemerges to prey on idealistic young men and women who spend so much time at their unholy computers that they try to spend less time there by spending a lot of time trying to optimize what the computer does, slowly, instead of reflecting on why they are there, while the computer is busy working, and why they try to solve this by adding a component that makes the computer be more error-prone at that same work, increasing the need of their presense at this idolized thinking machine to oversee and often repair, or worse, mindlessly restart its doing.&lt;br /&gt;
if the curse is not lifted, despair may befall them and all they see is the need to investigate and ruminate further on the workings of this tool, ignoring thereby the obivous flaws that stem from of its alchemic origins.&lt;br /&gt;
&lt;br /&gt;
just wait till you find out it has a backoff alghoritm deciding whether to call out to a remote server independent of that server functioning. graceful performance degradation is the goal, and degrading it is while we try to figure this out.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Node Selection algorithm ====&lt;br /&gt;
&lt;br /&gt;
as per my understanding, a flowchart goes here:&lt;br /&gt;
&lt;br /&gt;
# compile task&lt;br /&gt;
# evaluate whether to run locally by job nature&lt;br /&gt;
# determine if local host&#039;s load is notable&lt;br /&gt;
# look at distcc hosts list&lt;br /&gt;
# do something based off localhost entry if first&lt;br /&gt;
# filter for nodes with cpp flag&lt;br /&gt;
# do something based off localhost entry if not first&lt;br /&gt;
# further prioritize by server order, first is handled in some way&lt;br /&gt;
# skip nodes in backoff prisons&lt;br /&gt;
# balance and priotize by server thread number, if given&lt;br /&gt;
# send to suitable host&lt;br /&gt;
# if compile not successful, proceed on other node&lt;br /&gt;
# if nodes depleted, proceed on localhost&lt;br /&gt;
&lt;br /&gt;
== security ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== tcpwrapper style ip range filter ===&lt;br /&gt;
&lt;br /&gt;
the original security model consists of ip restrictions.&lt;br /&gt;
there seems to also be some GSSAPI user auth.&lt;br /&gt;
further, commands that can be called are restricted by name and location.&lt;br /&gt;
this appears to be a runtime whitelist lookup, meaning it&#039;s done and authorized by the same parts of the daemon as processes the compile request along with the intended compiler.&lt;br /&gt;
so the main weaknesses against malicious clients seem to be in sending things to compile, and in overriding the remote compiler to use.&lt;br /&gt;
it can be assumed that a malicious client able to exploit the compiler handshake can then run arbitrary stuff.&lt;br /&gt;
There&#039;s at least a github issue regarding this (link lost, but see here: https://gitlab.com/postmarketOS/pmbootstrap/-/work_items/1619) suggesting running over ssh. That does only partitally alleviate this risk with regard  to a key based verfication of a client versus a the standard ip restrictions which always include some parsing.&lt;br /&gt;
So this protects against someone directly exploiting the TCP code of distcc.&lt;br /&gt;
It does not protect against malicious clients.&lt;br /&gt;
(ssh force command can&#039;t be used or you&#039;ll not compile anything)&lt;br /&gt;
&lt;br /&gt;
The basic step for protecting access should be filtering who can access the distcc server, so use nftables etc. to restrict access to port 3262 (??) set up the internal filter the same way.&lt;br /&gt;
&lt;br /&gt;
=== seccomp ===&lt;br /&gt;
&lt;br /&gt;
The next thing is to confine the compiler calls to only write in their temp directory and that they can only run compilers (using nsjail, apparmor, selinux etc)&lt;br /&gt;
&lt;br /&gt;
the above issue also references the second bit of security, namely a seccomp filter which will already cover a good bit of the above&lt;br /&gt;
https://github.com/distcc/distcc/pull/235&lt;br /&gt;
the commit got closed without merge, from what I see.&lt;br /&gt;
&lt;br /&gt;
I will update the entry once it&#039;s clear if the patch was later added or instead nothing was done.&lt;br /&gt;
&lt;br /&gt;
=== privs ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The other internal security bit is that they do some priviledge dropping. it runs as a dedicated user (distcc), so you can also have an audit policy, and can/could use something like iptables&#039; to ensure it can only connect to the other distcc/memcached hosts, but nothing else.&lt;br /&gt;
&lt;br /&gt;
=== compiler list ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
One needs to investigate when compiler_whitelist.sh is exactly called. as far as I recall it doesn&#039;t close stdin/stdout.&lt;br /&gt;
&lt;br /&gt;
=== distcc-hardened ===&lt;br /&gt;
&lt;br /&gt;
Alpine adds some hardening patch, idk what nature/origina that has.&lt;br /&gt;
&lt;br /&gt;
=== selinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
there&#039;s also a selinux policy for distcc from gentoo or liguros if one is so inclined.  &lt;br /&gt;
links for further review:&lt;br /&gt;
&lt;br /&gt;
- https://repology.org/project/selinux-distcc/versions  &lt;br /&gt;
- https://gitlab.com/liguros/liguros-repo/-/tree/stable/sec-policy/selinux-distcc&lt;br /&gt;
&lt;br /&gt;
=== general posture ===&lt;br /&gt;
&lt;br /&gt;
Some security measures like the above should definitely be used since the project at its core relies on accepting foreign input over the network, has only a few part-time maintainers that cannot easily drive the project forward or do large refactors.&lt;br /&gt;
But the seccomp changes were done almost 10 years ago, so, if they were actually upstreamed, I&#039;d say they came through.&lt;br /&gt;
&lt;br /&gt;
A kind of overengineered solulion would be to use netlabel to ensure application integrity across hosts, meaning only a valid process would be able to send packets to the distcc nodes :-)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Alternatives ==&lt;br /&gt;
&lt;br /&gt;
Arch wiki refers to a fork by SUSE&lt;br /&gt;
https://github.com/icecc/icecream&lt;br /&gt;
&lt;br /&gt;
It appears &#039;maybe better&#039; but hard to tell. There&#039;s no mention if maybe SUSE&#039;s OBS uses it or something. Without more knowledge of their use I don&#039;t know how big a benefit will come from switching. At least you&#039;d wanna know they have a higher commitment to maintenance than the understaffed distcc &#039;team&#039; of current.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A commercial alternative (incredibuild https://www.incredibuild.com/) exists, but I have not tried it.&lt;br /&gt;
There are references to some &#039;forever free&#039; tier, also, but I could not yet find the terms and conditions for having a &#039;forever free thing&#039;. it also seems you need a windows-based &#039;coordinator&#039; host.&lt;br /&gt;
opinion: generally if there&#039;s some professional context with high (business) pressure for faster builds I would check that out, and then without time pressure build a great distcc setup for the long-term.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Architecturally it seems to be taking the ccache approach with a shared cache and smarter redistribution.&lt;br /&gt;
So anything that can call ccache is something they can scale out. I&#039;ll add a link later, for those whom it helps.&lt;br /&gt;
Naturally it is out of scope for this article.&lt;br /&gt;
Nonetheless it&#039;s interesting since the ordering of how to run ccache and how to run distcc is an issue that also exists in the OSS world. Not just that we don&#039;t have an automatic setup and integration of the tools (ccache, redis, distccd, distcc-pump) but we also don&#039;t have collected sufficient data to aid in deciding which aproach is the best.&lt;br /&gt;
Integrating into CIs (gitlab-runner specifically) is another item where cache persistence becomes very fragile.&lt;br /&gt;
Having an alpine build container that knows how to use ccache with redis and distcc-pump would be a possible step forward.&lt;br /&gt;
&lt;br /&gt;
== Other sources ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://retroflux.net/blog/distcc-adventures/&lt;/div&gt;</summary>
		<author><name>Darkfader</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Talk:Custom_Kernel&amp;diff=32241</id>
		<title>Talk:Custom Kernel</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Talk:Custom_Kernel&amp;diff=32241"/>
		<updated>2026-03-29T16:09:21Z</updated>

		<summary type="html">&lt;p&gt;Darkfader: /* build_NAME Answer */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Needs to be adjusted for other archs&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&amp;lt;span class=&amp;quot;autosigned&amp;quot;&amp;gt;—&amp;amp;nbsp;Preceding [[Help:Signature|unsigned]] comment added by [[User:Orson Teodoro|Orson Teodoro]] ([[User talk:Orson Teodoro|{{int:talkpagelinktext}}]] • [[Special:Contributions/Orson Teodoro|{{int:contribslink}}]]) 03:36, 4 March 2018&amp;lt;/span&amp;gt;&amp;lt;/small&amp;gt;‎&lt;br /&gt;
&lt;br /&gt;
== Locations/paths of build config files ==&lt;br /&gt;
&lt;br /&gt;
My goal is to build the Virt (not Standard/LTS) kernel using the defaults for Virt, and I don&#039;t understand which files are needed in exactly which paths.&lt;br /&gt;
&lt;br /&gt;
I had difficulty understanding the excerpt below. Is anyone willing to assist me in understanding it? For example, where/what is the &amp;quot;linux-4.15&amp;quot; folder?&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;When you are done with your edits either by editing directly the APKBUILD and copying the lts.ARCH.config as .config in the linux-4.15 folder. You will then move the .config back overriding the lts.ARCH.config generated by make menuconfig.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&amp;lt;span class=&amp;quot;autosigned&amp;quot;&amp;gt;—&amp;amp;nbsp;Preceding [[Help:Signature|unsigned]] comment added by [[User:-anthumchris-|-anthumchris-]] ([[User talk:-anthumchris-|{{int:talkpagelinktext}}]] • [[Special:Contributions/-anthumchris-|{{int:contribslink}}]]) 17:34, 23 November 2024‎&amp;lt;/span&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== build_NAME ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;After you are done using the menu in the build-NAME folder by doing make menuconfig&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
It is really not clear what is meant by &amp;quot;the build-NAME folder&amp;quot; here.&lt;br /&gt;
&lt;br /&gt;
== Locations/paths of build config files Answer ==&lt;br /&gt;
&lt;br /&gt;
Usually these are the directories you would look for in linux-lts apk package development (replace &amp;quot;x86_64&amp;quot; with different $ARCH if needed) (replace $YOUR_WORK_DIR to which directory you downloaded aports to), &lt;br /&gt;
&lt;br /&gt;
Below should contain &amp;lt;code&amp;gt;APKBUILD&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;lts.x86_64.config&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;virt.x86_64.config&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;.patch&amp;lt;/code&amp;gt; files (and more $ARCH&#039;s by default, but to keep it simple, I will just state the x86_64 files)&lt;br /&gt;
{{cmd|$YOUR_WORK_DIR/aports/main/linux-lts}}&lt;br /&gt;
&lt;br /&gt;
ALL &amp;lt;code&amp;gt;.patch&amp;lt;/code&amp;gt; files that are in $YOUR_WORK_DIR/aports/main/linux-lts are also in below&lt;br /&gt;
{{cmd|$YOUR_WORK_DIR/aports/main/linux-lts/src}}&lt;br /&gt;
&lt;br /&gt;
Below is a tar compressed linux file that decompresses into linux-$VERSION&lt;br /&gt;
{{cmd|$YOUR_WORK_DIR/aports/main/linux-lts/src/linux-$VERSION.tar.gz}}&lt;br /&gt;
&lt;br /&gt;
{{cmd|$YOUR_WORK_DIR/aports/main/linux-lts/src/linux-$VERSION}}&lt;br /&gt;
{{cmd|$YOUR_WORK_DIR/aports/main/linux-lts/src/build-lts.x86_64}}&lt;br /&gt;
{{cmd|$YOUR_WORK_DIR/aports/main/linux-lts/src/build-virt.x86_64}}&lt;br /&gt;
&lt;br /&gt;
In the &amp;quot;&amp;lt;code&amp;gt;APKBUILD&amp;lt;/code&amp;gt;&amp;quot; file, change this &amp;quot;&amp;lt;code&amp;gt;source&amp;lt;/code&amp;gt;&amp;quot; line to this:&lt;br /&gt;
{{cat|$YOUR_WORK_DIR/aports/main/linux-lts/APKBUILD|...&lt;br /&gt;
source{{=}}&amp;quot;https://cdn.kernel.org/pub/linux/kernel/v${pkgver%%.*}.x/linux-$_kernver.tar.xz&lt;br /&gt;
    0001-powerpc-boot-wrapper-Add-z-notext-flag-for-ppc64le.patch&lt;br /&gt;
    0002-x86-Compress-vmlinux-with-zstd-19-instead-of-22.patch&lt;br /&gt;
    0003-kexec-add-kexec_load_disabled-boot-option.patch&lt;br /&gt;
    0004-objtool-respect-AWK-setting.patch&lt;br /&gt;
    0005-powerpc-config-defang-gcc-check-for-stack-protector-.patch&lt;br /&gt;
&lt;br /&gt;
    lts.x86_64.config&lt;br /&gt;
&lt;br /&gt;
    virt.x86_64.config&lt;br /&gt;
    &amp;quot;&lt;br /&gt;
...}}&lt;br /&gt;
&lt;br /&gt;
do &amp;lt;code&amp;gt;make menuconfig&amp;lt;/code&amp;gt; within &amp;lt;code&amp;gt;$YOUR_WORK_DIR/aports/main/linux-lts/src/linux-$VERSION&amp;lt;/code&amp;gt; and copy the .config file to &amp;lt;code&amp;gt;$YOUR_WORK_DIR/aports/main/linux-lts/lts.x86_64.config&amp;lt;/code&amp;gt; and/or &amp;lt;code&amp;gt;$YOUR_WORK_DIR/aports/main/linux-lts/virt.x86_64.config&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&amp;lt;span class=&amp;quot;autosigned&amp;quot;&amp;gt;—&amp;amp;nbsp;Preceding [[Help:Signature|unsigned]] comment added by [[User:Pursuable1652|Pursuable1652]] ([[User talk:Pursuable1652|{{int:talkpagelinktext}}]] • [[Special:Contributions/Pursuable1652|{{int:contribslink}}]]) 16:55, 25 December 2024‎&amp;lt;/span&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== build_NAME Answer ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;After you are done using the menu in the build-NAME folder by doing make menuconfig&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
the &amp;quot;build-NAME&amp;quot; folder should actually be &amp;lt;code&amp;gt;$YOUR_WORK_DIR/aports/main/linux-lts/src/linux-$VERSION&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&amp;lt;span class=&amp;quot;autosigned&amp;quot;&amp;gt;—&amp;amp;nbsp;Preceding [[Help:Signature|unsigned]] comment added by [[User:Pursuable1652|Pursuable1652]] ([[User talk:Pursuable1652|{{int:talkpagelinktext}}]] • [[Special:Contributions/Pursuable1652|{{int:contribslink}}]]) 16:55, 25 December 2024‎&amp;lt;/span&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====&lt;br /&gt;
&lt;br /&gt;
I also need to run an abuild clean after doing the menuconfig.&lt;br /&gt;
those parts are still muddy.&lt;br /&gt;
&lt;br /&gt;
[[User:Darkfader|Darkfader]] ([[User talk:Darkfader|talk]]) 16:09, 29 March 2026 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Page ready for regular release? ==&lt;br /&gt;
Perhaps this [[Custom Kernel]] page is now ready for regular use, and the &amp;quot;This material is work-in-progress&amp;quot; banner can be removed, unless there is a shortcoming found.  This draft state has held since it was helpfully created in 2014.  &lt;br /&gt;
Thanks for kind updates by [[User:Prabuanand|Prabuanand]], [[User:Pawciobiel|Pawciobiel]], [[User:Teopp7|Teopp7]], [[User:Fossdd|Fossdd]], [[User:Anthumchris|Anthumchris]], [[User:Gsora|Gsora]], [[User:Zcrayfish|Zcrayfish]], [[User:Omni|Omni]], [[User:Nabbi|Nabbi]], [[User:Psykose|Psykose]], [[User:Egberts|Egberts]] and thanks also for kind contributions by others that have not been active on the wiki for over five years. [[User:John3-16|John3-16]] ([[User talk:John3-16|talk]]) 19:22, 30 December 2025 (UTC)&lt;br /&gt;
:Further to one month without objections, having tagged recent contributors, the &#039;&#039;&amp;quot;Work-in-progress&amp;quot;&#039;&#039; flag is being removed.  The contributor who kindly initiated this useful page duly placed the flag in the original [https://wiki.alpinelinux.org/w/index.php?title=Custom_Kernel&amp;amp;oldid=10201 draft version] in 2014 and last contributed to the wiki that year. [[User:John3-16|John3-16]] ([[User talk:John3-16|talk]]) 02:02, 1 February 2026 (UTC)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== kexec ===&lt;br /&gt;
&lt;br /&gt;
the kernel and tools now have better exploit-kernel protection and there&#039;s actually been some ransomware actors using kexec to load bad things[tm]&lt;br /&gt;
&lt;br /&gt;
is there a way to sign kernels on alpine? If so, maybe we should document that and link to it here.&lt;br /&gt;
CONFIG_KECEC_SIG etc.&lt;br /&gt;
&lt;br /&gt;
[[User:Darkfader|Darkfader]] ([[User talk:Darkfader|talk]]) 16:07, 29 March 2026 (UTC)&lt;/div&gt;</summary>
		<author><name>Darkfader</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Talk:Custom_Kernel&amp;diff=32240</id>
		<title>Talk:Custom Kernel</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Talk:Custom_Kernel&amp;diff=32240"/>
		<updated>2026-03-29T16:07:42Z</updated>

		<summary type="html">&lt;p&gt;Darkfader: sigs&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Needs to be adjusted for other archs&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&amp;lt;span class=&amp;quot;autosigned&amp;quot;&amp;gt;—&amp;amp;nbsp;Preceding [[Help:Signature|unsigned]] comment added by [[User:Orson Teodoro|Orson Teodoro]] ([[User talk:Orson Teodoro|{{int:talkpagelinktext}}]] • [[Special:Contributions/Orson Teodoro|{{int:contribslink}}]]) 03:36, 4 March 2018&amp;lt;/span&amp;gt;&amp;lt;/small&amp;gt;‎&lt;br /&gt;
&lt;br /&gt;
== Locations/paths of build config files ==&lt;br /&gt;
&lt;br /&gt;
My goal is to build the Virt (not Standard/LTS) kernel using the defaults for Virt, and I don&#039;t understand which files are needed in exactly which paths.&lt;br /&gt;
&lt;br /&gt;
I had difficulty understanding the excerpt below. Is anyone willing to assist me in understanding it? For example, where/what is the &amp;quot;linux-4.15&amp;quot; folder?&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;When you are done with your edits either by editing directly the APKBUILD and copying the lts.ARCH.config as .config in the linux-4.15 folder. You will then move the .config back overriding the lts.ARCH.config generated by make menuconfig.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&amp;lt;span class=&amp;quot;autosigned&amp;quot;&amp;gt;—&amp;amp;nbsp;Preceding [[Help:Signature|unsigned]] comment added by [[User:-anthumchris-|-anthumchris-]] ([[User talk:-anthumchris-|{{int:talkpagelinktext}}]] • [[Special:Contributions/-anthumchris-|{{int:contribslink}}]]) 17:34, 23 November 2024‎&amp;lt;/span&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== build_NAME ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;After you are done using the menu in the build-NAME folder by doing make menuconfig&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
It is really not clear what is meant by &amp;quot;the build-NAME folder&amp;quot; here.&lt;br /&gt;
&lt;br /&gt;
== Locations/paths of build config files Answer ==&lt;br /&gt;
&lt;br /&gt;
Usually these are the directories you would look for in linux-lts apk package development (replace &amp;quot;x86_64&amp;quot; with different $ARCH if needed) (replace $YOUR_WORK_DIR to which directory you downloaded aports to), &lt;br /&gt;
&lt;br /&gt;
Below should contain &amp;lt;code&amp;gt;APKBUILD&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;lts.x86_64.config&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;virt.x86_64.config&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;.patch&amp;lt;/code&amp;gt; files (and more $ARCH&#039;s by default, but to keep it simple, I will just state the x86_64 files)&lt;br /&gt;
{{cmd|$YOUR_WORK_DIR/aports/main/linux-lts}}&lt;br /&gt;
&lt;br /&gt;
ALL &amp;lt;code&amp;gt;.patch&amp;lt;/code&amp;gt; files that are in $YOUR_WORK_DIR/aports/main/linux-lts are also in below&lt;br /&gt;
{{cmd|$YOUR_WORK_DIR/aports/main/linux-lts/src}}&lt;br /&gt;
&lt;br /&gt;
Below is a tar compressed linux file that decompresses into linux-$VERSION&lt;br /&gt;
{{cmd|$YOUR_WORK_DIR/aports/main/linux-lts/src/linux-$VERSION.tar.gz}}&lt;br /&gt;
&lt;br /&gt;
{{cmd|$YOUR_WORK_DIR/aports/main/linux-lts/src/linux-$VERSION}}&lt;br /&gt;
{{cmd|$YOUR_WORK_DIR/aports/main/linux-lts/src/build-lts.x86_64}}&lt;br /&gt;
{{cmd|$YOUR_WORK_DIR/aports/main/linux-lts/src/build-virt.x86_64}}&lt;br /&gt;
&lt;br /&gt;
In the &amp;quot;&amp;lt;code&amp;gt;APKBUILD&amp;lt;/code&amp;gt;&amp;quot; file, change this &amp;quot;&amp;lt;code&amp;gt;source&amp;lt;/code&amp;gt;&amp;quot; line to this:&lt;br /&gt;
{{cat|$YOUR_WORK_DIR/aports/main/linux-lts/APKBUILD|...&lt;br /&gt;
source{{=}}&amp;quot;https://cdn.kernel.org/pub/linux/kernel/v${pkgver%%.*}.x/linux-$_kernver.tar.xz&lt;br /&gt;
    0001-powerpc-boot-wrapper-Add-z-notext-flag-for-ppc64le.patch&lt;br /&gt;
    0002-x86-Compress-vmlinux-with-zstd-19-instead-of-22.patch&lt;br /&gt;
    0003-kexec-add-kexec_load_disabled-boot-option.patch&lt;br /&gt;
    0004-objtool-respect-AWK-setting.patch&lt;br /&gt;
    0005-powerpc-config-defang-gcc-check-for-stack-protector-.patch&lt;br /&gt;
&lt;br /&gt;
    lts.x86_64.config&lt;br /&gt;
&lt;br /&gt;
    virt.x86_64.config&lt;br /&gt;
    &amp;quot;&lt;br /&gt;
...}}&lt;br /&gt;
&lt;br /&gt;
do &amp;lt;code&amp;gt;make menuconfig&amp;lt;/code&amp;gt; within &amp;lt;code&amp;gt;$YOUR_WORK_DIR/aports/main/linux-lts/src/linux-$VERSION&amp;lt;/code&amp;gt; and copy the .config file to &amp;lt;code&amp;gt;$YOUR_WORK_DIR/aports/main/linux-lts/lts.x86_64.config&amp;lt;/code&amp;gt; and/or &amp;lt;code&amp;gt;$YOUR_WORK_DIR/aports/main/linux-lts/virt.x86_64.config&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&amp;lt;span class=&amp;quot;autosigned&amp;quot;&amp;gt;—&amp;amp;nbsp;Preceding [[Help:Signature|unsigned]] comment added by [[User:Pursuable1652|Pursuable1652]] ([[User talk:Pursuable1652|{{int:talkpagelinktext}}]] • [[Special:Contributions/Pursuable1652|{{int:contribslink}}]]) 16:55, 25 December 2024‎&amp;lt;/span&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== build_NAME Answer ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;After you are done using the menu in the build-NAME folder by doing make menuconfig&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
the &amp;quot;build-NAME&amp;quot; folder should actually be &amp;lt;code&amp;gt;$YOUR_WORK_DIR/aports/main/linux-lts/src/linux-$VERSION&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&amp;lt;span class=&amp;quot;autosigned&amp;quot;&amp;gt;—&amp;amp;nbsp;Preceding [[Help:Signature|unsigned]] comment added by [[User:Pursuable1652|Pursuable1652]] ([[User talk:Pursuable1652|{{int:talkpagelinktext}}]] • [[Special:Contributions/Pursuable1652|{{int:contribslink}}]]) 16:55, 25 December 2024‎&amp;lt;/span&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Page ready for regular release? ==&lt;br /&gt;
Perhaps this [[Custom Kernel]] page is now ready for regular use, and the &amp;quot;This material is work-in-progress&amp;quot; banner can be removed, unless there is a shortcoming found.  This draft state has held since it was helpfully created in 2014.  &lt;br /&gt;
Thanks for kind updates by [[User:Prabuanand|Prabuanand]], [[User:Pawciobiel|Pawciobiel]], [[User:Teopp7|Teopp7]], [[User:Fossdd|Fossdd]], [[User:Anthumchris|Anthumchris]], [[User:Gsora|Gsora]], [[User:Zcrayfish|Zcrayfish]], [[User:Omni|Omni]], [[User:Nabbi|Nabbi]], [[User:Psykose|Psykose]], [[User:Egberts|Egberts]] and thanks also for kind contributions by others that have not been active on the wiki for over five years. [[User:John3-16|John3-16]] ([[User talk:John3-16|talk]]) 19:22, 30 December 2025 (UTC)&lt;br /&gt;
:Further to one month without objections, having tagged recent contributors, the &#039;&#039;&amp;quot;Work-in-progress&amp;quot;&#039;&#039; flag is being removed.  The contributor who kindly initiated this useful page duly placed the flag in the original [https://wiki.alpinelinux.org/w/index.php?title=Custom_Kernel&amp;amp;oldid=10201 draft version] in 2014 and last contributed to the wiki that year. [[User:John3-16|John3-16]] ([[User talk:John3-16|talk]]) 02:02, 1 February 2026 (UTC)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== kexec ===&lt;br /&gt;
&lt;br /&gt;
the kernel and tools now have better exploit-kernel protection and there&#039;s actually been some ransomware actors using kexec to load bad things[tm]&lt;br /&gt;
&lt;br /&gt;
is there a way to sign kernels on alpine? If so, maybe we should document that and link to it here.&lt;br /&gt;
CONFIG_KECEC_SIG etc.&lt;br /&gt;
&lt;br /&gt;
[[User:Darkfader|Darkfader]] ([[User talk:Darkfader|talk]]) 16:07, 29 March 2026 (UTC)&lt;/div&gt;</summary>
		<author><name>Darkfader</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Custom_Kernel&amp;diff=32239</id>
		<title>Custom Kernel</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Custom_Kernel&amp;diff=32239"/>
		<updated>2026-03-29T16:03:09Z</updated>

		<summary type="html">&lt;p&gt;Darkfader: /* Configuring kernel */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This process of building a &#039;&#039;&#039;custom configured kernel&#039;&#039;&#039; assumes you are running on Alpine Linux utilizing abuild &amp;amp; aports.&lt;br /&gt;
&lt;br /&gt;
== But why? ==&lt;br /&gt;
&lt;br /&gt;
You want to build a custom kernel to enable experimental hardware or features or outdated hardware, to reduce bloat further, to tune the kernel to the hardware.&lt;br /&gt;
&lt;br /&gt;
The lts kernel for most Alpine ARCHs uses defaults to balance throughput at the expense of some responsiveness, and support for many devices.  You can tweak the kernel for desktop use and low latency and responsiveness.&lt;br /&gt;
&lt;br /&gt;
You should disable modules to increase security.  By default, Alpine will install modules but not disable most of them.  Disabling modules will reduce an DMA attack but not eliminate it completely.  If you have a newer processor with VT-d, you can mitigate as long as you:&lt;br /&gt;
&lt;br /&gt;
Leave &amp;lt;code&amp;gt;CONFIG_INTEL_IOMMU_DEFAULT_ON=y&amp;lt;/code&amp;gt; or pass &amp;lt;code&amp;gt;intel_iommu=on&amp;lt;/code&amp;gt; as a kernel parameter and disable kernel logging so the attacker doesn&#039;t gain DMAR address information through dmesg.[https://blog.frizk.net/2016/11/disable-virtualization-based-security.html]  Also remove references to the kernel version to calculate the IOMMU addresses.[https://link.springer.com/content/pdf/10.1186/s13173-017-0066-7.pdf]&lt;br /&gt;
&lt;br /&gt;
You may also want to harden your kernel by adding at least some of the config changes recommended by &amp;lt;code&amp;gt;kernel-hardening-checker&amp;lt;/code&amp;gt; [https://github.com/a13xp0p0v/kernel-hardening-checker/]&lt;br /&gt;
&lt;br /&gt;
To increase the security of the boot process, if you have a TPM, you could set &amp;lt;code&amp;gt;CONFIG_INTEL_TXT=y&amp;lt;/code&amp;gt; (Enable Intel(R) Trusted Execution Technology (Intel(R) TXT)) (which is not enabled in the hardened kernel by default), then you would need the SINIT module (provided only by Intel)[https://software.intel.com/en-us/articles/intel-trusted-execution-technology], a possibly compiled TrustedGrub2[https://github.com/Rohde-Schwarz-Cybersecurity/TrustedGRUB2], trousers[https://sourceforge.net/projects/trousers/?source=navbar], tboot[https://sourceforge.net/projects/tboot/].  These packages are not in aports and it is unknown if these tools work on musl.  It&#039;s not recommended for Edge.  Also, there would be trigger packages to generate hashes for the kernel and the mkinitfs updates.&lt;br /&gt;
&lt;br /&gt;
== Setting up the Alpine Build System ==&lt;br /&gt;
&lt;br /&gt;
First, you need to follow the steps in [[Creating_an_Alpine_package#Setup_your_system_and_account|Setup your system and account for building packages]].  You also need to configure your {{path|/etc/apk/repositories}} so that they search locally for your apks.  See [[Creating_an_Alpine_package#Testing_the_package_locally|Testing the package locally]] for details.&lt;br /&gt;
&lt;br /&gt;
After setting up accounts and repos, change your shell&#039;s current working directory to &#039;&#039;&#039;aports&#039;&#039;&#039; that you just cloned.&lt;br /&gt;
&lt;br /&gt;
{{cmd|$ cd aports}}&lt;br /&gt;
&lt;br /&gt;
== Working with aports ==&lt;br /&gt;
&lt;br /&gt;
We will try using an existing lts kernel just tweaking the {{path|lts.ARCH.config}} file.  &lt;br /&gt;
&lt;br /&gt;
=== Switching to the proper release version ===&lt;br /&gt;
&lt;br /&gt;
You need to switch to the proper branch that matches the release so that the kernel compiles against the dependencies properly.&lt;br /&gt;
&lt;br /&gt;
{| cellpadding=&amp;quot;5&amp;quot; border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! Alpine version&lt;br /&gt;
! Remote branch&lt;br /&gt;
|-&lt;br /&gt;
| Edge&lt;br /&gt;
| master&lt;br /&gt;
|-&lt;br /&gt;
|{{#expr:{{AlpineLatest}}}}&lt;br /&gt;
|{{#expr:{{AlpineLatest}}}}-stable&lt;br /&gt;
|- &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The following is required to get access to the {{path|APKBUILD}} released for that version of Alpine and which you will create a commit for.&lt;br /&gt;
&lt;br /&gt;
If you are on {{#expr:{{AlpineLatest}}}} do:&lt;br /&gt;
&lt;br /&gt;
{{cmd|$ git checkout -b {{#expr:{{AlpineLatest}}}}-stable origin/{{#expr:{{AlpineLatest}}}}-stable}}&lt;br /&gt;
&lt;br /&gt;
If you are on Edge do:&lt;br /&gt;
&lt;br /&gt;
{{cmd|$ git checkout master}}&lt;br /&gt;
&lt;br /&gt;
=== Creating your config ===&lt;br /&gt;
&lt;br /&gt;
You can use {{pkg|linux-lts}} but what you should do is create a local branch by doing:&lt;br /&gt;
&lt;br /&gt;
For &amp;lt;var&amp;gt;linux-lts&amp;lt;/var&amp;gt; kernel on Alpine {{#expr:{{AlpineLatest}}}}:&lt;br /&gt;
&lt;br /&gt;
{{cmd|$ git checkout -b my-custom-kernel origin/{{#expr:{{AlpineLatest}}}}-stable}}&lt;br /&gt;
&lt;br /&gt;
For Alpine Edge:&lt;br /&gt;
&lt;br /&gt;
{{cmd|$ git checkout -b my-custom-kernel}}&lt;br /&gt;
&lt;br /&gt;
Doing it this way, you do less work in maintaining.  All you need to do is keep &#039;&#039;master&#039;&#039; or &#039;&#039;{{#expr:{{AlpineLatest}}}}-stable&#039;&#039; in sync[https://help.github.com/articles/syncing-a-fork/][https://help.github.com/articles/configuring-a-remote-for-a-fork/] and merge any conflicts.  &lt;br /&gt;
&lt;br /&gt;
First switch to the branch by doing:{{cmd|$ git checkout my-custom-kernel}} &lt;br /&gt;
Then, you need to navigate to the {{path|main/linux-lts}} folder where you should see a APKBUILD and some config- files.&lt;br /&gt;
&lt;br /&gt;
It is a good idea to use custom `FLAVOR` in order to change the name of your kernel and package (custom flavor or revision) so you newly build kernel will not override the existing linux-lts and it&#039;s modules. Flavor build will only use your config and omit files that are not for your cpu architectures or virt* configs.(Virt configs provide optimized kernel configurations for running Alpine as a guest in virtual machines.)&lt;br /&gt;
This will also speed up the process of applying kernel patches by applying it for your architecture only. (Obviously ARCH in the following example is whatever architecture x86, x86_64...you use.)&lt;br /&gt;
&lt;br /&gt;
First make a copy of your ARCH config file:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cp lts.x86_64.config lts-my_custom.x86_64.config&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Edit your custom config file and add your changes. When you are done with your edits you need to run checksum to update APKBUILD:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;FLAVOR=lts-my_custom abuild checksum&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then commit your changes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;git commit -a -m &amp;quot;Enabled these options ....&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You do this so that git can keep your code separate from Alpine&#039;s and so your changes float forward between kernel updates.&lt;br /&gt;
&lt;br /&gt;
== Adding custom patches ==&lt;br /&gt;
&lt;br /&gt;
Custom patches should be added to &#039;&#039;sources=&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
After you added the URL, you need to produce a checksum by doing &amp;lt;code&amp;gt;abuild checksum&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The custom patches may not be autopatched, due to being distributed as an archive or different patch level, so you need to define what to do with it in the prepare().&lt;br /&gt;
&lt;br /&gt;
== Configuring kernel ==&lt;br /&gt;
&lt;br /&gt;
There are multiple ways to prepare and change kernel config. The basic one is to just edit your custom config file. You can also attempt to create a config tailored for your currently running system and modules.&lt;br /&gt;
&lt;br /&gt;
Extract your kernel and apply the standard patches:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
abuild fetch &amp;amp;&amp;amp; abuild unpack &amp;amp;&amp;amp; abuild prepare&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To create a kernel config based on your currently running PC, use:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
make localmodconfig&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This command reads your current kernel&#039;s configuration from /proc/config.gz (if available) or /boot/config-* and creates a .config file that includes only the modules currently loaded on your system. This results in a minimal configuration tailored to your hardware.&lt;br /&gt;
Alternatively, you can use:&lt;br /&gt;
&amp;lt;pre&amp;gt;make localyesconfig&amp;lt;/pre&amp;gt;&lt;br /&gt;
This is similar to &#039;&#039;localmodconfig&#039;&#039;, but instead of building features as modules (m), it builds them directly into the kernel (y), which can result in a larger kernel image but eliminates the need for separate module files.&lt;br /&gt;
Note: Before running either command, make sure you have all the hardware you want to support actively in use (USB devices plugged in, network cards active, etc.) so their modules are loaded and included in the configuration.&lt;br /&gt;
&lt;br /&gt;
The alternative is to use the kernel configuration menu in the build-NAME folder, but before you do that you need to &amp;lt;code&amp;gt;sudo apk add {{pkg|ncurses-dev}}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After you are done using the menu in the build-NAME folder by doing:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;make menuconfig&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You want to remove &amp;lt;code&amp;gt;ncurses-dev&amp;lt;/code&amp;gt;.  When you are done, it will be stored in &#039;&#039;.config&#039;&#039; which you need to again override the {{path|lts.ARCH.config}} file.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cp .config ../../lts-my-kernel.x86_64.config&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you are done updating the {{path|config-NAME.ARCH}}, you need to update sums:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
abuild checksum&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The options in the kernel config are typically defaults.  If your device is old, it may be set to n by default.&lt;br /&gt;
&lt;br /&gt;
=== Vanilla targets and tuning ===&lt;br /&gt;
&lt;br /&gt;
{|cellpadding=&amp;quot;5&amp;quot; border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!ARCH&lt;br /&gt;
!Processor Type / CPU Selection / System Type&lt;br /&gt;
!Code Generation / Instruction Extensions&lt;br /&gt;
!Timer Frequency&lt;br /&gt;
!Preemption Model&lt;br /&gt;
!Bitness&lt;br /&gt;
|-&lt;br /&gt;
|s390x&lt;br /&gt;
|IBM zEnterprise 114 and 196&lt;br /&gt;
|IBM zBC12 and zEC12 (&amp;lt;code&amp;gt;-march=zEC12 -mtune=zEC12&amp;lt;/code&amp;gt;)&lt;br /&gt;
|1000 Hz&lt;br /&gt;
|No Forced Preemption (Server)&lt;br /&gt;
|64&lt;br /&gt;
|-&lt;br /&gt;
|ppc64le&lt;br /&gt;
|Server processors&lt;br /&gt;
|POWER8 (&amp;lt;code&amp;gt;-mcpu=power8&amp;lt;/code&amp;gt;), AltiVec (&amp;lt;code&amp;gt;-Wa,-maltivec&amp;lt;/code&amp;gt; to assembler or &amp;lt;code&amp;gt;-maltivec -mabi=altivec&amp;lt;/code&amp;gt;), VSX&lt;br /&gt;
|1000 HZ&lt;br /&gt;
|No Forced Preemption (Server)&lt;br /&gt;
|64&lt;br /&gt;
|-&lt;br /&gt;
|ppc&lt;br /&gt;
|&lt;br /&gt;
512x/52xx/6xx/7xx/74xx/82xx/83xx/86xx&lt;br /&gt;
* Apple PowerMac based machines&lt;br /&gt;
|AltiVec (&amp;lt;code&amp;gt;-Wa,-maltivec&amp;lt;/code&amp;gt; to assembler or &amp;lt;code&amp;gt;-maltivec -mabi=altivec&amp;lt;/code&amp;gt;) on &amp;gt;=74xx&lt;br /&gt;
|1000 HZ&lt;br /&gt;
|No Forced Preemption (Server)&lt;br /&gt;
|32&lt;br /&gt;
|-&lt;br /&gt;
|x86_64&lt;br /&gt;
|Generic-x86-64&lt;br /&gt;
|(-mtune=generic ; SIMD assembly modules enabled based on simple compile test and/or presence of CPU flag)&lt;br /&gt;
|1000 HZ&lt;br /&gt;
|Voluntary Kernel Preemption (Desktop)&lt;br /&gt;
|64&lt;br /&gt;
|-&lt;br /&gt;
|x86&lt;br /&gt;
|586/K5/5x86/6x86/6x86MX&lt;br /&gt;
|(-mtune=generic ; SIMD assembly modules enabled based on simple compile test and/or presence of CPU flag)&lt;br /&gt;
|1000 HZ&lt;br /&gt;
|Voluntary Kernel Preemption (Desktop)&lt;br /&gt;
|32&lt;br /&gt;
|-&lt;br /&gt;
|armv7&lt;br /&gt;
|&lt;br /&gt;
* ARMv7 based platforms (Cortex-A, PJ4, Scorpion, Krait)&lt;br /&gt;
* Freescale i.MX family -- Cortex A (i.MX51, i.MX53, i.MX6 Quad/DualLite, i.MX6 SoloLite, i.MX6 SoloX, i.MX6 UltraLite, i.MX7 Dual)&lt;br /&gt;
* Qualcomm -- (MSM8X60, MSM8960, MSM8974)&lt;br /&gt;
* Allwinner SoCs -- (A10 (sun4i), A10s / A13 (sun5i), A31 (sun6i), A20 (sun7i), sun8i Family, (sun9i))&lt;br /&gt;
* ARM Ldt Versatile Express family -- &lt;br /&gt;
|Either &amp;lt;code&amp;gt;-march=armv7-a&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;-march=armv5t -Wa,-march=armv7-a&amp;lt;/code&amp;gt; based on a compile test. &amp;lt;code&amp;gt;-mfpu=vfp&amp;lt;/code&amp;gt;&lt;br /&gt;
|1000 Hz&lt;br /&gt;
|Voluntary Kernel Preemption (Desktop)&lt;br /&gt;
|32&lt;br /&gt;
|-&lt;br /&gt;
|aarch64&lt;br /&gt;
|&lt;br /&gt;
* Allwinner sunxi 64-bit SoC Family&lt;br /&gt;
* Broadcom BCM2835 family&lt;br /&gt;
* Marvell Berlin SoC Family&lt;br /&gt;
* ARMv8 based Samsung Exynos SoC family&lt;br /&gt;
* ARMv8 based Freescale Layerscape SoC family&lt;br /&gt;
* Hisilicon SoC Family&lt;br /&gt;
* Mediatek MT65xx &amp;amp; MT81xx ARMv8 SoC&lt;br /&gt;
* Marvell EBU SoC Family&lt;br /&gt;
* Qualcomm Platforms&lt;br /&gt;
* Rockchip Platforms&lt;br /&gt;
* AMD Seattle SoC Family&lt;br /&gt;
* Altera&#039;s Stratix 10 SoCFPGA Family&lt;br /&gt;
* NVIDIA Tegra SoC Family&lt;br /&gt;
* Spreadtrum SoC platform&lt;br /&gt;
* Cavium Inc. Thunder SoC Family&lt;br /&gt;
* ARMv8 software model (Versatile Express)&lt;br /&gt;
* AppliedMicro X-Gene SOC Family&lt;br /&gt;
* Xilinx ZynqMP Family&lt;br /&gt;
|&lt;br /&gt;
|1000 HZ&lt;br /&gt;
|Voluntary Kernel Preemption (Desktop)&lt;br /&gt;
|64&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
If you do desktop multitasking, you may want to switch to Voluntary Kernel Preemption (Desktop) or Preemptible Kernel (Low-Latency Desktop) and up the Timer Frequency.  If you run a dedicated render farm node or a dedicated bitcoin miner use No Forced Preemption (Server) and decrease the Timer Frequency.&lt;br /&gt;
&lt;br /&gt;
Optimized modules (most are already compiled as modules):&lt;br /&gt;
* raid6 -- altivec, avx512, ssse3, avx2, mmx, sse, sse2, neon&lt;br /&gt;
* some operations of raid5 -- mmx (32 bit), sse (64 bit), avx&lt;br /&gt;
For Kernel API:&lt;br /&gt;
* 32-bit memcpy -- 3dnow&lt;br /&gt;
* 32-bit memory page clearing and copying -- sse (Athlon/K7 only), mmx&lt;br /&gt;
From x86/crypto, arm/crypto, powerpc/crypto:&lt;br /&gt;
* CAMELLIA -- avx2, avx, aes-ni&lt;br /&gt;
* CHACHA20 -- avx2, neon&lt;br /&gt;
* CAST5 -- avx&lt;br /&gt;
* CAST6 -- avx&lt;br /&gt;
* TWOFISH -- avx&lt;br /&gt;
* SERPENT -- avx2, avx, sse2&lt;br /&gt;
* SHA1 -- avx2, ssse3, neon, spe&lt;br /&gt;
* SHA2 -- avx2&lt;br /&gt;
* SHA256 -- ssse3, neon, spe&lt;br /&gt;
* SHA512 -- avx2, ssse3, neon&lt;br /&gt;
* POLY1305 -- avx2&lt;br /&gt;
* GHASH -- pclmulqdq (part of aes-ni), vmx (power8)&lt;br /&gt;
* AES -- aes-ni, neon, vmx (power8), spe&lt;br /&gt;
* CRC32 -- pclmulqdq, sse, neon, vmx (power8)&lt;br /&gt;
* CRCT10DIF -- pclmulqdq, sse, neon, vmx (power8)&lt;br /&gt;
&lt;br /&gt;
=== Fast reboots with kexec ===&lt;br /&gt;
{{main|kexec}}&lt;br /&gt;
&lt;br /&gt;
If you want to reboot the kernel fast avoiding the POST test, you need {{ic|doas apk add {{pkg|kexec-tools}}}} and enable kexec in the kernel:&lt;br /&gt;
&lt;br /&gt;
  Processor type and features&lt;br /&gt;
    [*] kexec system call&lt;br /&gt;
&lt;br /&gt;
=== Hibernation to prevent data loss ===&lt;br /&gt;
&lt;br /&gt;
  Power management and ACPI options&lt;br /&gt;
    [*] Hibernation (aka &#039;suspend to disk&#039;)&lt;br /&gt;
&lt;br /&gt;
Hibernation should be used if you have a laptop.  You don&#039;t want the laptop to suddenly shut off resulting in data loss, you want it to save your work based on a percentage of battery life (this requires special script).  When hibernation resumes, should lock and ask for credentials.  Depending on your needs, the hibernated image can be encrypted/decrypted which again requires additional customization to scripts.&lt;br /&gt;
&lt;br /&gt;
Hibernation with an unsanitized swap file is generally insecure because data and unlocked memory pages are swapped out in plaintext.  To increase the security either disable swap or use an encrypted swap.  The swap file/partition is typically used as the hibernation resume image.&lt;br /&gt;
&lt;br /&gt;
== Building ==&lt;br /&gt;
&lt;br /&gt;
Before building, make sure you have ccache installed.  This should reduce compile time on multiple builds.&lt;br /&gt;
You may also want to read up on compile flags - perhaps you want your build to be optimized for speed (or size which is the default).&lt;br /&gt;
Review &amp;lt;code&amp;gt;/etc/abuild.conf&amp;lt;/code&amp;gt; and set:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
PACKAGER_PRIVKEY=&amp;quot;/home/MY_USER_HERE/.abuild/my-email@mydomain.com-ID.rsa&amp;quot;&lt;br /&gt;
USE_CCACHE=1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Please note that kernel build process may not use some of the settings you set in `abuild.conf` so in order to customize compiler or linker and/or it&#039;s flags you may need to edit APKBUILD.&lt;br /&gt;
If you have your config ready, first try building with:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FLAVOR=lts-my_custom abuild -rK 2&amp;gt;&amp;amp;1 | tee build1.log&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will install most of the dependencies and keep buildtime temp dirs and files (srcdir/pkgdir/deps).&lt;br /&gt;
&lt;br /&gt;
If it complains about a dependency like {{pkg|elfutils-dev}} use &amp;lt;code&amp;gt;-rKd&amp;lt;/code&amp;gt;.&lt;br /&gt;
Then, when it prompts for values for new found config options just hold enter till it starts compiling the kernel.&lt;br /&gt;
Unless you use &amp;lt;code&amp;gt;FLAVOR&amp;lt;/code&amp;gt; or removed or commented out &amp;lt;code&amp;gt;virt.*.config&amp;lt;/code&amp;gt; configs in APKBUILD there should be two sets one for -lts and the other for the -virt.&lt;br /&gt;
Just {{Key|Ctrl}}+{{Key|C}} out of the compilation process after &lt;br /&gt;
the second set so you can further customize the config.&lt;br /&gt;
Then you go into the {{path|src/linux-VER}} and edit the config file.&lt;br /&gt;
Copy the {{path|.config}} file overriding the {{path|lts.ARCH.config}} in the srcdir.&lt;br /&gt;
&lt;br /&gt;
== Installing ==&lt;br /&gt;
&lt;br /&gt;
If the build was successful the kernel packages are located in &amp;lt;code&amp;gt;~/packages/main/ARCH&amp;lt;/code&amp;gt;&lt;br /&gt;
You probably already know how to install a package in your Alpine Linux...&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
In case your new kernel may be missing a module and can&#039;t boot it is generally a good idea to keep the default &amp;lt;code&amp;gt;linux-lts&amp;lt;/code&amp;gt;, so make sure you have it installed using the command: {{Cmd|# apk add {{pkg|linux-lts}}}}&lt;br /&gt;
&lt;br /&gt;
Normally during the installation using with [[apk]], there are tools that will update initramfs and a boot loader automatically for you. For easier debugging you may want to change boot loader config and remove &amp;lt;code&amp;gt;quiet&amp;lt;/code&amp;gt; from linux command line in {{Path|/etc/default/grub}} or {{Path|/etc/update-extlinux.conf}}.&lt;br /&gt;
Or perhaps you want to change other kernel options in {{Path|/etc/mkinitfs/mkinitfs.conf}}. Please remember to generate initramfs and update your bootloader manually, eg:&lt;br /&gt;
{{Cmd|&amp;lt;nowiki&amp;gt;# mkinitfs&lt;br /&gt;
# grub-mkconfig -o /boot/grub/grub.cfg&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
In case something goes wrong with a boot process it is also a good idea to have a bootable rescue Alpine USB ready.&lt;br /&gt;
&lt;br /&gt;
Once you have the default lts kernel and rescue USB &amp;lt;code&amp;gt;reboot&amp;lt;/code&amp;gt; the computer.&lt;br /&gt;
&lt;br /&gt;
If you are curious about correctness testing, some kernel modules or components do preform self tests at the beginning of the boot process.  The tools may have test suites that you run with the make command.&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [[Kernels]]&lt;br /&gt;
* [https://wiki.archlinux.org/title/Kernel Archwiki Kernels]&lt;br /&gt;
* [https://wiki.gentoo.org/wiki/Kernel Gentoo Wiki Kernel]&lt;br /&gt;
* [https://wiki.gentoo.org/wiki/Kernel/Configuration Gentoo Wiki Kernel Configuration]&lt;br /&gt;
* [[How to build the Alpine Linux kernel]]&lt;br /&gt;
* [[Kernel_live_patching|Kernel Live Patching (KLP)]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Kernel]]&lt;/div&gt;</summary>
		<author><name>Darkfader</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Custom_Kernel&amp;diff=32238</id>
		<title>Custom Kernel</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Custom_Kernel&amp;diff=32238"/>
		<updated>2026-03-29T15:31:10Z</updated>

		<summary type="html">&lt;p&gt;Darkfader: /* Configuring kernel */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This process of building a &#039;&#039;&#039;custom configured kernel&#039;&#039;&#039; assumes you are running on Alpine Linux utilizing abuild &amp;amp; aports.&lt;br /&gt;
&lt;br /&gt;
== But why? ==&lt;br /&gt;
&lt;br /&gt;
You want to build a custom kernel to enable experimental hardware or features or outdated hardware, to reduce bloat further, to tune the kernel to the hardware.&lt;br /&gt;
&lt;br /&gt;
The lts kernel for most Alpine ARCHs uses defaults to balance throughput at the expense of some responsiveness, and support for many devices.  You can tweak the kernel for desktop use and low latency and responsiveness.&lt;br /&gt;
&lt;br /&gt;
You should disable modules to increase security.  By default, Alpine will install modules but not disable most of them.  Disabling modules will reduce an DMA attack but not eliminate it completely.  If you have a newer processor with VT-d, you can mitigate as long as you:&lt;br /&gt;
&lt;br /&gt;
Leave &amp;lt;code&amp;gt;CONFIG_INTEL_IOMMU_DEFAULT_ON=y&amp;lt;/code&amp;gt; or pass &amp;lt;code&amp;gt;intel_iommu=on&amp;lt;/code&amp;gt; as a kernel parameter and disable kernel logging so the attacker doesn&#039;t gain DMAR address information through dmesg.[https://blog.frizk.net/2016/11/disable-virtualization-based-security.html]  Also remove references to the kernel version to calculate the IOMMU addresses.[https://link.springer.com/content/pdf/10.1186/s13173-017-0066-7.pdf]&lt;br /&gt;
&lt;br /&gt;
You may also want to harden your kernel by adding at least some of the config changes recommended by &amp;lt;code&amp;gt;kernel-hardening-checker&amp;lt;/code&amp;gt; [https://github.com/a13xp0p0v/kernel-hardening-checker/]&lt;br /&gt;
&lt;br /&gt;
To increase the security of the boot process, if you have a TPM, you could set &amp;lt;code&amp;gt;CONFIG_INTEL_TXT=y&amp;lt;/code&amp;gt; (Enable Intel(R) Trusted Execution Technology (Intel(R) TXT)) (which is not enabled in the hardened kernel by default), then you would need the SINIT module (provided only by Intel)[https://software.intel.com/en-us/articles/intel-trusted-execution-technology], a possibly compiled TrustedGrub2[https://github.com/Rohde-Schwarz-Cybersecurity/TrustedGRUB2], trousers[https://sourceforge.net/projects/trousers/?source=navbar], tboot[https://sourceforge.net/projects/tboot/].  These packages are not in aports and it is unknown if these tools work on musl.  It&#039;s not recommended for Edge.  Also, there would be trigger packages to generate hashes for the kernel and the mkinitfs updates.&lt;br /&gt;
&lt;br /&gt;
== Setting up the Alpine Build System ==&lt;br /&gt;
&lt;br /&gt;
First, you need to follow the steps in [[Creating_an_Alpine_package#Setup_your_system_and_account|Setup your system and account for building packages]].  You also need to configure your {{path|/etc/apk/repositories}} so that they search locally for your apks.  See [[Creating_an_Alpine_package#Testing_the_package_locally|Testing the package locally]] for details.&lt;br /&gt;
&lt;br /&gt;
After setting up accounts and repos, change your shell&#039;s current working directory to &#039;&#039;&#039;aports&#039;&#039;&#039; that you just cloned.&lt;br /&gt;
&lt;br /&gt;
{{cmd|$ cd aports}}&lt;br /&gt;
&lt;br /&gt;
== Working with aports ==&lt;br /&gt;
&lt;br /&gt;
We will try using an existing lts kernel just tweaking the {{path|lts.ARCH.config}} file.  &lt;br /&gt;
&lt;br /&gt;
=== Switching to the proper release version ===&lt;br /&gt;
&lt;br /&gt;
You need to switch to the proper branch that matches the release so that the kernel compiles against the dependencies properly.&lt;br /&gt;
&lt;br /&gt;
{| cellpadding=&amp;quot;5&amp;quot; border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! Alpine version&lt;br /&gt;
! Remote branch&lt;br /&gt;
|-&lt;br /&gt;
| Edge&lt;br /&gt;
| master&lt;br /&gt;
|-&lt;br /&gt;
|{{#expr:{{AlpineLatest}}}}&lt;br /&gt;
|{{#expr:{{AlpineLatest}}}}-stable&lt;br /&gt;
|- &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The following is required to get access to the {{path|APKBUILD}} released for that version of Alpine and which you will create a commit for.&lt;br /&gt;
&lt;br /&gt;
If you are on {{#expr:{{AlpineLatest}}}} do:&lt;br /&gt;
&lt;br /&gt;
{{cmd|$ git checkout -b {{#expr:{{AlpineLatest}}}}-stable origin/{{#expr:{{AlpineLatest}}}}-stable}}&lt;br /&gt;
&lt;br /&gt;
If you are on Edge do:&lt;br /&gt;
&lt;br /&gt;
{{cmd|$ git checkout master}}&lt;br /&gt;
&lt;br /&gt;
=== Creating your config ===&lt;br /&gt;
&lt;br /&gt;
You can use {{pkg|linux-lts}} but what you should do is create a local branch by doing:&lt;br /&gt;
&lt;br /&gt;
For &amp;lt;var&amp;gt;linux-lts&amp;lt;/var&amp;gt; kernel on Alpine {{#expr:{{AlpineLatest}}}}:&lt;br /&gt;
&lt;br /&gt;
{{cmd|$ git checkout -b my-custom-kernel origin/{{#expr:{{AlpineLatest}}}}-stable}}&lt;br /&gt;
&lt;br /&gt;
For Alpine Edge:&lt;br /&gt;
&lt;br /&gt;
{{cmd|$ git checkout -b my-custom-kernel}}&lt;br /&gt;
&lt;br /&gt;
Doing it this way, you do less work in maintaining.  All you need to do is keep &#039;&#039;master&#039;&#039; or &#039;&#039;{{#expr:{{AlpineLatest}}}}-stable&#039;&#039; in sync[https://help.github.com/articles/syncing-a-fork/][https://help.github.com/articles/configuring-a-remote-for-a-fork/] and merge any conflicts.  &lt;br /&gt;
&lt;br /&gt;
First switch to the branch by doing:{{cmd|$ git checkout my-custom-kernel}} &lt;br /&gt;
Then, you need to navigate to the {{path|main/linux-lts}} folder where you should see a APKBUILD and some config- files.&lt;br /&gt;
&lt;br /&gt;
It is a good idea to use custom `FLAVOR` in order to change the name of your kernel and package (custom flavor or revision) so you newly build kernel will not override the existing linux-lts and it&#039;s modules. Flavor build will only use your config and omit files that are not for your cpu architectures or virt* configs.(Virt configs provide optimized kernel configurations for running Alpine as a guest in virtual machines.)&lt;br /&gt;
This will also speed up the process of applying kernel patches by applying it for your architecture only. (Obviously ARCH in the following example is whatever architecture x86, x86_64...you use.)&lt;br /&gt;
&lt;br /&gt;
First make a copy of your ARCH config file:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cp lts.x86_64.config lts-my_custom.x86_64.config&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Edit your custom config file and add your changes. When you are done with your edits you need to run checksum to update APKBUILD:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;FLAVOR=lts-my_custom abuild checksum&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then commit your changes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;git commit -a -m &amp;quot;Enabled these options ....&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You do this so that git can keep your code separate from Alpine&#039;s and so your changes float forward between kernel updates.&lt;br /&gt;
&lt;br /&gt;
== Adding custom patches ==&lt;br /&gt;
&lt;br /&gt;
Custom patches should be added to &#039;&#039;sources=&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
After you added the URL, you need to produce a checksum by doing &amp;lt;code&amp;gt;abuild checksum&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The custom patches may not be autopatched, due to being distributed as an archive or different patch level, so you need to define what to do with it in the prepare().&lt;br /&gt;
&lt;br /&gt;
== Configuring kernel ==&lt;br /&gt;
&lt;br /&gt;
There are multiple ways to prepare and change kernel config. The basic one is to just edit your custom config file. You can also attempt to create a config tailored for your currently running system and modules.&lt;br /&gt;
&lt;br /&gt;
Extract your kernel and apply the standard patches:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
abuild fetch &amp;amp;&amp;amp; abuild unpack &amp;amp;&amp;amp; abuild prepare&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To create a kernel config based on your currently running PC, use:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
make localmodconfig&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This command reads your current kernel&#039;s configuration from /proc/config.gz (if available) or /boot/config-* and creates a .config file that includes only the modules currently loaded on your system. This results in a minimal configuration tailored to your hardware.&lt;br /&gt;
Alternatively, you can use:&lt;br /&gt;
&amp;lt;pre&amp;gt;make localyesconfig&amp;lt;/pre&amp;gt;&lt;br /&gt;
This is similar to &#039;&#039;localmodconfig&#039;&#039;, but instead of building features as modules (m), it builds them directly into the kernel (y), which can result in a larger kernel image but eliminates the need for separate module files.&lt;br /&gt;
Note: Before running either command, make sure you have all the hardware you want to support actively in use (USB devices plugged in, network cards active, etc.) so their modules are loaded and included in the configuration.&lt;br /&gt;
&lt;br /&gt;
The alternative is to use the kernel configuration menu in the build-NAME folder, but before you do that you need to &amp;lt;code&amp;gt;sudo apk add {{pkg|ncurses-dev}}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After you are done using the menu in the build-NAME folder by doing:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;make menuconfig&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You want to remove &amp;lt;code&amp;gt;ncurses-dev&amp;lt;/code&amp;gt;.  When you are done, it will be stored in &#039;&#039;.config&#039;&#039; which you need to again override the {{path|lts.ARCH.config}} file.&lt;br /&gt;
&lt;br /&gt;
When you are done updating the {{path|config-NAME.ARCH}}, you need to update sums:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
abuild checksum&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The options in the kernel config are typically defaults.  If your device is old, it may be set to n by default.&lt;br /&gt;
&lt;br /&gt;
=== Vanilla targets and tuning ===&lt;br /&gt;
&lt;br /&gt;
{|cellpadding=&amp;quot;5&amp;quot; border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!ARCH&lt;br /&gt;
!Processor Type / CPU Selection / System Type&lt;br /&gt;
!Code Generation / Instruction Extensions&lt;br /&gt;
!Timer Frequency&lt;br /&gt;
!Preemption Model&lt;br /&gt;
!Bitness&lt;br /&gt;
|-&lt;br /&gt;
|s390x&lt;br /&gt;
|IBM zEnterprise 114 and 196&lt;br /&gt;
|IBM zBC12 and zEC12 (&amp;lt;code&amp;gt;-march=zEC12 -mtune=zEC12&amp;lt;/code&amp;gt;)&lt;br /&gt;
|1000 Hz&lt;br /&gt;
|No Forced Preemption (Server)&lt;br /&gt;
|64&lt;br /&gt;
|-&lt;br /&gt;
|ppc64le&lt;br /&gt;
|Server processors&lt;br /&gt;
|POWER8 (&amp;lt;code&amp;gt;-mcpu=power8&amp;lt;/code&amp;gt;), AltiVec (&amp;lt;code&amp;gt;-Wa,-maltivec&amp;lt;/code&amp;gt; to assembler or &amp;lt;code&amp;gt;-maltivec -mabi=altivec&amp;lt;/code&amp;gt;), VSX&lt;br /&gt;
|1000 HZ&lt;br /&gt;
|No Forced Preemption (Server)&lt;br /&gt;
|64&lt;br /&gt;
|-&lt;br /&gt;
|ppc&lt;br /&gt;
|&lt;br /&gt;
512x/52xx/6xx/7xx/74xx/82xx/83xx/86xx&lt;br /&gt;
* Apple PowerMac based machines&lt;br /&gt;
|AltiVec (&amp;lt;code&amp;gt;-Wa,-maltivec&amp;lt;/code&amp;gt; to assembler or &amp;lt;code&amp;gt;-maltivec -mabi=altivec&amp;lt;/code&amp;gt;) on &amp;gt;=74xx&lt;br /&gt;
|1000 HZ&lt;br /&gt;
|No Forced Preemption (Server)&lt;br /&gt;
|32&lt;br /&gt;
|-&lt;br /&gt;
|x86_64&lt;br /&gt;
|Generic-x86-64&lt;br /&gt;
|(-mtune=generic ; SIMD assembly modules enabled based on simple compile test and/or presence of CPU flag)&lt;br /&gt;
|1000 HZ&lt;br /&gt;
|Voluntary Kernel Preemption (Desktop)&lt;br /&gt;
|64&lt;br /&gt;
|-&lt;br /&gt;
|x86&lt;br /&gt;
|586/K5/5x86/6x86/6x86MX&lt;br /&gt;
|(-mtune=generic ; SIMD assembly modules enabled based on simple compile test and/or presence of CPU flag)&lt;br /&gt;
|1000 HZ&lt;br /&gt;
|Voluntary Kernel Preemption (Desktop)&lt;br /&gt;
|32&lt;br /&gt;
|-&lt;br /&gt;
|armv7&lt;br /&gt;
|&lt;br /&gt;
* ARMv7 based platforms (Cortex-A, PJ4, Scorpion, Krait)&lt;br /&gt;
* Freescale i.MX family -- Cortex A (i.MX51, i.MX53, i.MX6 Quad/DualLite, i.MX6 SoloLite, i.MX6 SoloX, i.MX6 UltraLite, i.MX7 Dual)&lt;br /&gt;
* Qualcomm -- (MSM8X60, MSM8960, MSM8974)&lt;br /&gt;
* Allwinner SoCs -- (A10 (sun4i), A10s / A13 (sun5i), A31 (sun6i), A20 (sun7i), sun8i Family, (sun9i))&lt;br /&gt;
* ARM Ldt Versatile Express family -- &lt;br /&gt;
|Either &amp;lt;code&amp;gt;-march=armv7-a&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;-march=armv5t -Wa,-march=armv7-a&amp;lt;/code&amp;gt; based on a compile test. &amp;lt;code&amp;gt;-mfpu=vfp&amp;lt;/code&amp;gt;&lt;br /&gt;
|1000 Hz&lt;br /&gt;
|Voluntary Kernel Preemption (Desktop)&lt;br /&gt;
|32&lt;br /&gt;
|-&lt;br /&gt;
|aarch64&lt;br /&gt;
|&lt;br /&gt;
* Allwinner sunxi 64-bit SoC Family&lt;br /&gt;
* Broadcom BCM2835 family&lt;br /&gt;
* Marvell Berlin SoC Family&lt;br /&gt;
* ARMv8 based Samsung Exynos SoC family&lt;br /&gt;
* ARMv8 based Freescale Layerscape SoC family&lt;br /&gt;
* Hisilicon SoC Family&lt;br /&gt;
* Mediatek MT65xx &amp;amp; MT81xx ARMv8 SoC&lt;br /&gt;
* Marvell EBU SoC Family&lt;br /&gt;
* Qualcomm Platforms&lt;br /&gt;
* Rockchip Platforms&lt;br /&gt;
* AMD Seattle SoC Family&lt;br /&gt;
* Altera&#039;s Stratix 10 SoCFPGA Family&lt;br /&gt;
* NVIDIA Tegra SoC Family&lt;br /&gt;
* Spreadtrum SoC platform&lt;br /&gt;
* Cavium Inc. Thunder SoC Family&lt;br /&gt;
* ARMv8 software model (Versatile Express)&lt;br /&gt;
* AppliedMicro X-Gene SOC Family&lt;br /&gt;
* Xilinx ZynqMP Family&lt;br /&gt;
|&lt;br /&gt;
|1000 HZ&lt;br /&gt;
|Voluntary Kernel Preemption (Desktop)&lt;br /&gt;
|64&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
If you do desktop multitasking, you may want to switch to Voluntary Kernel Preemption (Desktop) or Preemptible Kernel (Low-Latency Desktop) and up the Timer Frequency.  If you run a dedicated render farm node or a dedicated bitcoin miner use No Forced Preemption (Server) and decrease the Timer Frequency.&lt;br /&gt;
&lt;br /&gt;
Optimized modules (most are already compiled as modules):&lt;br /&gt;
* raid6 -- altivec, avx512, ssse3, avx2, mmx, sse, sse2, neon&lt;br /&gt;
* some operations of raid5 -- mmx (32 bit), sse (64 bit), avx&lt;br /&gt;
For Kernel API:&lt;br /&gt;
* 32-bit memcpy -- 3dnow&lt;br /&gt;
* 32-bit memory page clearing and copying -- sse (Athlon/K7 only), mmx&lt;br /&gt;
From x86/crypto, arm/crypto, powerpc/crypto:&lt;br /&gt;
* CAMELLIA -- avx2, avx, aes-ni&lt;br /&gt;
* CHACHA20 -- avx2, neon&lt;br /&gt;
* CAST5 -- avx&lt;br /&gt;
* CAST6 -- avx&lt;br /&gt;
* TWOFISH -- avx&lt;br /&gt;
* SERPENT -- avx2, avx, sse2&lt;br /&gt;
* SHA1 -- avx2, ssse3, neon, spe&lt;br /&gt;
* SHA2 -- avx2&lt;br /&gt;
* SHA256 -- ssse3, neon, spe&lt;br /&gt;
* SHA512 -- avx2, ssse3, neon&lt;br /&gt;
* POLY1305 -- avx2&lt;br /&gt;
* GHASH -- pclmulqdq (part of aes-ni), vmx (power8)&lt;br /&gt;
* AES -- aes-ni, neon, vmx (power8), spe&lt;br /&gt;
* CRC32 -- pclmulqdq, sse, neon, vmx (power8)&lt;br /&gt;
* CRCT10DIF -- pclmulqdq, sse, neon, vmx (power8)&lt;br /&gt;
&lt;br /&gt;
=== Fast reboots with kexec ===&lt;br /&gt;
{{main|kexec}}&lt;br /&gt;
&lt;br /&gt;
If you want to reboot the kernel fast avoiding the POST test, you need {{ic|doas apk add {{pkg|kexec-tools}}}} and enable kexec in the kernel:&lt;br /&gt;
&lt;br /&gt;
  Processor type and features&lt;br /&gt;
    [*] kexec system call&lt;br /&gt;
&lt;br /&gt;
=== Hibernation to prevent data loss ===&lt;br /&gt;
&lt;br /&gt;
  Power management and ACPI options&lt;br /&gt;
    [*] Hibernation (aka &#039;suspend to disk&#039;)&lt;br /&gt;
&lt;br /&gt;
Hibernation should be used if you have a laptop.  You don&#039;t want the laptop to suddenly shut off resulting in data loss, you want it to save your work based on a percentage of battery life (this requires special script).  When hibernation resumes, should lock and ask for credentials.  Depending on your needs, the hibernated image can be encrypted/decrypted which again requires additional customization to scripts.&lt;br /&gt;
&lt;br /&gt;
Hibernation with an unsanitized swap file is generally insecure because data and unlocked memory pages are swapped out in plaintext.  To increase the security either disable swap or use an encrypted swap.  The swap file/partition is typically used as the hibernation resume image.&lt;br /&gt;
&lt;br /&gt;
== Building ==&lt;br /&gt;
&lt;br /&gt;
Before building, make sure you have ccache installed.  This should reduce compile time on multiple builds.&lt;br /&gt;
You may also want to read up on compile flags - perhaps you want your build to be optimized for speed (or size which is the default).&lt;br /&gt;
Review &amp;lt;code&amp;gt;/etc/abuild.conf&amp;lt;/code&amp;gt; and set:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
PACKAGER_PRIVKEY=&amp;quot;/home/MY_USER_HERE/.abuild/my-email@mydomain.com-ID.rsa&amp;quot;&lt;br /&gt;
USE_CCACHE=1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Please note that kernel build process may not use some of the settings you set in `abuild.conf` so in order to customize compiler or linker and/or it&#039;s flags you may need to edit APKBUILD.&lt;br /&gt;
If you have your config ready, first try building with:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FLAVOR=lts-my_custom abuild -rK 2&amp;gt;&amp;amp;1 | tee build1.log&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will install most of the dependencies and keep buildtime temp dirs and files (srcdir/pkgdir/deps).&lt;br /&gt;
&lt;br /&gt;
If it complains about a dependency like {{pkg|elfutils-dev}} use &amp;lt;code&amp;gt;-rKd&amp;lt;/code&amp;gt;.&lt;br /&gt;
Then, when it prompts for values for new found config options just hold enter till it starts compiling the kernel.&lt;br /&gt;
Unless you use &amp;lt;code&amp;gt;FLAVOR&amp;lt;/code&amp;gt; or removed or commented out &amp;lt;code&amp;gt;virt.*.config&amp;lt;/code&amp;gt; configs in APKBUILD there should be two sets one for -lts and the other for the -virt.&lt;br /&gt;
Just {{Key|Ctrl}}+{{Key|C}} out of the compilation process after &lt;br /&gt;
the second set so you can further customize the config.&lt;br /&gt;
Then you go into the {{path|src/linux-VER}} and edit the config file.&lt;br /&gt;
Copy the {{path|.config}} file overriding the {{path|lts.ARCH.config}} in the srcdir.&lt;br /&gt;
&lt;br /&gt;
== Installing ==&lt;br /&gt;
&lt;br /&gt;
If the build was successful the kernel packages are located in &amp;lt;code&amp;gt;~/packages/main/ARCH&amp;lt;/code&amp;gt;&lt;br /&gt;
You probably already know how to install a package in your Alpine Linux...&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
In case your new kernel may be missing a module and can&#039;t boot it is generally a good idea to keep the default &amp;lt;code&amp;gt;linux-lts&amp;lt;/code&amp;gt;, so make sure you have it installed using the command: {{Cmd|# apk add {{pkg|linux-lts}}}}&lt;br /&gt;
&lt;br /&gt;
Normally during the installation using with [[apk]], there are tools that will update initramfs and a boot loader automatically for you. For easier debugging you may want to change boot loader config and remove &amp;lt;code&amp;gt;quiet&amp;lt;/code&amp;gt; from linux command line in {{Path|/etc/default/grub}} or {{Path|/etc/update-extlinux.conf}}.&lt;br /&gt;
Or perhaps you want to change other kernel options in {{Path|/etc/mkinitfs/mkinitfs.conf}}. Please remember to generate initramfs and update your bootloader manually, eg:&lt;br /&gt;
{{Cmd|&amp;lt;nowiki&amp;gt;# mkinitfs&lt;br /&gt;
# grub-mkconfig -o /boot/grub/grub.cfg&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
In case something goes wrong with a boot process it is also a good idea to have a bootable rescue Alpine USB ready.&lt;br /&gt;
&lt;br /&gt;
Once you have the default lts kernel and rescue USB &amp;lt;code&amp;gt;reboot&amp;lt;/code&amp;gt; the computer.&lt;br /&gt;
&lt;br /&gt;
If you are curious about correctness testing, some kernel modules or components do preform self tests at the beginning of the boot process.  The tools may have test suites that you run with the make command.&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [[Kernels]]&lt;br /&gt;
* [https://wiki.archlinux.org/title/Kernel Archwiki Kernels]&lt;br /&gt;
* [https://wiki.gentoo.org/wiki/Kernel Gentoo Wiki Kernel]&lt;br /&gt;
* [https://wiki.gentoo.org/wiki/Kernel/Configuration Gentoo Wiki Kernel Configuration]&lt;br /&gt;
* [[How to build the Alpine Linux kernel]]&lt;br /&gt;
* [[Kernel_live_patching|Kernel Live Patching (KLP)]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Kernel]]&lt;/div&gt;</summary>
		<author><name>Darkfader</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32237</id>
		<title>User:Darkfader/distcc</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32237"/>
		<updated>2026-03-29T14:25:22Z</updated>

		<summary type="html">&lt;p&gt;Darkfader: /* Alternatives */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi,&lt;br /&gt;
&lt;br /&gt;
I&#039;m preparing this page. It can take a long time till I finish.&lt;br /&gt;
If you are also wishing to write on this topic, feel free to integrate the content.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Document overview ==&lt;br /&gt;
&lt;br /&gt;
I noticed that almost every distro has one partially complete, partially helpful document on how to use distcc on the distro.&lt;br /&gt;
Usually they also have one for ccache.&lt;br /&gt;
In either case, they&#039;re enough to get started, but not really a reliable watertight thing.&lt;br /&gt;
We definitely needed one of our own.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== goal ===&lt;br /&gt;
&lt;br /&gt;
to describe a working setup for building aports in easiest/fastests fashion&lt;br /&gt;
not planning to add versatility or features where it would make the setup more errorprone.&lt;br /&gt;
the page should describe enough of the steps to successfully compile an LTS kernel via aports and have that job be distributed over multiple nodes.&lt;br /&gt;
Logs should be set up and able to display errors, but not show any errors during the test compile.&lt;br /&gt;
&lt;br /&gt;
To include a path for analysis via testing components.&lt;br /&gt;
&lt;br /&gt;
distcc can greatly improve compile speeds for large software, it comes with a different set of features than ccache; it focusses not avoiding unneccessary compile work, but on a way to speed up the necessary one.&lt;br /&gt;
&lt;br /&gt;
There&#039;s valuable info in the docs of other distros, it should be referenced here (i.e. the arch wiki troubleshooting), when it makes sense, add a TOC for their content.&lt;br /&gt;
&lt;br /&gt;
=== audience ===&lt;br /&gt;
people running software builds on alpine and have multiple computers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This page will show a specific installation, specific configuration, and specific tests, resulting in a specific set of functionality that can be tested to be working.&lt;br /&gt;
&lt;br /&gt;
== installation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Packages ===&lt;br /&gt;
&lt;br /&gt;
you need, on each host&lt;br /&gt;
* distcc&lt;br /&gt;
* distccd-openrc&lt;br /&gt;
* distcc-pump&lt;br /&gt;
* distcc-pump-pyc&lt;br /&gt;
&lt;br /&gt;
the .pyc will speed up the invocations, without it &lt;br /&gt;
idk if one or both should be installed in that case. but it appears to be also automatically be precompiled in /usr/lib/python3.12/site-packages/include_server/__pycache__/ so what does the package do exactly?&lt;br /&gt;
&lt;br /&gt;
There&#039;s some references to cpython-312, so maybe it actually still uses classy python-c conversion or matbe that&#039;s just a component for reading C source code. I have zero idea.&lt;br /&gt;
&lt;br /&gt;
you also need stuff to do compiles&lt;br /&gt;
* alpine sdk&lt;br /&gt;
* clang&lt;br /&gt;
* binutils&lt;br /&gt;
...&lt;br /&gt;
* elfutils(-dev)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Settings ===&lt;br /&gt;
==== settings for distcc ====&lt;br /&gt;
&lt;br /&gt;
* there&#039;s /etc/default/distcc&lt;br /&gt;
* there&#039;s /etc/conf.d/distcc &lt;br /&gt;
&lt;br /&gt;
make all your settings here&lt;br /&gt;
take care with the listen address, if you specify an IP it&#039;ll not be on 127.0.0.1 in case you would have localhost in your list...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* command_whitelist.sh &lt;br /&gt;
&lt;br /&gt;
this is half functional, you need to set things here but you also need to maintain the symlinks that are collected under /usr/lib/distcc (for your compilers) and /usr/lib/distcc/bin (for itself)&lt;br /&gt;
&lt;br /&gt;
you MUST run the script to update the compilers!&lt;br /&gt;
Info for script and what files it will create&lt;br /&gt;
&lt;br /&gt;
/usr/sbin/update-distcc-symlinks&lt;br /&gt;
&lt;br /&gt;
tschike:/usr/bin# ls -l /usr/lib/distcc/&lt;br /&gt;
total 4&lt;br /&gt;
drwxr-xr-x 2 root root 4096 Mar  2 18:14 bin&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c89 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c99 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 cc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc-15.2.0 -&amp;gt; ../../bin/distcc&lt;br /&gt;
&lt;br /&gt;
distcc itself is in bin&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cpp -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 g++ -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 06:49 x86_64-alpine-linux-musl-gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
&lt;br /&gt;
the last symplink here is wrong, made by me and would not work...&lt;br /&gt;
BAD symlink.&lt;br /&gt;
&lt;br /&gt;
=== distcc hosts file ===&lt;br /&gt;
&lt;br /&gt;
idk about that thing it&#039;s odd&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== abuild.conf ===&lt;br /&gt;
&lt;br /&gt;
settings for aports&lt;br /&gt;
* cc=&lt;br /&gt;
* cxx=&lt;br /&gt;
* cpp=&lt;br /&gt;
* cflags=&lt;br /&gt;
* njobs&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== detail infos ==&lt;br /&gt;
&lt;br /&gt;
???&lt;br /&gt;
&lt;br /&gt;
=== hosts syntax ===&lt;br /&gt;
&lt;br /&gt;
* myhost otherhost&lt;br /&gt;
* myhost,cpp,lzo myotherhost,cpp,lzo&lt;br /&gt;
&lt;br /&gt;
==== the host ====&lt;br /&gt;
&lt;br /&gt;
hostname/ip&lt;br /&gt;
localhost&lt;br /&gt;
127.0.0.1&lt;br /&gt;
::1 - does not work&lt;br /&gt;
&lt;br /&gt;
==== protocol ====&lt;br /&gt;
&lt;br /&gt;
* no protocol given&lt;br /&gt;
* ,cpp,lzo protocol&lt;br /&gt;
&lt;br /&gt;
cpp implies lzo, it requires compression, even if you have 10gbit/s or more, it&#039;s just hardcoded&lt;br /&gt;
&lt;br /&gt;
=== threads ===&lt;br /&gt;
/number of workers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== architecture ==&lt;br /&gt;
it can handle C, C++, ObjC, maybe some other stuff&lt;br /&gt;
&lt;br /&gt;
* what happens with normal xmit&lt;br /&gt;
* what happens with pump mode&lt;br /&gt;
* at which step the include server is used and how it collects the includes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== distribution algorithm ===&lt;br /&gt;
honestly I simply don&#039;t get it&lt;br /&gt;
&lt;br /&gt;
* The order matters&lt;br /&gt;
* The number of threads matters&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== localhost ====&lt;br /&gt;
&lt;br /&gt;
* localhost precedence&lt;br /&gt;
* localhost fallback&lt;br /&gt;
&lt;br /&gt;
variable: DISTCC_FALLBACK&lt;br /&gt;
&lt;br /&gt;
0 = Fail to compile if it would need to fallback to a normal local gcc call&lt;br /&gt;
1 = If remote compile fails, just do it yourself&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Operation ==&lt;br /&gt;
&lt;br /&gt;
=== startup and shutdown ===&lt;br /&gt;
service distcc stop is not entirely reliable (it can take a minute after the stop until the processes are gone and sometimes it will never stop&lt;br /&gt;
this is very bad with openrc, the openrc script returns after a second and only relies on its service flags, not the process status.&lt;br /&gt;
manually check after stopping, wait a min, if needed, kill it all.&lt;br /&gt;
at some point the rc file needs to be rewritten, it can&#039;t stay like it is.&lt;br /&gt;
&lt;br /&gt;
if you used a pump mode session, that also needs a logout (pump --shutdown)&lt;br /&gt;
avoid running multiple startups without shutdown in one session. it&#039;s safe as far as I can tell but nothing cleans up these processes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== ccache and memcached ===&lt;br /&gt;
CCACHE is said to be conflicting with pump mode unless when you call them in the backend&lt;br /&gt;
so, where you start the compile, you don&#039;t use it&lt;br /&gt;
where the compile happens, you use it&lt;br /&gt;
they can share the cache via memcached, this is a nice trick for consistency&lt;br /&gt;
Upon looking at the ccache website, it seems the correct mechanism is not memcached but Redis. This would work just as well. Generally a cache shared in this way would be optimal for performance.&lt;br /&gt;
&lt;br /&gt;
=== dockerized / native ===&lt;br /&gt;
&lt;br /&gt;
it remains mostly the same, a container needs to make sure it monitors the right services (distccd, nginx, include_server)&lt;br /&gt;
if you&#039;re using zeroconf, you need to somehow expose the mdns service broadcasts &amp;amp; receptio&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== untested build container system ====&lt;br /&gt;
&lt;br /&gt;
See this one https://github.com/bensuperpc/docker-distcc&lt;br /&gt;
not yet tested, but this could be a good basis for a &#039;best practice&#039; container.&lt;br /&gt;
There&#039;s others, especially for crossbuilds, but those are also very complex to modify.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Processs list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
Workdir list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
=== alpine-chroot ===&lt;br /&gt;
&lt;br /&gt;
when using the &#039;official&#039; script there&#039;s still some odd pieces, seemed to be the processes died on logout. but not all of them.&lt;br /&gt;
&lt;br /&gt;
==== manual launch ====&lt;br /&gt;
&lt;br /&gt;
Starting the daemon would be using&lt;br /&gt;
/usr/bin/distccd --pid-file /var/run/distccd/distccd.pid -N 15 --user distcc --port 3632 --log-level=debug --log-file=/var/log/distccd.log --allow my-sub-net/24&lt;br /&gt;
&lt;br /&gt;
==== localhost? =====&lt;br /&gt;
unclear if you need to use --allow for 127.0.0.1/32 or something to allow the remote preproccesor.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Gitlab integration ===&lt;br /&gt;
&lt;br /&gt;
TBA&lt;br /&gt;
&lt;br /&gt;
Maybe work from this k8s howto, it&#039;s a bit more prod-grade than most:&lt;br /&gt;
&lt;br /&gt;
https://cinaq.com/blog/2020/05/10/speed-up-docker-builds-with-distcc-ccache-and-kubernetes/&lt;br /&gt;
&lt;br /&gt;
== Kernel specific settings ==&lt;br /&gt;
&lt;br /&gt;
currently (distcc 3.4-r9 on Alpine) you need a patch to build the kernel.&lt;br /&gt;
See &lt;br /&gt;
&lt;br /&gt;
=== Include server Settings ===&lt;br /&gt;
&lt;br /&gt;
cache reset triggers&lt;br /&gt;
This ought to be set before enabling pump mode.&lt;br /&gt;
&lt;br /&gt;
export INCLUDE_SERVER_ARGS=&amp;quot;--stat_reset_triggers=include/linux/compile.h:include/asm/asm-offsets.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
link to explanation TBA&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Disabling GCC Plugins ===&lt;br /&gt;
&lt;br /&gt;
KConfig unselect HAVE_GCC_PLUGINS&lt;br /&gt;
&lt;br /&gt;
Some info is here in the troubleshooting part of the Arch Wiki&lt;br /&gt;
https://wiki.archlinux.org/title/Distcc#Troubleshooting&lt;br /&gt;
&lt;br /&gt;
=== Patches ===&lt;br /&gt;
&lt;br /&gt;
Other things (for 6.6LTS)&lt;br /&gt;
PCIe Stub patch&lt;br /&gt;
&lt;br /&gt;
=== Autoconf === &lt;br /&gt;
&lt;br /&gt;
No known setup examples&lt;br /&gt;
Add whatever it publishes in mdns&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== troubleshooting / analysis ==&lt;br /&gt;
&lt;br /&gt;
=== testing ===&lt;br /&gt;
&lt;br /&gt;
# turn off fallback DISTCC_FALLBACK=1&lt;br /&gt;
# set distcc up to point at specific system under test DISTCC_HOSTS=&amp;quot;mytestbox,cpp,lzo&amp;quot;&lt;br /&gt;
# GCC example compiles&lt;br /&gt;
## code example C&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example C++&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example ObjC&lt;br /&gt;
## same with included header&lt;br /&gt;
# Cmake example compiles&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docoument the thing with compile launcher ccache;distcc&lt;br /&gt;
there&#039;s some blog post, point to that&lt;br /&gt;
no ccache here yet&lt;br /&gt;
show $CC differences distcc vs gcc, what configure scripts see&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Latency ===&lt;br /&gt;
&lt;br /&gt;
Latency of pump mode startups and fallbacks needs to be investigated.&lt;br /&gt;
LZO is enforced even if you have faster network&lt;br /&gt;
DNS Requests, very old bug report from Gcode, one request per call, is it true? how to get rid of it?&lt;br /&gt;
TMPDIR is respected, make sure it&#039;s on ramdisk even on the remote nodes.&lt;br /&gt;
Compile ideally never goes to disk when it doesn&#039;t have to.&lt;br /&gt;
How efficient is the include server collection and unpacking?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== failed to distribute, running locally instead ===&lt;br /&gt;
&lt;br /&gt;
the curse of the ancient, wise bulgarian witch compildora nottherea has befallen people all over the world. only strict and mindless adherence to rituals passed down from generation to generation has given hope to those who are under her ages old spell. again and again it reemerges to prey on idealistic young men and women who spend so much time at their unholy computers that they try to spend less time there by spending a lot of time trying to optimize what the computer does, slowly, instead of reflecting on why they are there, while the computer is busy working, and why they try to solve this by adding a component that makes the computer be more error-prone at that same work, increasing the need of their presense at this idolized thinking machine to oversee and often repair, or worse, mindlessly restart its doing.&lt;br /&gt;
if the curse is not lifted, despair may befall them and all they see is the need to investigate and ruminate further on the workings of this tool, ignoring thereby the obivous flaws that stem from of its alchemic origins.&lt;br /&gt;
&lt;br /&gt;
just wait till you find out it has a backoff alghoritm deciding whether to call out to a remote server independent of that server functioning. graceful performance degradation is the goal, and degrading it is while we try to figure this out.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Node Selection algorithm ====&lt;br /&gt;
&lt;br /&gt;
as per my understanding, a flowchart goes here:&lt;br /&gt;
&lt;br /&gt;
# compile task&lt;br /&gt;
# evaluate whether to run locally by job nature&lt;br /&gt;
# determine if local host&#039;s load is notable&lt;br /&gt;
# look at distcc hosts list&lt;br /&gt;
# do something based off localhost entry if first&lt;br /&gt;
# filter for nodes with cpp flag&lt;br /&gt;
# do something based off localhost entry if not first&lt;br /&gt;
# further prioritize by server order, first is handled in some way&lt;br /&gt;
# skip nodes in backoff prisons&lt;br /&gt;
# balance and priotize by server thread number, if given&lt;br /&gt;
# send to suitable host&lt;br /&gt;
# if compile not successful, proceed on other node&lt;br /&gt;
# if nodes depleted, proceed on localhost&lt;br /&gt;
&lt;br /&gt;
== security ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== tcpwrapper style ip range filter ===&lt;br /&gt;
&lt;br /&gt;
the original security model consists of ip restrictions.&lt;br /&gt;
there seems to also be some GSSAPI user auth.&lt;br /&gt;
further, commands that can be called are restricted by name and location.&lt;br /&gt;
this appears to be a runtime whitelist lookup, meaning it&#039;s done and authorized by the same parts of the daemon as processes the compile request along with the intended compiler.&lt;br /&gt;
so the main weaknesses against malicious clients seem to be in sending things to compile, and in overriding the remote compiler to use.&lt;br /&gt;
it can be assumed that a malicious client able to exploit the compiler handshake can then run arbitrary stuff.&lt;br /&gt;
There&#039;s at least a github issue regarding this (link lost, but see here: https://gitlab.com/postmarketOS/pmbootstrap/-/work_items/1619) suggesting running over ssh. That does only partitally alleviate this risk with regard  to a key based verfication of a client versus a the standard ip restrictions which always include some parsing.&lt;br /&gt;
So this protects against someone directly exploiting the TCP code of distcc.&lt;br /&gt;
It does not protect against malicious clients.&lt;br /&gt;
(ssh force command can&#039;t be used or you&#039;ll not compile anything)&lt;br /&gt;
&lt;br /&gt;
The basic step for protecting access should be filtering who can access the distcc server, so use nftables etc. to restrict access to port 3262 (??) set up the internal filter the same way.&lt;br /&gt;
&lt;br /&gt;
=== seccomp ===&lt;br /&gt;
&lt;br /&gt;
The next thing is to confine the compiler calls to only write in their temp directory and that they can only run compilers (using nsjail, apparmor, selinux etc)&lt;br /&gt;
&lt;br /&gt;
the above issue also references the second bit of security, namely a seccomp filter which will already cover a good bit of the above&lt;br /&gt;
https://github.com/distcc/distcc/pull/235&lt;br /&gt;
the commit got closed without merge, from what I see.&lt;br /&gt;
&lt;br /&gt;
I will update the entry once it&#039;s clear if the patch was later added or instead nothing was done.&lt;br /&gt;
&lt;br /&gt;
=== privs ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The other internal security bit is that they do some priviledge dropping. it runs as a dedicated user (distcc), so you can also have an audit policy, and can/could use something like iptables&#039; to ensure it can only connect to the other distcc/memcached hosts, but nothing else.&lt;br /&gt;
&lt;br /&gt;
=== compiler list ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
One needs to investigate when compiler_whitelist.sh is exactly called. as far as I recall it doesn&#039;t close stdin/stdout.&lt;br /&gt;
&lt;br /&gt;
=== distcc-hardened ===&lt;br /&gt;
&lt;br /&gt;
Alpine adds some hardening patch, idk what nature/origina that has.&lt;br /&gt;
&lt;br /&gt;
=== selinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
there&#039;s also a selinux policy for distcc from gentoo or liguros if one is so inclined.  &lt;br /&gt;
links for further review:&lt;br /&gt;
&lt;br /&gt;
- https://repology.org/project/selinux-distcc/versions  &lt;br /&gt;
- https://gitlab.com/liguros/liguros-repo/-/tree/stable/sec-policy/selinux-distcc&lt;br /&gt;
&lt;br /&gt;
=== general posture ===&lt;br /&gt;
&lt;br /&gt;
Some security measures like the above should definitely be used since the project at its core relies on accepting foreign input over the network, has only a few part-time maintainers that cannot easily drive the project forward or do large refactors.&lt;br /&gt;
But the seccomp changes were done almost 10 years ago, so, if they were actually upstreamed, I&#039;d say they came through.&lt;br /&gt;
&lt;br /&gt;
A kind of overengineered solulion would be to use netlabel to ensure application integrity across hosts, meaning only a valid process would be able to send packets to the distcc nodes :-)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Alternatives ==&lt;br /&gt;
&lt;br /&gt;
Arch wiki refers to a fork by SUSE&lt;br /&gt;
https://github.com/icecc/icecream&lt;br /&gt;
&lt;br /&gt;
It appears &#039;maybe better&#039; but hard to tell. There&#039;s no mention if maybe SUSE&#039;s OBS uses it or something. Without more knowledge of their use I don&#039;t know how big a benefit will come from switching. At least you&#039;d wanna know they have a higher commitment to maintenance than the understaffed distcc &#039;team&#039; of current.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A commercial alternative (incredibuild https://www.incredibuild.com/) exists, but I have not tried it.&lt;br /&gt;
There are references to some &#039;forever free&#039; tier, also, but I could not yet find the terms and conditions for having a &#039;forever free thing&#039;. it also seems you need a windows-based &#039;coordinator&#039; host.&lt;br /&gt;
opinion: generally if there&#039;s some professional context with high (business) pressure for faster builds I would check that out, and then without time pressure build a great distcc setup for the long-term.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Architecturally it seems to be taking the ccache approach with a shared cache and smarter redistribution.&lt;br /&gt;
So anything that can call ccache is something they can scale out. I&#039;ll add a link later, for those whom it helps.&lt;br /&gt;
Naturally it is out of scope for this article.&lt;br /&gt;
Nonetheless it&#039;s interesting since the ordering of how to run ccache and how to run distcc is an issue that also exists in the OSS world. Not just that we don&#039;t have an automatic setup and integration of the tools (ccache, redis, distccd, distcc-pump) but we also don&#039;t have collected sufficient data to aid in deciding which aproach is the best.&lt;br /&gt;
Integrating into CIs (gitlab-runner specifically) is another item where cache persistence becomes very fragile.&lt;br /&gt;
Having an alpine build container that knows how to use ccache with redis and distcc-pump would be a possible step forward.&lt;br /&gt;
&lt;br /&gt;
== Other sources ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://retroflux.net/blog/distcc-adventures/&lt;/div&gt;</summary>
		<author><name>Darkfader</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32236</id>
		<title>User:Darkfader/distcc</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32236"/>
		<updated>2026-03-29T14:23:32Z</updated>

		<summary type="html">&lt;p&gt;Darkfader: /* Alternatives */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi,&lt;br /&gt;
&lt;br /&gt;
I&#039;m preparing this page. It can take a long time till I finish.&lt;br /&gt;
If you are also wishing to write on this topic, feel free to integrate the content.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Document overview ==&lt;br /&gt;
&lt;br /&gt;
I noticed that almost every distro has one partially complete, partially helpful document on how to use distcc on the distro.&lt;br /&gt;
Usually they also have one for ccache.&lt;br /&gt;
In either case, they&#039;re enough to get started, but not really a reliable watertight thing.&lt;br /&gt;
We definitely needed one of our own.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== goal ===&lt;br /&gt;
&lt;br /&gt;
to describe a working setup for building aports in easiest/fastests fashion&lt;br /&gt;
not planning to add versatility or features where it would make the setup more errorprone.&lt;br /&gt;
the page should describe enough of the steps to successfully compile an LTS kernel via aports and have that job be distributed over multiple nodes.&lt;br /&gt;
Logs should be set up and able to display errors, but not show any errors during the test compile.&lt;br /&gt;
&lt;br /&gt;
To include a path for analysis via testing components.&lt;br /&gt;
&lt;br /&gt;
distcc can greatly improve compile speeds for large software, it comes with a different set of features than ccache; it focusses not avoiding unneccessary compile work, but on a way to speed up the necessary one.&lt;br /&gt;
&lt;br /&gt;
There&#039;s valuable info in the docs of other distros, it should be referenced here (i.e. the arch wiki troubleshooting), when it makes sense, add a TOC for their content.&lt;br /&gt;
&lt;br /&gt;
=== audience ===&lt;br /&gt;
people running software builds on alpine and have multiple computers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This page will show a specific installation, specific configuration, and specific tests, resulting in a specific set of functionality that can be tested to be working.&lt;br /&gt;
&lt;br /&gt;
== installation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Packages ===&lt;br /&gt;
&lt;br /&gt;
you need, on each host&lt;br /&gt;
* distcc&lt;br /&gt;
* distccd-openrc&lt;br /&gt;
* distcc-pump&lt;br /&gt;
* distcc-pump-pyc&lt;br /&gt;
&lt;br /&gt;
the .pyc will speed up the invocations, without it &lt;br /&gt;
idk if one or both should be installed in that case. but it appears to be also automatically be precompiled in /usr/lib/python3.12/site-packages/include_server/__pycache__/ so what does the package do exactly?&lt;br /&gt;
&lt;br /&gt;
There&#039;s some references to cpython-312, so maybe it actually still uses classy python-c conversion or matbe that&#039;s just a component for reading C source code. I have zero idea.&lt;br /&gt;
&lt;br /&gt;
you also need stuff to do compiles&lt;br /&gt;
* alpine sdk&lt;br /&gt;
* clang&lt;br /&gt;
* binutils&lt;br /&gt;
...&lt;br /&gt;
* elfutils(-dev)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Settings ===&lt;br /&gt;
==== settings for distcc ====&lt;br /&gt;
&lt;br /&gt;
* there&#039;s /etc/default/distcc&lt;br /&gt;
* there&#039;s /etc/conf.d/distcc &lt;br /&gt;
&lt;br /&gt;
make all your settings here&lt;br /&gt;
take care with the listen address, if you specify an IP it&#039;ll not be on 127.0.0.1 in case you would have localhost in your list...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* command_whitelist.sh &lt;br /&gt;
&lt;br /&gt;
this is half functional, you need to set things here but you also need to maintain the symlinks that are collected under /usr/lib/distcc (for your compilers) and /usr/lib/distcc/bin (for itself)&lt;br /&gt;
&lt;br /&gt;
you MUST run the script to update the compilers!&lt;br /&gt;
Info for script and what files it will create&lt;br /&gt;
&lt;br /&gt;
/usr/sbin/update-distcc-symlinks&lt;br /&gt;
&lt;br /&gt;
tschike:/usr/bin# ls -l /usr/lib/distcc/&lt;br /&gt;
total 4&lt;br /&gt;
drwxr-xr-x 2 root root 4096 Mar  2 18:14 bin&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c89 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c99 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 cc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc-15.2.0 -&amp;gt; ../../bin/distcc&lt;br /&gt;
&lt;br /&gt;
distcc itself is in bin&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cpp -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 g++ -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 06:49 x86_64-alpine-linux-musl-gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
&lt;br /&gt;
the last symplink here is wrong, made by me and would not work...&lt;br /&gt;
BAD symlink.&lt;br /&gt;
&lt;br /&gt;
=== distcc hosts file ===&lt;br /&gt;
&lt;br /&gt;
idk about that thing it&#039;s odd&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== abuild.conf ===&lt;br /&gt;
&lt;br /&gt;
settings for aports&lt;br /&gt;
* cc=&lt;br /&gt;
* cxx=&lt;br /&gt;
* cpp=&lt;br /&gt;
* cflags=&lt;br /&gt;
* njobs&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== detail infos ==&lt;br /&gt;
&lt;br /&gt;
???&lt;br /&gt;
&lt;br /&gt;
=== hosts syntax ===&lt;br /&gt;
&lt;br /&gt;
* myhost otherhost&lt;br /&gt;
* myhost,cpp,lzo myotherhost,cpp,lzo&lt;br /&gt;
&lt;br /&gt;
==== the host ====&lt;br /&gt;
&lt;br /&gt;
hostname/ip&lt;br /&gt;
localhost&lt;br /&gt;
127.0.0.1&lt;br /&gt;
::1 - does not work&lt;br /&gt;
&lt;br /&gt;
==== protocol ====&lt;br /&gt;
&lt;br /&gt;
* no protocol given&lt;br /&gt;
* ,cpp,lzo protocol&lt;br /&gt;
&lt;br /&gt;
cpp implies lzo, it requires compression, even if you have 10gbit/s or more, it&#039;s just hardcoded&lt;br /&gt;
&lt;br /&gt;
=== threads ===&lt;br /&gt;
/number of workers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== architecture ==&lt;br /&gt;
it can handle C, C++, ObjC, maybe some other stuff&lt;br /&gt;
&lt;br /&gt;
* what happens with normal xmit&lt;br /&gt;
* what happens with pump mode&lt;br /&gt;
* at which step the include server is used and how it collects the includes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== distribution algorithm ===&lt;br /&gt;
honestly I simply don&#039;t get it&lt;br /&gt;
&lt;br /&gt;
* The order matters&lt;br /&gt;
* The number of threads matters&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== localhost ====&lt;br /&gt;
&lt;br /&gt;
* localhost precedence&lt;br /&gt;
* localhost fallback&lt;br /&gt;
&lt;br /&gt;
variable: DISTCC_FALLBACK&lt;br /&gt;
&lt;br /&gt;
0 = Fail to compile if it would need to fallback to a normal local gcc call&lt;br /&gt;
1 = If remote compile fails, just do it yourself&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Operation ==&lt;br /&gt;
&lt;br /&gt;
=== startup and shutdown ===&lt;br /&gt;
service distcc stop is not entirely reliable (it can take a minute after the stop until the processes are gone and sometimes it will never stop&lt;br /&gt;
this is very bad with openrc, the openrc script returns after a second and only relies on its service flags, not the process status.&lt;br /&gt;
manually check after stopping, wait a min, if needed, kill it all.&lt;br /&gt;
at some point the rc file needs to be rewritten, it can&#039;t stay like it is.&lt;br /&gt;
&lt;br /&gt;
if you used a pump mode session, that also needs a logout (pump --shutdown)&lt;br /&gt;
avoid running multiple startups without shutdown in one session. it&#039;s safe as far as I can tell but nothing cleans up these processes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== ccache and memcached ===&lt;br /&gt;
CCACHE is said to be conflicting with pump mode unless when you call them in the backend&lt;br /&gt;
so, where you start the compile, you don&#039;t use it&lt;br /&gt;
where the compile happens, you use it&lt;br /&gt;
they can share the cache via memcached, this is a nice trick for consistency&lt;br /&gt;
Upon looking at the ccache website, it seems the correct mechanism is not memcached but Redis. This would work just as well. Generally a cache shared in this way would be optimal for performance.&lt;br /&gt;
&lt;br /&gt;
=== dockerized / native ===&lt;br /&gt;
&lt;br /&gt;
it remains mostly the same, a container needs to make sure it monitors the right services (distccd, nginx, include_server)&lt;br /&gt;
if you&#039;re using zeroconf, you need to somehow expose the mdns service broadcasts &amp;amp; receptio&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== untested build container system ====&lt;br /&gt;
&lt;br /&gt;
See this one https://github.com/bensuperpc/docker-distcc&lt;br /&gt;
not yet tested, but this could be a good basis for a &#039;best practice&#039; container.&lt;br /&gt;
There&#039;s others, especially for crossbuilds, but those are also very complex to modify.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Processs list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
Workdir list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
=== alpine-chroot ===&lt;br /&gt;
&lt;br /&gt;
when using the &#039;official&#039; script there&#039;s still some odd pieces, seemed to be the processes died on logout. but not all of them.&lt;br /&gt;
&lt;br /&gt;
==== manual launch ====&lt;br /&gt;
&lt;br /&gt;
Starting the daemon would be using&lt;br /&gt;
/usr/bin/distccd --pid-file /var/run/distccd/distccd.pid -N 15 --user distcc --port 3632 --log-level=debug --log-file=/var/log/distccd.log --allow my-sub-net/24&lt;br /&gt;
&lt;br /&gt;
==== localhost? =====&lt;br /&gt;
unclear if you need to use --allow for 127.0.0.1/32 or something to allow the remote preproccesor.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Gitlab integration ===&lt;br /&gt;
&lt;br /&gt;
TBA&lt;br /&gt;
&lt;br /&gt;
Maybe work from this k8s howto, it&#039;s a bit more prod-grade than most:&lt;br /&gt;
&lt;br /&gt;
https://cinaq.com/blog/2020/05/10/speed-up-docker-builds-with-distcc-ccache-and-kubernetes/&lt;br /&gt;
&lt;br /&gt;
== Kernel specific settings ==&lt;br /&gt;
&lt;br /&gt;
currently (distcc 3.4-r9 on Alpine) you need a patch to build the kernel.&lt;br /&gt;
See &lt;br /&gt;
&lt;br /&gt;
=== Include server Settings ===&lt;br /&gt;
&lt;br /&gt;
cache reset triggers&lt;br /&gt;
This ought to be set before enabling pump mode.&lt;br /&gt;
&lt;br /&gt;
export INCLUDE_SERVER_ARGS=&amp;quot;--stat_reset_triggers=include/linux/compile.h:include/asm/asm-offsets.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
link to explanation TBA&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Disabling GCC Plugins ===&lt;br /&gt;
&lt;br /&gt;
KConfig unselect HAVE_GCC_PLUGINS&lt;br /&gt;
&lt;br /&gt;
Some info is here in the troubleshooting part of the Arch Wiki&lt;br /&gt;
https://wiki.archlinux.org/title/Distcc#Troubleshooting&lt;br /&gt;
&lt;br /&gt;
=== Patches ===&lt;br /&gt;
&lt;br /&gt;
Other things (for 6.6LTS)&lt;br /&gt;
PCIe Stub patch&lt;br /&gt;
&lt;br /&gt;
=== Autoconf === &lt;br /&gt;
&lt;br /&gt;
No known setup examples&lt;br /&gt;
Add whatever it publishes in mdns&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== troubleshooting / analysis ==&lt;br /&gt;
&lt;br /&gt;
=== testing ===&lt;br /&gt;
&lt;br /&gt;
# turn off fallback DISTCC_FALLBACK=1&lt;br /&gt;
# set distcc up to point at specific system under test DISTCC_HOSTS=&amp;quot;mytestbox,cpp,lzo&amp;quot;&lt;br /&gt;
# GCC example compiles&lt;br /&gt;
## code example C&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example C++&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example ObjC&lt;br /&gt;
## same with included header&lt;br /&gt;
# Cmake example compiles&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docoument the thing with compile launcher ccache;distcc&lt;br /&gt;
there&#039;s some blog post, point to that&lt;br /&gt;
no ccache here yet&lt;br /&gt;
show $CC differences distcc vs gcc, what configure scripts see&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Latency ===&lt;br /&gt;
&lt;br /&gt;
Latency of pump mode startups and fallbacks needs to be investigated.&lt;br /&gt;
LZO is enforced even if you have faster network&lt;br /&gt;
DNS Requests, very old bug report from Gcode, one request per call, is it true? how to get rid of it?&lt;br /&gt;
TMPDIR is respected, make sure it&#039;s on ramdisk even on the remote nodes.&lt;br /&gt;
Compile ideally never goes to disk when it doesn&#039;t have to.&lt;br /&gt;
How efficient is the include server collection and unpacking?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== failed to distribute, running locally instead ===&lt;br /&gt;
&lt;br /&gt;
the curse of the ancient, wise bulgarian witch compildora nottherea has befallen people all over the world. only strict and mindless adherence to rituals passed down from generation to generation has given hope to those who are under her ages old spell. again and again it reemerges to prey on idealistic young men and women who spend so much time at their unholy computers that they try to spend less time there by spending a lot of time trying to optimize what the computer does, slowly, instead of reflecting on why they are there, while the computer is busy working, and why they try to solve this by adding a component that makes the computer be more error-prone at that same work, increasing the need of their presense at this idolized thinking machine to oversee and often repair, or worse, mindlessly restart its doing.&lt;br /&gt;
if the curse is not lifted, despair may befall them and all they see is the need to investigate and ruminate further on the workings of this tool, ignoring thereby the obivous flaws that stem from of its alchemic origins.&lt;br /&gt;
&lt;br /&gt;
just wait till you find out it has a backoff alghoritm deciding whether to call out to a remote server independent of that server functioning. graceful performance degradation is the goal, and degrading it is while we try to figure this out.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Node Selection algorithm ====&lt;br /&gt;
&lt;br /&gt;
as per my understanding, a flowchart goes here:&lt;br /&gt;
&lt;br /&gt;
# compile task&lt;br /&gt;
# evaluate whether to run locally by job nature&lt;br /&gt;
# determine if local host&#039;s load is notable&lt;br /&gt;
# look at distcc hosts list&lt;br /&gt;
# do something based off localhost entry if first&lt;br /&gt;
# filter for nodes with cpp flag&lt;br /&gt;
# do something based off localhost entry if not first&lt;br /&gt;
# further prioritize by server order, first is handled in some way&lt;br /&gt;
# skip nodes in backoff prisons&lt;br /&gt;
# balance and priotize by server thread number, if given&lt;br /&gt;
# send to suitable host&lt;br /&gt;
# if compile not successful, proceed on other node&lt;br /&gt;
# if nodes depleted, proceed on localhost&lt;br /&gt;
&lt;br /&gt;
== security ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== tcpwrapper style ip range filter ===&lt;br /&gt;
&lt;br /&gt;
the original security model consists of ip restrictions.&lt;br /&gt;
there seems to also be some GSSAPI user auth.&lt;br /&gt;
further, commands that can be called are restricted by name and location.&lt;br /&gt;
this appears to be a runtime whitelist lookup, meaning it&#039;s done and authorized by the same parts of the daemon as processes the compile request along with the intended compiler.&lt;br /&gt;
so the main weaknesses against malicious clients seem to be in sending things to compile, and in overriding the remote compiler to use.&lt;br /&gt;
it can be assumed that a malicious client able to exploit the compiler handshake can then run arbitrary stuff.&lt;br /&gt;
There&#039;s at least a github issue regarding this (link lost, but see here: https://gitlab.com/postmarketOS/pmbootstrap/-/work_items/1619) suggesting running over ssh. That does only partitally alleviate this risk with regard  to a key based verfication of a client versus a the standard ip restrictions which always include some parsing.&lt;br /&gt;
So this protects against someone directly exploiting the TCP code of distcc.&lt;br /&gt;
It does not protect against malicious clients.&lt;br /&gt;
(ssh force command can&#039;t be used or you&#039;ll not compile anything)&lt;br /&gt;
&lt;br /&gt;
The basic step for protecting access should be filtering who can access the distcc server, so use nftables etc. to restrict access to port 3262 (??) set up the internal filter the same way.&lt;br /&gt;
&lt;br /&gt;
=== seccomp ===&lt;br /&gt;
&lt;br /&gt;
The next thing is to confine the compiler calls to only write in their temp directory and that they can only run compilers (using nsjail, apparmor, selinux etc)&lt;br /&gt;
&lt;br /&gt;
the above issue also references the second bit of security, namely a seccomp filter which will already cover a good bit of the above&lt;br /&gt;
https://github.com/distcc/distcc/pull/235&lt;br /&gt;
the commit got closed without merge, from what I see.&lt;br /&gt;
&lt;br /&gt;
I will update the entry once it&#039;s clear if the patch was later added or instead nothing was done.&lt;br /&gt;
&lt;br /&gt;
=== privs ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The other internal security bit is that they do some priviledge dropping. it runs as a dedicated user (distcc), so you can also have an audit policy, and can/could use something like iptables&#039; to ensure it can only connect to the other distcc/memcached hosts, but nothing else.&lt;br /&gt;
&lt;br /&gt;
=== compiler list ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
One needs to investigate when compiler_whitelist.sh is exactly called. as far as I recall it doesn&#039;t close stdin/stdout.&lt;br /&gt;
&lt;br /&gt;
=== distcc-hardened ===&lt;br /&gt;
&lt;br /&gt;
Alpine adds some hardening patch, idk what nature/origina that has.&lt;br /&gt;
&lt;br /&gt;
=== selinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
there&#039;s also a selinux policy for distcc from gentoo or liguros if one is so inclined.  &lt;br /&gt;
links for further review:&lt;br /&gt;
&lt;br /&gt;
- https://repology.org/project/selinux-distcc/versions  &lt;br /&gt;
- https://gitlab.com/liguros/liguros-repo/-/tree/stable/sec-policy/selinux-distcc&lt;br /&gt;
&lt;br /&gt;
=== general posture ===&lt;br /&gt;
&lt;br /&gt;
Some security measures like the above should definitely be used since the project at its core relies on accepting foreign input over the network, has only a few part-time maintainers that cannot easily drive the project forward or do large refactors.&lt;br /&gt;
But the seccomp changes were done almost 10 years ago, so, if they were actually upstreamed, I&#039;d say they came through.&lt;br /&gt;
&lt;br /&gt;
A kind of overengineered solulion would be to use netlabel to ensure application integrity across hosts, meaning only a valid process would be able to send packets to the distcc nodes :-)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Alternatives ==&lt;br /&gt;
&lt;br /&gt;
Arch wiki refers to a fork by SUSE&lt;br /&gt;
https://github.com/icecc/icecream&lt;br /&gt;
&lt;br /&gt;
It appears &#039;maybe better&#039; but hard to tell. There&#039;s no mention if maybe SUSE&#039;s OBS uses it or something. Without more knowledge of their use I don&#039;t know how big a benefit will come from switching. At least you&#039;d wanna know they have a higher commitment to maintenance than the understaffed distcc &#039;team&#039; of current.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A commercial alternative (incredibuild https://www.incredibuild.com/) exists, but I have not tried it.&lt;br /&gt;
There are references to some &#039;forever free&#039; tier, also, but I could not yet find the terms and conditions for having a &#039;forever free thing&#039;. it also seems you need a windows-based &#039;coordinator&#039; host.&lt;br /&gt;
generally if there&#039;s some professional context with high (business) pressure for faster builds I would check that out, and then there&#039;s more time to get a great distcc setup built in the meantime.&lt;br /&gt;
&lt;br /&gt;
Architecturally it seems to be taking the ccache approach with a shared cache and smarter redistribution.&lt;br /&gt;
So anything that can call ccache is something they can scale out. I&#039;ll add a link later, for those whom it helps.&lt;br /&gt;
Naturally it is out of scope for this article.&lt;br /&gt;
Nonetheless it&#039;s interesting since the ordering of how to run ccache and how to run distcc is an issue that also exists in the OSS world. Not just that we don&#039;t have an automatic setup and integration of the tools (ccache, redis, distccd, distcc-pump) but we also don&#039;t have collected sufficient data to aid in deciding which aproach is the best.&lt;br /&gt;
Integrating into CIs (gitlab-runner specifically) is another item where cache persistence becomes very fragile.&lt;br /&gt;
Having an alpine build container that knows how to use ccache with redis and distcc-pump would be a possible step forward.&lt;br /&gt;
&lt;br /&gt;
== Other sources ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://retroflux.net/blog/distcc-adventures/&lt;/div&gt;</summary>
		<author><name>Darkfader</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32205</id>
		<title>User:Darkfader/distcc</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32205"/>
		<updated>2026-03-28T22:42:55Z</updated>

		<summary type="html">&lt;p&gt;Darkfader: /* selinux */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi,&lt;br /&gt;
&lt;br /&gt;
I&#039;m preparing this page. It can take a long time till I finish.&lt;br /&gt;
If you are also wishing to write on this topic, feel free to integrate the content.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Document overview ==&lt;br /&gt;
&lt;br /&gt;
I noticed that almost every distro has one partially complete, partially helpful document on how to use distcc on the distro.&lt;br /&gt;
Usually they also have one for ccache.&lt;br /&gt;
In either case, they&#039;re enough to get started, but not really a reliable watertight thing.&lt;br /&gt;
We definitely needed one of our own.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== goal ===&lt;br /&gt;
&lt;br /&gt;
to describe a working setup for building aports in easiest/fastests fashion&lt;br /&gt;
not planning to add versatility or features where it would make the setup more errorprone.&lt;br /&gt;
the page should describe enough of the steps to successfully compile an LTS kernel via aports and have that job be distributed over multiple nodes.&lt;br /&gt;
Logs should be set up and able to display errors, but not show any errors during the test compile.&lt;br /&gt;
&lt;br /&gt;
To include a path for analysis via testing components.&lt;br /&gt;
&lt;br /&gt;
distcc can greatly improve compile speeds for large software, it comes with a different set of features than ccache; it focusses not avoiding unneccessary compile work, but on a way to speed up the necessary one.&lt;br /&gt;
&lt;br /&gt;
There&#039;s valuable info in the docs of other distros, it should be referenced here (i.e. the arch wiki troubleshooting), when it makes sense, add a TOC for their content.&lt;br /&gt;
&lt;br /&gt;
=== audience ===&lt;br /&gt;
people running software builds on alpine and have multiple computers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This page will show a specific installation, specific configuration, and specific tests, resulting in a specific set of functionality that can be tested to be working.&lt;br /&gt;
&lt;br /&gt;
== installation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Packages ===&lt;br /&gt;
&lt;br /&gt;
you need, on each host&lt;br /&gt;
* distcc&lt;br /&gt;
* distccd-openrc&lt;br /&gt;
* distcc-pump&lt;br /&gt;
* distcc-pump-pyc&lt;br /&gt;
&lt;br /&gt;
the .pyc will speed up the invocations, without it &lt;br /&gt;
idk if one or both should be installed in that case. but it appears to be also automatically be precompiled in /usr/lib/python3.12/site-packages/include_server/__pycache__/ so what does the package do exactly?&lt;br /&gt;
&lt;br /&gt;
There&#039;s some references to cpython-312, so maybe it actually still uses classy python-c conversion or matbe that&#039;s just a component for reading C source code. I have zero idea.&lt;br /&gt;
&lt;br /&gt;
you also need stuff to do compiles&lt;br /&gt;
* alpine sdk&lt;br /&gt;
* clang&lt;br /&gt;
* binutils&lt;br /&gt;
...&lt;br /&gt;
* elfutils(-dev)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Settings ===&lt;br /&gt;
==== settings for distcc ====&lt;br /&gt;
&lt;br /&gt;
* there&#039;s /etc/default/distcc&lt;br /&gt;
* there&#039;s /etc/conf.d/distcc &lt;br /&gt;
&lt;br /&gt;
make all your settings here&lt;br /&gt;
take care with the listen address, if you specify an IP it&#039;ll not be on 127.0.0.1 in case you would have localhost in your list...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* command_whitelist.sh &lt;br /&gt;
&lt;br /&gt;
this is half functional, you need to set things here but you also need to maintain the symlinks that are collected under /usr/lib/distcc (for your compilers) and /usr/lib/distcc/bin (for itself)&lt;br /&gt;
&lt;br /&gt;
you MUST run the script to update the compilers!&lt;br /&gt;
Info for script and what files it will create&lt;br /&gt;
&lt;br /&gt;
/usr/sbin/update-distcc-symlinks&lt;br /&gt;
&lt;br /&gt;
tschike:/usr/bin# ls -l /usr/lib/distcc/&lt;br /&gt;
total 4&lt;br /&gt;
drwxr-xr-x 2 root root 4096 Mar  2 18:14 bin&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c89 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c99 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 cc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc-15.2.0 -&amp;gt; ../../bin/distcc&lt;br /&gt;
&lt;br /&gt;
distcc itself is in bin&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cpp -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 g++ -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 06:49 x86_64-alpine-linux-musl-gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
&lt;br /&gt;
the last symplink here is wrong, made by me and would not work...&lt;br /&gt;
BAD symlink.&lt;br /&gt;
&lt;br /&gt;
=== distcc hosts file ===&lt;br /&gt;
&lt;br /&gt;
idk about that thing it&#039;s odd&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== abuild.conf ===&lt;br /&gt;
&lt;br /&gt;
settings for aports&lt;br /&gt;
* cc=&lt;br /&gt;
* cxx=&lt;br /&gt;
* cpp=&lt;br /&gt;
* cflags=&lt;br /&gt;
* njobs&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== detail infos ==&lt;br /&gt;
&lt;br /&gt;
???&lt;br /&gt;
&lt;br /&gt;
=== hosts syntax ===&lt;br /&gt;
&lt;br /&gt;
* myhost otherhost&lt;br /&gt;
* myhost,cpp,lzo myotherhost,cpp,lzo&lt;br /&gt;
&lt;br /&gt;
==== the host ====&lt;br /&gt;
&lt;br /&gt;
hostname/ip&lt;br /&gt;
localhost&lt;br /&gt;
127.0.0.1&lt;br /&gt;
::1 - does not work&lt;br /&gt;
&lt;br /&gt;
==== protocol ====&lt;br /&gt;
&lt;br /&gt;
* no protocol given&lt;br /&gt;
* ,cpp,lzo protocol&lt;br /&gt;
&lt;br /&gt;
cpp implies lzo, it requires compression, even if you have 10gbit/s or more, it&#039;s just hardcoded&lt;br /&gt;
&lt;br /&gt;
=== threads ===&lt;br /&gt;
/number of workers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== architecture ==&lt;br /&gt;
it can handle C, C++, ObjC, maybe some other stuff&lt;br /&gt;
&lt;br /&gt;
* what happens with normal xmit&lt;br /&gt;
* what happens with pump mode&lt;br /&gt;
* at which step the include server is used and how it collects the includes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== distribution algorithm ===&lt;br /&gt;
honestly I simply don&#039;t get it&lt;br /&gt;
&lt;br /&gt;
* The order matters&lt;br /&gt;
* The number of threads matters&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== localhost ====&lt;br /&gt;
&lt;br /&gt;
* localhost precedence&lt;br /&gt;
* localhost fallback&lt;br /&gt;
&lt;br /&gt;
variable: DISTCC_FALLBACK&lt;br /&gt;
&lt;br /&gt;
0 = Fail to compile if it would need to fallback to a normal local gcc call&lt;br /&gt;
1 = If remote compile fails, just do it yourself&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Operation ==&lt;br /&gt;
&lt;br /&gt;
=== startup and shutdown ===&lt;br /&gt;
service distcc stop is not entirely reliable (it can take a minute after the stop until the processes are gone and sometimes it will never stop&lt;br /&gt;
this is very bad with openrc, the openrc script returns after a second and only relies on its service flags, not the process status.&lt;br /&gt;
manually check after stopping, wait a min, if needed, kill it all.&lt;br /&gt;
at some point the rc file needs to be rewritten, it can&#039;t stay like it is.&lt;br /&gt;
&lt;br /&gt;
if you used a pump mode session, that also needs a logout (pump --shutdown)&lt;br /&gt;
avoid running multiple startups without shutdown in one session. it&#039;s safe as far as I can tell but nothing cleans up these processes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== ccache and memcached ===&lt;br /&gt;
CCACHE is said to be conflicting with pump mode unless when you call them in the backend&lt;br /&gt;
so, where you start the compile, you don&#039;t use it&lt;br /&gt;
where the compile happens, you use it&lt;br /&gt;
they can share the cache via memcached, this is a nice trick for consistency&lt;br /&gt;
Upon looking at the ccache website, it seems the correct mechanism is not memcached but Redis. This would work just as well. Generally a cache shared in this way would be optimal for performance.&lt;br /&gt;
&lt;br /&gt;
=== dockerized / native ===&lt;br /&gt;
&lt;br /&gt;
it remains mostly the same, a container needs to make sure it monitors the right services (distccd, nginx, include_server)&lt;br /&gt;
if you&#039;re using zeroconf, you need to somehow expose the mdns service broadcasts &amp;amp; receptio&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== untested build container system ====&lt;br /&gt;
&lt;br /&gt;
See this one https://github.com/bensuperpc/docker-distcc&lt;br /&gt;
not yet tested, but this could be a good basis for a &#039;best practice&#039; container.&lt;br /&gt;
There&#039;s others, especially for crossbuilds, but those are also very complex to modify.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Processs list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
Workdir list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
=== alpine-chroot ===&lt;br /&gt;
&lt;br /&gt;
when using the &#039;official&#039; script there&#039;s still some odd pieces, seemed to be the processes died on logout. but not all of them.&lt;br /&gt;
&lt;br /&gt;
==== manual launch ====&lt;br /&gt;
&lt;br /&gt;
Starting the daemon would be using&lt;br /&gt;
/usr/bin/distccd --pid-file /var/run/distccd/distccd.pid -N 15 --user distcc --port 3632 --log-level=debug --log-file=/var/log/distccd.log --allow my-sub-net/24&lt;br /&gt;
&lt;br /&gt;
==== localhost? =====&lt;br /&gt;
unclear if you need to use --allow for 127.0.0.1/32 or something to allow the remote preproccesor.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Gitlab integration ===&lt;br /&gt;
&lt;br /&gt;
TBA&lt;br /&gt;
&lt;br /&gt;
Maybe work from this k8s howto, it&#039;s a bit more prod-grade than most:&lt;br /&gt;
&lt;br /&gt;
https://cinaq.com/blog/2020/05/10/speed-up-docker-builds-with-distcc-ccache-and-kubernetes/&lt;br /&gt;
&lt;br /&gt;
== Kernel specific settings ==&lt;br /&gt;
&lt;br /&gt;
currently (distcc 3.4-r9 on Alpine) you need a patch to build the kernel.&lt;br /&gt;
See &lt;br /&gt;
&lt;br /&gt;
=== Include server Settings ===&lt;br /&gt;
&lt;br /&gt;
cache reset triggers&lt;br /&gt;
This ought to be set before enabling pump mode.&lt;br /&gt;
&lt;br /&gt;
export INCLUDE_SERVER_ARGS=&amp;quot;--stat_reset_triggers=include/linux/compile.h:include/asm/asm-offsets.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
link to explanation TBA&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Disabling GCC Plugins ===&lt;br /&gt;
&lt;br /&gt;
KConfig unselect HAVE_GCC_PLUGINS&lt;br /&gt;
&lt;br /&gt;
Some info is here in the troubleshooting part of the Arch Wiki&lt;br /&gt;
https://wiki.archlinux.org/title/Distcc#Troubleshooting&lt;br /&gt;
&lt;br /&gt;
=== Patches ===&lt;br /&gt;
&lt;br /&gt;
Other things (for 6.6LTS)&lt;br /&gt;
PCIe Stub patch&lt;br /&gt;
&lt;br /&gt;
=== Autoconf === &lt;br /&gt;
&lt;br /&gt;
No known setup examples&lt;br /&gt;
Add whatever it publishes in mdns&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== troubleshooting / analysis ==&lt;br /&gt;
&lt;br /&gt;
=== testing ===&lt;br /&gt;
&lt;br /&gt;
# turn off fallback DISTCC_FALLBACK=1&lt;br /&gt;
# set distcc up to point at specific system under test DISTCC_HOSTS=&amp;quot;mytestbox,cpp,lzo&amp;quot;&lt;br /&gt;
# GCC example compiles&lt;br /&gt;
## code example C&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example C++&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example ObjC&lt;br /&gt;
## same with included header&lt;br /&gt;
# Cmake example compiles&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docoument the thing with compile launcher ccache;distcc&lt;br /&gt;
there&#039;s some blog post, point to that&lt;br /&gt;
no ccache here yet&lt;br /&gt;
show $CC differences distcc vs gcc, what configure scripts see&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Latency ===&lt;br /&gt;
&lt;br /&gt;
Latency of pump mode startups and fallbacks needs to be investigated.&lt;br /&gt;
LZO is enforced even if you have faster network&lt;br /&gt;
DNS Requests, very old bug report from Gcode, one request per call, is it true? how to get rid of it?&lt;br /&gt;
TMPDIR is respected, make sure it&#039;s on ramdisk even on the remote nodes.&lt;br /&gt;
Compile ideally never goes to disk when it doesn&#039;t have to.&lt;br /&gt;
How efficient is the include server collection and unpacking?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== failed to distribute, running locally instead ===&lt;br /&gt;
&lt;br /&gt;
the curse of the ancient, wise bulgarian witch compildora nottherea has befallen people all over the world. only strict and mindless adherence to rituals passed down from generation to generation has given hope to those who are under her ages old spell. again and again it reemerges to prey on idealistic young men and women who spend so much time at their unholy computers that they try to spend less time there by spending a lot of time trying to optimize what the computer does, slowly, instead of reflecting on why they are there, while the computer is busy working, and why they try to solve this by adding a component that makes the computer be more error-prone at that same work, increasing the need of their presense at this idolized thinking machine to oversee and often repair, or worse, mindlessly restart its doing.&lt;br /&gt;
if the curse is not lifted, despair may befall them and all they see is the need to investigate and ruminate further on the workings of this tool, ignoring thereby the obivous flaws that stem from of its alchemic origins.&lt;br /&gt;
&lt;br /&gt;
just wait till you find out it has a backoff alghoritm deciding whether to call out to a remote server independent of that server functioning. graceful performance degradation is the goal, and degrading it is while we try to figure this out.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Node Selection algorithm ====&lt;br /&gt;
&lt;br /&gt;
as per my understanding, a flowchart goes here:&lt;br /&gt;
&lt;br /&gt;
# compile task&lt;br /&gt;
# evaluate whether to run locally by job nature&lt;br /&gt;
# determine if local host&#039;s load is notable&lt;br /&gt;
# look at distcc hosts list&lt;br /&gt;
# do something based off localhost entry if first&lt;br /&gt;
# filter for nodes with cpp flag&lt;br /&gt;
# do something based off localhost entry if not first&lt;br /&gt;
# further prioritize by server order, first is handled in some way&lt;br /&gt;
# skip nodes in backoff prisons&lt;br /&gt;
# balance and priotize by server thread number, if given&lt;br /&gt;
# send to suitable host&lt;br /&gt;
# if compile not successful, proceed on other node&lt;br /&gt;
# if nodes depleted, proceed on localhost&lt;br /&gt;
&lt;br /&gt;
== security ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== tcpwrapper style ip range filter ===&lt;br /&gt;
&lt;br /&gt;
the original security model consists of ip restrictions.&lt;br /&gt;
there seems to also be some GSSAPI user auth.&lt;br /&gt;
further, commands that can be called are restricted by name and location.&lt;br /&gt;
this appears to be a runtime whitelist lookup, meaning it&#039;s done and authorized by the same parts of the daemon as processes the compile request along with the intended compiler.&lt;br /&gt;
so the main weaknesses against malicious clients seem to be in sending things to compile, and in overriding the remote compiler to use.&lt;br /&gt;
it can be assumed that a malicious client able to exploit the compiler handshake can then run arbitrary stuff.&lt;br /&gt;
There&#039;s at least a github issue regarding this (link lost, but see here: https://gitlab.com/postmarketOS/pmbootstrap/-/work_items/1619) suggesting running over ssh. That does only partitally alleviate this risk with regard  to a key based verfication of a client versus a the standard ip restrictions which always include some parsing.&lt;br /&gt;
So this protects against someone directly exploiting the TCP code of distcc.&lt;br /&gt;
It does not protect against malicious clients.&lt;br /&gt;
(ssh force command can&#039;t be used or you&#039;ll not compile anything)&lt;br /&gt;
&lt;br /&gt;
The basic step for protecting access should be filtering who can access the distcc server, so use nftables etc. to restrict access to port 3262 (??) set up the internal filter the same way.&lt;br /&gt;
&lt;br /&gt;
=== seccomp ===&lt;br /&gt;
&lt;br /&gt;
The next thing is to confine the compiler calls to only write in their temp directory and that they can only run compilers (using nsjail, apparmor, selinux etc)&lt;br /&gt;
&lt;br /&gt;
the above issue also references the second bit of security, namely a seccomp filter which will already cover a good bit of the above&lt;br /&gt;
https://github.com/distcc/distcc/pull/235&lt;br /&gt;
the commit got closed without merge, from what I see.&lt;br /&gt;
&lt;br /&gt;
I will update the entry once it&#039;s clear if the patch was later added or instead nothing was done.&lt;br /&gt;
&lt;br /&gt;
=== privs ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The other internal security bit is that they do some priviledge dropping. it runs as a dedicated user (distcc), so you can also have an audit policy, and can/could use something like iptables&#039; to ensure it can only connect to the other distcc/memcached hosts, but nothing else.&lt;br /&gt;
&lt;br /&gt;
=== compiler list ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
One needs to investigate when compiler_whitelist.sh is exactly called. as far as I recall it doesn&#039;t close stdin/stdout.&lt;br /&gt;
&lt;br /&gt;
=== distcc-hardened ===&lt;br /&gt;
&lt;br /&gt;
Alpine adds some hardening patch, idk what nature/origina that has.&lt;br /&gt;
&lt;br /&gt;
=== selinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
there&#039;s also a selinux policy for distcc from gentoo or liguros if one is so inclined.  &lt;br /&gt;
links for further review:&lt;br /&gt;
&lt;br /&gt;
- https://repology.org/project/selinux-distcc/versions  &lt;br /&gt;
- https://gitlab.com/liguros/liguros-repo/-/tree/stable/sec-policy/selinux-distcc&lt;br /&gt;
&lt;br /&gt;
=== general posture ===&lt;br /&gt;
&lt;br /&gt;
Some security measures like the above should definitely be used since the project at its core relies on accepting foreign input over the network, has only a few part-time maintainers that cannot easily drive the project forward or do large refactors.&lt;br /&gt;
But the seccomp changes were done almost 10 years ago, so, if they were actually upstreamed, I&#039;d say they came through.&lt;br /&gt;
&lt;br /&gt;
A kind of overengineered solulion would be to use netlabel to ensure application integrity across hosts, meaning only a valid process would be able to send packets to the distcc nodes :-)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Alternatives ==&lt;br /&gt;
&lt;br /&gt;
Arch wiki refers to a fork by SUSE&lt;br /&gt;
https://github.com/icecc/icecream&lt;br /&gt;
&lt;br /&gt;
It appears &#039;maybe better&#039; but hard to tell. There&#039;s no mention if maybe SUSE&#039;s OBS uses it or something. Without more knowledge of their use I don&#039;t know how big a benefit will come from switching. At least you&#039;d wanna know they have a higher commitment to maintenance than the understaffed distcc &#039;team&#039; of current.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A commercial alternative (incredibuild https://www.incredibuild.com/) exists, but I have not tried it.&lt;br /&gt;
THey advertise some &#039;forever free&#039; tier; generally if there&#039;s high (business) pressure for faster builds I would check that out.&lt;br /&gt;
&lt;br /&gt;
Architecturally it seems to be taking the ccache approach with a shared cache and smarter redistribution.&lt;br /&gt;
So anything that can call ccache is something they can scale out. I&#039;ll add a link later, for those whom it helps.&lt;br /&gt;
Naturally it is out of scope for this article.&lt;br /&gt;
Nonetheless it&#039;s interesting since the ordering of how to run ccache and how to run distcc is an issue that also exists in the OSS world. Not just that we don&#039;t have an automatic setup and integration of the tools (ccache, redis, distccd, distcc-pump) but we also don&#039;t have collected sufficient data to aid in deciding which aproach is the best.&lt;br /&gt;
Integrating into CIs (gitlab-runner specifically) is another item where cache persistence becomes very fragile.&lt;br /&gt;
Having an alpine build container that knows how to use ccache with redis and distcc-pump would be a possible step forward.&lt;br /&gt;
&lt;br /&gt;
== Other sources ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://retroflux.net/blog/distcc-adventures/&lt;/div&gt;</summary>
		<author><name>Darkfader</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32204</id>
		<title>User:Darkfader/distcc</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32204"/>
		<updated>2026-03-28T18:14:36Z</updated>

		<summary type="html">&lt;p&gt;Darkfader: /* selinux */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi,&lt;br /&gt;
&lt;br /&gt;
I&#039;m preparing this page. It can take a long time till I finish.&lt;br /&gt;
If you are also wishing to write on this topic, feel free to integrate the content.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Document overview ==&lt;br /&gt;
&lt;br /&gt;
I noticed that almost every distro has one partially complete, partially helpful document on how to use distcc on the distro.&lt;br /&gt;
Usually they also have one for ccache.&lt;br /&gt;
In either case, they&#039;re enough to get started, but not really a reliable watertight thing.&lt;br /&gt;
We definitely needed one of our own.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== goal ===&lt;br /&gt;
&lt;br /&gt;
to describe a working setup for building aports in easiest/fastests fashion&lt;br /&gt;
not planning to add versatility or features where it would make the setup more errorprone.&lt;br /&gt;
the page should describe enough of the steps to successfully compile an LTS kernel via aports and have that job be distributed over multiple nodes.&lt;br /&gt;
Logs should be set up and able to display errors, but not show any errors during the test compile.&lt;br /&gt;
&lt;br /&gt;
To include a path for analysis via testing components.&lt;br /&gt;
&lt;br /&gt;
distcc can greatly improve compile speeds for large software, it comes with a different set of features than ccache; it focusses not avoiding unneccessary compile work, but on a way to speed up the necessary one.&lt;br /&gt;
&lt;br /&gt;
There&#039;s valuable info in the docs of other distros, it should be referenced here (i.e. the arch wiki troubleshooting), when it makes sense, add a TOC for their content.&lt;br /&gt;
&lt;br /&gt;
=== audience ===&lt;br /&gt;
people running software builds on alpine and have multiple computers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This page will show a specific installation, specific configuration, and specific tests, resulting in a specific set of functionality that can be tested to be working.&lt;br /&gt;
&lt;br /&gt;
== installation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Packages ===&lt;br /&gt;
&lt;br /&gt;
you need, on each host&lt;br /&gt;
* distcc&lt;br /&gt;
* distccd-openrc&lt;br /&gt;
* distcc-pump&lt;br /&gt;
* distcc-pump-pyc&lt;br /&gt;
&lt;br /&gt;
the .pyc will speed up the invocations, without it &lt;br /&gt;
idk if one or both should be installed in that case. but it appears to be also automatically be precompiled in /usr/lib/python3.12/site-packages/include_server/__pycache__/ so what does the package do exactly?&lt;br /&gt;
&lt;br /&gt;
There&#039;s some references to cpython-312, so maybe it actually still uses classy python-c conversion or matbe that&#039;s just a component for reading C source code. I have zero idea.&lt;br /&gt;
&lt;br /&gt;
you also need stuff to do compiles&lt;br /&gt;
* alpine sdk&lt;br /&gt;
* clang&lt;br /&gt;
* binutils&lt;br /&gt;
...&lt;br /&gt;
* elfutils(-dev)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Settings ===&lt;br /&gt;
==== settings for distcc ====&lt;br /&gt;
&lt;br /&gt;
* there&#039;s /etc/default/distcc&lt;br /&gt;
* there&#039;s /etc/conf.d/distcc &lt;br /&gt;
&lt;br /&gt;
make all your settings here&lt;br /&gt;
take care with the listen address, if you specify an IP it&#039;ll not be on 127.0.0.1 in case you would have localhost in your list...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* command_whitelist.sh &lt;br /&gt;
&lt;br /&gt;
this is half functional, you need to set things here but you also need to maintain the symlinks that are collected under /usr/lib/distcc (for your compilers) and /usr/lib/distcc/bin (for itself)&lt;br /&gt;
&lt;br /&gt;
you MUST run the script to update the compilers!&lt;br /&gt;
Info for script and what files it will create&lt;br /&gt;
&lt;br /&gt;
/usr/sbin/update-distcc-symlinks&lt;br /&gt;
&lt;br /&gt;
tschike:/usr/bin# ls -l /usr/lib/distcc/&lt;br /&gt;
total 4&lt;br /&gt;
drwxr-xr-x 2 root root 4096 Mar  2 18:14 bin&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c89 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c99 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 cc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc-15.2.0 -&amp;gt; ../../bin/distcc&lt;br /&gt;
&lt;br /&gt;
distcc itself is in bin&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cpp -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 g++ -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 06:49 x86_64-alpine-linux-musl-gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
&lt;br /&gt;
the last symplink here is wrong, made by me and would not work...&lt;br /&gt;
BAD symlink.&lt;br /&gt;
&lt;br /&gt;
=== distcc hosts file ===&lt;br /&gt;
&lt;br /&gt;
idk about that thing it&#039;s odd&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== abuild.conf ===&lt;br /&gt;
&lt;br /&gt;
settings for aports&lt;br /&gt;
* cc=&lt;br /&gt;
* cxx=&lt;br /&gt;
* cpp=&lt;br /&gt;
* cflags=&lt;br /&gt;
* njobs&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== detail infos ==&lt;br /&gt;
&lt;br /&gt;
???&lt;br /&gt;
&lt;br /&gt;
=== hosts syntax ===&lt;br /&gt;
&lt;br /&gt;
* myhost otherhost&lt;br /&gt;
* myhost,cpp,lzo myotherhost,cpp,lzo&lt;br /&gt;
&lt;br /&gt;
==== the host ====&lt;br /&gt;
&lt;br /&gt;
hostname/ip&lt;br /&gt;
localhost&lt;br /&gt;
127.0.0.1&lt;br /&gt;
::1 - does not work&lt;br /&gt;
&lt;br /&gt;
==== protocol ====&lt;br /&gt;
&lt;br /&gt;
* no protocol given&lt;br /&gt;
* ,cpp,lzo protocol&lt;br /&gt;
&lt;br /&gt;
cpp implies lzo, it requires compression, even if you have 10gbit/s or more, it&#039;s just hardcoded&lt;br /&gt;
&lt;br /&gt;
=== threads ===&lt;br /&gt;
/number of workers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== architecture ==&lt;br /&gt;
it can handle C, C++, ObjC, maybe some other stuff&lt;br /&gt;
&lt;br /&gt;
* what happens with normal xmit&lt;br /&gt;
* what happens with pump mode&lt;br /&gt;
* at which step the include server is used and how it collects the includes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== distribution algorithm ===&lt;br /&gt;
honestly I simply don&#039;t get it&lt;br /&gt;
&lt;br /&gt;
* The order matters&lt;br /&gt;
* The number of threads matters&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== localhost ====&lt;br /&gt;
&lt;br /&gt;
* localhost precedence&lt;br /&gt;
* localhost fallback&lt;br /&gt;
&lt;br /&gt;
variable: DISTCC_FALLBACK&lt;br /&gt;
&lt;br /&gt;
0 = Fail to compile if it would need to fallback to a normal local gcc call&lt;br /&gt;
1 = If remote compile fails, just do it yourself&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Operation ==&lt;br /&gt;
&lt;br /&gt;
=== startup and shutdown ===&lt;br /&gt;
service distcc stop is not entirely reliable (it can take a minute after the stop until the processes are gone and sometimes it will never stop&lt;br /&gt;
this is very bad with openrc, the openrc script returns after a second and only relies on its service flags, not the process status.&lt;br /&gt;
manually check after stopping, wait a min, if needed, kill it all.&lt;br /&gt;
at some point the rc file needs to be rewritten, it can&#039;t stay like it is.&lt;br /&gt;
&lt;br /&gt;
if you used a pump mode session, that also needs a logout (pump --shutdown)&lt;br /&gt;
avoid running multiple startups without shutdown in one session. it&#039;s safe as far as I can tell but nothing cleans up these processes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== ccache and memcached ===&lt;br /&gt;
CCACHE is said to be conflicting with pump mode unless when you call them in the backend&lt;br /&gt;
so, where you start the compile, you don&#039;t use it&lt;br /&gt;
where the compile happens, you use it&lt;br /&gt;
they can share the cache via memcached, this is a nice trick for consistency&lt;br /&gt;
Upon looking at the ccache website, it seems the correct mechanism is not memcached but Redis. This would work just as well. Generally a cache shared in this way would be optimal for performance.&lt;br /&gt;
&lt;br /&gt;
=== dockerized / native ===&lt;br /&gt;
&lt;br /&gt;
it remains mostly the same, a container needs to make sure it monitors the right services (distccd, nginx, include_server)&lt;br /&gt;
if you&#039;re using zeroconf, you need to somehow expose the mdns service broadcasts &amp;amp; receptio&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== untested build container system ====&lt;br /&gt;
&lt;br /&gt;
See this one https://github.com/bensuperpc/docker-distcc&lt;br /&gt;
not yet tested, but this could be a good basis for a &#039;best practice&#039; container.&lt;br /&gt;
There&#039;s others, especially for crossbuilds, but those are also very complex to modify.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Processs list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
Workdir list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
=== alpine-chroot ===&lt;br /&gt;
&lt;br /&gt;
when using the &#039;official&#039; script there&#039;s still some odd pieces, seemed to be the processes died on logout. but not all of them.&lt;br /&gt;
&lt;br /&gt;
==== manual launch ====&lt;br /&gt;
&lt;br /&gt;
Starting the daemon would be using&lt;br /&gt;
/usr/bin/distccd --pid-file /var/run/distccd/distccd.pid -N 15 --user distcc --port 3632 --log-level=debug --log-file=/var/log/distccd.log --allow my-sub-net/24&lt;br /&gt;
&lt;br /&gt;
==== localhost? =====&lt;br /&gt;
unclear if you need to use --allow for 127.0.0.1/32 or something to allow the remote preproccesor.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Gitlab integration ===&lt;br /&gt;
&lt;br /&gt;
TBA&lt;br /&gt;
&lt;br /&gt;
Maybe work from this k8s howto, it&#039;s a bit more prod-grade than most:&lt;br /&gt;
&lt;br /&gt;
https://cinaq.com/blog/2020/05/10/speed-up-docker-builds-with-distcc-ccache-and-kubernetes/&lt;br /&gt;
&lt;br /&gt;
== Kernel specific settings ==&lt;br /&gt;
&lt;br /&gt;
currently (distcc 3.4-r9 on Alpine) you need a patch to build the kernel.&lt;br /&gt;
See &lt;br /&gt;
&lt;br /&gt;
=== Include server Settings ===&lt;br /&gt;
&lt;br /&gt;
cache reset triggers&lt;br /&gt;
This ought to be set before enabling pump mode.&lt;br /&gt;
&lt;br /&gt;
export INCLUDE_SERVER_ARGS=&amp;quot;--stat_reset_triggers=include/linux/compile.h:include/asm/asm-offsets.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
link to explanation TBA&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Disabling GCC Plugins ===&lt;br /&gt;
&lt;br /&gt;
KConfig unselect HAVE_GCC_PLUGINS&lt;br /&gt;
&lt;br /&gt;
Some info is here in the troubleshooting part of the Arch Wiki&lt;br /&gt;
https://wiki.archlinux.org/title/Distcc#Troubleshooting&lt;br /&gt;
&lt;br /&gt;
=== Patches ===&lt;br /&gt;
&lt;br /&gt;
Other things (for 6.6LTS)&lt;br /&gt;
PCIe Stub patch&lt;br /&gt;
&lt;br /&gt;
=== Autoconf === &lt;br /&gt;
&lt;br /&gt;
No known setup examples&lt;br /&gt;
Add whatever it publishes in mdns&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== troubleshooting / analysis ==&lt;br /&gt;
&lt;br /&gt;
=== testing ===&lt;br /&gt;
&lt;br /&gt;
# turn off fallback DISTCC_FALLBACK=1&lt;br /&gt;
# set distcc up to point at specific system under test DISTCC_HOSTS=&amp;quot;mytestbox,cpp,lzo&amp;quot;&lt;br /&gt;
# GCC example compiles&lt;br /&gt;
## code example C&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example C++&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example ObjC&lt;br /&gt;
## same with included header&lt;br /&gt;
# Cmake example compiles&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docoument the thing with compile launcher ccache;distcc&lt;br /&gt;
there&#039;s some blog post, point to that&lt;br /&gt;
no ccache here yet&lt;br /&gt;
show $CC differences distcc vs gcc, what configure scripts see&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Latency ===&lt;br /&gt;
&lt;br /&gt;
Latency of pump mode startups and fallbacks needs to be investigated.&lt;br /&gt;
LZO is enforced even if you have faster network&lt;br /&gt;
DNS Requests, very old bug report from Gcode, one request per call, is it true? how to get rid of it?&lt;br /&gt;
TMPDIR is respected, make sure it&#039;s on ramdisk even on the remote nodes.&lt;br /&gt;
Compile ideally never goes to disk when it doesn&#039;t have to.&lt;br /&gt;
How efficient is the include server collection and unpacking?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== failed to distribute, running locally instead ===&lt;br /&gt;
&lt;br /&gt;
the curse of the ancient, wise bulgarian witch compildora nottherea has befallen people all over the world. only strict and mindless adherence to rituals passed down from generation to generation has given hope to those who are under her ages old spell. again and again it reemerges to prey on idealistic young men and women who spend so much time at their unholy computers that they try to spend less time there by spending a lot of time trying to optimize what the computer does, slowly, instead of reflecting on why they are there, while the computer is busy working, and why they try to solve this by adding a component that makes the computer be more error-prone at that same work, increasing the need of their presense at this idolized thinking machine to oversee and often repair, or worse, mindlessly restart its doing.&lt;br /&gt;
if the curse is not lifted, despair may befall them and all they see is the need to investigate and ruminate further on the workings of this tool, ignoring thereby the obivous flaws that stem from of its alchemic origins.&lt;br /&gt;
&lt;br /&gt;
just wait till you find out it has a backoff alghoritm deciding whether to call out to a remote server independent of that server functioning. graceful performance degradation is the goal, and degrading it is while we try to figure this out.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Node Selection algorithm ====&lt;br /&gt;
&lt;br /&gt;
as per my understanding, a flowchart goes here:&lt;br /&gt;
&lt;br /&gt;
# compile task&lt;br /&gt;
# evaluate whether to run locally by job nature&lt;br /&gt;
# determine if local host&#039;s load is notable&lt;br /&gt;
# look at distcc hosts list&lt;br /&gt;
# do something based off localhost entry if first&lt;br /&gt;
# filter for nodes with cpp flag&lt;br /&gt;
# do something based off localhost entry if not first&lt;br /&gt;
# further prioritize by server order, first is handled in some way&lt;br /&gt;
# skip nodes in backoff prisons&lt;br /&gt;
# balance and priotize by server thread number, if given&lt;br /&gt;
# send to suitable host&lt;br /&gt;
# if compile not successful, proceed on other node&lt;br /&gt;
# if nodes depleted, proceed on localhost&lt;br /&gt;
&lt;br /&gt;
== security ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== tcpwrapper style ip range filter ===&lt;br /&gt;
&lt;br /&gt;
the original security model consists of ip restrictions.&lt;br /&gt;
there seems to also be some GSSAPI user auth.&lt;br /&gt;
further, commands that can be called are restricted by name and location.&lt;br /&gt;
this appears to be a runtime whitelist lookup, meaning it&#039;s done and authorized by the same parts of the daemon as processes the compile request along with the intended compiler.&lt;br /&gt;
so the main weaknesses against malicious clients seem to be in sending things to compile, and in overriding the remote compiler to use.&lt;br /&gt;
it can be assumed that a malicious client able to exploit the compiler handshake can then run arbitrary stuff.&lt;br /&gt;
There&#039;s at least a github issue regarding this (link lost, but see here: https://gitlab.com/postmarketOS/pmbootstrap/-/work_items/1619) suggesting running over ssh. That does only partitally alleviate this risk with regard  to a key based verfication of a client versus a the standard ip restrictions which always include some parsing.&lt;br /&gt;
So this protects against someone directly exploiting the TCP code of distcc.&lt;br /&gt;
It does not protect against malicious clients.&lt;br /&gt;
(ssh force command can&#039;t be used or you&#039;ll not compile anything)&lt;br /&gt;
&lt;br /&gt;
The basic step for protecting access should be filtering who can access the distcc server, so use nftables etc. to restrict access to port 3262 (??) set up the internal filter the same way.&lt;br /&gt;
&lt;br /&gt;
=== seccomp ===&lt;br /&gt;
&lt;br /&gt;
The next thing is to confine the compiler calls to only write in their temp directory and that they can only run compilers (using nsjail, apparmor, selinux etc)&lt;br /&gt;
&lt;br /&gt;
the above issue also references the second bit of security, namely a seccomp filter which will already cover a good bit of the above&lt;br /&gt;
https://github.com/distcc/distcc/pull/235&lt;br /&gt;
the commit got closed without merge, from what I see.&lt;br /&gt;
&lt;br /&gt;
I will update the entry once it&#039;s clear if the patch was later added or instead nothing was done.&lt;br /&gt;
&lt;br /&gt;
=== privs ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The other internal security bit is that they do some priviledge dropping. it runs as a dedicated user (distcc), so you can also have an audit policy, and can/could use something like iptables&#039; to ensure it can only connect to the other distcc/memcached hosts, but nothing else.&lt;br /&gt;
&lt;br /&gt;
=== compiler list ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
One needs to investigate when compiler_whitelist.sh is exactly called. as far as I recall it doesn&#039;t close stdin/stdout.&lt;br /&gt;
&lt;br /&gt;
=== distcc-hardened ===&lt;br /&gt;
&lt;br /&gt;
Alpine adds some hardening patch, idk what nature/origina that has.&lt;br /&gt;
&lt;br /&gt;
=== selinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
there&#039;s also a selinux policy for distcc from gentoo or liguros if one is so inclined.  &lt;br /&gt;
https://repology.org/project/selinux-distcc/versions  &lt;br /&gt;
https://gitlab.com/liguros/liguros-repo/-/tree/stable/sec-policy/selinux-distcc&lt;br /&gt;
&lt;br /&gt;
=== general posture ===&lt;br /&gt;
&lt;br /&gt;
Some security measures like the above should definitely be used since the project at its core relies on accepting foreign input over the network, has only a few part-time maintainers that cannot easily drive the project forward or do large refactors.&lt;br /&gt;
But the seccomp changes were done almost 10 years ago, so, if they were actually upstreamed, I&#039;d say they came through.&lt;br /&gt;
&lt;br /&gt;
A kind of overengineered solulion would be to use netlabel to ensure application integrity across hosts, meaning only a valid process would be able to send packets to the distcc nodes :-)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Alternatives ==&lt;br /&gt;
&lt;br /&gt;
Arch wiki refers to a fork by SUSE&lt;br /&gt;
https://github.com/icecc/icecream&lt;br /&gt;
&lt;br /&gt;
It appears &#039;maybe better&#039; but hard to tell. There&#039;s no mention if maybe SUSE&#039;s OBS uses it or something. Without more knowledge of their use I don&#039;t know how big a benefit will come from switching. At least you&#039;d wanna know they have a higher commitment to maintenance than the understaffed distcc &#039;team&#039; of current.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A commercial alternative (incredibuild https://www.incredibuild.com/) exists, but I have not tried it.&lt;br /&gt;
THey advertise some &#039;forever free&#039; tier; generally if there&#039;s high (business) pressure for faster builds I would check that out.&lt;br /&gt;
&lt;br /&gt;
Architecturally it seems to be taking the ccache approach with a shared cache and smarter redistribution.&lt;br /&gt;
So anything that can call ccache is something they can scale out. I&#039;ll add a link later, for those whom it helps.&lt;br /&gt;
Naturally it is out of scope for this article.&lt;br /&gt;
Nonetheless it&#039;s interesting since the ordering of how to run ccache and how to run distcc is an issue that also exists in the OSS world. Not just that we don&#039;t have an automatic setup and integration of the tools (ccache, redis, distccd, distcc-pump) but we also don&#039;t have collected sufficient data to aid in deciding which aproach is the best.&lt;br /&gt;
Integrating into CIs (gitlab-runner specifically) is another item where cache persistence becomes very fragile.&lt;br /&gt;
Having an alpine build container that knows how to use ccache with redis and distcc-pump would be a possible step forward.&lt;br /&gt;
&lt;br /&gt;
== Other sources ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://retroflux.net/blog/distcc-adventures/&lt;/div&gt;</summary>
		<author><name>Darkfader</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32203</id>
		<title>User:Darkfader/distcc</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32203"/>
		<updated>2026-03-28T18:13:39Z</updated>

		<summary type="html">&lt;p&gt;Darkfader: /* Gitlab integration */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi,&lt;br /&gt;
&lt;br /&gt;
I&#039;m preparing this page. It can take a long time till I finish.&lt;br /&gt;
If you are also wishing to write on this topic, feel free to integrate the content.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Document overview ==&lt;br /&gt;
&lt;br /&gt;
I noticed that almost every distro has one partially complete, partially helpful document on how to use distcc on the distro.&lt;br /&gt;
Usually they also have one for ccache.&lt;br /&gt;
In either case, they&#039;re enough to get started, but not really a reliable watertight thing.&lt;br /&gt;
We definitely needed one of our own.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== goal ===&lt;br /&gt;
&lt;br /&gt;
to describe a working setup for building aports in easiest/fastests fashion&lt;br /&gt;
not planning to add versatility or features where it would make the setup more errorprone.&lt;br /&gt;
the page should describe enough of the steps to successfully compile an LTS kernel via aports and have that job be distributed over multiple nodes.&lt;br /&gt;
Logs should be set up and able to display errors, but not show any errors during the test compile.&lt;br /&gt;
&lt;br /&gt;
To include a path for analysis via testing components.&lt;br /&gt;
&lt;br /&gt;
distcc can greatly improve compile speeds for large software, it comes with a different set of features than ccache; it focusses not avoiding unneccessary compile work, but on a way to speed up the necessary one.&lt;br /&gt;
&lt;br /&gt;
There&#039;s valuable info in the docs of other distros, it should be referenced here (i.e. the arch wiki troubleshooting), when it makes sense, add a TOC for their content.&lt;br /&gt;
&lt;br /&gt;
=== audience ===&lt;br /&gt;
people running software builds on alpine and have multiple computers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This page will show a specific installation, specific configuration, and specific tests, resulting in a specific set of functionality that can be tested to be working.&lt;br /&gt;
&lt;br /&gt;
== installation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Packages ===&lt;br /&gt;
&lt;br /&gt;
you need, on each host&lt;br /&gt;
* distcc&lt;br /&gt;
* distccd-openrc&lt;br /&gt;
* distcc-pump&lt;br /&gt;
* distcc-pump-pyc&lt;br /&gt;
&lt;br /&gt;
the .pyc will speed up the invocations, without it &lt;br /&gt;
idk if one or both should be installed in that case. but it appears to be also automatically be precompiled in /usr/lib/python3.12/site-packages/include_server/__pycache__/ so what does the package do exactly?&lt;br /&gt;
&lt;br /&gt;
There&#039;s some references to cpython-312, so maybe it actually still uses classy python-c conversion or matbe that&#039;s just a component for reading C source code. I have zero idea.&lt;br /&gt;
&lt;br /&gt;
you also need stuff to do compiles&lt;br /&gt;
* alpine sdk&lt;br /&gt;
* clang&lt;br /&gt;
* binutils&lt;br /&gt;
...&lt;br /&gt;
* elfutils(-dev)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Settings ===&lt;br /&gt;
==== settings for distcc ====&lt;br /&gt;
&lt;br /&gt;
* there&#039;s /etc/default/distcc&lt;br /&gt;
* there&#039;s /etc/conf.d/distcc &lt;br /&gt;
&lt;br /&gt;
make all your settings here&lt;br /&gt;
take care with the listen address, if you specify an IP it&#039;ll not be on 127.0.0.1 in case you would have localhost in your list...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* command_whitelist.sh &lt;br /&gt;
&lt;br /&gt;
this is half functional, you need to set things here but you also need to maintain the symlinks that are collected under /usr/lib/distcc (for your compilers) and /usr/lib/distcc/bin (for itself)&lt;br /&gt;
&lt;br /&gt;
you MUST run the script to update the compilers!&lt;br /&gt;
Info for script and what files it will create&lt;br /&gt;
&lt;br /&gt;
/usr/sbin/update-distcc-symlinks&lt;br /&gt;
&lt;br /&gt;
tschike:/usr/bin# ls -l /usr/lib/distcc/&lt;br /&gt;
total 4&lt;br /&gt;
drwxr-xr-x 2 root root 4096 Mar  2 18:14 bin&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c89 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c99 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 cc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc-15.2.0 -&amp;gt; ../../bin/distcc&lt;br /&gt;
&lt;br /&gt;
distcc itself is in bin&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cpp -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 g++ -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 06:49 x86_64-alpine-linux-musl-gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
&lt;br /&gt;
the last symplink here is wrong, made by me and would not work...&lt;br /&gt;
BAD symlink.&lt;br /&gt;
&lt;br /&gt;
=== distcc hosts file ===&lt;br /&gt;
&lt;br /&gt;
idk about that thing it&#039;s odd&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== abuild.conf ===&lt;br /&gt;
&lt;br /&gt;
settings for aports&lt;br /&gt;
* cc=&lt;br /&gt;
* cxx=&lt;br /&gt;
* cpp=&lt;br /&gt;
* cflags=&lt;br /&gt;
* njobs&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== detail infos ==&lt;br /&gt;
&lt;br /&gt;
???&lt;br /&gt;
&lt;br /&gt;
=== hosts syntax ===&lt;br /&gt;
&lt;br /&gt;
* myhost otherhost&lt;br /&gt;
* myhost,cpp,lzo myotherhost,cpp,lzo&lt;br /&gt;
&lt;br /&gt;
==== the host ====&lt;br /&gt;
&lt;br /&gt;
hostname/ip&lt;br /&gt;
localhost&lt;br /&gt;
127.0.0.1&lt;br /&gt;
::1 - does not work&lt;br /&gt;
&lt;br /&gt;
==== protocol ====&lt;br /&gt;
&lt;br /&gt;
* no protocol given&lt;br /&gt;
* ,cpp,lzo protocol&lt;br /&gt;
&lt;br /&gt;
cpp implies lzo, it requires compression, even if you have 10gbit/s or more, it&#039;s just hardcoded&lt;br /&gt;
&lt;br /&gt;
=== threads ===&lt;br /&gt;
/number of workers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== architecture ==&lt;br /&gt;
it can handle C, C++, ObjC, maybe some other stuff&lt;br /&gt;
&lt;br /&gt;
* what happens with normal xmit&lt;br /&gt;
* what happens with pump mode&lt;br /&gt;
* at which step the include server is used and how it collects the includes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== distribution algorithm ===&lt;br /&gt;
honestly I simply don&#039;t get it&lt;br /&gt;
&lt;br /&gt;
* The order matters&lt;br /&gt;
* The number of threads matters&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== localhost ====&lt;br /&gt;
&lt;br /&gt;
* localhost precedence&lt;br /&gt;
* localhost fallback&lt;br /&gt;
&lt;br /&gt;
variable: DISTCC_FALLBACK&lt;br /&gt;
&lt;br /&gt;
0 = Fail to compile if it would need to fallback to a normal local gcc call&lt;br /&gt;
1 = If remote compile fails, just do it yourself&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Operation ==&lt;br /&gt;
&lt;br /&gt;
=== startup and shutdown ===&lt;br /&gt;
service distcc stop is not entirely reliable (it can take a minute after the stop until the processes are gone and sometimes it will never stop&lt;br /&gt;
this is very bad with openrc, the openrc script returns after a second and only relies on its service flags, not the process status.&lt;br /&gt;
manually check after stopping, wait a min, if needed, kill it all.&lt;br /&gt;
at some point the rc file needs to be rewritten, it can&#039;t stay like it is.&lt;br /&gt;
&lt;br /&gt;
if you used a pump mode session, that also needs a logout (pump --shutdown)&lt;br /&gt;
avoid running multiple startups without shutdown in one session. it&#039;s safe as far as I can tell but nothing cleans up these processes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== ccache and memcached ===&lt;br /&gt;
CCACHE is said to be conflicting with pump mode unless when you call them in the backend&lt;br /&gt;
so, where you start the compile, you don&#039;t use it&lt;br /&gt;
where the compile happens, you use it&lt;br /&gt;
they can share the cache via memcached, this is a nice trick for consistency&lt;br /&gt;
Upon looking at the ccache website, it seems the correct mechanism is not memcached but Redis. This would work just as well. Generally a cache shared in this way would be optimal for performance.&lt;br /&gt;
&lt;br /&gt;
=== dockerized / native ===&lt;br /&gt;
&lt;br /&gt;
it remains mostly the same, a container needs to make sure it monitors the right services (distccd, nginx, include_server)&lt;br /&gt;
if you&#039;re using zeroconf, you need to somehow expose the mdns service broadcasts &amp;amp; receptio&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== untested build container system ====&lt;br /&gt;
&lt;br /&gt;
See this one https://github.com/bensuperpc/docker-distcc&lt;br /&gt;
not yet tested, but this could be a good basis for a &#039;best practice&#039; container.&lt;br /&gt;
There&#039;s others, especially for crossbuilds, but those are also very complex to modify.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Processs list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
Workdir list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
=== alpine-chroot ===&lt;br /&gt;
&lt;br /&gt;
when using the &#039;official&#039; script there&#039;s still some odd pieces, seemed to be the processes died on logout. but not all of them.&lt;br /&gt;
&lt;br /&gt;
==== manual launch ====&lt;br /&gt;
&lt;br /&gt;
Starting the daemon would be using&lt;br /&gt;
/usr/bin/distccd --pid-file /var/run/distccd/distccd.pid -N 15 --user distcc --port 3632 --log-level=debug --log-file=/var/log/distccd.log --allow my-sub-net/24&lt;br /&gt;
&lt;br /&gt;
==== localhost? =====&lt;br /&gt;
unclear if you need to use --allow for 127.0.0.1/32 or something to allow the remote preproccesor.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Gitlab integration ===&lt;br /&gt;
&lt;br /&gt;
TBA&lt;br /&gt;
&lt;br /&gt;
Maybe work from this k8s howto, it&#039;s a bit more prod-grade than most:&lt;br /&gt;
&lt;br /&gt;
https://cinaq.com/blog/2020/05/10/speed-up-docker-builds-with-distcc-ccache-and-kubernetes/&lt;br /&gt;
&lt;br /&gt;
== Kernel specific settings ==&lt;br /&gt;
&lt;br /&gt;
currently (distcc 3.4-r9 on Alpine) you need a patch to build the kernel.&lt;br /&gt;
See &lt;br /&gt;
&lt;br /&gt;
=== Include server Settings ===&lt;br /&gt;
&lt;br /&gt;
cache reset triggers&lt;br /&gt;
This ought to be set before enabling pump mode.&lt;br /&gt;
&lt;br /&gt;
export INCLUDE_SERVER_ARGS=&amp;quot;--stat_reset_triggers=include/linux/compile.h:include/asm/asm-offsets.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
link to explanation TBA&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Disabling GCC Plugins ===&lt;br /&gt;
&lt;br /&gt;
KConfig unselect HAVE_GCC_PLUGINS&lt;br /&gt;
&lt;br /&gt;
Some info is here in the troubleshooting part of the Arch Wiki&lt;br /&gt;
https://wiki.archlinux.org/title/Distcc#Troubleshooting&lt;br /&gt;
&lt;br /&gt;
=== Patches ===&lt;br /&gt;
&lt;br /&gt;
Other things (for 6.6LTS)&lt;br /&gt;
PCIe Stub patch&lt;br /&gt;
&lt;br /&gt;
=== Autoconf === &lt;br /&gt;
&lt;br /&gt;
No known setup examples&lt;br /&gt;
Add whatever it publishes in mdns&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== troubleshooting / analysis ==&lt;br /&gt;
&lt;br /&gt;
=== testing ===&lt;br /&gt;
&lt;br /&gt;
# turn off fallback DISTCC_FALLBACK=1&lt;br /&gt;
# set distcc up to point at specific system under test DISTCC_HOSTS=&amp;quot;mytestbox,cpp,lzo&amp;quot;&lt;br /&gt;
# GCC example compiles&lt;br /&gt;
## code example C&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example C++&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example ObjC&lt;br /&gt;
## same with included header&lt;br /&gt;
# Cmake example compiles&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docoument the thing with compile launcher ccache;distcc&lt;br /&gt;
there&#039;s some blog post, point to that&lt;br /&gt;
no ccache here yet&lt;br /&gt;
show $CC differences distcc vs gcc, what configure scripts see&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Latency ===&lt;br /&gt;
&lt;br /&gt;
Latency of pump mode startups and fallbacks needs to be investigated.&lt;br /&gt;
LZO is enforced even if you have faster network&lt;br /&gt;
DNS Requests, very old bug report from Gcode, one request per call, is it true? how to get rid of it?&lt;br /&gt;
TMPDIR is respected, make sure it&#039;s on ramdisk even on the remote nodes.&lt;br /&gt;
Compile ideally never goes to disk when it doesn&#039;t have to.&lt;br /&gt;
How efficient is the include server collection and unpacking?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== failed to distribute, running locally instead ===&lt;br /&gt;
&lt;br /&gt;
the curse of the ancient, wise bulgarian witch compildora nottherea has befallen people all over the world. only strict and mindless adherence to rituals passed down from generation to generation has given hope to those who are under her ages old spell. again and again it reemerges to prey on idealistic young men and women who spend so much time at their unholy computers that they try to spend less time there by spending a lot of time trying to optimize what the computer does, slowly, instead of reflecting on why they are there, while the computer is busy working, and why they try to solve this by adding a component that makes the computer be more error-prone at that same work, increasing the need of their presense at this idolized thinking machine to oversee and often repair, or worse, mindlessly restart its doing.&lt;br /&gt;
if the curse is not lifted, despair may befall them and all they see is the need to investigate and ruminate further on the workings of this tool, ignoring thereby the obivous flaws that stem from of its alchemic origins.&lt;br /&gt;
&lt;br /&gt;
just wait till you find out it has a backoff alghoritm deciding whether to call out to a remote server independent of that server functioning. graceful performance degradation is the goal, and degrading it is while we try to figure this out.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Node Selection algorithm ====&lt;br /&gt;
&lt;br /&gt;
as per my understanding, a flowchart goes here:&lt;br /&gt;
&lt;br /&gt;
# compile task&lt;br /&gt;
# evaluate whether to run locally by job nature&lt;br /&gt;
# determine if local host&#039;s load is notable&lt;br /&gt;
# look at distcc hosts list&lt;br /&gt;
# do something based off localhost entry if first&lt;br /&gt;
# filter for nodes with cpp flag&lt;br /&gt;
# do something based off localhost entry if not first&lt;br /&gt;
# further prioritize by server order, first is handled in some way&lt;br /&gt;
# skip nodes in backoff prisons&lt;br /&gt;
# balance and priotize by server thread number, if given&lt;br /&gt;
# send to suitable host&lt;br /&gt;
# if compile not successful, proceed on other node&lt;br /&gt;
# if nodes depleted, proceed on localhost&lt;br /&gt;
&lt;br /&gt;
== security ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== tcpwrapper style ip range filter ===&lt;br /&gt;
&lt;br /&gt;
the original security model consists of ip restrictions.&lt;br /&gt;
there seems to also be some GSSAPI user auth.&lt;br /&gt;
further, commands that can be called are restricted by name and location.&lt;br /&gt;
this appears to be a runtime whitelist lookup, meaning it&#039;s done and authorized by the same parts of the daemon as processes the compile request along with the intended compiler.&lt;br /&gt;
so the main weaknesses against malicious clients seem to be in sending things to compile, and in overriding the remote compiler to use.&lt;br /&gt;
it can be assumed that a malicious client able to exploit the compiler handshake can then run arbitrary stuff.&lt;br /&gt;
There&#039;s at least a github issue regarding this (link lost, but see here: https://gitlab.com/postmarketOS/pmbootstrap/-/work_items/1619) suggesting running over ssh. That does only partitally alleviate this risk with regard  to a key based verfication of a client versus a the standard ip restrictions which always include some parsing.&lt;br /&gt;
So this protects against someone directly exploiting the TCP code of distcc.&lt;br /&gt;
It does not protect against malicious clients.&lt;br /&gt;
(ssh force command can&#039;t be used or you&#039;ll not compile anything)&lt;br /&gt;
&lt;br /&gt;
The basic step for protecting access should be filtering who can access the distcc server, so use nftables etc. to restrict access to port 3262 (??) set up the internal filter the same way.&lt;br /&gt;
&lt;br /&gt;
=== seccomp ===&lt;br /&gt;
&lt;br /&gt;
The next thing is to confine the compiler calls to only write in their temp directory and that they can only run compilers (using nsjail, apparmor, selinux etc)&lt;br /&gt;
&lt;br /&gt;
the above issue also references the second bit of security, namely a seccomp filter which will already cover a good bit of the above&lt;br /&gt;
https://github.com/distcc/distcc/pull/235&lt;br /&gt;
the commit got closed without merge, from what I see.&lt;br /&gt;
&lt;br /&gt;
I will update the entry once it&#039;s clear if the patch was later added or instead nothing was done.&lt;br /&gt;
&lt;br /&gt;
=== privs ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The other internal security bit is that they do some priviledge dropping. it runs as a dedicated user (distcc), so you can also have an audit policy, and can/could use something like iptables&#039; to ensure it can only connect to the other distcc/memcached hosts, but nothing else.&lt;br /&gt;
&lt;br /&gt;
=== compiler list ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
One needs to investigate when compiler_whitelist.sh is exactly called. as far as I recall it doesn&#039;t close stdin/stdout.&lt;br /&gt;
&lt;br /&gt;
=== distcc-hardened ===&lt;br /&gt;
&lt;br /&gt;
Alpine adds some hardening patch, idk what nature/origina that has.&lt;br /&gt;
&lt;br /&gt;
=== selinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
there&#039;s also a selinux policy for distcc from gentoo or liguros if one is so inclined.&lt;br /&gt;
https://repology.org/project/selinux-distcc/versions&lt;br /&gt;
&lt;br /&gt;
=== general posture ===&lt;br /&gt;
&lt;br /&gt;
Some security measures like the above should definitely be used since the project at its core relies on accepting foreign input over the network, has only a few part-time maintainers that cannot easily drive the project forward or do large refactors.&lt;br /&gt;
But the seccomp changes were done almost 10 years ago, so, if they were actually upstreamed, I&#039;d say they came through.&lt;br /&gt;
&lt;br /&gt;
A kind of overengineered solulion would be to use netlabel to ensure application integrity across hosts, meaning only a valid process would be able to send packets to the distcc nodes :-)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Alternatives ==&lt;br /&gt;
&lt;br /&gt;
Arch wiki refers to a fork by SUSE&lt;br /&gt;
https://github.com/icecc/icecream&lt;br /&gt;
&lt;br /&gt;
It appears &#039;maybe better&#039; but hard to tell. There&#039;s no mention if maybe SUSE&#039;s OBS uses it or something. Without more knowledge of their use I don&#039;t know how big a benefit will come from switching. At least you&#039;d wanna know they have a higher commitment to maintenance than the understaffed distcc &#039;team&#039; of current.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A commercial alternative (incredibuild https://www.incredibuild.com/) exists, but I have not tried it.&lt;br /&gt;
THey advertise some &#039;forever free&#039; tier; generally if there&#039;s high (business) pressure for faster builds I would check that out.&lt;br /&gt;
&lt;br /&gt;
Architecturally it seems to be taking the ccache approach with a shared cache and smarter redistribution.&lt;br /&gt;
So anything that can call ccache is something they can scale out. I&#039;ll add a link later, for those whom it helps.&lt;br /&gt;
Naturally it is out of scope for this article.&lt;br /&gt;
Nonetheless it&#039;s interesting since the ordering of how to run ccache and how to run distcc is an issue that also exists in the OSS world. Not just that we don&#039;t have an automatic setup and integration of the tools (ccache, redis, distccd, distcc-pump) but we also don&#039;t have collected sufficient data to aid in deciding which aproach is the best.&lt;br /&gt;
Integrating into CIs (gitlab-runner specifically) is another item where cache persistence becomes very fragile.&lt;br /&gt;
Having an alpine build container that knows how to use ccache with redis and distcc-pump would be a possible step forward.&lt;br /&gt;
&lt;br /&gt;
== Other sources ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://retroflux.net/blog/distcc-adventures/&lt;/div&gt;</summary>
		<author><name>Darkfader</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32201</id>
		<title>User:Darkfader/distcc</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32201"/>
		<updated>2026-03-28T16:33:18Z</updated>

		<summary type="html">&lt;p&gt;Darkfader: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi,&lt;br /&gt;
&lt;br /&gt;
I&#039;m preparing this page. It can take a long time till I finish.&lt;br /&gt;
If you are also wishing to write on this topic, feel free to integrate the content.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Document overview ==&lt;br /&gt;
&lt;br /&gt;
I noticed that almost every distro has one partially complete, partially helpful document on how to use distcc on the distro.&lt;br /&gt;
Usually they also have one for ccache.&lt;br /&gt;
In either case, they&#039;re enough to get started, but not really a reliable watertight thing.&lt;br /&gt;
We definitely needed one of our own.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== goal ===&lt;br /&gt;
&lt;br /&gt;
to describe a working setup for building aports in easiest/fastests fashion&lt;br /&gt;
not planning to add versatility or features where it would make the setup more errorprone.&lt;br /&gt;
the page should describe enough of the steps to successfully compile an LTS kernel via aports and have that job be distributed over multiple nodes.&lt;br /&gt;
Logs should be set up and able to display errors, but not show any errors during the test compile.&lt;br /&gt;
&lt;br /&gt;
To include a path for analysis via testing components.&lt;br /&gt;
&lt;br /&gt;
distcc can greatly improve compile speeds for large software, it comes with a different set of features than ccache; it focusses not avoiding unneccessary compile work, but on a way to speed up the necessary one.&lt;br /&gt;
&lt;br /&gt;
There&#039;s valuable info in the docs of other distros, it should be referenced here (i.e. the arch wiki troubleshooting), when it makes sense, add a TOC for their content.&lt;br /&gt;
&lt;br /&gt;
=== audience ===&lt;br /&gt;
people running software builds on alpine and have multiple computers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This page will show a specific installation, specific configuration, and specific tests, resulting in a specific set of functionality that can be tested to be working.&lt;br /&gt;
&lt;br /&gt;
== installation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Packages ===&lt;br /&gt;
&lt;br /&gt;
you need, on each host&lt;br /&gt;
* distcc&lt;br /&gt;
* distccd-openrc&lt;br /&gt;
* distcc-pump&lt;br /&gt;
* distcc-pump-pyc&lt;br /&gt;
&lt;br /&gt;
the .pyc will speed up the invocations, without it &lt;br /&gt;
idk if one or both should be installed in that case. but it appears to be also automatically be precompiled in /usr/lib/python3.12/site-packages/include_server/__pycache__/ so what does the package do exactly?&lt;br /&gt;
&lt;br /&gt;
There&#039;s some references to cpython-312, so maybe it actually still uses classy python-c conversion or matbe that&#039;s just a component for reading C source code. I have zero idea.&lt;br /&gt;
&lt;br /&gt;
you also need stuff to do compiles&lt;br /&gt;
* alpine sdk&lt;br /&gt;
* clang&lt;br /&gt;
* binutils&lt;br /&gt;
...&lt;br /&gt;
* elfutils(-dev)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Settings ===&lt;br /&gt;
==== settings for distcc ====&lt;br /&gt;
&lt;br /&gt;
* there&#039;s /etc/default/distcc&lt;br /&gt;
* there&#039;s /etc/conf.d/distcc &lt;br /&gt;
&lt;br /&gt;
make all your settings here&lt;br /&gt;
take care with the listen address, if you specify an IP it&#039;ll not be on 127.0.0.1 in case you would have localhost in your list...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* command_whitelist.sh &lt;br /&gt;
&lt;br /&gt;
this is half functional, you need to set things here but you also need to maintain the symlinks that are collected under /usr/lib/distcc (for your compilers) and /usr/lib/distcc/bin (for itself)&lt;br /&gt;
&lt;br /&gt;
you MUST run the script to update the compilers!&lt;br /&gt;
Info for script and what files it will create&lt;br /&gt;
&lt;br /&gt;
/usr/sbin/update-distcc-symlinks&lt;br /&gt;
&lt;br /&gt;
tschike:/usr/bin# ls -l /usr/lib/distcc/&lt;br /&gt;
total 4&lt;br /&gt;
drwxr-xr-x 2 root root 4096 Mar  2 18:14 bin&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c89 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c99 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 cc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc-15.2.0 -&amp;gt; ../../bin/distcc&lt;br /&gt;
&lt;br /&gt;
distcc itself is in bin&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cpp -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 g++ -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 06:49 x86_64-alpine-linux-musl-gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
&lt;br /&gt;
the last symplink here is wrong, made by me and would not work...&lt;br /&gt;
BAD symlink.&lt;br /&gt;
&lt;br /&gt;
=== distcc hosts file ===&lt;br /&gt;
&lt;br /&gt;
idk about that thing it&#039;s odd&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== abuild.conf ===&lt;br /&gt;
&lt;br /&gt;
settings for aports&lt;br /&gt;
* cc=&lt;br /&gt;
* cxx=&lt;br /&gt;
* cpp=&lt;br /&gt;
* cflags=&lt;br /&gt;
* njobs&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== detail infos ==&lt;br /&gt;
&lt;br /&gt;
???&lt;br /&gt;
&lt;br /&gt;
=== hosts syntax ===&lt;br /&gt;
&lt;br /&gt;
* myhost otherhost&lt;br /&gt;
* myhost,cpp,lzo myotherhost,cpp,lzo&lt;br /&gt;
&lt;br /&gt;
==== the host ====&lt;br /&gt;
&lt;br /&gt;
hostname/ip&lt;br /&gt;
localhost&lt;br /&gt;
127.0.0.1&lt;br /&gt;
::1 - does not work&lt;br /&gt;
&lt;br /&gt;
==== protocol ====&lt;br /&gt;
&lt;br /&gt;
* no protocol given&lt;br /&gt;
* ,cpp,lzo protocol&lt;br /&gt;
&lt;br /&gt;
cpp implies lzo, it requires compression, even if you have 10gbit/s or more, it&#039;s just hardcoded&lt;br /&gt;
&lt;br /&gt;
=== threads ===&lt;br /&gt;
/number of workers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== architecture ==&lt;br /&gt;
it can handle C, C++, ObjC, maybe some other stuff&lt;br /&gt;
&lt;br /&gt;
* what happens with normal xmit&lt;br /&gt;
* what happens with pump mode&lt;br /&gt;
* at which step the include server is used and how it collects the includes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== distribution algorithm ===&lt;br /&gt;
honestly I simply don&#039;t get it&lt;br /&gt;
&lt;br /&gt;
* The order matters&lt;br /&gt;
* The number of threads matters&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== localhost ====&lt;br /&gt;
&lt;br /&gt;
* localhost precedence&lt;br /&gt;
* localhost fallback&lt;br /&gt;
&lt;br /&gt;
variable: DISTCC_FALLBACK&lt;br /&gt;
&lt;br /&gt;
0 = Fail to compile if it would need to fallback to a normal local gcc call&lt;br /&gt;
1 = If remote compile fails, just do it yourself&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Operation ==&lt;br /&gt;
&lt;br /&gt;
=== startup and shutdown ===&lt;br /&gt;
service distcc stop is not entirely reliable (it can take a minute after the stop until the processes are gone and sometimes it will never stop&lt;br /&gt;
this is very bad with openrc, the openrc script returns after a second and only relies on its service flags, not the process status.&lt;br /&gt;
manually check after stopping, wait a min, if needed, kill it all.&lt;br /&gt;
at some point the rc file needs to be rewritten, it can&#039;t stay like it is.&lt;br /&gt;
&lt;br /&gt;
if you used a pump mode session, that also needs a logout (pump --shutdown)&lt;br /&gt;
avoid running multiple startups without shutdown in one session. it&#039;s safe as far as I can tell but nothing cleans up these processes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== ccache and memcached ===&lt;br /&gt;
CCACHE is said to be conflicting with pump mode unless when you call them in the backend&lt;br /&gt;
so, where you start the compile, you don&#039;t use it&lt;br /&gt;
where the compile happens, you use it&lt;br /&gt;
they can share the cache via memcached, this is a nice trick for consistency&lt;br /&gt;
Upon looking at the ccache website, it seems the correct mechanism is not memcached but Redis. This would work just as well. Generally a cache shared in this way would be optimal for performance.&lt;br /&gt;
&lt;br /&gt;
=== dockerized / native ===&lt;br /&gt;
&lt;br /&gt;
it remains mostly the same, a container needs to make sure it monitors the right services (distccd, nginx, include_server)&lt;br /&gt;
if you&#039;re using zeroconf, you need to somehow expose the mdns service broadcasts &amp;amp; receptio&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== untested build container system ====&lt;br /&gt;
&lt;br /&gt;
See this one https://github.com/bensuperpc/docker-distcc&lt;br /&gt;
not yet tested, but this could be a good basis for a &#039;best practice&#039; container.&lt;br /&gt;
There&#039;s others, especially for crossbuilds, but those are also very complex to modify.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Processs list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
Workdir list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
=== alpine-chroot ===&lt;br /&gt;
&lt;br /&gt;
when using the &#039;official&#039; script there&#039;s still some odd pieces, seemed to be the processes died on logout. but not all of them.&lt;br /&gt;
&lt;br /&gt;
==== manual launch ====&lt;br /&gt;
&lt;br /&gt;
Starting the daemon would be using&lt;br /&gt;
/usr/bin/distccd --pid-file /var/run/distccd/distccd.pid -N 15 --user distcc --port 3632 --log-level=debug --log-file=/var/log/distccd.log --allow my-sub-net/24&lt;br /&gt;
&lt;br /&gt;
==== localhost? =====&lt;br /&gt;
unclear if you need to use --allow for 127.0.0.1/32 or something to allow the remote preproccesor.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Gitlab integration ===&lt;br /&gt;
&lt;br /&gt;
TBA&lt;br /&gt;
&lt;br /&gt;
== Kernel specific settings ==&lt;br /&gt;
&lt;br /&gt;
currently (distcc 3.4-r9 on Alpine) you need a patch to build the kernel.&lt;br /&gt;
See &lt;br /&gt;
&lt;br /&gt;
=== Include server Settings ===&lt;br /&gt;
&lt;br /&gt;
cache reset triggers&lt;br /&gt;
This ought to be set before enabling pump mode.&lt;br /&gt;
&lt;br /&gt;
export INCLUDE_SERVER_ARGS=&amp;quot;--stat_reset_triggers=include/linux/compile.h:include/asm/asm-offsets.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
link to explanation TBA&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Disabling GCC Plugins ===&lt;br /&gt;
&lt;br /&gt;
KConfig unselect HAVE_GCC_PLUGINS&lt;br /&gt;
&lt;br /&gt;
Some info is here in the troubleshooting part of the Arch Wiki&lt;br /&gt;
https://wiki.archlinux.org/title/Distcc#Troubleshooting&lt;br /&gt;
&lt;br /&gt;
=== Patches ===&lt;br /&gt;
&lt;br /&gt;
Other things (for 6.6LTS)&lt;br /&gt;
PCIe Stub patch&lt;br /&gt;
&lt;br /&gt;
=== Autoconf === &lt;br /&gt;
&lt;br /&gt;
No known setup examples&lt;br /&gt;
Add whatever it publishes in mdns&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== troubleshooting / analysis ==&lt;br /&gt;
&lt;br /&gt;
=== testing ===&lt;br /&gt;
&lt;br /&gt;
# turn off fallback DISTCC_FALLBACK=1&lt;br /&gt;
# set distcc up to point at specific system under test DISTCC_HOSTS=&amp;quot;mytestbox,cpp,lzo&amp;quot;&lt;br /&gt;
# GCC example compiles&lt;br /&gt;
## code example C&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example C++&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example ObjC&lt;br /&gt;
## same with included header&lt;br /&gt;
# Cmake example compiles&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docoument the thing with compile launcher ccache;distcc&lt;br /&gt;
there&#039;s some blog post, point to that&lt;br /&gt;
no ccache here yet&lt;br /&gt;
show $CC differences distcc vs gcc, what configure scripts see&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Latency ===&lt;br /&gt;
&lt;br /&gt;
Latency of pump mode startups and fallbacks needs to be investigated.&lt;br /&gt;
LZO is enforced even if you have faster network&lt;br /&gt;
DNS Requests, very old bug report from Gcode, one request per call, is it true? how to get rid of it?&lt;br /&gt;
TMPDIR is respected, make sure it&#039;s on ramdisk even on the remote nodes.&lt;br /&gt;
Compile ideally never goes to disk when it doesn&#039;t have to.&lt;br /&gt;
How efficient is the include server collection and unpacking?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== failed to distribute, running locally instead ===&lt;br /&gt;
&lt;br /&gt;
the curse of the ancient, wise bulgarian witch compildora nottherea has befallen people all over the world. only strict and mindless adherence to rituals passed down from generation to generation has given hope to those who are under her ages old spell. again and again it reemerges to prey on idealistic young men and women who spend so much time at their unholy computers that they try to spend less time there by spending a lot of time trying to optimize what the computer does, slowly, instead of reflecting on why they are there, while the computer is busy working, and why they try to solve this by adding a component that makes the computer be more error-prone at that same work, increasing the need of their presense at this idolized thinking machine to oversee and often repair, or worse, mindlessly restart its doing.&lt;br /&gt;
if the curse is not lifted, despair may befall them and all they see is the need to investigate and ruminate further on the workings of this tool, ignoring thereby the obivous flaws that stem from of its alchemic origins.&lt;br /&gt;
&lt;br /&gt;
just wait till you find out it has a backoff alghoritm deciding whether to call out to a remote server independent of that server functioning. graceful performance degradation is the goal, and degrading it is while we try to figure this out.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Node Selection algorithm ====&lt;br /&gt;
&lt;br /&gt;
as per my understanding, a flowchart goes here:&lt;br /&gt;
&lt;br /&gt;
# compile task&lt;br /&gt;
# evaluate whether to run locally by job nature&lt;br /&gt;
# determine if local host&#039;s load is notable&lt;br /&gt;
# look at distcc hosts list&lt;br /&gt;
# do something based off localhost entry if first&lt;br /&gt;
# filter for nodes with cpp flag&lt;br /&gt;
# do something based off localhost entry if not first&lt;br /&gt;
# further prioritize by server order, first is handled in some way&lt;br /&gt;
# skip nodes in backoff prisons&lt;br /&gt;
# balance and priotize by server thread number, if given&lt;br /&gt;
# send to suitable host&lt;br /&gt;
# if compile not successful, proceed on other node&lt;br /&gt;
# if nodes depleted, proceed on localhost&lt;br /&gt;
&lt;br /&gt;
== security ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== tcpwrapper style ip range filter ===&lt;br /&gt;
&lt;br /&gt;
the original security model consists of ip restrictions.&lt;br /&gt;
there seems to also be some GSSAPI user auth.&lt;br /&gt;
further, commands that can be called are restricted by name and location.&lt;br /&gt;
this appears to be a runtime whitelist lookup, meaning it&#039;s done and authorized by the same parts of the daemon as processes the compile request along with the intended compiler.&lt;br /&gt;
so the main weaknesses against malicious clients seem to be in sending things to compile, and in overriding the remote compiler to use.&lt;br /&gt;
it can be assumed that a malicious client able to exploit the compiler handshake can then run arbitrary stuff.&lt;br /&gt;
There&#039;s at least a github issue regarding this (link lost, but see here: https://gitlab.com/postmarketOS/pmbootstrap/-/work_items/1619) suggesting running over ssh. That does only partitally alleviate this risk with regard  to a key based verfication of a client versus a the standard ip restrictions which always include some parsing.&lt;br /&gt;
So this protects against someone directly exploiting the TCP code of distcc.&lt;br /&gt;
It does not protect against malicious clients.&lt;br /&gt;
(ssh force command can&#039;t be used or you&#039;ll not compile anything)&lt;br /&gt;
&lt;br /&gt;
The basic step for protecting access should be filtering who can access the distcc server, so use nftables etc. to restrict access to port 3262 (??) set up the internal filter the same way.&lt;br /&gt;
&lt;br /&gt;
=== seccomp ===&lt;br /&gt;
&lt;br /&gt;
The next thing is to confine the compiler calls to only write in their temp directory and that they can only run compilers (using nsjail, apparmor, selinux etc)&lt;br /&gt;
&lt;br /&gt;
the above issue also references the second bit of security, namely a seccomp filter which will already cover a good bit of the above&lt;br /&gt;
https://github.com/distcc/distcc/pull/235&lt;br /&gt;
the commit got closed without merge, from what I see.&lt;br /&gt;
&lt;br /&gt;
I will update the entry once it&#039;s clear if the patch was later added or instead nothing was done.&lt;br /&gt;
&lt;br /&gt;
=== privs ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The other internal security bit is that they do some priviledge dropping. it runs as a dedicated user (distcc), so you can also have an audit policy, and can/could use something like iptables&#039; to ensure it can only connect to the other distcc/memcached hosts, but nothing else.&lt;br /&gt;
&lt;br /&gt;
=== compiler list ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
One needs to investigate when compiler_whitelist.sh is exactly called. as far as I recall it doesn&#039;t close stdin/stdout.&lt;br /&gt;
&lt;br /&gt;
=== distcc-hardened ===&lt;br /&gt;
&lt;br /&gt;
Alpine adds some hardening patch, idk what nature/origina that has.&lt;br /&gt;
&lt;br /&gt;
=== selinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
there&#039;s also a selinux policy for distcc from gentoo or liguros if one is so inclined.&lt;br /&gt;
https://repology.org/project/selinux-distcc/versions&lt;br /&gt;
&lt;br /&gt;
=== general posture ===&lt;br /&gt;
&lt;br /&gt;
Some security measures like the above should definitely be used since the project at its core relies on accepting foreign input over the network, has only a few part-time maintainers that cannot easily drive the project forward or do large refactors.&lt;br /&gt;
But the seccomp changes were done almost 10 years ago, so, if they were actually upstreamed, I&#039;d say they came through.&lt;br /&gt;
&lt;br /&gt;
A kind of overengineered solulion would be to use netlabel to ensure application integrity across hosts, meaning only a valid process would be able to send packets to the distcc nodes :-)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Alternatives ==&lt;br /&gt;
&lt;br /&gt;
Arch wiki refers to a fork by SUSE&lt;br /&gt;
https://github.com/icecc/icecream&lt;br /&gt;
&lt;br /&gt;
It appears &#039;maybe better&#039; but hard to tell. There&#039;s no mention if maybe SUSE&#039;s OBS uses it or something. Without more knowledge of their use I don&#039;t know how big a benefit will come from switching. At least you&#039;d wanna know they have a higher commitment to maintenance than the understaffed distcc &#039;team&#039; of current.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A commercial alternative (incredibuild https://www.incredibuild.com/) exists, but I have not tried it.&lt;br /&gt;
THey advertise some &#039;forever free&#039; tier; generally if there&#039;s high (business) pressure for faster builds I would check that out.&lt;br /&gt;
&lt;br /&gt;
Architecturally it seems to be taking the ccache approach with a shared cache and smarter redistribution.&lt;br /&gt;
So anything that can call ccache is something they can scale out. I&#039;ll add a link later, for those whom it helps.&lt;br /&gt;
Naturally it is out of scope for this article.&lt;br /&gt;
Nonetheless it&#039;s interesting since the ordering of how to run ccache and how to run distcc is an issue that also exists in the OSS world. Not just that we don&#039;t have an automatic setup and integration of the tools (ccache, redis, distccd, distcc-pump) but we also don&#039;t have collected sufficient data to aid in deciding which aproach is the best.&lt;br /&gt;
Integrating into CIs (gitlab-runner specifically) is another item where cache persistence becomes very fragile.&lt;br /&gt;
Having an alpine build container that knows how to use ccache with redis and distcc-pump would be a possible step forward.&lt;br /&gt;
&lt;br /&gt;
== Other sources ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://retroflux.net/blog/distcc-adventures/&lt;/div&gt;</summary>
		<author><name>Darkfader</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32200</id>
		<title>User:Darkfader/distcc</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32200"/>
		<updated>2026-03-28T16:32:18Z</updated>

		<summary type="html">&lt;p&gt;Darkfader: /* Operation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi,&lt;br /&gt;
&lt;br /&gt;
I&#039;m preparing this page. It can take a long time till I finish.&lt;br /&gt;
If you are also wishing to write on this topic, feel free to integrate the content.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Document overview ==&lt;br /&gt;
&lt;br /&gt;
I noticed that almost every distro has one partially complete, partially helpful document on how to use distcc on the distro.&lt;br /&gt;
Usually they also have one for ccache.&lt;br /&gt;
In either case, they&#039;re enough to get started, but not really a reliable watertight thing.&lt;br /&gt;
We definitely needed one of our own.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== goal ===&lt;br /&gt;
&lt;br /&gt;
to describe a working setup for building aports in easiest/fastests fashion&lt;br /&gt;
not planning to add versatility or features where it would make the setup more errorprone.&lt;br /&gt;
the page should describe enough of the steps to successfully compile an LTS kernel via aports and have that job be distributed over multiple nodes.&lt;br /&gt;
Logs should be set up and able to display errors, but not show any errors during the test compile.&lt;br /&gt;
&lt;br /&gt;
To include a path for analysis via testing components.&lt;br /&gt;
&lt;br /&gt;
distcc can greatly improve compile speeds for large software, it comes with a different set of features than ccache; it focusses not avoiding unneccessary compile work, but on a way to speed up the necessary one.&lt;br /&gt;
&lt;br /&gt;
There&#039;s valuable info in the docs of other distros, it should be referenced here (i.e. the arch wiki troubleshooting), when it makes sense, add a TOC for their content.&lt;br /&gt;
&lt;br /&gt;
=== audience ===&lt;br /&gt;
people running software builds on alpine and have multiple computers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This page will show a specific installation, specific configuration, and specific tests, resulting in a specific set of functionality that can be tested to be working.&lt;br /&gt;
&lt;br /&gt;
== installation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Packages ===&lt;br /&gt;
&lt;br /&gt;
you need, on each host&lt;br /&gt;
* distcc&lt;br /&gt;
* distccd-openrc&lt;br /&gt;
* distcc-pump&lt;br /&gt;
* distcc-pump-pyc&lt;br /&gt;
&lt;br /&gt;
the .pyc will speed up the invocations, without it &lt;br /&gt;
idk if one or both should be installed in that case. but it appears to be also automatically be precompiled in /usr/lib/python3.12/site-packages/include_server/__pycache__/ so what does the package do exactly?&lt;br /&gt;
&lt;br /&gt;
There&#039;s some references to cpython-312, so maybe it actually still uses classy python-c conversion or matbe that&#039;s just a component for reading C source code. I have zero idea.&lt;br /&gt;
&lt;br /&gt;
you also need stuff to do compiles&lt;br /&gt;
* alpine sdk&lt;br /&gt;
* clang&lt;br /&gt;
* binutils&lt;br /&gt;
...&lt;br /&gt;
* elfutils(-dev)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Settings ===&lt;br /&gt;
==== settings for distcc ====&lt;br /&gt;
&lt;br /&gt;
* there&#039;s /etc/default/distcc&lt;br /&gt;
* there&#039;s /etc/conf.d/distcc &lt;br /&gt;
&lt;br /&gt;
make all your settings here&lt;br /&gt;
take care with the listen address, if you specify an IP it&#039;ll not be on 127.0.0.1 in case you would have localhost in your list...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* command_whitelist.sh &lt;br /&gt;
&lt;br /&gt;
this is half functional, you need to set things here but you also need to maintain the symlinks that are collected under /usr/lib/distcc (for your compilers) and /usr/lib/distcc/bin (for itself)&lt;br /&gt;
&lt;br /&gt;
you MUST run the script to update the compilers!&lt;br /&gt;
Info for script and what files it will create&lt;br /&gt;
&lt;br /&gt;
/usr/sbin/update-distcc-symlinks&lt;br /&gt;
&lt;br /&gt;
tschike:/usr/bin# ls -l /usr/lib/distcc/&lt;br /&gt;
total 4&lt;br /&gt;
drwxr-xr-x 2 root root 4096 Mar  2 18:14 bin&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c89 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c99 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 cc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc-15.2.0 -&amp;gt; ../../bin/distcc&lt;br /&gt;
&lt;br /&gt;
distcc itself is in bin&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cpp -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 g++ -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 06:49 x86_64-alpine-linux-musl-gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
&lt;br /&gt;
the last symplink here is wrong, made by me and would not work...&lt;br /&gt;
BAD symlink.&lt;br /&gt;
&lt;br /&gt;
=== distcc hosts file ===&lt;br /&gt;
&lt;br /&gt;
idk about that thing it&#039;s odd&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== abuild.conf ===&lt;br /&gt;
&lt;br /&gt;
settings for aports&lt;br /&gt;
* cc=&lt;br /&gt;
* cxx=&lt;br /&gt;
* cpp=&lt;br /&gt;
* cflags=&lt;br /&gt;
* njobs&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== untested build container system ===&lt;br /&gt;
&lt;br /&gt;
See this one https://github.com/bensuperpc/docker-distcc&lt;br /&gt;
not yet tested, but this could be a good basis for a &#039;best practice&#039; container.&lt;br /&gt;
There&#039;s others, especially for crossbuilds, but those are also very complex to modify.&lt;br /&gt;
&lt;br /&gt;
== detail infos ==&lt;br /&gt;
&lt;br /&gt;
???&lt;br /&gt;
&lt;br /&gt;
=== hosts syntax ===&lt;br /&gt;
&lt;br /&gt;
* myhost otherhost&lt;br /&gt;
* myhost,cpp,lzo myotherhost,cpp,lzo&lt;br /&gt;
&lt;br /&gt;
==== the host ====&lt;br /&gt;
&lt;br /&gt;
hostname/ip&lt;br /&gt;
localhost&lt;br /&gt;
127.0.0.1&lt;br /&gt;
::1 - does not work&lt;br /&gt;
&lt;br /&gt;
==== protocol ====&lt;br /&gt;
&lt;br /&gt;
* no protocol given&lt;br /&gt;
* ,cpp,lzo protocol&lt;br /&gt;
&lt;br /&gt;
cpp implies lzo, it requires compression, even if you have 10gbit/s or more, it&#039;s just hardcoded&lt;br /&gt;
&lt;br /&gt;
=== threads ===&lt;br /&gt;
/number of workers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== architecture ==&lt;br /&gt;
it can handle C, C++, ObjC, maybe some other stuff&lt;br /&gt;
&lt;br /&gt;
* what happens with normal xmit&lt;br /&gt;
* what happens with pump mode&lt;br /&gt;
* at which step the include server is used and how it collects the includes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== distribution algorithm ===&lt;br /&gt;
honestly I simply don&#039;t get it&lt;br /&gt;
&lt;br /&gt;
* The order matters&lt;br /&gt;
* The number of threads matters&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== localhost ====&lt;br /&gt;
&lt;br /&gt;
* localhost precedence&lt;br /&gt;
* localhost fallback&lt;br /&gt;
&lt;br /&gt;
variable: DISTCC_FALLBACK&lt;br /&gt;
&lt;br /&gt;
0 = Fail to compile if it would need to fallback to a normal local gcc call&lt;br /&gt;
1 = If remote compile fails, just do it yourself&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Operation ==&lt;br /&gt;
&lt;br /&gt;
=== startup and shutdown ===&lt;br /&gt;
service distcc stop is not entirely reliable (it can take a minute after the stop until the processes are gone and sometimes it will never stop&lt;br /&gt;
this is very bad with openrc, the openrc script returns after a second and only relies on its service flags, not the process status.&lt;br /&gt;
manually check after stopping, wait a min, if needed, kill it all.&lt;br /&gt;
at some point the rc file needs to be rewritten, it can&#039;t stay like it is.&lt;br /&gt;
&lt;br /&gt;
if you used a pump mode session, that also needs a logout (pump --shutdown)&lt;br /&gt;
avoid running multiple startups without shutdown in one session. it&#039;s safe as far as I can tell but nothing cleans up these processes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== ccache and memcached ===&lt;br /&gt;
CCACHE is said to be conflicting with pump mode unless when you call them in the backend&lt;br /&gt;
so, where you start the compile, you don&#039;t use it&lt;br /&gt;
where the compile happens, you use it&lt;br /&gt;
they can share the cache via memcached, this is a nice trick for consistency&lt;br /&gt;
Upon looking at the ccache website, it seems the correct mechanism is not memcached but Redis. This would work just as well. Generally a cache shared in this way would be optimal for performance.&lt;br /&gt;
&lt;br /&gt;
=== dockerized / native ===&lt;br /&gt;
&lt;br /&gt;
it remains mostly the same, a container needs to make sure it monitors the right services (distccd, nginx, include_server)&lt;br /&gt;
if you&#039;re using zeroconf, you need to somehow expose the mdns service broadcasts &amp;amp; reception&lt;br /&gt;
&lt;br /&gt;
Processs list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
Workdir list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
=== alpine-chroot ===&lt;br /&gt;
&lt;br /&gt;
when using the &#039;official&#039; script there&#039;s still some odd pieces, seemed to be the processes died on logout. but not all of them.&lt;br /&gt;
&lt;br /&gt;
==== manual launch ====&lt;br /&gt;
&lt;br /&gt;
Starting the daemon would be using&lt;br /&gt;
/usr/bin/distccd --pid-file /var/run/distccd/distccd.pid -N 15 --user distcc --port 3632 --log-level=debug --log-file=/var/log/distccd.log --allow my-sub-net/24&lt;br /&gt;
&lt;br /&gt;
==== localhost? =====&lt;br /&gt;
unclear if you need to use --allow for 127.0.0.1/32 or something to allow the remote preproccesor.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Gitlab integration ===&lt;br /&gt;
&lt;br /&gt;
TBA&lt;br /&gt;
&lt;br /&gt;
== Kernel specific settings ==&lt;br /&gt;
&lt;br /&gt;
currently (distcc 3.4-r9 on Alpine) you need a patch to build the kernel.&lt;br /&gt;
See &lt;br /&gt;
&lt;br /&gt;
=== Include server Settings ===&lt;br /&gt;
&lt;br /&gt;
cache reset triggers&lt;br /&gt;
This ought to be set before enabling pump mode.&lt;br /&gt;
&lt;br /&gt;
export INCLUDE_SERVER_ARGS=&amp;quot;--stat_reset_triggers=include/linux/compile.h:include/asm/asm-offsets.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
link to explanation TBA&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Disabling GCC Plugins ===&lt;br /&gt;
&lt;br /&gt;
KConfig unselect HAVE_GCC_PLUGINS&lt;br /&gt;
&lt;br /&gt;
Some info is here in the troubleshooting part of the Arch Wiki&lt;br /&gt;
https://wiki.archlinux.org/title/Distcc#Troubleshooting&lt;br /&gt;
&lt;br /&gt;
=== Patches ===&lt;br /&gt;
&lt;br /&gt;
Other things (for 6.6LTS)&lt;br /&gt;
PCIe Stub patch&lt;br /&gt;
&lt;br /&gt;
=== Autoconf === &lt;br /&gt;
&lt;br /&gt;
No known setup examples&lt;br /&gt;
Add whatever it publishes in mdns&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== troubleshooting / analysis ==&lt;br /&gt;
&lt;br /&gt;
=== testing ===&lt;br /&gt;
&lt;br /&gt;
# turn off fallback DISTCC_FALLBACK=1&lt;br /&gt;
# set distcc up to point at specific system under test DISTCC_HOSTS=&amp;quot;mytestbox,cpp,lzo&amp;quot;&lt;br /&gt;
# GCC example compiles&lt;br /&gt;
## code example C&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example C++&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example ObjC&lt;br /&gt;
## same with included header&lt;br /&gt;
# Cmake example compiles&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docoument the thing with compile launcher ccache;distcc&lt;br /&gt;
there&#039;s some blog post, point to that&lt;br /&gt;
no ccache here yet&lt;br /&gt;
show $CC differences distcc vs gcc, what configure scripts see&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Latency ===&lt;br /&gt;
&lt;br /&gt;
Latency of pump mode startups and fallbacks needs to be investigated.&lt;br /&gt;
LZO is enforced even if you have faster network&lt;br /&gt;
DNS Requests, very old bug report from Gcode, one request per call, is it true? how to get rid of it?&lt;br /&gt;
TMPDIR is respected, make sure it&#039;s on ramdisk even on the remote nodes.&lt;br /&gt;
Compile ideally never goes to disk when it doesn&#039;t have to.&lt;br /&gt;
How efficient is the include server collection and unpacking?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== failed to distribute, running locally instead ===&lt;br /&gt;
&lt;br /&gt;
the curse of the ancient, wise bulgarian witch compildora nottherea has befallen people all over the world. only strict and mindless adherence to rituals passed down from generation to generation has given hope to those who are under her ages old spell. again and again it reemerges to prey on idealistic young men and women who spend so much time at their unholy computers that they try to spend less time there by spending a lot of time trying to optimize what the computer does, slowly, instead of reflecting on why they are there, while the computer is busy working, and why they try to solve this by adding a component that makes the computer be more error-prone at that same work, increasing the need of their presense at this idolized thinking machine to oversee and often repair, or worse, mindlessly restart its doing.&lt;br /&gt;
if the curse is not lifted, despair may befall them and all they see is the need to investigate and ruminate further on the workings of this tool, ignoring thereby the obivous flaws that stem from of its alchemic origins.&lt;br /&gt;
&lt;br /&gt;
just wait till you find out it has a backoff alghoritm deciding whether to call out to a remote server independent of that server functioning. graceful performance degradation is the goal, and degrading it is while we try to figure this out.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Node Selection algorithm ====&lt;br /&gt;
&lt;br /&gt;
as per my understanding, a flowchart goes here:&lt;br /&gt;
&lt;br /&gt;
# compile task&lt;br /&gt;
# evaluate whether to run locally by job nature&lt;br /&gt;
# determine if local host&#039;s load is notable&lt;br /&gt;
# look at distcc hosts list&lt;br /&gt;
# do something based off localhost entry if first&lt;br /&gt;
# filter for nodes with cpp flag&lt;br /&gt;
# do something based off localhost entry if not first&lt;br /&gt;
# further prioritize by server order, first is handled in some way&lt;br /&gt;
# skip nodes in backoff prisons&lt;br /&gt;
# balance and priotize by server thread number, if given&lt;br /&gt;
# send to suitable host&lt;br /&gt;
# if compile not successful, proceed on other node&lt;br /&gt;
# if nodes depleted, proceed on localhost&lt;br /&gt;
&lt;br /&gt;
== security ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== tcpwrapper style ip range filter ===&lt;br /&gt;
&lt;br /&gt;
the original security model consists of ip restrictions.&lt;br /&gt;
there seems to also be some GSSAPI user auth.&lt;br /&gt;
further, commands that can be called are restricted by name and location.&lt;br /&gt;
this appears to be a runtime whitelist lookup, meaning it&#039;s done and authorized by the same parts of the daemon as processes the compile request along with the intended compiler.&lt;br /&gt;
so the main weaknesses against malicious clients seem to be in sending things to compile, and in overriding the remote compiler to use.&lt;br /&gt;
it can be assumed that a malicious client able to exploit the compiler handshake can then run arbitrary stuff.&lt;br /&gt;
There&#039;s at least a github issue regarding this (link lost, but see here: https://gitlab.com/postmarketOS/pmbootstrap/-/work_items/1619) suggesting running over ssh. That does only partitally alleviate this risk with regard  to a key based verfication of a client versus a the standard ip restrictions which always include some parsing.&lt;br /&gt;
So this protects against someone directly exploiting the TCP code of distcc.&lt;br /&gt;
It does not protect against malicious clients.&lt;br /&gt;
(ssh force command can&#039;t be used or you&#039;ll not compile anything)&lt;br /&gt;
&lt;br /&gt;
The basic step for protecting access should be filtering who can access the distcc server, so use nftables etc. to restrict access to port 3262 (??) set up the internal filter the same way.&lt;br /&gt;
&lt;br /&gt;
=== seccomp ===&lt;br /&gt;
&lt;br /&gt;
The next thing is to confine the compiler calls to only write in their temp directory and that they can only run compilers (using nsjail, apparmor, selinux etc)&lt;br /&gt;
&lt;br /&gt;
the above issue also references the second bit of security, namely a seccomp filter which will already cover a good bit of the above&lt;br /&gt;
https://github.com/distcc/distcc/pull/235&lt;br /&gt;
the commit got closed without merge, from what I see.&lt;br /&gt;
&lt;br /&gt;
I will update the entry once it&#039;s clear if the patch was later added or instead nothing was done.&lt;br /&gt;
&lt;br /&gt;
=== privs ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The other internal security bit is that they do some priviledge dropping. it runs as a dedicated user (distcc), so you can also have an audit policy, and can/could use something like iptables&#039; to ensure it can only connect to the other distcc/memcached hosts, but nothing else.&lt;br /&gt;
&lt;br /&gt;
=== compiler list ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
One needs to investigate when compiler_whitelist.sh is exactly called. as far as I recall it doesn&#039;t close stdin/stdout.&lt;br /&gt;
&lt;br /&gt;
=== distcc-hardened ===&lt;br /&gt;
&lt;br /&gt;
Alpine adds some hardening patch, idk what nature/origina that has.&lt;br /&gt;
&lt;br /&gt;
=== selinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
there&#039;s also a selinux policy for distcc from gentoo or liguros if one is so inclined.&lt;br /&gt;
https://repology.org/project/selinux-distcc/versions&lt;br /&gt;
&lt;br /&gt;
=== general posture ===&lt;br /&gt;
&lt;br /&gt;
Some security measures like the above should definitely be used since the project at its core relies on accepting foreign input over the network, has only a few part-time maintainers that cannot easily drive the project forward or do large refactors.&lt;br /&gt;
But the seccomp changes were done almost 10 years ago, so, if they were actually upstreamed, I&#039;d say they came through.&lt;br /&gt;
&lt;br /&gt;
A kind of overengineered solulion would be to use netlabel to ensure application integrity across hosts, meaning only a valid process would be able to send packets to the distcc nodes :-)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Alternatives ==&lt;br /&gt;
&lt;br /&gt;
Arch wiki refers to a fork by SUSE&lt;br /&gt;
https://github.com/icecc/icecream&lt;br /&gt;
&lt;br /&gt;
It appears &#039;maybe better&#039; but hard to tell. There&#039;s no mention if maybe SUSE&#039;s OBS uses it or something. Without more knowledge of their use I don&#039;t know how big a benefit will come from switching. At least you&#039;d wanna know they have a higher commitment to maintenance than the understaffed distcc &#039;team&#039; of current.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A commercial alternative (incredibuild https://www.incredibuild.com/) exists, but I have not tried it.&lt;br /&gt;
THey advertise some &#039;forever free&#039; tier; generally if there&#039;s high (business) pressure for faster builds I would check that out.&lt;br /&gt;
&lt;br /&gt;
Architecturally it seems to be taking the ccache approach with a shared cache and smarter redistribution.&lt;br /&gt;
So anything that can call ccache is something they can scale out. I&#039;ll add a link later, for those whom it helps.&lt;br /&gt;
Naturally it is out of scope for this article.&lt;br /&gt;
Nonetheless it&#039;s interesting since the ordering of how to run ccache and how to run distcc is an issue that also exists in the OSS world. Not just that we don&#039;t have an automatic setup and integration of the tools (ccache, redis, distccd, distcc-pump) but we also don&#039;t have collected sufficient data to aid in deciding which aproach is the best.&lt;br /&gt;
Integrating into CIs (gitlab-runner specifically) is another item where cache persistence becomes very fragile.&lt;br /&gt;
Having an alpine build container that knows how to use ccache with redis and distcc-pump would be a possible step forward.&lt;br /&gt;
&lt;br /&gt;
== Other sources ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://retroflux.net/blog/distcc-adventures/&lt;/div&gt;</summary>
		<author><name>Darkfader</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32199</id>
		<title>User:Darkfader/distcc</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32199"/>
		<updated>2026-03-28T16:31:00Z</updated>

		<summary type="html">&lt;p&gt;Darkfader: /* Alternatives */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi,&lt;br /&gt;
&lt;br /&gt;
I&#039;m preparing this page. It can take a long time till I finish.&lt;br /&gt;
If you are also wishing to write on this topic, feel free to integrate the content.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Document overview ==&lt;br /&gt;
&lt;br /&gt;
I noticed that almost every distro has one partially complete, partially helpful document on how to use distcc on the distro.&lt;br /&gt;
Usually they also have one for ccache.&lt;br /&gt;
In either case, they&#039;re enough to get started, but not really a reliable watertight thing.&lt;br /&gt;
We definitely needed one of our own.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== goal ===&lt;br /&gt;
&lt;br /&gt;
to describe a working setup for building aports in easiest/fastests fashion&lt;br /&gt;
not planning to add versatility or features where it would make the setup more errorprone.&lt;br /&gt;
the page should describe enough of the steps to successfully compile an LTS kernel via aports and have that job be distributed over multiple nodes.&lt;br /&gt;
Logs should be set up and able to display errors, but not show any errors during the test compile.&lt;br /&gt;
&lt;br /&gt;
To include a path for analysis via testing components.&lt;br /&gt;
&lt;br /&gt;
distcc can greatly improve compile speeds for large software, it comes with a different set of features than ccache; it focusses not avoiding unneccessary compile work, but on a way to speed up the necessary one.&lt;br /&gt;
&lt;br /&gt;
There&#039;s valuable info in the docs of other distros, it should be referenced here (i.e. the arch wiki troubleshooting), when it makes sense, add a TOC for their content.&lt;br /&gt;
&lt;br /&gt;
=== audience ===&lt;br /&gt;
people running software builds on alpine and have multiple computers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This page will show a specific installation, specific configuration, and specific tests, resulting in a specific set of functionality that can be tested to be working.&lt;br /&gt;
&lt;br /&gt;
== installation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Packages ===&lt;br /&gt;
&lt;br /&gt;
you need, on each host&lt;br /&gt;
* distcc&lt;br /&gt;
* distccd-openrc&lt;br /&gt;
* distcc-pump&lt;br /&gt;
* distcc-pump-pyc&lt;br /&gt;
&lt;br /&gt;
the .pyc will speed up the invocations, without it &lt;br /&gt;
idk if one or both should be installed in that case. but it appears to be also automatically be precompiled in /usr/lib/python3.12/site-packages/include_server/__pycache__/ so what does the package do exactly?&lt;br /&gt;
&lt;br /&gt;
There&#039;s some references to cpython-312, so maybe it actually still uses classy python-c conversion or matbe that&#039;s just a component for reading C source code. I have zero idea.&lt;br /&gt;
&lt;br /&gt;
you also need stuff to do compiles&lt;br /&gt;
* alpine sdk&lt;br /&gt;
* clang&lt;br /&gt;
* binutils&lt;br /&gt;
...&lt;br /&gt;
* elfutils(-dev)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Settings ===&lt;br /&gt;
==== settings for distcc ====&lt;br /&gt;
&lt;br /&gt;
* there&#039;s /etc/default/distcc&lt;br /&gt;
* there&#039;s /etc/conf.d/distcc &lt;br /&gt;
&lt;br /&gt;
make all your settings here&lt;br /&gt;
take care with the listen address, if you specify an IP it&#039;ll not be on 127.0.0.1 in case you would have localhost in your list...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* command_whitelist.sh &lt;br /&gt;
&lt;br /&gt;
this is half functional, you need to set things here but you also need to maintain the symlinks that are collected under /usr/lib/distcc (for your compilers) and /usr/lib/distcc/bin (for itself)&lt;br /&gt;
&lt;br /&gt;
you MUST run the script to update the compilers!&lt;br /&gt;
Info for script and what files it will create&lt;br /&gt;
&lt;br /&gt;
/usr/sbin/update-distcc-symlinks&lt;br /&gt;
&lt;br /&gt;
tschike:/usr/bin# ls -l /usr/lib/distcc/&lt;br /&gt;
total 4&lt;br /&gt;
drwxr-xr-x 2 root root 4096 Mar  2 18:14 bin&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c89 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c99 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 cc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc-15.2.0 -&amp;gt; ../../bin/distcc&lt;br /&gt;
&lt;br /&gt;
distcc itself is in bin&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cpp -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 g++ -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 06:49 x86_64-alpine-linux-musl-gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
&lt;br /&gt;
the last symplink here is wrong, made by me and would not work...&lt;br /&gt;
BAD symlink.&lt;br /&gt;
&lt;br /&gt;
=== distcc hosts file ===&lt;br /&gt;
&lt;br /&gt;
idk about that thing it&#039;s odd&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== abuild.conf ===&lt;br /&gt;
&lt;br /&gt;
settings for aports&lt;br /&gt;
* cc=&lt;br /&gt;
* cxx=&lt;br /&gt;
* cpp=&lt;br /&gt;
* cflags=&lt;br /&gt;
* njobs&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== untested build container system ===&lt;br /&gt;
&lt;br /&gt;
See this one https://github.com/bensuperpc/docker-distcc&lt;br /&gt;
not yet tested, but this could be a good basis for a &#039;best practice&#039; container.&lt;br /&gt;
There&#039;s others, especially for crossbuilds, but those are also very complex to modify.&lt;br /&gt;
&lt;br /&gt;
== detail infos ==&lt;br /&gt;
&lt;br /&gt;
???&lt;br /&gt;
&lt;br /&gt;
=== hosts syntax ===&lt;br /&gt;
&lt;br /&gt;
* myhost otherhost&lt;br /&gt;
* myhost,cpp,lzo myotherhost,cpp,lzo&lt;br /&gt;
&lt;br /&gt;
==== the host ====&lt;br /&gt;
&lt;br /&gt;
hostname/ip&lt;br /&gt;
localhost&lt;br /&gt;
127.0.0.1&lt;br /&gt;
::1 - does not work&lt;br /&gt;
&lt;br /&gt;
==== protocol ====&lt;br /&gt;
&lt;br /&gt;
* no protocol given&lt;br /&gt;
* ,cpp,lzo protocol&lt;br /&gt;
&lt;br /&gt;
cpp implies lzo, it requires compression, even if you have 10gbit/s or more, it&#039;s just hardcoded&lt;br /&gt;
&lt;br /&gt;
=== threads ===&lt;br /&gt;
/number of workers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== architecture ==&lt;br /&gt;
it can handle C, C++, ObjC, maybe some other stuff&lt;br /&gt;
&lt;br /&gt;
* what happens with normal xmit&lt;br /&gt;
* what happens with pump mode&lt;br /&gt;
* at which step the include server is used and how it collects the includes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== distribution algorithm ===&lt;br /&gt;
honestly I simply don&#039;t get it&lt;br /&gt;
&lt;br /&gt;
* The order matters&lt;br /&gt;
* The number of threads matters&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== localhost ====&lt;br /&gt;
&lt;br /&gt;
* localhost precedence&lt;br /&gt;
* localhost fallback&lt;br /&gt;
&lt;br /&gt;
variable: DISTCC_FALLBACK&lt;br /&gt;
&lt;br /&gt;
0 = Fail to compile if it would need to fallback to a normal local gcc call&lt;br /&gt;
1 = If remote compile fails, just do it yourself&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Operation ==&lt;br /&gt;
&lt;br /&gt;
=== startup and shutdown ===&lt;br /&gt;
service distcc stop is not entirely reliable (it can take a minute after the stop until the processes are gone and sometimes it will never stop&lt;br /&gt;
this is very bad with openrc, the openrc script returns after a second and only relies on its service flags, not the process status.&lt;br /&gt;
manually check after stopping, wait a min, if needed, kill it all.&lt;br /&gt;
at some point the rc file needs to be rewritten, it can&#039;t stay like it is.&lt;br /&gt;
&lt;br /&gt;
if you used a pump mode session, that also needs a logout (pump --shutdown)&lt;br /&gt;
avoid running multiple startups without shutdown in one session. it&#039;s safe as far as I can tell but nothing cleans up these processes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== ccache and memcached ===&lt;br /&gt;
CCACHE is said to be conflicting with pump mode unless when you call them in the backend&lt;br /&gt;
so, where you start the compile, you don&#039;t use it&lt;br /&gt;
where the compile happens, you use it&lt;br /&gt;
they can share the cache via memcached, this is a nice trick for consistency&lt;br /&gt;
Upon looking at the ccache website, it seems the correct mechanism is not memcached but Redis. This would work just as well. Generally a cache shared in this way would be optimal for performance.&lt;br /&gt;
&lt;br /&gt;
=== dockerized / native ===&lt;br /&gt;
&lt;br /&gt;
it remains mostly the same, a container needs to make sure it monitors the right services (distccd, nginx, include_server)&lt;br /&gt;
if you&#039;re using zeroconf, you need to somehow expose the mdns service broadcasts &amp;amp; reception&lt;br /&gt;
&lt;br /&gt;
Processs list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
Workdir list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
=== alpine-chroot ===&lt;br /&gt;
&lt;br /&gt;
when using the &#039;official&#039; script there&#039;s still some odd pieces, seemed to be the processes died on logout. but not all of them.&lt;br /&gt;
&lt;br /&gt;
==== manual launch ====&lt;br /&gt;
&lt;br /&gt;
Starting the daemon would be using&lt;br /&gt;
/usr/bin/distccd --pid-file /var/run/distccd/distccd.pid -N 15 --user distcc --port 3632 --log-level=debug --log-file=/var/log/distccd.log --allow my-sub-net/24&lt;br /&gt;
&lt;br /&gt;
==== localhost? =====&lt;br /&gt;
unclear if you need to use --allow for 127.0.0.1/32 or something to allow the remote preproccesor.&lt;br /&gt;
&lt;br /&gt;
== Kernel specific settings ==&lt;br /&gt;
&lt;br /&gt;
currently (distcc 3.4-r9 on Alpine) you need a patch to build the kernel.&lt;br /&gt;
See &lt;br /&gt;
&lt;br /&gt;
=== Include server Settings ===&lt;br /&gt;
&lt;br /&gt;
cache reset triggers&lt;br /&gt;
This ought to be set before enabling pump mode.&lt;br /&gt;
&lt;br /&gt;
export INCLUDE_SERVER_ARGS=&amp;quot;--stat_reset_triggers=include/linux/compile.h:include/asm/asm-offsets.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
link to explanation TBA&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Disabling GCC Plugins ===&lt;br /&gt;
&lt;br /&gt;
KConfig unselect HAVE_GCC_PLUGINS&lt;br /&gt;
&lt;br /&gt;
Some info is here in the troubleshooting part of the Arch Wiki&lt;br /&gt;
https://wiki.archlinux.org/title/Distcc#Troubleshooting&lt;br /&gt;
&lt;br /&gt;
=== Patches ===&lt;br /&gt;
&lt;br /&gt;
Other things (for 6.6LTS)&lt;br /&gt;
PCIe Stub patch&lt;br /&gt;
&lt;br /&gt;
=== Autoconf === &lt;br /&gt;
&lt;br /&gt;
No known setup examples&lt;br /&gt;
Add whatever it publishes in mdns&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== troubleshooting / analysis ==&lt;br /&gt;
&lt;br /&gt;
=== testing ===&lt;br /&gt;
&lt;br /&gt;
# turn off fallback DISTCC_FALLBACK=1&lt;br /&gt;
# set distcc up to point at specific system under test DISTCC_HOSTS=&amp;quot;mytestbox,cpp,lzo&amp;quot;&lt;br /&gt;
# GCC example compiles&lt;br /&gt;
## code example C&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example C++&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example ObjC&lt;br /&gt;
## same with included header&lt;br /&gt;
# Cmake example compiles&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docoument the thing with compile launcher ccache;distcc&lt;br /&gt;
there&#039;s some blog post, point to that&lt;br /&gt;
no ccache here yet&lt;br /&gt;
show $CC differences distcc vs gcc, what configure scripts see&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Latency ===&lt;br /&gt;
&lt;br /&gt;
Latency of pump mode startups and fallbacks needs to be investigated.&lt;br /&gt;
LZO is enforced even if you have faster network&lt;br /&gt;
DNS Requests, very old bug report from Gcode, one request per call, is it true? how to get rid of it?&lt;br /&gt;
TMPDIR is respected, make sure it&#039;s on ramdisk even on the remote nodes.&lt;br /&gt;
Compile ideally never goes to disk when it doesn&#039;t have to.&lt;br /&gt;
How efficient is the include server collection and unpacking?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== failed to distribute, running locally instead ===&lt;br /&gt;
&lt;br /&gt;
the curse of the ancient, wise bulgarian witch compildora nottherea has befallen people all over the world. only strict and mindless adherence to rituals passed down from generation to generation has given hope to those who are under her ages old spell. again and again it reemerges to prey on idealistic young men and women who spend so much time at their unholy computers that they try to spend less time there by spending a lot of time trying to optimize what the computer does, slowly, instead of reflecting on why they are there, while the computer is busy working, and why they try to solve this by adding a component that makes the computer be more error-prone at that same work, increasing the need of their presense at this idolized thinking machine to oversee and often repair, or worse, mindlessly restart its doing.&lt;br /&gt;
if the curse is not lifted, despair may befall them and all they see is the need to investigate and ruminate further on the workings of this tool, ignoring thereby the obivous flaws that stem from of its alchemic origins.&lt;br /&gt;
&lt;br /&gt;
just wait till you find out it has a backoff alghoritm deciding whether to call out to a remote server independent of that server functioning. graceful performance degradation is the goal, and degrading it is while we try to figure this out.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Node Selection algorithm ====&lt;br /&gt;
&lt;br /&gt;
as per my understanding, a flowchart goes here:&lt;br /&gt;
&lt;br /&gt;
# compile task&lt;br /&gt;
# evaluate whether to run locally by job nature&lt;br /&gt;
# determine if local host&#039;s load is notable&lt;br /&gt;
# look at distcc hosts list&lt;br /&gt;
# do something based off localhost entry if first&lt;br /&gt;
# filter for nodes with cpp flag&lt;br /&gt;
# do something based off localhost entry if not first&lt;br /&gt;
# further prioritize by server order, first is handled in some way&lt;br /&gt;
# skip nodes in backoff prisons&lt;br /&gt;
# balance and priotize by server thread number, if given&lt;br /&gt;
# send to suitable host&lt;br /&gt;
# if compile not successful, proceed on other node&lt;br /&gt;
# if nodes depleted, proceed on localhost&lt;br /&gt;
&lt;br /&gt;
== security ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== tcpwrapper style ip range filter ===&lt;br /&gt;
&lt;br /&gt;
the original security model consists of ip restrictions.&lt;br /&gt;
there seems to also be some GSSAPI user auth.&lt;br /&gt;
further, commands that can be called are restricted by name and location.&lt;br /&gt;
this appears to be a runtime whitelist lookup, meaning it&#039;s done and authorized by the same parts of the daemon as processes the compile request along with the intended compiler.&lt;br /&gt;
so the main weaknesses against malicious clients seem to be in sending things to compile, and in overriding the remote compiler to use.&lt;br /&gt;
it can be assumed that a malicious client able to exploit the compiler handshake can then run arbitrary stuff.&lt;br /&gt;
There&#039;s at least a github issue regarding this (link lost, but see here: https://gitlab.com/postmarketOS/pmbootstrap/-/work_items/1619) suggesting running over ssh. That does only partitally alleviate this risk with regard  to a key based verfication of a client versus a the standard ip restrictions which always include some parsing.&lt;br /&gt;
So this protects against someone directly exploiting the TCP code of distcc.&lt;br /&gt;
It does not protect against malicious clients.&lt;br /&gt;
(ssh force command can&#039;t be used or you&#039;ll not compile anything)&lt;br /&gt;
&lt;br /&gt;
The basic step for protecting access should be filtering who can access the distcc server, so use nftables etc. to restrict access to port 3262 (??) set up the internal filter the same way.&lt;br /&gt;
&lt;br /&gt;
=== seccomp ===&lt;br /&gt;
&lt;br /&gt;
The next thing is to confine the compiler calls to only write in their temp directory and that they can only run compilers (using nsjail, apparmor, selinux etc)&lt;br /&gt;
&lt;br /&gt;
the above issue also references the second bit of security, namely a seccomp filter which will already cover a good bit of the above&lt;br /&gt;
https://github.com/distcc/distcc/pull/235&lt;br /&gt;
the commit got closed without merge, from what I see.&lt;br /&gt;
&lt;br /&gt;
I will update the entry once it&#039;s clear if the patch was later added or instead nothing was done.&lt;br /&gt;
&lt;br /&gt;
=== privs ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The other internal security bit is that they do some priviledge dropping. it runs as a dedicated user (distcc), so you can also have an audit policy, and can/could use something like iptables&#039; to ensure it can only connect to the other distcc/memcached hosts, but nothing else.&lt;br /&gt;
&lt;br /&gt;
=== compiler list ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
One needs to investigate when compiler_whitelist.sh is exactly called. as far as I recall it doesn&#039;t close stdin/stdout.&lt;br /&gt;
&lt;br /&gt;
=== distcc-hardened ===&lt;br /&gt;
&lt;br /&gt;
Alpine adds some hardening patch, idk what nature/origina that has.&lt;br /&gt;
&lt;br /&gt;
=== selinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
there&#039;s also a selinux policy for distcc from gentoo or liguros if one is so inclined.&lt;br /&gt;
https://repology.org/project/selinux-distcc/versions&lt;br /&gt;
&lt;br /&gt;
=== general posture ===&lt;br /&gt;
&lt;br /&gt;
Some security measures like the above should definitely be used since the project at its core relies on accepting foreign input over the network, has only a few part-time maintainers that cannot easily drive the project forward or do large refactors.&lt;br /&gt;
But the seccomp changes were done almost 10 years ago, so, if they were actually upstreamed, I&#039;d say they came through.&lt;br /&gt;
&lt;br /&gt;
A kind of overengineered solulion would be to use netlabel to ensure application integrity across hosts, meaning only a valid process would be able to send packets to the distcc nodes :-)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Alternatives ==&lt;br /&gt;
&lt;br /&gt;
Arch wiki refers to a fork by SUSE&lt;br /&gt;
https://github.com/icecc/icecream&lt;br /&gt;
&lt;br /&gt;
It appears &#039;maybe better&#039; but hard to tell. There&#039;s no mention if maybe SUSE&#039;s OBS uses it or something. Without more knowledge of their use I don&#039;t know how big a benefit will come from switching. At least you&#039;d wanna know they have a higher commitment to maintenance than the understaffed distcc &#039;team&#039; of current.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A commercial alternative (incredibuild https://www.incredibuild.com/) exists, but I have not tried it.&lt;br /&gt;
THey advertise some &#039;forever free&#039; tier; generally if there&#039;s high (business) pressure for faster builds I would check that out.&lt;br /&gt;
&lt;br /&gt;
Architecturally it seems to be taking the ccache approach with a shared cache and smarter redistribution.&lt;br /&gt;
So anything that can call ccache is something they can scale out. I&#039;ll add a link later, for those whom it helps.&lt;br /&gt;
Naturally it is out of scope for this article.&lt;br /&gt;
Nonetheless it&#039;s interesting since the ordering of how to run ccache and how to run distcc is an issue that also exists in the OSS world. Not just that we don&#039;t have an automatic setup and integration of the tools (ccache, redis, distccd, distcc-pump) but we also don&#039;t have collected sufficient data to aid in deciding which aproach is the best.&lt;br /&gt;
Integrating into CIs (gitlab-runner specifically) is another item where cache persistence becomes very fragile.&lt;br /&gt;
Having an alpine build container that knows how to use ccache with redis and distcc-pump would be a possible step forward.&lt;br /&gt;
&lt;br /&gt;
== Other sources ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://retroflux.net/blog/distcc-adventures/&lt;/div&gt;</summary>
		<author><name>Darkfader</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32198</id>
		<title>User:Darkfader/distcc</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32198"/>
		<updated>2026-03-28T16:30:17Z</updated>

		<summary type="html">&lt;p&gt;Darkfader: /* Alternatives */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi,&lt;br /&gt;
&lt;br /&gt;
I&#039;m preparing this page. It can take a long time till I finish.&lt;br /&gt;
If you are also wishing to write on this topic, feel free to integrate the content.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Document overview ==&lt;br /&gt;
&lt;br /&gt;
I noticed that almost every distro has one partially complete, partially helpful document on how to use distcc on the distro.&lt;br /&gt;
Usually they also have one for ccache.&lt;br /&gt;
In either case, they&#039;re enough to get started, but not really a reliable watertight thing.&lt;br /&gt;
We definitely needed one of our own.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== goal ===&lt;br /&gt;
&lt;br /&gt;
to describe a working setup for building aports in easiest/fastests fashion&lt;br /&gt;
not planning to add versatility or features where it would make the setup more errorprone.&lt;br /&gt;
the page should describe enough of the steps to successfully compile an LTS kernel via aports and have that job be distributed over multiple nodes.&lt;br /&gt;
Logs should be set up and able to display errors, but not show any errors during the test compile.&lt;br /&gt;
&lt;br /&gt;
To include a path for analysis via testing components.&lt;br /&gt;
&lt;br /&gt;
distcc can greatly improve compile speeds for large software, it comes with a different set of features than ccache; it focusses not avoiding unneccessary compile work, but on a way to speed up the necessary one.&lt;br /&gt;
&lt;br /&gt;
There&#039;s valuable info in the docs of other distros, it should be referenced here (i.e. the arch wiki troubleshooting), when it makes sense, add a TOC for their content.&lt;br /&gt;
&lt;br /&gt;
=== audience ===&lt;br /&gt;
people running software builds on alpine and have multiple computers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This page will show a specific installation, specific configuration, and specific tests, resulting in a specific set of functionality that can be tested to be working.&lt;br /&gt;
&lt;br /&gt;
== installation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Packages ===&lt;br /&gt;
&lt;br /&gt;
you need, on each host&lt;br /&gt;
* distcc&lt;br /&gt;
* distccd-openrc&lt;br /&gt;
* distcc-pump&lt;br /&gt;
* distcc-pump-pyc&lt;br /&gt;
&lt;br /&gt;
the .pyc will speed up the invocations, without it &lt;br /&gt;
idk if one or both should be installed in that case. but it appears to be also automatically be precompiled in /usr/lib/python3.12/site-packages/include_server/__pycache__/ so what does the package do exactly?&lt;br /&gt;
&lt;br /&gt;
There&#039;s some references to cpython-312, so maybe it actually still uses classy python-c conversion or matbe that&#039;s just a component for reading C source code. I have zero idea.&lt;br /&gt;
&lt;br /&gt;
you also need stuff to do compiles&lt;br /&gt;
* alpine sdk&lt;br /&gt;
* clang&lt;br /&gt;
* binutils&lt;br /&gt;
...&lt;br /&gt;
* elfutils(-dev)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Settings ===&lt;br /&gt;
==== settings for distcc ====&lt;br /&gt;
&lt;br /&gt;
* there&#039;s /etc/default/distcc&lt;br /&gt;
* there&#039;s /etc/conf.d/distcc &lt;br /&gt;
&lt;br /&gt;
make all your settings here&lt;br /&gt;
take care with the listen address, if you specify an IP it&#039;ll not be on 127.0.0.1 in case you would have localhost in your list...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* command_whitelist.sh &lt;br /&gt;
&lt;br /&gt;
this is half functional, you need to set things here but you also need to maintain the symlinks that are collected under /usr/lib/distcc (for your compilers) and /usr/lib/distcc/bin (for itself)&lt;br /&gt;
&lt;br /&gt;
you MUST run the script to update the compilers!&lt;br /&gt;
Info for script and what files it will create&lt;br /&gt;
&lt;br /&gt;
/usr/sbin/update-distcc-symlinks&lt;br /&gt;
&lt;br /&gt;
tschike:/usr/bin# ls -l /usr/lib/distcc/&lt;br /&gt;
total 4&lt;br /&gt;
drwxr-xr-x 2 root root 4096 Mar  2 18:14 bin&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c89 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c99 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 cc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc-15.2.0 -&amp;gt; ../../bin/distcc&lt;br /&gt;
&lt;br /&gt;
distcc itself is in bin&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cpp -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 g++ -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 06:49 x86_64-alpine-linux-musl-gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
&lt;br /&gt;
the last symplink here is wrong, made by me and would not work...&lt;br /&gt;
BAD symlink.&lt;br /&gt;
&lt;br /&gt;
=== distcc hosts file ===&lt;br /&gt;
&lt;br /&gt;
idk about that thing it&#039;s odd&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== abuild.conf ===&lt;br /&gt;
&lt;br /&gt;
settings for aports&lt;br /&gt;
* cc=&lt;br /&gt;
* cxx=&lt;br /&gt;
* cpp=&lt;br /&gt;
* cflags=&lt;br /&gt;
* njobs&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== untested build container system ===&lt;br /&gt;
&lt;br /&gt;
See this one https://github.com/bensuperpc/docker-distcc&lt;br /&gt;
not yet tested, but this could be a good basis for a &#039;best practice&#039; container.&lt;br /&gt;
There&#039;s others, especially for crossbuilds, but those are also very complex to modify.&lt;br /&gt;
&lt;br /&gt;
== detail infos ==&lt;br /&gt;
&lt;br /&gt;
???&lt;br /&gt;
&lt;br /&gt;
=== hosts syntax ===&lt;br /&gt;
&lt;br /&gt;
* myhost otherhost&lt;br /&gt;
* myhost,cpp,lzo myotherhost,cpp,lzo&lt;br /&gt;
&lt;br /&gt;
==== the host ====&lt;br /&gt;
&lt;br /&gt;
hostname/ip&lt;br /&gt;
localhost&lt;br /&gt;
127.0.0.1&lt;br /&gt;
::1 - does not work&lt;br /&gt;
&lt;br /&gt;
==== protocol ====&lt;br /&gt;
&lt;br /&gt;
* no protocol given&lt;br /&gt;
* ,cpp,lzo protocol&lt;br /&gt;
&lt;br /&gt;
cpp implies lzo, it requires compression, even if you have 10gbit/s or more, it&#039;s just hardcoded&lt;br /&gt;
&lt;br /&gt;
=== threads ===&lt;br /&gt;
/number of workers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== architecture ==&lt;br /&gt;
it can handle C, C++, ObjC, maybe some other stuff&lt;br /&gt;
&lt;br /&gt;
* what happens with normal xmit&lt;br /&gt;
* what happens with pump mode&lt;br /&gt;
* at which step the include server is used and how it collects the includes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== distribution algorithm ===&lt;br /&gt;
honestly I simply don&#039;t get it&lt;br /&gt;
&lt;br /&gt;
* The order matters&lt;br /&gt;
* The number of threads matters&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== localhost ====&lt;br /&gt;
&lt;br /&gt;
* localhost precedence&lt;br /&gt;
* localhost fallback&lt;br /&gt;
&lt;br /&gt;
variable: DISTCC_FALLBACK&lt;br /&gt;
&lt;br /&gt;
0 = Fail to compile if it would need to fallback to a normal local gcc call&lt;br /&gt;
1 = If remote compile fails, just do it yourself&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Operation ==&lt;br /&gt;
&lt;br /&gt;
=== startup and shutdown ===&lt;br /&gt;
service distcc stop is not entirely reliable (it can take a minute after the stop until the processes are gone and sometimes it will never stop&lt;br /&gt;
this is very bad with openrc, the openrc script returns after a second and only relies on its service flags, not the process status.&lt;br /&gt;
manually check after stopping, wait a min, if needed, kill it all.&lt;br /&gt;
at some point the rc file needs to be rewritten, it can&#039;t stay like it is.&lt;br /&gt;
&lt;br /&gt;
if you used a pump mode session, that also needs a logout (pump --shutdown)&lt;br /&gt;
avoid running multiple startups without shutdown in one session. it&#039;s safe as far as I can tell but nothing cleans up these processes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== ccache and memcached ===&lt;br /&gt;
CCACHE is said to be conflicting with pump mode unless when you call them in the backend&lt;br /&gt;
so, where you start the compile, you don&#039;t use it&lt;br /&gt;
where the compile happens, you use it&lt;br /&gt;
they can share the cache via memcached, this is a nice trick for consistency&lt;br /&gt;
Upon looking at the ccache website, it seems the correct mechanism is not memcached but Redis. This would work just as well. Generally a cache shared in this way would be optimal for performance.&lt;br /&gt;
&lt;br /&gt;
=== dockerized / native ===&lt;br /&gt;
&lt;br /&gt;
it remains mostly the same, a container needs to make sure it monitors the right services (distccd, nginx, include_server)&lt;br /&gt;
if you&#039;re using zeroconf, you need to somehow expose the mdns service broadcasts &amp;amp; reception&lt;br /&gt;
&lt;br /&gt;
Processs list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
Workdir list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
=== alpine-chroot ===&lt;br /&gt;
&lt;br /&gt;
when using the &#039;official&#039; script there&#039;s still some odd pieces, seemed to be the processes died on logout. but not all of them.&lt;br /&gt;
&lt;br /&gt;
==== manual launch ====&lt;br /&gt;
&lt;br /&gt;
Starting the daemon would be using&lt;br /&gt;
/usr/bin/distccd --pid-file /var/run/distccd/distccd.pid -N 15 --user distcc --port 3632 --log-level=debug --log-file=/var/log/distccd.log --allow my-sub-net/24&lt;br /&gt;
&lt;br /&gt;
==== localhost? =====&lt;br /&gt;
unclear if you need to use --allow for 127.0.0.1/32 or something to allow the remote preproccesor.&lt;br /&gt;
&lt;br /&gt;
== Kernel specific settings ==&lt;br /&gt;
&lt;br /&gt;
currently (distcc 3.4-r9 on Alpine) you need a patch to build the kernel.&lt;br /&gt;
See &lt;br /&gt;
&lt;br /&gt;
=== Include server Settings ===&lt;br /&gt;
&lt;br /&gt;
cache reset triggers&lt;br /&gt;
This ought to be set before enabling pump mode.&lt;br /&gt;
&lt;br /&gt;
export INCLUDE_SERVER_ARGS=&amp;quot;--stat_reset_triggers=include/linux/compile.h:include/asm/asm-offsets.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
link to explanation TBA&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Disabling GCC Plugins ===&lt;br /&gt;
&lt;br /&gt;
KConfig unselect HAVE_GCC_PLUGINS&lt;br /&gt;
&lt;br /&gt;
Some info is here in the troubleshooting part of the Arch Wiki&lt;br /&gt;
https://wiki.archlinux.org/title/Distcc#Troubleshooting&lt;br /&gt;
&lt;br /&gt;
=== Patches ===&lt;br /&gt;
&lt;br /&gt;
Other things (for 6.6LTS)&lt;br /&gt;
PCIe Stub patch&lt;br /&gt;
&lt;br /&gt;
=== Autoconf === &lt;br /&gt;
&lt;br /&gt;
No known setup examples&lt;br /&gt;
Add whatever it publishes in mdns&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== troubleshooting / analysis ==&lt;br /&gt;
&lt;br /&gt;
=== testing ===&lt;br /&gt;
&lt;br /&gt;
# turn off fallback DISTCC_FALLBACK=1&lt;br /&gt;
# set distcc up to point at specific system under test DISTCC_HOSTS=&amp;quot;mytestbox,cpp,lzo&amp;quot;&lt;br /&gt;
# GCC example compiles&lt;br /&gt;
## code example C&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example C++&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example ObjC&lt;br /&gt;
## same with included header&lt;br /&gt;
# Cmake example compiles&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docoument the thing with compile launcher ccache;distcc&lt;br /&gt;
there&#039;s some blog post, point to that&lt;br /&gt;
no ccache here yet&lt;br /&gt;
show $CC differences distcc vs gcc, what configure scripts see&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Latency ===&lt;br /&gt;
&lt;br /&gt;
Latency of pump mode startups and fallbacks needs to be investigated.&lt;br /&gt;
LZO is enforced even if you have faster network&lt;br /&gt;
DNS Requests, very old bug report from Gcode, one request per call, is it true? how to get rid of it?&lt;br /&gt;
TMPDIR is respected, make sure it&#039;s on ramdisk even on the remote nodes.&lt;br /&gt;
Compile ideally never goes to disk when it doesn&#039;t have to.&lt;br /&gt;
How efficient is the include server collection and unpacking?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== failed to distribute, running locally instead ===&lt;br /&gt;
&lt;br /&gt;
the curse of the ancient, wise bulgarian witch compildora nottherea has befallen people all over the world. only strict and mindless adherence to rituals passed down from generation to generation has given hope to those who are under her ages old spell. again and again it reemerges to prey on idealistic young men and women who spend so much time at their unholy computers that they try to spend less time there by spending a lot of time trying to optimize what the computer does, slowly, instead of reflecting on why they are there, while the computer is busy working, and why they try to solve this by adding a component that makes the computer be more error-prone at that same work, increasing the need of their presense at this idolized thinking machine to oversee and often repair, or worse, mindlessly restart its doing.&lt;br /&gt;
if the curse is not lifted, despair may befall them and all they see is the need to investigate and ruminate further on the workings of this tool, ignoring thereby the obivous flaws that stem from of its alchemic origins.&lt;br /&gt;
&lt;br /&gt;
just wait till you find out it has a backoff alghoritm deciding whether to call out to a remote server independent of that server functioning. graceful performance degradation is the goal, and degrading it is while we try to figure this out.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Node Selection algorithm ====&lt;br /&gt;
&lt;br /&gt;
as per my understanding, a flowchart goes here:&lt;br /&gt;
&lt;br /&gt;
# compile task&lt;br /&gt;
# evaluate whether to run locally by job nature&lt;br /&gt;
# determine if local host&#039;s load is notable&lt;br /&gt;
# look at distcc hosts list&lt;br /&gt;
# do something based off localhost entry if first&lt;br /&gt;
# filter for nodes with cpp flag&lt;br /&gt;
# do something based off localhost entry if not first&lt;br /&gt;
# further prioritize by server order, first is handled in some way&lt;br /&gt;
# skip nodes in backoff prisons&lt;br /&gt;
# balance and priotize by server thread number, if given&lt;br /&gt;
# send to suitable host&lt;br /&gt;
# if compile not successful, proceed on other node&lt;br /&gt;
# if nodes depleted, proceed on localhost&lt;br /&gt;
&lt;br /&gt;
== security ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== tcpwrapper style ip range filter ===&lt;br /&gt;
&lt;br /&gt;
the original security model consists of ip restrictions.&lt;br /&gt;
there seems to also be some GSSAPI user auth.&lt;br /&gt;
further, commands that can be called are restricted by name and location.&lt;br /&gt;
this appears to be a runtime whitelist lookup, meaning it&#039;s done and authorized by the same parts of the daemon as processes the compile request along with the intended compiler.&lt;br /&gt;
so the main weaknesses against malicious clients seem to be in sending things to compile, and in overriding the remote compiler to use.&lt;br /&gt;
it can be assumed that a malicious client able to exploit the compiler handshake can then run arbitrary stuff.&lt;br /&gt;
There&#039;s at least a github issue regarding this (link lost, but see here: https://gitlab.com/postmarketOS/pmbootstrap/-/work_items/1619) suggesting running over ssh. That does only partitally alleviate this risk with regard  to a key based verfication of a client versus a the standard ip restrictions which always include some parsing.&lt;br /&gt;
So this protects against someone directly exploiting the TCP code of distcc.&lt;br /&gt;
It does not protect against malicious clients.&lt;br /&gt;
(ssh force command can&#039;t be used or you&#039;ll not compile anything)&lt;br /&gt;
&lt;br /&gt;
The basic step for protecting access should be filtering who can access the distcc server, so use nftables etc. to restrict access to port 3262 (??) set up the internal filter the same way.&lt;br /&gt;
&lt;br /&gt;
=== seccomp ===&lt;br /&gt;
&lt;br /&gt;
The next thing is to confine the compiler calls to only write in their temp directory and that they can only run compilers (using nsjail, apparmor, selinux etc)&lt;br /&gt;
&lt;br /&gt;
the above issue also references the second bit of security, namely a seccomp filter which will already cover a good bit of the above&lt;br /&gt;
https://github.com/distcc/distcc/pull/235&lt;br /&gt;
the commit got closed without merge, from what I see.&lt;br /&gt;
&lt;br /&gt;
I will update the entry once it&#039;s clear if the patch was later added or instead nothing was done.&lt;br /&gt;
&lt;br /&gt;
=== privs ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The other internal security bit is that they do some priviledge dropping. it runs as a dedicated user (distcc), so you can also have an audit policy, and can/could use something like iptables&#039; to ensure it can only connect to the other distcc/memcached hosts, but nothing else.&lt;br /&gt;
&lt;br /&gt;
=== compiler list ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
One needs to investigate when compiler_whitelist.sh is exactly called. as far as I recall it doesn&#039;t close stdin/stdout.&lt;br /&gt;
&lt;br /&gt;
=== distcc-hardened ===&lt;br /&gt;
&lt;br /&gt;
Alpine adds some hardening patch, idk what nature/origina that has.&lt;br /&gt;
&lt;br /&gt;
=== selinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
there&#039;s also a selinux policy for distcc from gentoo or liguros if one is so inclined.&lt;br /&gt;
https://repology.org/project/selinux-distcc/versions&lt;br /&gt;
&lt;br /&gt;
=== general posture ===&lt;br /&gt;
&lt;br /&gt;
Some security measures like the above should definitely be used since the project at its core relies on accepting foreign input over the network, has only a few part-time maintainers that cannot easily drive the project forward or do large refactors.&lt;br /&gt;
But the seccomp changes were done almost 10 years ago, so, if they were actually upstreamed, I&#039;d say they came through.&lt;br /&gt;
&lt;br /&gt;
A kind of overengineered solulion would be to use netlabel to ensure application integrity across hosts, meaning only a valid process would be able to send packets to the distcc nodes :-)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Alternatives ==&lt;br /&gt;
&lt;br /&gt;
Arch wiki refers to a fork by SUSE&lt;br /&gt;
https://github.com/icecc/icecream&lt;br /&gt;
&lt;br /&gt;
It appears &#039;maybe better&#039; but hard to tell. There&#039;s no mention if maybe SUSE&#039;s OBS uses it or something. Without more knowledge of their use I don&#039;t know how big a benefit will come from switching.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A commercial alternative (incredibuild https://www.incredibuild.com/) exists, but I have not tried it.&lt;br /&gt;
THey advertise some &#039;forever free&#039; tier; generally if there&#039;s high (business) pressure for faster builds I would check that out.&lt;br /&gt;
&lt;br /&gt;
Architecturally it seems to be taking the ccache approach with a shared cache and smarter redistribution.&lt;br /&gt;
So anything that can call ccache is something they can scale out. I&#039;ll add a link later, for those whom it helps.&lt;br /&gt;
Naturally it is out of scope for this article.&lt;br /&gt;
Nonetheless it&#039;s interesting since the ordering of how to run ccache and how to run distcc is an issue that also exists in the OSS world. Not just that we don&#039;t have an automatic setup and integration of the tools (ccache, redis, distccd, distcc-pump) but we also don&#039;t have collected sufficient data to aid in deciding which aproach is the best.&lt;br /&gt;
Integrating into CIs (gitlab-runner specifically) is another item where cache persistence becomes very fragile.&lt;br /&gt;
Having an alpine build container that knows how to use ccache with redis and distcc-pump would be a possible step forward.&lt;br /&gt;
&lt;br /&gt;
== Other sources ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://retroflux.net/blog/distcc-adventures/&lt;/div&gt;</summary>
		<author><name>Darkfader</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32197</id>
		<title>User:Darkfader/distcc</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32197"/>
		<updated>2026-03-28T16:28:24Z</updated>

		<summary type="html">&lt;p&gt;Darkfader: /* Alternatives */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi,&lt;br /&gt;
&lt;br /&gt;
I&#039;m preparing this page. It can take a long time till I finish.&lt;br /&gt;
If you are also wishing to write on this topic, feel free to integrate the content.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Document overview ==&lt;br /&gt;
&lt;br /&gt;
I noticed that almost every distro has one partially complete, partially helpful document on how to use distcc on the distro.&lt;br /&gt;
Usually they also have one for ccache.&lt;br /&gt;
In either case, they&#039;re enough to get started, but not really a reliable watertight thing.&lt;br /&gt;
We definitely needed one of our own.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== goal ===&lt;br /&gt;
&lt;br /&gt;
to describe a working setup for building aports in easiest/fastests fashion&lt;br /&gt;
not planning to add versatility or features where it would make the setup more errorprone.&lt;br /&gt;
the page should describe enough of the steps to successfully compile an LTS kernel via aports and have that job be distributed over multiple nodes.&lt;br /&gt;
Logs should be set up and able to display errors, but not show any errors during the test compile.&lt;br /&gt;
&lt;br /&gt;
To include a path for analysis via testing components.&lt;br /&gt;
&lt;br /&gt;
distcc can greatly improve compile speeds for large software, it comes with a different set of features than ccache; it focusses not avoiding unneccessary compile work, but on a way to speed up the necessary one.&lt;br /&gt;
&lt;br /&gt;
There&#039;s valuable info in the docs of other distros, it should be referenced here (i.e. the arch wiki troubleshooting), when it makes sense, add a TOC for their content.&lt;br /&gt;
&lt;br /&gt;
=== audience ===&lt;br /&gt;
people running software builds on alpine and have multiple computers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This page will show a specific installation, specific configuration, and specific tests, resulting in a specific set of functionality that can be tested to be working.&lt;br /&gt;
&lt;br /&gt;
== installation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Packages ===&lt;br /&gt;
&lt;br /&gt;
you need, on each host&lt;br /&gt;
* distcc&lt;br /&gt;
* distccd-openrc&lt;br /&gt;
* distcc-pump&lt;br /&gt;
* distcc-pump-pyc&lt;br /&gt;
&lt;br /&gt;
the .pyc will speed up the invocations, without it &lt;br /&gt;
idk if one or both should be installed in that case. but it appears to be also automatically be precompiled in /usr/lib/python3.12/site-packages/include_server/__pycache__/ so what does the package do exactly?&lt;br /&gt;
&lt;br /&gt;
There&#039;s some references to cpython-312, so maybe it actually still uses classy python-c conversion or matbe that&#039;s just a component for reading C source code. I have zero idea.&lt;br /&gt;
&lt;br /&gt;
you also need stuff to do compiles&lt;br /&gt;
* alpine sdk&lt;br /&gt;
* clang&lt;br /&gt;
* binutils&lt;br /&gt;
...&lt;br /&gt;
* elfutils(-dev)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Settings ===&lt;br /&gt;
==== settings for distcc ====&lt;br /&gt;
&lt;br /&gt;
* there&#039;s /etc/default/distcc&lt;br /&gt;
* there&#039;s /etc/conf.d/distcc &lt;br /&gt;
&lt;br /&gt;
make all your settings here&lt;br /&gt;
take care with the listen address, if you specify an IP it&#039;ll not be on 127.0.0.1 in case you would have localhost in your list...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* command_whitelist.sh &lt;br /&gt;
&lt;br /&gt;
this is half functional, you need to set things here but you also need to maintain the symlinks that are collected under /usr/lib/distcc (for your compilers) and /usr/lib/distcc/bin (for itself)&lt;br /&gt;
&lt;br /&gt;
you MUST run the script to update the compilers!&lt;br /&gt;
Info for script and what files it will create&lt;br /&gt;
&lt;br /&gt;
/usr/sbin/update-distcc-symlinks&lt;br /&gt;
&lt;br /&gt;
tschike:/usr/bin# ls -l /usr/lib/distcc/&lt;br /&gt;
total 4&lt;br /&gt;
drwxr-xr-x 2 root root 4096 Mar  2 18:14 bin&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c89 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c99 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 cc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc-15.2.0 -&amp;gt; ../../bin/distcc&lt;br /&gt;
&lt;br /&gt;
distcc itself is in bin&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cpp -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 g++ -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 06:49 x86_64-alpine-linux-musl-gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
&lt;br /&gt;
the last symplink here is wrong, made by me and would not work...&lt;br /&gt;
BAD symlink.&lt;br /&gt;
&lt;br /&gt;
=== distcc hosts file ===&lt;br /&gt;
&lt;br /&gt;
idk about that thing it&#039;s odd&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== abuild.conf ===&lt;br /&gt;
&lt;br /&gt;
settings for aports&lt;br /&gt;
* cc=&lt;br /&gt;
* cxx=&lt;br /&gt;
* cpp=&lt;br /&gt;
* cflags=&lt;br /&gt;
* njobs&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== untested build container system ===&lt;br /&gt;
&lt;br /&gt;
See this one https://github.com/bensuperpc/docker-distcc&lt;br /&gt;
not yet tested, but this could be a good basis for a &#039;best practice&#039; container.&lt;br /&gt;
There&#039;s others, especially for crossbuilds, but those are also very complex to modify.&lt;br /&gt;
&lt;br /&gt;
== detail infos ==&lt;br /&gt;
&lt;br /&gt;
???&lt;br /&gt;
&lt;br /&gt;
=== hosts syntax ===&lt;br /&gt;
&lt;br /&gt;
* myhost otherhost&lt;br /&gt;
* myhost,cpp,lzo myotherhost,cpp,lzo&lt;br /&gt;
&lt;br /&gt;
==== the host ====&lt;br /&gt;
&lt;br /&gt;
hostname/ip&lt;br /&gt;
localhost&lt;br /&gt;
127.0.0.1&lt;br /&gt;
::1 - does not work&lt;br /&gt;
&lt;br /&gt;
==== protocol ====&lt;br /&gt;
&lt;br /&gt;
* no protocol given&lt;br /&gt;
* ,cpp,lzo protocol&lt;br /&gt;
&lt;br /&gt;
cpp implies lzo, it requires compression, even if you have 10gbit/s or more, it&#039;s just hardcoded&lt;br /&gt;
&lt;br /&gt;
=== threads ===&lt;br /&gt;
/number of workers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== architecture ==&lt;br /&gt;
it can handle C, C++, ObjC, maybe some other stuff&lt;br /&gt;
&lt;br /&gt;
* what happens with normal xmit&lt;br /&gt;
* what happens with pump mode&lt;br /&gt;
* at which step the include server is used and how it collects the includes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== distribution algorithm ===&lt;br /&gt;
honestly I simply don&#039;t get it&lt;br /&gt;
&lt;br /&gt;
* The order matters&lt;br /&gt;
* The number of threads matters&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== localhost ====&lt;br /&gt;
&lt;br /&gt;
* localhost precedence&lt;br /&gt;
* localhost fallback&lt;br /&gt;
&lt;br /&gt;
variable: DISTCC_FALLBACK&lt;br /&gt;
&lt;br /&gt;
0 = Fail to compile if it would need to fallback to a normal local gcc call&lt;br /&gt;
1 = If remote compile fails, just do it yourself&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Operation ==&lt;br /&gt;
&lt;br /&gt;
=== startup and shutdown ===&lt;br /&gt;
service distcc stop is not entirely reliable (it can take a minute after the stop until the processes are gone and sometimes it will never stop&lt;br /&gt;
this is very bad with openrc, the openrc script returns after a second and only relies on its service flags, not the process status.&lt;br /&gt;
manually check after stopping, wait a min, if needed, kill it all.&lt;br /&gt;
at some point the rc file needs to be rewritten, it can&#039;t stay like it is.&lt;br /&gt;
&lt;br /&gt;
if you used a pump mode session, that also needs a logout (pump --shutdown)&lt;br /&gt;
avoid running multiple startups without shutdown in one session. it&#039;s safe as far as I can tell but nothing cleans up these processes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== ccache and memcached ===&lt;br /&gt;
CCACHE is said to be conflicting with pump mode unless when you call them in the backend&lt;br /&gt;
so, where you start the compile, you don&#039;t use it&lt;br /&gt;
where the compile happens, you use it&lt;br /&gt;
they can share the cache via memcached, this is a nice trick for consistency&lt;br /&gt;
Upon looking at the ccache website, it seems the correct mechanism is not memcached but Redis. This would work just as well. Generally a cache shared in this way would be optimal for performance.&lt;br /&gt;
&lt;br /&gt;
=== dockerized / native ===&lt;br /&gt;
&lt;br /&gt;
it remains mostly the same, a container needs to make sure it monitors the right services (distccd, nginx, include_server)&lt;br /&gt;
if you&#039;re using zeroconf, you need to somehow expose the mdns service broadcasts &amp;amp; reception&lt;br /&gt;
&lt;br /&gt;
Processs list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
Workdir list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
=== alpine-chroot ===&lt;br /&gt;
&lt;br /&gt;
when using the &#039;official&#039; script there&#039;s still some odd pieces, seemed to be the processes died on logout. but not all of them.&lt;br /&gt;
&lt;br /&gt;
==== manual launch ====&lt;br /&gt;
&lt;br /&gt;
Starting the daemon would be using&lt;br /&gt;
/usr/bin/distccd --pid-file /var/run/distccd/distccd.pid -N 15 --user distcc --port 3632 --log-level=debug --log-file=/var/log/distccd.log --allow my-sub-net/24&lt;br /&gt;
&lt;br /&gt;
==== localhost? =====&lt;br /&gt;
unclear if you need to use --allow for 127.0.0.1/32 or something to allow the remote preproccesor.&lt;br /&gt;
&lt;br /&gt;
== Kernel specific settings ==&lt;br /&gt;
&lt;br /&gt;
currently (distcc 3.4-r9 on Alpine) you need a patch to build the kernel.&lt;br /&gt;
See &lt;br /&gt;
&lt;br /&gt;
=== Include server Settings ===&lt;br /&gt;
&lt;br /&gt;
cache reset triggers&lt;br /&gt;
This ought to be set before enabling pump mode.&lt;br /&gt;
&lt;br /&gt;
export INCLUDE_SERVER_ARGS=&amp;quot;--stat_reset_triggers=include/linux/compile.h:include/asm/asm-offsets.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
link to explanation TBA&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Disabling GCC Plugins ===&lt;br /&gt;
&lt;br /&gt;
KConfig unselect HAVE_GCC_PLUGINS&lt;br /&gt;
&lt;br /&gt;
Some info is here in the troubleshooting part of the Arch Wiki&lt;br /&gt;
https://wiki.archlinux.org/title/Distcc#Troubleshooting&lt;br /&gt;
&lt;br /&gt;
=== Patches ===&lt;br /&gt;
&lt;br /&gt;
Other things (for 6.6LTS)&lt;br /&gt;
PCIe Stub patch&lt;br /&gt;
&lt;br /&gt;
=== Autoconf === &lt;br /&gt;
&lt;br /&gt;
No known setup examples&lt;br /&gt;
Add whatever it publishes in mdns&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== troubleshooting / analysis ==&lt;br /&gt;
&lt;br /&gt;
=== testing ===&lt;br /&gt;
&lt;br /&gt;
# turn off fallback DISTCC_FALLBACK=1&lt;br /&gt;
# set distcc up to point at specific system under test DISTCC_HOSTS=&amp;quot;mytestbox,cpp,lzo&amp;quot;&lt;br /&gt;
# GCC example compiles&lt;br /&gt;
## code example C&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example C++&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example ObjC&lt;br /&gt;
## same with included header&lt;br /&gt;
# Cmake example compiles&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docoument the thing with compile launcher ccache;distcc&lt;br /&gt;
there&#039;s some blog post, point to that&lt;br /&gt;
no ccache here yet&lt;br /&gt;
show $CC differences distcc vs gcc, what configure scripts see&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Latency ===&lt;br /&gt;
&lt;br /&gt;
Latency of pump mode startups and fallbacks needs to be investigated.&lt;br /&gt;
LZO is enforced even if you have faster network&lt;br /&gt;
DNS Requests, very old bug report from Gcode, one request per call, is it true? how to get rid of it?&lt;br /&gt;
TMPDIR is respected, make sure it&#039;s on ramdisk even on the remote nodes.&lt;br /&gt;
Compile ideally never goes to disk when it doesn&#039;t have to.&lt;br /&gt;
How efficient is the include server collection and unpacking?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== failed to distribute, running locally instead ===&lt;br /&gt;
&lt;br /&gt;
the curse of the ancient, wise bulgarian witch compildora nottherea has befallen people all over the world. only strict and mindless adherence to rituals passed down from generation to generation has given hope to those who are under her ages old spell. again and again it reemerges to prey on idealistic young men and women who spend so much time at their unholy computers that they try to spend less time there by spending a lot of time trying to optimize what the computer does, slowly, instead of reflecting on why they are there, while the computer is busy working, and why they try to solve this by adding a component that makes the computer be more error-prone at that same work, increasing the need of their presense at this idolized thinking machine to oversee and often repair, or worse, mindlessly restart its doing.&lt;br /&gt;
if the curse is not lifted, despair may befall them and all they see is the need to investigate and ruminate further on the workings of this tool, ignoring thereby the obivous flaws that stem from of its alchemic origins.&lt;br /&gt;
&lt;br /&gt;
just wait till you find out it has a backoff alghoritm deciding whether to call out to a remote server independent of that server functioning. graceful performance degradation is the goal, and degrading it is while we try to figure this out.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Node Selection algorithm ====&lt;br /&gt;
&lt;br /&gt;
as per my understanding, a flowchart goes here:&lt;br /&gt;
&lt;br /&gt;
# compile task&lt;br /&gt;
# evaluate whether to run locally by job nature&lt;br /&gt;
# determine if local host&#039;s load is notable&lt;br /&gt;
# look at distcc hosts list&lt;br /&gt;
# do something based off localhost entry if first&lt;br /&gt;
# filter for nodes with cpp flag&lt;br /&gt;
# do something based off localhost entry if not first&lt;br /&gt;
# further prioritize by server order, first is handled in some way&lt;br /&gt;
# skip nodes in backoff prisons&lt;br /&gt;
# balance and priotize by server thread number, if given&lt;br /&gt;
# send to suitable host&lt;br /&gt;
# if compile not successful, proceed on other node&lt;br /&gt;
# if nodes depleted, proceed on localhost&lt;br /&gt;
&lt;br /&gt;
== security ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== tcpwrapper style ip range filter ===&lt;br /&gt;
&lt;br /&gt;
the original security model consists of ip restrictions.&lt;br /&gt;
there seems to also be some GSSAPI user auth.&lt;br /&gt;
further, commands that can be called are restricted by name and location.&lt;br /&gt;
this appears to be a runtime whitelist lookup, meaning it&#039;s done and authorized by the same parts of the daemon as processes the compile request along with the intended compiler.&lt;br /&gt;
so the main weaknesses against malicious clients seem to be in sending things to compile, and in overriding the remote compiler to use.&lt;br /&gt;
it can be assumed that a malicious client able to exploit the compiler handshake can then run arbitrary stuff.&lt;br /&gt;
There&#039;s at least a github issue regarding this (link lost, but see here: https://gitlab.com/postmarketOS/pmbootstrap/-/work_items/1619) suggesting running over ssh. That does only partitally alleviate this risk with regard  to a key based verfication of a client versus a the standard ip restrictions which always include some parsing.&lt;br /&gt;
So this protects against someone directly exploiting the TCP code of distcc.&lt;br /&gt;
It does not protect against malicious clients.&lt;br /&gt;
(ssh force command can&#039;t be used or you&#039;ll not compile anything)&lt;br /&gt;
&lt;br /&gt;
The basic step for protecting access should be filtering who can access the distcc server, so use nftables etc. to restrict access to port 3262 (??) set up the internal filter the same way.&lt;br /&gt;
&lt;br /&gt;
=== seccomp ===&lt;br /&gt;
&lt;br /&gt;
The next thing is to confine the compiler calls to only write in their temp directory and that they can only run compilers (using nsjail, apparmor, selinux etc)&lt;br /&gt;
&lt;br /&gt;
the above issue also references the second bit of security, namely a seccomp filter which will already cover a good bit of the above&lt;br /&gt;
https://github.com/distcc/distcc/pull/235&lt;br /&gt;
the commit got closed without merge, from what I see.&lt;br /&gt;
&lt;br /&gt;
I will update the entry once it&#039;s clear if the patch was later added or instead nothing was done.&lt;br /&gt;
&lt;br /&gt;
=== privs ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The other internal security bit is that they do some priviledge dropping. it runs as a dedicated user (distcc), so you can also have an audit policy, and can/could use something like iptables&#039; to ensure it can only connect to the other distcc/memcached hosts, but nothing else.&lt;br /&gt;
&lt;br /&gt;
=== compiler list ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
One needs to investigate when compiler_whitelist.sh is exactly called. as far as I recall it doesn&#039;t close stdin/stdout.&lt;br /&gt;
&lt;br /&gt;
=== distcc-hardened ===&lt;br /&gt;
&lt;br /&gt;
Alpine adds some hardening patch, idk what nature/origina that has.&lt;br /&gt;
&lt;br /&gt;
=== selinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
there&#039;s also a selinux policy for distcc from gentoo or liguros if one is so inclined.&lt;br /&gt;
https://repology.org/project/selinux-distcc/versions&lt;br /&gt;
&lt;br /&gt;
=== general posture ===&lt;br /&gt;
&lt;br /&gt;
Some security measures like the above should definitely be used since the project at its core relies on accepting foreign input over the network, has only a few part-time maintainers that cannot easily drive the project forward or do large refactors.&lt;br /&gt;
But the seccomp changes were done almost 10 years ago, so, if they were actually upstreamed, I&#039;d say they came through.&lt;br /&gt;
&lt;br /&gt;
A kind of overengineered solulion would be to use netlabel to ensure application integrity across hosts, meaning only a valid process would be able to send packets to the distcc nodes :-)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Alternatives ==&lt;br /&gt;
&lt;br /&gt;
Arch wiki refers to a fork by SUSE&lt;br /&gt;
https://github.com/icecc/icecream&lt;br /&gt;
&lt;br /&gt;
It appears &#039;maybe better&#039; but hard to tell.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A commercial alternative (incredibuild https://www.incredibuild.com/) exists, but I have not tried it.&lt;br /&gt;
&lt;br /&gt;
Architecturally it seems to be taking the ccache approach with a shared cache and smarter redistribution.&lt;br /&gt;
So anything that can call ccache is something they can scale out. I&#039;ll add a link later, for those whom it helps.&lt;br /&gt;
Naturally it is out of scope for this article.&lt;br /&gt;
Nonetheless it&#039;s interesting since the ordering of how to run ccache and how to run distcc is an issue that also exists in the OSS world. Not just that we don&#039;t have an automatic setup and integration of the tools (ccache, redis, distccd, distcc-pump) but we also don&#039;t have collected sufficient data to aid in deciding which aproach is the best.&lt;br /&gt;
Integrating into CIs (gitlab-runner specifically) is another item where cache persistence becomes very fragile.&lt;br /&gt;
Having an alpine build container that knows how to use ccache with redis and distcc-pump would be a possible step forward.&lt;br /&gt;
&lt;br /&gt;
== Other sources ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://retroflux.net/blog/distcc-adventures/&lt;/div&gt;</summary>
		<author><name>Darkfader</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32196</id>
		<title>User:Darkfader/distcc</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32196"/>
		<updated>2026-03-28T16:22:32Z</updated>

		<summary type="html">&lt;p&gt;Darkfader: /* general posture */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi,&lt;br /&gt;
&lt;br /&gt;
I&#039;m preparing this page. It can take a long time till I finish.&lt;br /&gt;
If you are also wishing to write on this topic, feel free to integrate the content.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Document overview ==&lt;br /&gt;
&lt;br /&gt;
I noticed that almost every distro has one partially complete, partially helpful document on how to use distcc on the distro.&lt;br /&gt;
Usually they also have one for ccache.&lt;br /&gt;
In either case, they&#039;re enough to get started, but not really a reliable watertight thing.&lt;br /&gt;
We definitely needed one of our own.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== goal ===&lt;br /&gt;
&lt;br /&gt;
to describe a working setup for building aports in easiest/fastests fashion&lt;br /&gt;
not planning to add versatility or features where it would make the setup more errorprone.&lt;br /&gt;
the page should describe enough of the steps to successfully compile an LTS kernel via aports and have that job be distributed over multiple nodes.&lt;br /&gt;
Logs should be set up and able to display errors, but not show any errors during the test compile.&lt;br /&gt;
&lt;br /&gt;
To include a path for analysis via testing components.&lt;br /&gt;
&lt;br /&gt;
distcc can greatly improve compile speeds for large software, it comes with a different set of features than ccache; it focusses not avoiding unneccessary compile work, but on a way to speed up the necessary one.&lt;br /&gt;
&lt;br /&gt;
There&#039;s valuable info in the docs of other distros, it should be referenced here (i.e. the arch wiki troubleshooting), when it makes sense, add a TOC for their content.&lt;br /&gt;
&lt;br /&gt;
=== audience ===&lt;br /&gt;
people running software builds on alpine and have multiple computers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This page will show a specific installation, specific configuration, and specific tests, resulting in a specific set of functionality that can be tested to be working.&lt;br /&gt;
&lt;br /&gt;
== installation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Packages ===&lt;br /&gt;
&lt;br /&gt;
you need, on each host&lt;br /&gt;
* distcc&lt;br /&gt;
* distccd-openrc&lt;br /&gt;
* distcc-pump&lt;br /&gt;
* distcc-pump-pyc&lt;br /&gt;
&lt;br /&gt;
the .pyc will speed up the invocations, without it &lt;br /&gt;
idk if one or both should be installed in that case. but it appears to be also automatically be precompiled in /usr/lib/python3.12/site-packages/include_server/__pycache__/ so what does the package do exactly?&lt;br /&gt;
&lt;br /&gt;
There&#039;s some references to cpython-312, so maybe it actually still uses classy python-c conversion or matbe that&#039;s just a component for reading C source code. I have zero idea.&lt;br /&gt;
&lt;br /&gt;
you also need stuff to do compiles&lt;br /&gt;
* alpine sdk&lt;br /&gt;
* clang&lt;br /&gt;
* binutils&lt;br /&gt;
...&lt;br /&gt;
* elfutils(-dev)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Settings ===&lt;br /&gt;
==== settings for distcc ====&lt;br /&gt;
&lt;br /&gt;
* there&#039;s /etc/default/distcc&lt;br /&gt;
* there&#039;s /etc/conf.d/distcc &lt;br /&gt;
&lt;br /&gt;
make all your settings here&lt;br /&gt;
take care with the listen address, if you specify an IP it&#039;ll not be on 127.0.0.1 in case you would have localhost in your list...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* command_whitelist.sh &lt;br /&gt;
&lt;br /&gt;
this is half functional, you need to set things here but you also need to maintain the symlinks that are collected under /usr/lib/distcc (for your compilers) and /usr/lib/distcc/bin (for itself)&lt;br /&gt;
&lt;br /&gt;
you MUST run the script to update the compilers!&lt;br /&gt;
Info for script and what files it will create&lt;br /&gt;
&lt;br /&gt;
/usr/sbin/update-distcc-symlinks&lt;br /&gt;
&lt;br /&gt;
tschike:/usr/bin# ls -l /usr/lib/distcc/&lt;br /&gt;
total 4&lt;br /&gt;
drwxr-xr-x 2 root root 4096 Mar  2 18:14 bin&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c89 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c99 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 cc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc-15.2.0 -&amp;gt; ../../bin/distcc&lt;br /&gt;
&lt;br /&gt;
distcc itself is in bin&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cpp -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 g++ -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 06:49 x86_64-alpine-linux-musl-gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
&lt;br /&gt;
the last symplink here is wrong, made by me and would not work...&lt;br /&gt;
BAD symlink.&lt;br /&gt;
&lt;br /&gt;
=== distcc hosts file ===&lt;br /&gt;
&lt;br /&gt;
idk about that thing it&#039;s odd&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== abuild.conf ===&lt;br /&gt;
&lt;br /&gt;
settings for aports&lt;br /&gt;
* cc=&lt;br /&gt;
* cxx=&lt;br /&gt;
* cpp=&lt;br /&gt;
* cflags=&lt;br /&gt;
* njobs&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== untested build container system ===&lt;br /&gt;
&lt;br /&gt;
See this one https://github.com/bensuperpc/docker-distcc&lt;br /&gt;
not yet tested, but this could be a good basis for a &#039;best practice&#039; container.&lt;br /&gt;
There&#039;s others, especially for crossbuilds, but those are also very complex to modify.&lt;br /&gt;
&lt;br /&gt;
== detail infos ==&lt;br /&gt;
&lt;br /&gt;
???&lt;br /&gt;
&lt;br /&gt;
=== hosts syntax ===&lt;br /&gt;
&lt;br /&gt;
* myhost otherhost&lt;br /&gt;
* myhost,cpp,lzo myotherhost,cpp,lzo&lt;br /&gt;
&lt;br /&gt;
==== the host ====&lt;br /&gt;
&lt;br /&gt;
hostname/ip&lt;br /&gt;
localhost&lt;br /&gt;
127.0.0.1&lt;br /&gt;
::1 - does not work&lt;br /&gt;
&lt;br /&gt;
==== protocol ====&lt;br /&gt;
&lt;br /&gt;
* no protocol given&lt;br /&gt;
* ,cpp,lzo protocol&lt;br /&gt;
&lt;br /&gt;
cpp implies lzo, it requires compression, even if you have 10gbit/s or more, it&#039;s just hardcoded&lt;br /&gt;
&lt;br /&gt;
=== threads ===&lt;br /&gt;
/number of workers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== architecture ==&lt;br /&gt;
it can handle C, C++, ObjC, maybe some other stuff&lt;br /&gt;
&lt;br /&gt;
* what happens with normal xmit&lt;br /&gt;
* what happens with pump mode&lt;br /&gt;
* at which step the include server is used and how it collects the includes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== distribution algorithm ===&lt;br /&gt;
honestly I simply don&#039;t get it&lt;br /&gt;
&lt;br /&gt;
* The order matters&lt;br /&gt;
* The number of threads matters&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== localhost ====&lt;br /&gt;
&lt;br /&gt;
* localhost precedence&lt;br /&gt;
* localhost fallback&lt;br /&gt;
&lt;br /&gt;
variable: DISTCC_FALLBACK&lt;br /&gt;
&lt;br /&gt;
0 = Fail to compile if it would need to fallback to a normal local gcc call&lt;br /&gt;
1 = If remote compile fails, just do it yourself&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Operation ==&lt;br /&gt;
&lt;br /&gt;
=== startup and shutdown ===&lt;br /&gt;
service distcc stop is not entirely reliable (it can take a minute after the stop until the processes are gone and sometimes it will never stop&lt;br /&gt;
this is very bad with openrc, the openrc script returns after a second and only relies on its service flags, not the process status.&lt;br /&gt;
manually check after stopping, wait a min, if needed, kill it all.&lt;br /&gt;
at some point the rc file needs to be rewritten, it can&#039;t stay like it is.&lt;br /&gt;
&lt;br /&gt;
if you used a pump mode session, that also needs a logout (pump --shutdown)&lt;br /&gt;
avoid running multiple startups without shutdown in one session. it&#039;s safe as far as I can tell but nothing cleans up these processes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== ccache and memcached ===&lt;br /&gt;
CCACHE is said to be conflicting with pump mode unless when you call them in the backend&lt;br /&gt;
so, where you start the compile, you don&#039;t use it&lt;br /&gt;
where the compile happens, you use it&lt;br /&gt;
they can share the cache via memcached, this is a nice trick for consistency&lt;br /&gt;
Upon looking at the ccache website, it seems the correct mechanism is not memcached but Redis. This would work just as well. Generally a cache shared in this way would be optimal for performance.&lt;br /&gt;
&lt;br /&gt;
=== dockerized / native ===&lt;br /&gt;
&lt;br /&gt;
it remains mostly the same, a container needs to make sure it monitors the right services (distccd, nginx, include_server)&lt;br /&gt;
if you&#039;re using zeroconf, you need to somehow expose the mdns service broadcasts &amp;amp; reception&lt;br /&gt;
&lt;br /&gt;
Processs list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
Workdir list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
=== alpine-chroot ===&lt;br /&gt;
&lt;br /&gt;
when using the &#039;official&#039; script there&#039;s still some odd pieces, seemed to be the processes died on logout. but not all of them.&lt;br /&gt;
&lt;br /&gt;
==== manual launch ====&lt;br /&gt;
&lt;br /&gt;
Starting the daemon would be using&lt;br /&gt;
/usr/bin/distccd --pid-file /var/run/distccd/distccd.pid -N 15 --user distcc --port 3632 --log-level=debug --log-file=/var/log/distccd.log --allow my-sub-net/24&lt;br /&gt;
&lt;br /&gt;
==== localhost? =====&lt;br /&gt;
unclear if you need to use --allow for 127.0.0.1/32 or something to allow the remote preproccesor.&lt;br /&gt;
&lt;br /&gt;
== Kernel specific settings ==&lt;br /&gt;
&lt;br /&gt;
currently (distcc 3.4-r9 on Alpine) you need a patch to build the kernel.&lt;br /&gt;
See &lt;br /&gt;
&lt;br /&gt;
=== Include server Settings ===&lt;br /&gt;
&lt;br /&gt;
cache reset triggers&lt;br /&gt;
This ought to be set before enabling pump mode.&lt;br /&gt;
&lt;br /&gt;
export INCLUDE_SERVER_ARGS=&amp;quot;--stat_reset_triggers=include/linux/compile.h:include/asm/asm-offsets.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
link to explanation TBA&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Disabling GCC Plugins ===&lt;br /&gt;
&lt;br /&gt;
KConfig unselect HAVE_GCC_PLUGINS&lt;br /&gt;
&lt;br /&gt;
Some info is here in the troubleshooting part of the Arch Wiki&lt;br /&gt;
https://wiki.archlinux.org/title/Distcc#Troubleshooting&lt;br /&gt;
&lt;br /&gt;
=== Patches ===&lt;br /&gt;
&lt;br /&gt;
Other things (for 6.6LTS)&lt;br /&gt;
PCIe Stub patch&lt;br /&gt;
&lt;br /&gt;
=== Autoconf === &lt;br /&gt;
&lt;br /&gt;
No known setup examples&lt;br /&gt;
Add whatever it publishes in mdns&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== troubleshooting / analysis ==&lt;br /&gt;
&lt;br /&gt;
=== testing ===&lt;br /&gt;
&lt;br /&gt;
# turn off fallback DISTCC_FALLBACK=1&lt;br /&gt;
# set distcc up to point at specific system under test DISTCC_HOSTS=&amp;quot;mytestbox,cpp,lzo&amp;quot;&lt;br /&gt;
# GCC example compiles&lt;br /&gt;
## code example C&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example C++&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example ObjC&lt;br /&gt;
## same with included header&lt;br /&gt;
# Cmake example compiles&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docoument the thing with compile launcher ccache;distcc&lt;br /&gt;
there&#039;s some blog post, point to that&lt;br /&gt;
no ccache here yet&lt;br /&gt;
show $CC differences distcc vs gcc, what configure scripts see&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Latency ===&lt;br /&gt;
&lt;br /&gt;
Latency of pump mode startups and fallbacks needs to be investigated.&lt;br /&gt;
LZO is enforced even if you have faster network&lt;br /&gt;
DNS Requests, very old bug report from Gcode, one request per call, is it true? how to get rid of it?&lt;br /&gt;
TMPDIR is respected, make sure it&#039;s on ramdisk even on the remote nodes.&lt;br /&gt;
Compile ideally never goes to disk when it doesn&#039;t have to.&lt;br /&gt;
How efficient is the include server collection and unpacking?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== failed to distribute, running locally instead ===&lt;br /&gt;
&lt;br /&gt;
the curse of the ancient, wise bulgarian witch compildora nottherea has befallen people all over the world. only strict and mindless adherence to rituals passed down from generation to generation has given hope to those who are under her ages old spell. again and again it reemerges to prey on idealistic young men and women who spend so much time at their unholy computers that they try to spend less time there by spending a lot of time trying to optimize what the computer does, slowly, instead of reflecting on why they are there, while the computer is busy working, and why they try to solve this by adding a component that makes the computer be more error-prone at that same work, increasing the need of their presense at this idolized thinking machine to oversee and often repair, or worse, mindlessly restart its doing.&lt;br /&gt;
if the curse is not lifted, despair may befall them and all they see is the need to investigate and ruminate further on the workings of this tool, ignoring thereby the obivous flaws that stem from of its alchemic origins.&lt;br /&gt;
&lt;br /&gt;
just wait till you find out it has a backoff alghoritm deciding whether to call out to a remote server independent of that server functioning. graceful performance degradation is the goal, and degrading it is while we try to figure this out.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Node Selection algorithm ====&lt;br /&gt;
&lt;br /&gt;
as per my understanding, a flowchart goes here:&lt;br /&gt;
&lt;br /&gt;
# compile task&lt;br /&gt;
# evaluate whether to run locally by job nature&lt;br /&gt;
# determine if local host&#039;s load is notable&lt;br /&gt;
# look at distcc hosts list&lt;br /&gt;
# do something based off localhost entry if first&lt;br /&gt;
# filter for nodes with cpp flag&lt;br /&gt;
# do something based off localhost entry if not first&lt;br /&gt;
# further prioritize by server order, first is handled in some way&lt;br /&gt;
# skip nodes in backoff prisons&lt;br /&gt;
# balance and priotize by server thread number, if given&lt;br /&gt;
# send to suitable host&lt;br /&gt;
# if compile not successful, proceed on other node&lt;br /&gt;
# if nodes depleted, proceed on localhost&lt;br /&gt;
&lt;br /&gt;
== security ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== tcpwrapper style ip range filter ===&lt;br /&gt;
&lt;br /&gt;
the original security model consists of ip restrictions.&lt;br /&gt;
there seems to also be some GSSAPI user auth.&lt;br /&gt;
further, commands that can be called are restricted by name and location.&lt;br /&gt;
this appears to be a runtime whitelist lookup, meaning it&#039;s done and authorized by the same parts of the daemon as processes the compile request along with the intended compiler.&lt;br /&gt;
so the main weaknesses against malicious clients seem to be in sending things to compile, and in overriding the remote compiler to use.&lt;br /&gt;
it can be assumed that a malicious client able to exploit the compiler handshake can then run arbitrary stuff.&lt;br /&gt;
There&#039;s at least a github issue regarding this (link lost, but see here: https://gitlab.com/postmarketOS/pmbootstrap/-/work_items/1619) suggesting running over ssh. That does only partitally alleviate this risk with regard  to a key based verfication of a client versus a the standard ip restrictions which always include some parsing.&lt;br /&gt;
So this protects against someone directly exploiting the TCP code of distcc.&lt;br /&gt;
It does not protect against malicious clients.&lt;br /&gt;
(ssh force command can&#039;t be used or you&#039;ll not compile anything)&lt;br /&gt;
&lt;br /&gt;
The basic step for protecting access should be filtering who can access the distcc server, so use nftables etc. to restrict access to port 3262 (??) set up the internal filter the same way.&lt;br /&gt;
&lt;br /&gt;
=== seccomp ===&lt;br /&gt;
&lt;br /&gt;
The next thing is to confine the compiler calls to only write in their temp directory and that they can only run compilers (using nsjail, apparmor, selinux etc)&lt;br /&gt;
&lt;br /&gt;
the above issue also references the second bit of security, namely a seccomp filter which will already cover a good bit of the above&lt;br /&gt;
https://github.com/distcc/distcc/pull/235&lt;br /&gt;
the commit got closed without merge, from what I see.&lt;br /&gt;
&lt;br /&gt;
I will update the entry once it&#039;s clear if the patch was later added or instead nothing was done.&lt;br /&gt;
&lt;br /&gt;
=== privs ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The other internal security bit is that they do some priviledge dropping. it runs as a dedicated user (distcc), so you can also have an audit policy, and can/could use something like iptables&#039; to ensure it can only connect to the other distcc/memcached hosts, but nothing else.&lt;br /&gt;
&lt;br /&gt;
=== compiler list ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
One needs to investigate when compiler_whitelist.sh is exactly called. as far as I recall it doesn&#039;t close stdin/stdout.&lt;br /&gt;
&lt;br /&gt;
=== distcc-hardened ===&lt;br /&gt;
&lt;br /&gt;
Alpine adds some hardening patch, idk what nature/origina that has.&lt;br /&gt;
&lt;br /&gt;
=== selinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
there&#039;s also a selinux policy for distcc from gentoo or liguros if one is so inclined.&lt;br /&gt;
https://repology.org/project/selinux-distcc/versions&lt;br /&gt;
&lt;br /&gt;
=== general posture ===&lt;br /&gt;
&lt;br /&gt;
Some security measures like the above should definitely be used since the project at its core relies on accepting foreign input over the network, has only a few part-time maintainers that cannot easily drive the project forward or do large refactors.&lt;br /&gt;
But the seccomp changes were done almost 10 years ago, so, if they were actually upstreamed, I&#039;d say they came through.&lt;br /&gt;
&lt;br /&gt;
A kind of overengineered solulion would be to use netlabel to ensure application integrity across hosts, meaning only a valid process would be able to send packets to the distcc nodes :-)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Alternatives ==&lt;br /&gt;
&lt;br /&gt;
Arch wiki refers to a fork by SUSE&lt;br /&gt;
https://github.com/icecc/icecream&lt;br /&gt;
&lt;br /&gt;
It appears &#039;maybe better&#039; but hard to tell.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A commercial alternative (incredibuild) exists, but I have not tried it.&lt;br /&gt;
&lt;br /&gt;
Architecturally it seems to be taking the ccache approach with a shared cache and smarter redistribution.&lt;br /&gt;
So anything that can call ccache is something they can scale out. I&#039;ll add a link later, for those whom it helps.&lt;br /&gt;
Naturally it is out of scope for this article.&lt;br /&gt;
Nonetheless it&#039;s interesting since the ordering of how to run ccache and how to run distcc is an issue that also exists in the OSS world. Not just that we don&#039;t have an automatic setup and integration of the tools (ccache, redis, distccd, distcc-pump) but we also don&#039;t have collected sufficient data to aid in deciding which aproach is the best.&lt;br /&gt;
Integrating into CIs (gitlab-runner specifically) is another item where cache persistence becomes very fragile.&lt;br /&gt;
Having an alpine build container that knows how to use ccache with redis and distcc-pump would be a possible step forward.&lt;br /&gt;
&lt;br /&gt;
== Other sources ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://retroflux.net/blog/distcc-adventures/&lt;/div&gt;</summary>
		<author><name>Darkfader</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader&amp;diff=32195</id>
		<title>User:Darkfader</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader&amp;diff=32195"/>
		<updated>2026-03-28T16:20:55Z</updated>

		<summary type="html">&lt;p&gt;Darkfader: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==About me==&lt;br /&gt;
&lt;br /&gt;
UNIX Sysadmin, Server hugger and cluster fixer, Monitoring addict (Check_MK).&lt;br /&gt;
&lt;br /&gt;
Blog: http://deranfangvomende.wordpress.com&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Links ===&lt;br /&gt;
&lt;br /&gt;
 * DistCC howto: https://wiki.alpinelinux.org/wiki/User:Darkfader/distcc&lt;br /&gt;
 * Collection of public Octeon SDKs: https://codeberg.org/darkfader/octeon-sdk-all&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Love Alpine Linux because===&lt;br /&gt;
 * Only thing on par or close to &#039;proper&#039; Carrier Grade Linux Distros&lt;br /&gt;
 * the virtualization choices and DMVPN&lt;br /&gt;
 * boot to ram&lt;br /&gt;
 * the community&lt;br /&gt;
 * the speed&lt;br /&gt;
 * APK&lt;br /&gt;
 * only Linux distro never driving me crazy.&lt;br /&gt;
&lt;br /&gt;
===Areas of interest===&lt;br /&gt;
&lt;br /&gt;
Alpine things I keep trying to do things with&lt;br /&gt;
&lt;br /&gt;
 * Xen (a decade ago :/)&lt;br /&gt;
 * Re-do OpenNebula frontend port&lt;br /&gt;
 * CFEngine / Rudder ports&lt;br /&gt;
 * Elastic Agent&lt;br /&gt;
&lt;br /&gt;
===Odd systems===&lt;br /&gt;
&lt;br /&gt;
 * MIPS64/Octeon3,&lt;br /&gt;
 * CubieTruck Xen host&lt;br /&gt;
 * RISC-V on Milk-V duo 64MB&lt;br /&gt;
 * rental VPS running in memory&lt;/div&gt;</summary>
		<author><name>Darkfader</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32183</id>
		<title>User:Darkfader/distcc</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32183"/>
		<updated>2026-03-26T01:13:47Z</updated>

		<summary type="html">&lt;p&gt;Darkfader: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi,&lt;br /&gt;
&lt;br /&gt;
I&#039;m preparing this page. It can take a long time till I finish.&lt;br /&gt;
If you are also wishing to write on this topic, feel free to integrate the content.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Document overview ==&lt;br /&gt;
&lt;br /&gt;
I noticed that almost every distro has one partially complete, partially helpful document on how to use distcc on the distro.&lt;br /&gt;
Usually they also have one for ccache.&lt;br /&gt;
In either case, they&#039;re enough to get started, but not really a reliable watertight thing.&lt;br /&gt;
We definitely needed one of our own.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== goal ===&lt;br /&gt;
&lt;br /&gt;
to describe a working setup for building aports in easiest/fastests fashion&lt;br /&gt;
not planning to add versatility or features where it would make the setup more errorprone.&lt;br /&gt;
the page should describe enough of the steps to successfully compile an LTS kernel via aports and have that job be distributed over multiple nodes.&lt;br /&gt;
Logs should be set up and able to display errors, but not show any errors during the test compile.&lt;br /&gt;
&lt;br /&gt;
To include a path for analysis via testing components.&lt;br /&gt;
&lt;br /&gt;
distcc can greatly improve compile speeds for large software, it comes with a different set of features than ccache; it focusses not avoiding unneccessary compile work, but on a way to speed up the necessary one.&lt;br /&gt;
&lt;br /&gt;
There&#039;s valuable info in the docs of other distros, it should be referenced here (i.e. the arch wiki troubleshooting), when it makes sense, add a TOC for their content.&lt;br /&gt;
&lt;br /&gt;
=== audience ===&lt;br /&gt;
people running software builds on alpine and have multiple computers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This page will show a specific installation, specific configuration, and specific tests, resulting in a specific set of functionality that can be tested to be working.&lt;br /&gt;
&lt;br /&gt;
== installation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Packages ===&lt;br /&gt;
&lt;br /&gt;
you need, on each host&lt;br /&gt;
* distcc&lt;br /&gt;
* distccd-openrc&lt;br /&gt;
* distcc-pump&lt;br /&gt;
* distcc-pump-pyc&lt;br /&gt;
&lt;br /&gt;
the .pyc will speed up the invocations, without it &lt;br /&gt;
idk if one or both should be installed in that case. but it appears to be also automatically be precompiled in /usr/lib/python3.12/site-packages/include_server/__pycache__/ so what does the package do exactly?&lt;br /&gt;
&lt;br /&gt;
There&#039;s some references to cpython-312, so maybe it actually still uses classy python-c conversion or matbe that&#039;s just a component for reading C source code. I have zero idea.&lt;br /&gt;
&lt;br /&gt;
you also need stuff to do compiles&lt;br /&gt;
* alpine sdk&lt;br /&gt;
* clang&lt;br /&gt;
* binutils&lt;br /&gt;
...&lt;br /&gt;
* elfutils(-dev)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Settings ===&lt;br /&gt;
==== settings for distcc ====&lt;br /&gt;
&lt;br /&gt;
* there&#039;s /etc/default/distcc&lt;br /&gt;
* there&#039;s /etc/conf.d/distcc &lt;br /&gt;
&lt;br /&gt;
make all your settings here&lt;br /&gt;
take care with the listen address, if you specify an IP it&#039;ll not be on 127.0.0.1 in case you would have localhost in your list...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* command_whitelist.sh &lt;br /&gt;
&lt;br /&gt;
this is half functional, you need to set things here but you also need to maintain the symlinks that are collected under /usr/lib/distcc (for your compilers) and /usr/lib/distcc/bin (for itself)&lt;br /&gt;
&lt;br /&gt;
you MUST run the script to update the compilers!&lt;br /&gt;
Info for script and what files it will create&lt;br /&gt;
&lt;br /&gt;
/usr/sbin/update-distcc-symlinks&lt;br /&gt;
&lt;br /&gt;
tschike:/usr/bin# ls -l /usr/lib/distcc/&lt;br /&gt;
total 4&lt;br /&gt;
drwxr-xr-x 2 root root 4096 Mar  2 18:14 bin&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c89 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c99 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 cc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc-15.2.0 -&amp;gt; ../../bin/distcc&lt;br /&gt;
&lt;br /&gt;
distcc itself is in bin&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cpp -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 g++ -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 06:49 x86_64-alpine-linux-musl-gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
&lt;br /&gt;
the last symplink here is wrong, made by me and would not work...&lt;br /&gt;
BAD symlink.&lt;br /&gt;
&lt;br /&gt;
=== distcc hosts file ===&lt;br /&gt;
&lt;br /&gt;
idk about that thing it&#039;s odd&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== abuild.conf ===&lt;br /&gt;
&lt;br /&gt;
settings for aports&lt;br /&gt;
* cc=&lt;br /&gt;
* cxx=&lt;br /&gt;
* cpp=&lt;br /&gt;
* cflags=&lt;br /&gt;
* njobs&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== untested build container system ===&lt;br /&gt;
&lt;br /&gt;
See this one https://github.com/bensuperpc/docker-distcc&lt;br /&gt;
not yet tested, but this could be a good basis for a &#039;best practice&#039; container.&lt;br /&gt;
There&#039;s others, especially for crossbuilds, but those are also very complex to modify.&lt;br /&gt;
&lt;br /&gt;
== detail infos ==&lt;br /&gt;
&lt;br /&gt;
???&lt;br /&gt;
&lt;br /&gt;
=== hosts syntax ===&lt;br /&gt;
&lt;br /&gt;
* myhost otherhost&lt;br /&gt;
* myhost,cpp,lzo myotherhost,cpp,lzo&lt;br /&gt;
&lt;br /&gt;
==== the host ====&lt;br /&gt;
&lt;br /&gt;
hostname/ip&lt;br /&gt;
localhost&lt;br /&gt;
127.0.0.1&lt;br /&gt;
::1 - does not work&lt;br /&gt;
&lt;br /&gt;
==== protocol ====&lt;br /&gt;
&lt;br /&gt;
* no protocol given&lt;br /&gt;
* ,cpp,lzo protocol&lt;br /&gt;
&lt;br /&gt;
cpp implies lzo, it requires compression, even if you have 10gbit/s or more, it&#039;s just hardcoded&lt;br /&gt;
&lt;br /&gt;
=== threads ===&lt;br /&gt;
/number of workers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== architecture ==&lt;br /&gt;
it can handle C, C++, ObjC, maybe some other stuff&lt;br /&gt;
&lt;br /&gt;
* what happens with normal xmit&lt;br /&gt;
* what happens with pump mode&lt;br /&gt;
* at which step the include server is used and how it collects the includes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== distribution algorithm ===&lt;br /&gt;
honestly I simply don&#039;t get it&lt;br /&gt;
&lt;br /&gt;
* The order matters&lt;br /&gt;
* The number of threads matters&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== localhost ====&lt;br /&gt;
&lt;br /&gt;
* localhost precedence&lt;br /&gt;
* localhost fallback&lt;br /&gt;
&lt;br /&gt;
variable: DISTCC_FALLBACK&lt;br /&gt;
&lt;br /&gt;
0 = Fail to compile if it would need to fallback to a normal local gcc call&lt;br /&gt;
1 = If remote compile fails, just do it yourself&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Operation ==&lt;br /&gt;
&lt;br /&gt;
=== startup and shutdown ===&lt;br /&gt;
service distcc stop is not entirely reliable (it can take a minute after the stop until the processes are gone and sometimes it will never stop&lt;br /&gt;
this is very bad with openrc, the openrc script returns after a second and only relies on its service flags, not the process status.&lt;br /&gt;
manually check after stopping, wait a min, if needed, kill it all.&lt;br /&gt;
at some point the rc file needs to be rewritten, it can&#039;t stay like it is.&lt;br /&gt;
&lt;br /&gt;
if you used a pump mode session, that also needs a logout (pump --shutdown)&lt;br /&gt;
avoid running multiple startups without shutdown in one session. it&#039;s safe as far as I can tell but nothing cleans up these processes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== ccache and memcached ===&lt;br /&gt;
CCACHE is said to be conflicting with pump mode unless when you call them in the backend&lt;br /&gt;
so, where you start the compile, you don&#039;t use it&lt;br /&gt;
where the compile happens, you use it&lt;br /&gt;
they can share the cache via memcached, this is a nice trick for consistency&lt;br /&gt;
Upon looking at the ccache website, it seems the correct mechanism is not memcached but Redis. This would work just as well. Generally a cache shared in this way would be optimal for performance.&lt;br /&gt;
&lt;br /&gt;
=== dockerized / native ===&lt;br /&gt;
&lt;br /&gt;
it remains mostly the same, a container needs to make sure it monitors the right services (distccd, nginx, include_server)&lt;br /&gt;
if you&#039;re using zeroconf, you need to somehow expose the mdns service broadcasts &amp;amp; reception&lt;br /&gt;
&lt;br /&gt;
Processs list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
Workdir list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
=== alpine-chroot ===&lt;br /&gt;
&lt;br /&gt;
when using the &#039;official&#039; script there&#039;s still some odd pieces, seemed to be the processes died on logout. but not all of them.&lt;br /&gt;
&lt;br /&gt;
==== manual launch ====&lt;br /&gt;
&lt;br /&gt;
Starting the daemon would be using&lt;br /&gt;
/usr/bin/distccd --pid-file /var/run/distccd/distccd.pid -N 15 --user distcc --port 3632 --log-level=debug --log-file=/var/log/distccd.log --allow my-sub-net/24&lt;br /&gt;
&lt;br /&gt;
==== localhost? =====&lt;br /&gt;
unclear if you need to use --allow for 127.0.0.1/32 or something to allow the remote preproccesor.&lt;br /&gt;
&lt;br /&gt;
== Kernel specific settings ==&lt;br /&gt;
&lt;br /&gt;
currently (distcc 3.4-r9 on Alpine) you need a patch to build the kernel.&lt;br /&gt;
See &lt;br /&gt;
&lt;br /&gt;
=== Include server Settings ===&lt;br /&gt;
&lt;br /&gt;
cache reset triggers&lt;br /&gt;
This ought to be set before enabling pump mode.&lt;br /&gt;
&lt;br /&gt;
export INCLUDE_SERVER_ARGS=&amp;quot;--stat_reset_triggers=include/linux/compile.h:include/asm/asm-offsets.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
link to explanation TBA&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Disabling GCC Plugins ===&lt;br /&gt;
&lt;br /&gt;
KConfig unselect HAVE_GCC_PLUGINS&lt;br /&gt;
&lt;br /&gt;
Some info is here in the troubleshooting part of the Arch Wiki&lt;br /&gt;
https://wiki.archlinux.org/title/Distcc#Troubleshooting&lt;br /&gt;
&lt;br /&gt;
=== Patches ===&lt;br /&gt;
&lt;br /&gt;
Other things (for 6.6LTS)&lt;br /&gt;
PCIe Stub patch&lt;br /&gt;
&lt;br /&gt;
=== Autoconf === &lt;br /&gt;
&lt;br /&gt;
No known setup examples&lt;br /&gt;
Add whatever it publishes in mdns&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== troubleshooting / analysis ==&lt;br /&gt;
&lt;br /&gt;
=== testing ===&lt;br /&gt;
&lt;br /&gt;
# turn off fallback DISTCC_FALLBACK=1&lt;br /&gt;
# set distcc up to point at specific system under test DISTCC_HOSTS=&amp;quot;mytestbox,cpp,lzo&amp;quot;&lt;br /&gt;
# GCC example compiles&lt;br /&gt;
## code example C&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example C++&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example ObjC&lt;br /&gt;
## same with included header&lt;br /&gt;
# Cmake example compiles&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docoument the thing with compile launcher ccache;distcc&lt;br /&gt;
there&#039;s some blog post, point to that&lt;br /&gt;
no ccache here yet&lt;br /&gt;
show $CC differences distcc vs gcc, what configure scripts see&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Latency ===&lt;br /&gt;
&lt;br /&gt;
Latency of pump mode startups and fallbacks needs to be investigated.&lt;br /&gt;
LZO is enforced even if you have faster network&lt;br /&gt;
DNS Requests, very old bug report from Gcode, one request per call, is it true? how to get rid of it?&lt;br /&gt;
TMPDIR is respected, make sure it&#039;s on ramdisk even on the remote nodes.&lt;br /&gt;
Compile ideally never goes to disk when it doesn&#039;t have to.&lt;br /&gt;
How efficient is the include server collection and unpacking?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== failed to distribute, running locally instead ===&lt;br /&gt;
&lt;br /&gt;
the curse of the ancient, wise bulgarian witch compildora nottherea has befallen people all over the world. only strict and mindless adherence to rituals passed down from generation to generation has given hope to those who are under her ages old spell. again and again it reemerges to prey on idealistic young men and women who spend so much time at their unholy computers that they try to spend less time there by spending a lot of time trying to optimize what the computer does, slowly, instead of reflecting on why they are there, while the computer is busy working, and why they try to solve this by adding a component that makes the computer be more error-prone at that same work, increasing the need of their presense at this idolized thinking machine to oversee and often repair, or worse, mindlessly restart its doing.&lt;br /&gt;
if the curse is not lifted, despair may befall them and all they see is the need to investigate and ruminate further on the workings of this tool, ignoring thereby the obivous flaws that stem from of its alchemic origins.&lt;br /&gt;
&lt;br /&gt;
just wait till you find out it has a backoff alghoritm deciding whether to call out to a remote server independent of that server functioning. graceful performance degradation is the goal, and degrading it is while we try to figure this out.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Node Selection algorithm ====&lt;br /&gt;
&lt;br /&gt;
as per my understanding, a flowchart goes here:&lt;br /&gt;
&lt;br /&gt;
# compile task&lt;br /&gt;
# evaluate whether to run locally by job nature&lt;br /&gt;
# determine if local host&#039;s load is notable&lt;br /&gt;
# look at distcc hosts list&lt;br /&gt;
# do something based off localhost entry if first&lt;br /&gt;
# filter for nodes with cpp flag&lt;br /&gt;
# do something based off localhost entry if not first&lt;br /&gt;
# further prioritize by server order, first is handled in some way&lt;br /&gt;
# skip nodes in backoff prisons&lt;br /&gt;
# balance and priotize by server thread number, if given&lt;br /&gt;
# send to suitable host&lt;br /&gt;
# if compile not successful, proceed on other node&lt;br /&gt;
# if nodes depleted, proceed on localhost&lt;br /&gt;
&lt;br /&gt;
== security ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== tcpwrapper style ip range filter ===&lt;br /&gt;
&lt;br /&gt;
the original security model consists of ip restrictions.&lt;br /&gt;
there seems to also be some GSSAPI user auth.&lt;br /&gt;
further, commands that can be called are restricted by name and location.&lt;br /&gt;
this appears to be a runtime whitelist lookup, meaning it&#039;s done and authorized by the same parts of the daemon as processes the compile request along with the intended compiler.&lt;br /&gt;
so the main weaknesses against malicious clients seem to be in sending things to compile, and in overriding the remote compiler to use.&lt;br /&gt;
it can be assumed that a malicious client able to exploit the compiler handshake can then run arbitrary stuff.&lt;br /&gt;
There&#039;s at least a github issue regarding this (link lost, but see here: https://gitlab.com/postmarketOS/pmbootstrap/-/work_items/1619) suggesting running over ssh. That does only partitally alleviate this risk with regard  to a key based verfication of a client versus a the standard ip restrictions which always include some parsing.&lt;br /&gt;
So this protects against someone directly exploiting the TCP code of distcc.&lt;br /&gt;
It does not protect against malicious clients.&lt;br /&gt;
(ssh force command can&#039;t be used or you&#039;ll not compile anything)&lt;br /&gt;
&lt;br /&gt;
The basic step for protecting access should be filtering who can access the distcc server, so use nftables etc. to restrict access to port 3262 (??) set up the internal filter the same way.&lt;br /&gt;
&lt;br /&gt;
=== seccomp ===&lt;br /&gt;
&lt;br /&gt;
The next thing is to confine the compiler calls to only write in their temp directory and that they can only run compilers (using nsjail, apparmor, selinux etc)&lt;br /&gt;
&lt;br /&gt;
the above issue also references the second bit of security, namely a seccomp filter which will already cover a good bit of the above&lt;br /&gt;
https://github.com/distcc/distcc/pull/235&lt;br /&gt;
the commit got closed without merge, from what I see.&lt;br /&gt;
&lt;br /&gt;
I will update the entry once it&#039;s clear if the patch was later added or instead nothing was done.&lt;br /&gt;
&lt;br /&gt;
=== privs ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The other internal security bit is that they do some priviledge dropping. it runs as a dedicated user (distcc), so you can also have an audit policy, and can/could use something like iptables&#039; to ensure it can only connect to the other distcc/memcached hosts, but nothing else.&lt;br /&gt;
&lt;br /&gt;
=== compiler list ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
One needs to investigate when compiler_whitelist.sh is exactly called. as far as I recall it doesn&#039;t close stdin/stdout.&lt;br /&gt;
&lt;br /&gt;
=== distcc-hardened ===&lt;br /&gt;
&lt;br /&gt;
Alpine adds some hardening patch, idk what nature/origina that has.&lt;br /&gt;
&lt;br /&gt;
=== selinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
there&#039;s also a selinux policy for distcc from gentoo or liguros if one is so inclined.&lt;br /&gt;
https://repology.org/project/selinux-distcc/versions&lt;br /&gt;
&lt;br /&gt;
=== general posture ===&lt;br /&gt;
&lt;br /&gt;
Some security measures like the above should definitely be used since the project at its core relies on accepting foreign input over the network, has only a few part-time maintainers that cannot easily drive the project forward or do large refactors.&lt;br /&gt;
But the seccomp changes were done almost 10 years ago, so, if they were actually upstreamed, I&#039;d say they came through.&lt;br /&gt;
&lt;br /&gt;
A kind of overengineered solulion would be to use netlabel to ensure application integrity across hosts, meaning only a valid process would be able to send packets to the distcc nodes :-)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Arch wiki refers to a fork by SUSE&lt;br /&gt;
https://github.com/icecc/icecream&lt;br /&gt;
&lt;br /&gt;
It appears &#039;maybe better&#039; but hard to tell.&lt;br /&gt;
&lt;br /&gt;
A commercial alternative exists, but I have not tried it.&lt;br /&gt;
Architecturally it seems to be taking the ccache approach with a shared cache and smarter redistribution.&lt;br /&gt;
So anything that can call ccache is something they can scale out. I&#039;ll add a link later, for those whom it helps.&lt;br /&gt;
Naturally it is out of scope for this article.&lt;br /&gt;
Nonetheless it&#039;s interesting since the ordering of how to run ccache and how to run distcc is an issue that also exists in the OSS world. Not just that we don&#039;t have an automatic setup and integration of the tools (ccache, redis, distccd, distcc-pump) but we also don&#039;t have collected sufficient data to aid in deciding which aproach is the best.&lt;br /&gt;
Integrating into CIs (gitlab-runner specifically) is another item where cache persistence becomes very fragile.&lt;br /&gt;
Having an alpine build container that knows how to use ccache with redis and distcc-pump would be a possible step forward.&lt;br /&gt;
&lt;br /&gt;
== Other sources ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://retroflux.net/blog/distcc-adventures/&lt;/div&gt;</summary>
		<author><name>Darkfader</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32182</id>
		<title>User:Darkfader/distcc</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32182"/>
		<updated>2026-03-26T01:12:03Z</updated>

		<summary type="html">&lt;p&gt;Darkfader: /* installation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi,&lt;br /&gt;
&lt;br /&gt;
I&#039;m preparing this page. It can take a long time till I finish.&lt;br /&gt;
If you are also wishing to write on this topic, feel free to integrate the content.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Document overview ==&lt;br /&gt;
&lt;br /&gt;
I noticed that almost every distro has one partially complete, partially helpful document on how to use distcc on the distro.&lt;br /&gt;
Usually they also have one for ccache.&lt;br /&gt;
In either case, they&#039;re enough to get started, but not really a reliable watertight thing.&lt;br /&gt;
We definitely needed one of our own.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== goal ===&lt;br /&gt;
&lt;br /&gt;
to describe a working setup for building aports in easiest/fastests fashion&lt;br /&gt;
not planning to add versatility or features where it would make the setup more errorprone.&lt;br /&gt;
the page should describe enough of the steps to successfully compile an LTS kernel via aports and have that job be distributed over multiple nodes.&lt;br /&gt;
Logs should be set up and able to display errors, but not show any errors during the test compile.&lt;br /&gt;
&lt;br /&gt;
To include a path for analysis via testing components.&lt;br /&gt;
&lt;br /&gt;
distcc can greatly improve compile speeds for large software, it comes with a different set of features than ccache; it focusses not avoiding unneccessary compile work, but on a way to speed up the necessary one.&lt;br /&gt;
&lt;br /&gt;
There&#039;s valuable info in the docs of other distros, it should be referenced here (i.e. the arch wiki troubleshooting), when it makes sense, add a TOC for their content.&lt;br /&gt;
&lt;br /&gt;
=== audience ===&lt;br /&gt;
people running software builds on alpine and have multiple computers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This page will show a specific installation, specific configuration, and specific tests, resulting in a specific set of functionality that can be tested to be working.&lt;br /&gt;
&lt;br /&gt;
== installation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Packages ===&lt;br /&gt;
&lt;br /&gt;
you need, on each host&lt;br /&gt;
* distcc&lt;br /&gt;
* distccd-openrc&lt;br /&gt;
* distcc-pump&lt;br /&gt;
* distcc-pump-pyc&lt;br /&gt;
&lt;br /&gt;
the .pyc will speed up the invocations, without it &lt;br /&gt;
idk if one or both should be installed in that case. but it appears to be also automatically be precompiled in /usr/lib/python3.12/site-packages/include_server/__pycache__/ so what does the package do exactly?&lt;br /&gt;
&lt;br /&gt;
There&#039;s some references to cpython-312, so maybe it actually still uses classy python-c conversion or matbe that&#039;s just a component for reading C source code. I have zero idea.&lt;br /&gt;
&lt;br /&gt;
you also need stuff to do compiles&lt;br /&gt;
* alpine sdk&lt;br /&gt;
* clang&lt;br /&gt;
* binutils&lt;br /&gt;
...&lt;br /&gt;
* elfutils(-dev)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Settings ===&lt;br /&gt;
==== settings for distcc ====&lt;br /&gt;
&lt;br /&gt;
* there&#039;s /etc/default/distcc&lt;br /&gt;
* there&#039;s /etc/conf.d/distcc &lt;br /&gt;
&lt;br /&gt;
make all your settings here&lt;br /&gt;
take care with the listen address, if you specify an IP it&#039;ll not be on 127.0.0.1 in case you would have localhost in your list...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* command_whitelist.sh &lt;br /&gt;
&lt;br /&gt;
this is half functional, you need to set things here but you also need to maintain the symlinks that are collected under /usr/lib/distcc (for your compilers) and /usr/lib/distcc/bin (for itself)&lt;br /&gt;
&lt;br /&gt;
you MUST run the script to update the compilers!&lt;br /&gt;
Info for script and what files it will create&lt;br /&gt;
&lt;br /&gt;
/usr/sbin/update-distcc-symlinks&lt;br /&gt;
&lt;br /&gt;
tschike:/usr/bin# ls -l /usr/lib/distcc/&lt;br /&gt;
total 4&lt;br /&gt;
drwxr-xr-x 2 root root 4096 Mar  2 18:14 bin&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c89 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c99 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 cc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc-15.2.0 -&amp;gt; ../../bin/distcc&lt;br /&gt;
&lt;br /&gt;
distcc itself is in bin&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cpp -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 g++ -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 06:49 x86_64-alpine-linux-musl-gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
&lt;br /&gt;
the last symplink here is wrong, made by me and would not work...&lt;br /&gt;
BAD symlink.&lt;br /&gt;
&lt;br /&gt;
=== distcc hosts file ===&lt;br /&gt;
&lt;br /&gt;
idk about that thing it&#039;s odd&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== abuild.conf ===&lt;br /&gt;
&lt;br /&gt;
settings for aports&lt;br /&gt;
* cc=&lt;br /&gt;
* cxx=&lt;br /&gt;
* cpp=&lt;br /&gt;
* cflags=&lt;br /&gt;
* njobs&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== untested build container system ===&lt;br /&gt;
&lt;br /&gt;
See this one https://github.com/bensuperpc/docker-distcc&lt;br /&gt;
not yet tested, but this could be a good basis for a &#039;best practice&#039; container.&lt;br /&gt;
There&#039;s others, especially for crossbuilds, but those are also very complex to modify.&lt;br /&gt;
&lt;br /&gt;
== detail infos ==&lt;br /&gt;
&lt;br /&gt;
???&lt;br /&gt;
&lt;br /&gt;
=== hosts syntax ===&lt;br /&gt;
&lt;br /&gt;
* myhost otherhost&lt;br /&gt;
* myhost,cpp,lzo myotherhost,cpp,lzo&lt;br /&gt;
&lt;br /&gt;
==== the host ====&lt;br /&gt;
&lt;br /&gt;
hostname/ip&lt;br /&gt;
localhost&lt;br /&gt;
127.0.0.1&lt;br /&gt;
::1 - does not work&lt;br /&gt;
&lt;br /&gt;
==== protocol ====&lt;br /&gt;
&lt;br /&gt;
* no protocol given&lt;br /&gt;
* ,cpp,lzo protocol&lt;br /&gt;
&lt;br /&gt;
cpp implies lzo, it requires compression, even if you have 10gbit/s or more, it&#039;s just hardcoded&lt;br /&gt;
&lt;br /&gt;
=== threads ===&lt;br /&gt;
/number of workers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== architecture ==&lt;br /&gt;
it can handle C, C++, ObjC, maybe some other stuff&lt;br /&gt;
&lt;br /&gt;
* what happens with normal xmit&lt;br /&gt;
* what happens with pump mode&lt;br /&gt;
* at which step the include server is used and how it collects the includes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== distribution algorithm ===&lt;br /&gt;
honestly I simply don&#039;t get it&lt;br /&gt;
&lt;br /&gt;
* The order matters&lt;br /&gt;
* The number of threads matters&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== localhost ====&lt;br /&gt;
&lt;br /&gt;
* localhost precedence&lt;br /&gt;
* localhost fallback&lt;br /&gt;
&lt;br /&gt;
variable: DISTCC_FALLBACK&lt;br /&gt;
&lt;br /&gt;
0 = Fail to compile if it would need to fallback to a normal local gcc call&lt;br /&gt;
1 = If remote compile fails, just do it yourself&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Operation ==&lt;br /&gt;
&lt;br /&gt;
=== startup and shutdown ===&lt;br /&gt;
service distcc stop is not entirely reliable (it can take a minute after the stop until the processes are gone and sometimes it will never stop&lt;br /&gt;
this is very bad with openrc, the openrc script returns after a second and only relies on its service flags, not the process status.&lt;br /&gt;
manually check after stopping, wait a min, if needed, kill it all.&lt;br /&gt;
at some point the rc file needs to be rewritten, it can&#039;t stay like it is.&lt;br /&gt;
&lt;br /&gt;
if you used a pump mode session, that also needs a logout (pump --shutdown)&lt;br /&gt;
avoid running multiple startups without shutdown in one session. it&#039;s safe as far as I can tell but nothing cleans up these processes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== ccache and memcached ===&lt;br /&gt;
CCACHE is said to be conflicting with pump mode unless when you call them in the backend&lt;br /&gt;
so, where you start the compile, you don&#039;t use it&lt;br /&gt;
where the compile happens, you use it&lt;br /&gt;
they can share the cache via memcached, this is a nice trick for consistency&lt;br /&gt;
Upon looking at the ccache website, it seems the correct mechanism is not memcached but Redis. This would work just as well. Generally a cache shared in this way would be optimal for performance.&lt;br /&gt;
&lt;br /&gt;
=== dockerized / native ===&lt;br /&gt;
&lt;br /&gt;
it remains mostly the same, a container needs to make sure it monitors the right services (distccd, nginx, include_server)&lt;br /&gt;
if you&#039;re using zeroconf, you need to somehow expose the mdns service broadcasts &amp;amp; reception&lt;br /&gt;
&lt;br /&gt;
Processs list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
Workdir list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
=== alpine-chroot ===&lt;br /&gt;
&lt;br /&gt;
when using the &#039;official&#039; script there&#039;s still some odd pieces, seemed to be the processes died on logout. but not all of them.&lt;br /&gt;
&lt;br /&gt;
==== manual launch ====&lt;br /&gt;
&lt;br /&gt;
Starting the daemon would be using&lt;br /&gt;
/usr/bin/distccd --pid-file /var/run/distccd/distccd.pid -N 15 --user distcc --port 3632 --log-level=debug --log-file=/var/log/distccd.log --allow my-sub-net/24&lt;br /&gt;
&lt;br /&gt;
==== localhost? =====&lt;br /&gt;
unclear if you need to use --allow for 127.0.0.1/32 or something to allow the remote preproccesor.&lt;br /&gt;
&lt;br /&gt;
== Kernel specific settings ==&lt;br /&gt;
&lt;br /&gt;
currently (distcc 3.4-r9 on Alpine) you need a patch to build the kernel.&lt;br /&gt;
See &lt;br /&gt;
&lt;br /&gt;
=== Include server Settings ===&lt;br /&gt;
&lt;br /&gt;
cache reset triggers&lt;br /&gt;
This ought to be set before enabling pump mode.&lt;br /&gt;
&lt;br /&gt;
export INCLUDE_SERVER_ARGS=&amp;quot;--stat_reset_triggers=include/linux/compile.h:include/asm/asm-offsets.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
link to explanation TBA&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Disabling GCC Plugins ===&lt;br /&gt;
&lt;br /&gt;
KConfig unselect HAVE_GCC_PLUGINS&lt;br /&gt;
&lt;br /&gt;
Some info is here in the troubleshooting part of the Arch Wiki&lt;br /&gt;
https://wiki.archlinux.org/title/Distcc#Troubleshooting&lt;br /&gt;
&lt;br /&gt;
=== Patches ===&lt;br /&gt;
&lt;br /&gt;
Other things (for 6.6LTS)&lt;br /&gt;
PCIe Stub patch&lt;br /&gt;
&lt;br /&gt;
=== Autoconf === &lt;br /&gt;
&lt;br /&gt;
No known setup examples&lt;br /&gt;
Add whatever it publishes in mdns&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== troubleshooting / analysis ==&lt;br /&gt;
&lt;br /&gt;
=== testing ===&lt;br /&gt;
&lt;br /&gt;
# turn off fallback DISTCC_FALLBACK=1&lt;br /&gt;
# set distcc up to point at specific system under test DISTCC_HOSTS=&amp;quot;mytestbox,cpp,lzo&amp;quot;&lt;br /&gt;
# GCC example compiles&lt;br /&gt;
## code example C&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example C++&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example ObjC&lt;br /&gt;
## same with included header&lt;br /&gt;
# Cmake example compiles&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docoument the thing with compile launcher ccache;distcc&lt;br /&gt;
there&#039;s some blog post, point to that&lt;br /&gt;
no ccache here yet&lt;br /&gt;
show $CC differences distcc vs gcc, what configure scripts see&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Latency ===&lt;br /&gt;
&lt;br /&gt;
Latency of pump mode startups and fallbacks needs to be investigated.&lt;br /&gt;
LZO is enforced even if you have faster network&lt;br /&gt;
DNS Requests, very old bug report from Gcode, one request per call, is it true? how to get rid of it?&lt;br /&gt;
TMPDIR is respected, make sure it&#039;s on ramdisk even on the remote nodes.&lt;br /&gt;
Compile ideally never goes to disk when it doesn&#039;t have to.&lt;br /&gt;
How efficient is the include server collection and unpacking?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== failed to distribute, running locally instead ===&lt;br /&gt;
&lt;br /&gt;
the curse of the ancient, wise bulgarian witch compildora nottherea has befallen people all over the world. only strict and mindless adherence to rituals passed down from generation to generation has given hope to those who are under her ages old spell. again and again it reemerges to prey on idealistic young men and women who spend so much time at their unholy computers that they try to spend less time there by spending a lot of time trying to optimize what the computer does, slowly, instead of reflecting on why they are there, while the computer is busy working, and why they try to solve this by adding a component that makes the computer be more error-prone at that same work, increasing the need of their presense at this idolized thinking machine to oversee and often repair, or worse, mindlessly restart its doing.&lt;br /&gt;
if the curse is not lifted, despair may befall them and all they see is the need to investigate and ruminate further on the workings of this tool, ignoring thereby the obivous flaws that stem from of its alchemic origins.&lt;br /&gt;
&lt;br /&gt;
just wait till you find out it has a backoff alghoritm deciding whether to call out to a remote server independent of that server functioning. graceful performance degradation is the goal, and degrading it is while we try to figure this out.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Node Selection algorithm ====&lt;br /&gt;
&lt;br /&gt;
as per my understanding, a flowchart goes here:&lt;br /&gt;
&lt;br /&gt;
# compile task&lt;br /&gt;
# evaluate whether to run locally by job nature&lt;br /&gt;
# determine if local host&#039;s load is notable&lt;br /&gt;
# look at distcc hosts list&lt;br /&gt;
# do something based off localhost entry if first&lt;br /&gt;
# filter for nodes with cpp flag&lt;br /&gt;
# do something based off localhost entry if not first&lt;br /&gt;
# further prioritize by server order, first is handled in some way&lt;br /&gt;
# skip nodes in backoff prisons&lt;br /&gt;
# balance and priotize by server thread number, if given&lt;br /&gt;
# send to suitable host&lt;br /&gt;
# if compile not successful, proceed on other node&lt;br /&gt;
# if nodes depleted, proceed on localhost&lt;br /&gt;
&lt;br /&gt;
== security ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== tcpwrapper style ip range filter ===&lt;br /&gt;
&lt;br /&gt;
the original security model consists of ip restrictions.&lt;br /&gt;
there seems to also be some GSSAPI user auth.&lt;br /&gt;
further, commands that can be called are restricted by name and location.&lt;br /&gt;
this appears to be a runtime whitelist lookup, meaning it&#039;s done and authorized by the same parts of the daemon as processes the compile request along with the intended compiler.&lt;br /&gt;
so the main weaknesses against malicious clients seem to be in sending things to compile, and in overriding the remote compiler to use.&lt;br /&gt;
it can be assumed that a malicious client able to exploit the compiler handshake can then run arbitrary stuff.&lt;br /&gt;
There&#039;s at least a github issue regarding this (link lost, but see here: https://gitlab.com/postmarketOS/pmbootstrap/-/work_items/1619) suggesting running over ssh. That does only partitally alleviate this risk with regard  to a key based verfication of a client versus a the standard ip restrictions which always include some parsing.&lt;br /&gt;
So this protects against someone directly exploiting the TCP code of distcc.&lt;br /&gt;
It does not protect against malicious clients.&lt;br /&gt;
(ssh force command can&#039;t be used or you&#039;ll not compile anything)&lt;br /&gt;
&lt;br /&gt;
The basic step for protecting access should be filtering who can access the distcc server, so use nftables etc. to restrict access to port 3262 (??) set up the internal filter the same way.&lt;br /&gt;
&lt;br /&gt;
=== seccomp ===&lt;br /&gt;
&lt;br /&gt;
The next thing is to confine the compiler calls to only write in their temp directory and that they can only run compilers (using nsjail, apparmor, selinux etc)&lt;br /&gt;
&lt;br /&gt;
the above issue also references the second bit of security, namely a seccomp filter which will already cover a good bit of the above&lt;br /&gt;
https://github.com/distcc/distcc/pull/235&lt;br /&gt;
the commit got closed without merge, from what I see.&lt;br /&gt;
&lt;br /&gt;
I will update the entry once it&#039;s clear if the patch was later added or instead nothing was done.&lt;br /&gt;
&lt;br /&gt;
=== privs ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The other internal security bit is that they do some priviledge dropping. it runs as a dedicated user (distcc), so you can also have an audit policy, and can/could use something like iptables&#039; to ensure it can only connect to the other distcc/memcached hosts, but nothing else.&lt;br /&gt;
&lt;br /&gt;
=== compiler list ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
One needs to investigate when compiler_whitelist.sh is exactly called. as far as I recall it doesn&#039;t close stdin/stdout.&lt;br /&gt;
&lt;br /&gt;
=== distcc-hardened ===&lt;br /&gt;
&lt;br /&gt;
Alpine adds some hardening patch, idk what nature/origina that has.&lt;br /&gt;
&lt;br /&gt;
=== selinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
there&#039;s also a selinux policy for distcc from gentoo or liguros if one is so inclined.&lt;br /&gt;
https://repology.org/project/selinux-distcc/versions&lt;br /&gt;
&lt;br /&gt;
=== general posture ===&lt;br /&gt;
&lt;br /&gt;
Some security measures like the above should definitely be used since the project at its core relies on accepting foreign input over the network, has only a few part-time maintainers that cannot easily drive the project forward or do large refactors.&lt;br /&gt;
But the seccomp changes were done almost 10 years ago, so, if they were actually upstreamed, I&#039;d say they came through.&lt;br /&gt;
&lt;br /&gt;
A kind of overengineered solulion would be to use netlabel to ensure application integrity across hosts, meaning only a valid process would be able to send packets to the distcc nodes :-)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Arch wiki refers to a fork by SUSE&lt;br /&gt;
https://github.com/icecc/icecream&lt;br /&gt;
&lt;br /&gt;
It appears &#039;maybe better&#039; but hard to tell.&lt;br /&gt;
&lt;br /&gt;
A commercial alternative exists, but I have not tried it.&lt;br /&gt;
Architecturally it seems to be taking the ccache approach with a shared cache and smarter redistribution.&lt;br /&gt;
So anything that can call ccache is something they can scale out. I&#039;ll add a link later, for those whom it helps.&lt;br /&gt;
Naturally it is out of scope for this article.&lt;br /&gt;
Nonetheless it&#039;s interesting since the ordering of how to run ccache and how to run distcc is an issue that also exists in the OSS world. Not just that we don&#039;t have an automatic setup and integration of the tools (ccache, redis, distccd, distcc-pump) but we also don&#039;t have collected sufficient data to aid in deciding which aproach is the best.&lt;br /&gt;
Integrating into CIs (gitlab-runner specifically) is another item where cache persistence becomes very fragile.&lt;br /&gt;
Having an alpine build container that knows how to use ccache with redis and distcc-pump would be a possible step forward.&lt;/div&gt;</summary>
		<author><name>Darkfader</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32181</id>
		<title>User:Darkfader/distcc</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32181"/>
		<updated>2026-03-26T01:09:24Z</updated>

		<summary type="html">&lt;p&gt;Darkfader: /* tcpwrapper style ip range filter */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi,&lt;br /&gt;
&lt;br /&gt;
I&#039;m preparing this page. It can take a long time till I finish.&lt;br /&gt;
If you are also wishing to write on this topic, feel free to integrate the content.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Document overview ==&lt;br /&gt;
&lt;br /&gt;
I noticed that almost every distro has one partially complete, partially helpful document on how to use distcc on the distro.&lt;br /&gt;
Usually they also have one for ccache.&lt;br /&gt;
In either case, they&#039;re enough to get started, but not really a reliable watertight thing.&lt;br /&gt;
We definitely needed one of our own.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== goal ===&lt;br /&gt;
&lt;br /&gt;
to describe a working setup for building aports in easiest/fastests fashion&lt;br /&gt;
not planning to add versatility or features where it would make the setup more errorprone.&lt;br /&gt;
the page should describe enough of the steps to successfully compile an LTS kernel via aports and have that job be distributed over multiple nodes.&lt;br /&gt;
Logs should be set up and able to display errors, but not show any errors during the test compile.&lt;br /&gt;
&lt;br /&gt;
To include a path for analysis via testing components.&lt;br /&gt;
&lt;br /&gt;
distcc can greatly improve compile speeds for large software, it comes with a different set of features than ccache; it focusses not avoiding unneccessary compile work, but on a way to speed up the necessary one.&lt;br /&gt;
&lt;br /&gt;
There&#039;s valuable info in the docs of other distros, it should be referenced here (i.e. the arch wiki troubleshooting), when it makes sense, add a TOC for their content.&lt;br /&gt;
&lt;br /&gt;
=== audience ===&lt;br /&gt;
people running software builds on alpine and have multiple computers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This page will show a specific installation, specific configuration, and specific tests, resulting in a specific set of functionality that can be tested to be working.&lt;br /&gt;
&lt;br /&gt;
== installation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Packages ===&lt;br /&gt;
&lt;br /&gt;
you need, on each host&lt;br /&gt;
* distcc&lt;br /&gt;
* distccd-openrc&lt;br /&gt;
* distcc-pump&lt;br /&gt;
* distcc-pump-pyc&lt;br /&gt;
&lt;br /&gt;
the .pyc will speed up the invocations, without it &lt;br /&gt;
idk if one or both should be installed in that case. but it appears to be also automatically be precompiled in /usr/lib/python3.12/site-packages/include_server/__pycache__/ so what does the package do exactly?&lt;br /&gt;
&lt;br /&gt;
There&#039;s some references to cpython-312, so maybe it actually still uses classy python-c conversion or matbe that&#039;s just a component for reading C source code. I have zero idea.&lt;br /&gt;
&lt;br /&gt;
you also need stuff to do compiles&lt;br /&gt;
* alpine sdk&lt;br /&gt;
* clang&lt;br /&gt;
* binutils&lt;br /&gt;
...&lt;br /&gt;
* elfutils(-dev)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Settings ===&lt;br /&gt;
==== settings for distcc ====&lt;br /&gt;
&lt;br /&gt;
* there&#039;s /etc/default/distcc&lt;br /&gt;
* there&#039;s /etc/conf.d/distcc &lt;br /&gt;
&lt;br /&gt;
make all your settings here&lt;br /&gt;
take care with the listen address, if you specify an IP it&#039;ll not be on 127.0.0.1 in case you would have localhost in your list...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* command_whitelist.sh &lt;br /&gt;
&lt;br /&gt;
this is half functional, you need to set things here but you also need to maintain the symlinks that are collected under /usr/lib/distcc (for your compilers) and /usr/lib/distcc/bin (for itself)&lt;br /&gt;
&lt;br /&gt;
you MUST run the script to update the compilers!&lt;br /&gt;
Info for script and what files it will create&lt;br /&gt;
&lt;br /&gt;
/usr/sbin/update-distcc-symlinks&lt;br /&gt;
&lt;br /&gt;
tschike:/usr/bin# ls -l /usr/lib/distcc/&lt;br /&gt;
total 4&lt;br /&gt;
drwxr-xr-x 2 root root 4096 Mar  2 18:14 bin&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c89 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c99 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 cc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc-15.2.0 -&amp;gt; ../../bin/distcc&lt;br /&gt;
&lt;br /&gt;
distcc itself is in bin&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cpp -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 g++ -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 06:49 x86_64-alpine-linux-musl-gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
&lt;br /&gt;
the last symplink here is wrong, made by me and would not work...&lt;br /&gt;
BAD symlink.&lt;br /&gt;
&lt;br /&gt;
=== distcc hosts file ===&lt;br /&gt;
&lt;br /&gt;
idk about that thing it&#039;s odd&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== abuild.conf ===&lt;br /&gt;
&lt;br /&gt;
settings for aports&lt;br /&gt;
* cc=&lt;br /&gt;
* cxx=&lt;br /&gt;
* cpp=&lt;br /&gt;
* cflags=&lt;br /&gt;
* njobs&lt;br /&gt;
&lt;br /&gt;
== detail infos ==&lt;br /&gt;
&lt;br /&gt;
???&lt;br /&gt;
&lt;br /&gt;
=== hosts syntax ===&lt;br /&gt;
&lt;br /&gt;
* myhost otherhost&lt;br /&gt;
* myhost,cpp,lzo myotherhost,cpp,lzo&lt;br /&gt;
&lt;br /&gt;
==== the host ====&lt;br /&gt;
&lt;br /&gt;
hostname/ip&lt;br /&gt;
localhost&lt;br /&gt;
127.0.0.1&lt;br /&gt;
::1 - does not work&lt;br /&gt;
&lt;br /&gt;
==== protocol ====&lt;br /&gt;
&lt;br /&gt;
* no protocol given&lt;br /&gt;
* ,cpp,lzo protocol&lt;br /&gt;
&lt;br /&gt;
cpp implies lzo, it requires compression, even if you have 10gbit/s or more, it&#039;s just hardcoded&lt;br /&gt;
&lt;br /&gt;
=== threads ===&lt;br /&gt;
/number of workers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== architecture ==&lt;br /&gt;
it can handle C, C++, ObjC, maybe some other stuff&lt;br /&gt;
&lt;br /&gt;
* what happens with normal xmit&lt;br /&gt;
* what happens with pump mode&lt;br /&gt;
* at which step the include server is used and how it collects the includes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== distribution algorithm ===&lt;br /&gt;
honestly I simply don&#039;t get it&lt;br /&gt;
&lt;br /&gt;
* The order matters&lt;br /&gt;
* The number of threads matters&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== localhost ====&lt;br /&gt;
&lt;br /&gt;
* localhost precedence&lt;br /&gt;
* localhost fallback&lt;br /&gt;
&lt;br /&gt;
variable: DISTCC_FALLBACK&lt;br /&gt;
&lt;br /&gt;
0 = Fail to compile if it would need to fallback to a normal local gcc call&lt;br /&gt;
1 = If remote compile fails, just do it yourself&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Operation ==&lt;br /&gt;
&lt;br /&gt;
=== startup and shutdown ===&lt;br /&gt;
service distcc stop is not entirely reliable (it can take a minute after the stop until the processes are gone and sometimes it will never stop&lt;br /&gt;
this is very bad with openrc, the openrc script returns after a second and only relies on its service flags, not the process status.&lt;br /&gt;
manually check after stopping, wait a min, if needed, kill it all.&lt;br /&gt;
at some point the rc file needs to be rewritten, it can&#039;t stay like it is.&lt;br /&gt;
&lt;br /&gt;
if you used a pump mode session, that also needs a logout (pump --shutdown)&lt;br /&gt;
avoid running multiple startups without shutdown in one session. it&#039;s safe as far as I can tell but nothing cleans up these processes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== ccache and memcached ===&lt;br /&gt;
CCACHE is said to be conflicting with pump mode unless when you call them in the backend&lt;br /&gt;
so, where you start the compile, you don&#039;t use it&lt;br /&gt;
where the compile happens, you use it&lt;br /&gt;
they can share the cache via memcached, this is a nice trick for consistency&lt;br /&gt;
Upon looking at the ccache website, it seems the correct mechanism is not memcached but Redis. This would work just as well. Generally a cache shared in this way would be optimal for performance.&lt;br /&gt;
&lt;br /&gt;
=== dockerized / native ===&lt;br /&gt;
&lt;br /&gt;
it remains mostly the same, a container needs to make sure it monitors the right services (distccd, nginx, include_server)&lt;br /&gt;
if you&#039;re using zeroconf, you need to somehow expose the mdns service broadcasts &amp;amp; reception&lt;br /&gt;
&lt;br /&gt;
Processs list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
Workdir list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
=== alpine-chroot ===&lt;br /&gt;
&lt;br /&gt;
when using the &#039;official&#039; script there&#039;s still some odd pieces, seemed to be the processes died on logout. but not all of them.&lt;br /&gt;
&lt;br /&gt;
==== manual launch ====&lt;br /&gt;
&lt;br /&gt;
Starting the daemon would be using&lt;br /&gt;
/usr/bin/distccd --pid-file /var/run/distccd/distccd.pid -N 15 --user distcc --port 3632 --log-level=debug --log-file=/var/log/distccd.log --allow my-sub-net/24&lt;br /&gt;
&lt;br /&gt;
==== localhost? =====&lt;br /&gt;
unclear if you need to use --allow for 127.0.0.1/32 or something to allow the remote preproccesor.&lt;br /&gt;
&lt;br /&gt;
== Kernel specific settings ==&lt;br /&gt;
&lt;br /&gt;
currently (distcc 3.4-r9 on Alpine) you need a patch to build the kernel.&lt;br /&gt;
See &lt;br /&gt;
&lt;br /&gt;
=== Include server Settings ===&lt;br /&gt;
&lt;br /&gt;
cache reset triggers&lt;br /&gt;
This ought to be set before enabling pump mode.&lt;br /&gt;
&lt;br /&gt;
export INCLUDE_SERVER_ARGS=&amp;quot;--stat_reset_triggers=include/linux/compile.h:include/asm/asm-offsets.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
link to explanation TBA&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Disabling GCC Plugins ===&lt;br /&gt;
&lt;br /&gt;
KConfig unselect HAVE_GCC_PLUGINS&lt;br /&gt;
&lt;br /&gt;
Some info is here in the troubleshooting part of the Arch Wiki&lt;br /&gt;
https://wiki.archlinux.org/title/Distcc#Troubleshooting&lt;br /&gt;
&lt;br /&gt;
=== Patches ===&lt;br /&gt;
&lt;br /&gt;
Other things (for 6.6LTS)&lt;br /&gt;
PCIe Stub patch&lt;br /&gt;
&lt;br /&gt;
=== Autoconf === &lt;br /&gt;
&lt;br /&gt;
No known setup examples&lt;br /&gt;
Add whatever it publishes in mdns&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== troubleshooting / analysis ==&lt;br /&gt;
&lt;br /&gt;
=== testing ===&lt;br /&gt;
&lt;br /&gt;
# turn off fallback DISTCC_FALLBACK=1&lt;br /&gt;
# set distcc up to point at specific system under test DISTCC_HOSTS=&amp;quot;mytestbox,cpp,lzo&amp;quot;&lt;br /&gt;
# GCC example compiles&lt;br /&gt;
## code example C&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example C++&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example ObjC&lt;br /&gt;
## same with included header&lt;br /&gt;
# Cmake example compiles&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docoument the thing with compile launcher ccache;distcc&lt;br /&gt;
there&#039;s some blog post, point to that&lt;br /&gt;
no ccache here yet&lt;br /&gt;
show $CC differences distcc vs gcc, what configure scripts see&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Latency ===&lt;br /&gt;
&lt;br /&gt;
Latency of pump mode startups and fallbacks needs to be investigated.&lt;br /&gt;
LZO is enforced even if you have faster network&lt;br /&gt;
DNS Requests, very old bug report from Gcode, one request per call, is it true? how to get rid of it?&lt;br /&gt;
TMPDIR is respected, make sure it&#039;s on ramdisk even on the remote nodes.&lt;br /&gt;
Compile ideally never goes to disk when it doesn&#039;t have to.&lt;br /&gt;
How efficient is the include server collection and unpacking?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== failed to distribute, running locally instead ===&lt;br /&gt;
&lt;br /&gt;
the curse of the ancient, wise bulgarian witch compildora nottherea has befallen people all over the world. only strict and mindless adherence to rituals passed down from generation to generation has given hope to those who are under her ages old spell. again and again it reemerges to prey on idealistic young men and women who spend so much time at their unholy computers that they try to spend less time there by spending a lot of time trying to optimize what the computer does, slowly, instead of reflecting on why they are there, while the computer is busy working, and why they try to solve this by adding a component that makes the computer be more error-prone at that same work, increasing the need of their presense at this idolized thinking machine to oversee and often repair, or worse, mindlessly restart its doing.&lt;br /&gt;
if the curse is not lifted, despair may befall them and all they see is the need to investigate and ruminate further on the workings of this tool, ignoring thereby the obivous flaws that stem from of its alchemic origins.&lt;br /&gt;
&lt;br /&gt;
just wait till you find out it has a backoff alghoritm deciding whether to call out to a remote server independent of that server functioning. graceful performance degradation is the goal, and degrading it is while we try to figure this out.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Node Selection algorithm ====&lt;br /&gt;
&lt;br /&gt;
as per my understanding, a flowchart goes here:&lt;br /&gt;
&lt;br /&gt;
# compile task&lt;br /&gt;
# evaluate whether to run locally by job nature&lt;br /&gt;
# determine if local host&#039;s load is notable&lt;br /&gt;
# look at distcc hosts list&lt;br /&gt;
# do something based off localhost entry if first&lt;br /&gt;
# filter for nodes with cpp flag&lt;br /&gt;
# do something based off localhost entry if not first&lt;br /&gt;
# further prioritize by server order, first is handled in some way&lt;br /&gt;
# skip nodes in backoff prisons&lt;br /&gt;
# balance and priotize by server thread number, if given&lt;br /&gt;
# send to suitable host&lt;br /&gt;
# if compile not successful, proceed on other node&lt;br /&gt;
# if nodes depleted, proceed on localhost&lt;br /&gt;
&lt;br /&gt;
== security ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== tcpwrapper style ip range filter ===&lt;br /&gt;
&lt;br /&gt;
the original security model consists of ip restrictions.&lt;br /&gt;
there seems to also be some GSSAPI user auth.&lt;br /&gt;
further, commands that can be called are restricted by name and location.&lt;br /&gt;
this appears to be a runtime whitelist lookup, meaning it&#039;s done and authorized by the same parts of the daemon as processes the compile request along with the intended compiler.&lt;br /&gt;
so the main weaknesses against malicious clients seem to be in sending things to compile, and in overriding the remote compiler to use.&lt;br /&gt;
it can be assumed that a malicious client able to exploit the compiler handshake can then run arbitrary stuff.&lt;br /&gt;
There&#039;s at least a github issue regarding this (link lost, but see here: https://gitlab.com/postmarketOS/pmbootstrap/-/work_items/1619) suggesting running over ssh. That does only partitally alleviate this risk with regard  to a key based verfication of a client versus a the standard ip restrictions which always include some parsing.&lt;br /&gt;
So this protects against someone directly exploiting the TCP code of distcc.&lt;br /&gt;
It does not protect against malicious clients.&lt;br /&gt;
(ssh force command can&#039;t be used or you&#039;ll not compile anything)&lt;br /&gt;
&lt;br /&gt;
The basic step for protecting access should be filtering who can access the distcc server, so use nftables etc. to restrict access to port 3262 (??) set up the internal filter the same way.&lt;br /&gt;
&lt;br /&gt;
=== seccomp ===&lt;br /&gt;
&lt;br /&gt;
The next thing is to confine the compiler calls to only write in their temp directory and that they can only run compilers (using nsjail, apparmor, selinux etc)&lt;br /&gt;
&lt;br /&gt;
the above issue also references the second bit of security, namely a seccomp filter which will already cover a good bit of the above&lt;br /&gt;
https://github.com/distcc/distcc/pull/235&lt;br /&gt;
the commit got closed without merge, from what I see.&lt;br /&gt;
&lt;br /&gt;
I will update the entry once it&#039;s clear if the patch was later added or instead nothing was done.&lt;br /&gt;
&lt;br /&gt;
=== privs ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The other internal security bit is that they do some priviledge dropping. it runs as a dedicated user (distcc), so you can also have an audit policy, and can/could use something like iptables&#039; to ensure it can only connect to the other distcc/memcached hosts, but nothing else.&lt;br /&gt;
&lt;br /&gt;
=== compiler list ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
One needs to investigate when compiler_whitelist.sh is exactly called. as far as I recall it doesn&#039;t close stdin/stdout.&lt;br /&gt;
&lt;br /&gt;
=== distcc-hardened ===&lt;br /&gt;
&lt;br /&gt;
Alpine adds some hardening patch, idk what nature/origina that has.&lt;br /&gt;
&lt;br /&gt;
=== selinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
there&#039;s also a selinux policy for distcc from gentoo or liguros if one is so inclined.&lt;br /&gt;
https://repology.org/project/selinux-distcc/versions&lt;br /&gt;
&lt;br /&gt;
=== general posture ===&lt;br /&gt;
&lt;br /&gt;
Some security measures like the above should definitely be used since the project at its core relies on accepting foreign input over the network, has only a few part-time maintainers that cannot easily drive the project forward or do large refactors.&lt;br /&gt;
But the seccomp changes were done almost 10 years ago, so, if they were actually upstreamed, I&#039;d say they came through.&lt;br /&gt;
&lt;br /&gt;
A kind of overengineered solulion would be to use netlabel to ensure application integrity across hosts, meaning only a valid process would be able to send packets to the distcc nodes :-)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Arch wiki refers to a fork by SUSE&lt;br /&gt;
https://github.com/icecc/icecream&lt;br /&gt;
&lt;br /&gt;
It appears &#039;maybe better&#039; but hard to tell.&lt;br /&gt;
&lt;br /&gt;
A commercial alternative exists, but I have not tried it.&lt;br /&gt;
Architecturally it seems to be taking the ccache approach with a shared cache and smarter redistribution.&lt;br /&gt;
So anything that can call ccache is something they can scale out. I&#039;ll add a link later, for those whom it helps.&lt;br /&gt;
Naturally it is out of scope for this article.&lt;br /&gt;
Nonetheless it&#039;s interesting since the ordering of how to run ccache and how to run distcc is an issue that also exists in the OSS world. Not just that we don&#039;t have an automatic setup and integration of the tools (ccache, redis, distccd, distcc-pump) but we also don&#039;t have collected sufficient data to aid in deciding which aproach is the best.&lt;br /&gt;
Integrating into CIs (gitlab-runner specifically) is another item where cache persistence becomes very fragile.&lt;br /&gt;
Having an alpine build container that knows how to use ccache with redis and distcc-pump would be a possible step forward.&lt;/div&gt;</summary>
		<author><name>Darkfader</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32180</id>
		<title>User:Darkfader/distcc</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32180"/>
		<updated>2026-03-26T01:08:21Z</updated>

		<summary type="html">&lt;p&gt;Darkfader: /* general posture */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi,&lt;br /&gt;
&lt;br /&gt;
I&#039;m preparing this page. It can take a long time till I finish.&lt;br /&gt;
If you are also wishing to write on this topic, feel free to integrate the content.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Document overview ==&lt;br /&gt;
&lt;br /&gt;
I noticed that almost every distro has one partially complete, partially helpful document on how to use distcc on the distro.&lt;br /&gt;
Usually they also have one for ccache.&lt;br /&gt;
In either case, they&#039;re enough to get started, but not really a reliable watertight thing.&lt;br /&gt;
We definitely needed one of our own.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== goal ===&lt;br /&gt;
&lt;br /&gt;
to describe a working setup for building aports in easiest/fastests fashion&lt;br /&gt;
not planning to add versatility or features where it would make the setup more errorprone.&lt;br /&gt;
the page should describe enough of the steps to successfully compile an LTS kernel via aports and have that job be distributed over multiple nodes.&lt;br /&gt;
Logs should be set up and able to display errors, but not show any errors during the test compile.&lt;br /&gt;
&lt;br /&gt;
To include a path for analysis via testing components.&lt;br /&gt;
&lt;br /&gt;
distcc can greatly improve compile speeds for large software, it comes with a different set of features than ccache; it focusses not avoiding unneccessary compile work, but on a way to speed up the necessary one.&lt;br /&gt;
&lt;br /&gt;
There&#039;s valuable info in the docs of other distros, it should be referenced here (i.e. the arch wiki troubleshooting), when it makes sense, add a TOC for their content.&lt;br /&gt;
&lt;br /&gt;
=== audience ===&lt;br /&gt;
people running software builds on alpine and have multiple computers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This page will show a specific installation, specific configuration, and specific tests, resulting in a specific set of functionality that can be tested to be working.&lt;br /&gt;
&lt;br /&gt;
== installation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Packages ===&lt;br /&gt;
&lt;br /&gt;
you need, on each host&lt;br /&gt;
* distcc&lt;br /&gt;
* distccd-openrc&lt;br /&gt;
* distcc-pump&lt;br /&gt;
* distcc-pump-pyc&lt;br /&gt;
&lt;br /&gt;
the .pyc will speed up the invocations, without it &lt;br /&gt;
idk if one or both should be installed in that case. but it appears to be also automatically be precompiled in /usr/lib/python3.12/site-packages/include_server/__pycache__/ so what does the package do exactly?&lt;br /&gt;
&lt;br /&gt;
There&#039;s some references to cpython-312, so maybe it actually still uses classy python-c conversion or matbe that&#039;s just a component for reading C source code. I have zero idea.&lt;br /&gt;
&lt;br /&gt;
you also need stuff to do compiles&lt;br /&gt;
* alpine sdk&lt;br /&gt;
* clang&lt;br /&gt;
* binutils&lt;br /&gt;
...&lt;br /&gt;
* elfutils(-dev)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Settings ===&lt;br /&gt;
==== settings for distcc ====&lt;br /&gt;
&lt;br /&gt;
* there&#039;s /etc/default/distcc&lt;br /&gt;
* there&#039;s /etc/conf.d/distcc &lt;br /&gt;
&lt;br /&gt;
make all your settings here&lt;br /&gt;
take care with the listen address, if you specify an IP it&#039;ll not be on 127.0.0.1 in case you would have localhost in your list...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* command_whitelist.sh &lt;br /&gt;
&lt;br /&gt;
this is half functional, you need to set things here but you also need to maintain the symlinks that are collected under /usr/lib/distcc (for your compilers) and /usr/lib/distcc/bin (for itself)&lt;br /&gt;
&lt;br /&gt;
you MUST run the script to update the compilers!&lt;br /&gt;
Info for script and what files it will create&lt;br /&gt;
&lt;br /&gt;
/usr/sbin/update-distcc-symlinks&lt;br /&gt;
&lt;br /&gt;
tschike:/usr/bin# ls -l /usr/lib/distcc/&lt;br /&gt;
total 4&lt;br /&gt;
drwxr-xr-x 2 root root 4096 Mar  2 18:14 bin&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c89 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c99 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 cc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc-15.2.0 -&amp;gt; ../../bin/distcc&lt;br /&gt;
&lt;br /&gt;
distcc itself is in bin&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cpp -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 g++ -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 06:49 x86_64-alpine-linux-musl-gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
&lt;br /&gt;
the last symplink here is wrong, made by me and would not work...&lt;br /&gt;
BAD symlink.&lt;br /&gt;
&lt;br /&gt;
=== distcc hosts file ===&lt;br /&gt;
&lt;br /&gt;
idk about that thing it&#039;s odd&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== abuild.conf ===&lt;br /&gt;
&lt;br /&gt;
settings for aports&lt;br /&gt;
* cc=&lt;br /&gt;
* cxx=&lt;br /&gt;
* cpp=&lt;br /&gt;
* cflags=&lt;br /&gt;
* njobs&lt;br /&gt;
&lt;br /&gt;
== detail infos ==&lt;br /&gt;
&lt;br /&gt;
???&lt;br /&gt;
&lt;br /&gt;
=== hosts syntax ===&lt;br /&gt;
&lt;br /&gt;
* myhost otherhost&lt;br /&gt;
* myhost,cpp,lzo myotherhost,cpp,lzo&lt;br /&gt;
&lt;br /&gt;
==== the host ====&lt;br /&gt;
&lt;br /&gt;
hostname/ip&lt;br /&gt;
localhost&lt;br /&gt;
127.0.0.1&lt;br /&gt;
::1 - does not work&lt;br /&gt;
&lt;br /&gt;
==== protocol ====&lt;br /&gt;
&lt;br /&gt;
* no protocol given&lt;br /&gt;
* ,cpp,lzo protocol&lt;br /&gt;
&lt;br /&gt;
cpp implies lzo, it requires compression, even if you have 10gbit/s or more, it&#039;s just hardcoded&lt;br /&gt;
&lt;br /&gt;
=== threads ===&lt;br /&gt;
/number of workers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== architecture ==&lt;br /&gt;
it can handle C, C++, ObjC, maybe some other stuff&lt;br /&gt;
&lt;br /&gt;
* what happens with normal xmit&lt;br /&gt;
* what happens with pump mode&lt;br /&gt;
* at which step the include server is used and how it collects the includes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== distribution algorithm ===&lt;br /&gt;
honestly I simply don&#039;t get it&lt;br /&gt;
&lt;br /&gt;
* The order matters&lt;br /&gt;
* The number of threads matters&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== localhost ====&lt;br /&gt;
&lt;br /&gt;
* localhost precedence&lt;br /&gt;
* localhost fallback&lt;br /&gt;
&lt;br /&gt;
variable: DISTCC_FALLBACK&lt;br /&gt;
&lt;br /&gt;
0 = Fail to compile if it would need to fallback to a normal local gcc call&lt;br /&gt;
1 = If remote compile fails, just do it yourself&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Operation ==&lt;br /&gt;
&lt;br /&gt;
=== startup and shutdown ===&lt;br /&gt;
service distcc stop is not entirely reliable (it can take a minute after the stop until the processes are gone and sometimes it will never stop&lt;br /&gt;
this is very bad with openrc, the openrc script returns after a second and only relies on its service flags, not the process status.&lt;br /&gt;
manually check after stopping, wait a min, if needed, kill it all.&lt;br /&gt;
at some point the rc file needs to be rewritten, it can&#039;t stay like it is.&lt;br /&gt;
&lt;br /&gt;
if you used a pump mode session, that also needs a logout (pump --shutdown)&lt;br /&gt;
avoid running multiple startups without shutdown in one session. it&#039;s safe as far as I can tell but nothing cleans up these processes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== ccache and memcached ===&lt;br /&gt;
CCACHE is said to be conflicting with pump mode unless when you call them in the backend&lt;br /&gt;
so, where you start the compile, you don&#039;t use it&lt;br /&gt;
where the compile happens, you use it&lt;br /&gt;
they can share the cache via memcached, this is a nice trick for consistency&lt;br /&gt;
Upon looking at the ccache website, it seems the correct mechanism is not memcached but Redis. This would work just as well. Generally a cache shared in this way would be optimal for performance.&lt;br /&gt;
&lt;br /&gt;
=== dockerized / native ===&lt;br /&gt;
&lt;br /&gt;
it remains mostly the same, a container needs to make sure it monitors the right services (distccd, nginx, include_server)&lt;br /&gt;
if you&#039;re using zeroconf, you need to somehow expose the mdns service broadcasts &amp;amp; reception&lt;br /&gt;
&lt;br /&gt;
Processs list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
Workdir list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
=== alpine-chroot ===&lt;br /&gt;
&lt;br /&gt;
when using the &#039;official&#039; script there&#039;s still some odd pieces, seemed to be the processes died on logout. but not all of them.&lt;br /&gt;
&lt;br /&gt;
==== manual launch ====&lt;br /&gt;
&lt;br /&gt;
Starting the daemon would be using&lt;br /&gt;
/usr/bin/distccd --pid-file /var/run/distccd/distccd.pid -N 15 --user distcc --port 3632 --log-level=debug --log-file=/var/log/distccd.log --allow my-sub-net/24&lt;br /&gt;
&lt;br /&gt;
==== localhost? =====&lt;br /&gt;
unclear if you need to use --allow for 127.0.0.1/32 or something to allow the remote preproccesor.&lt;br /&gt;
&lt;br /&gt;
== Kernel specific settings ==&lt;br /&gt;
&lt;br /&gt;
currently (distcc 3.4-r9 on Alpine) you need a patch to build the kernel.&lt;br /&gt;
See &lt;br /&gt;
&lt;br /&gt;
=== Include server Settings ===&lt;br /&gt;
&lt;br /&gt;
cache reset triggers&lt;br /&gt;
This ought to be set before enabling pump mode.&lt;br /&gt;
&lt;br /&gt;
export INCLUDE_SERVER_ARGS=&amp;quot;--stat_reset_triggers=include/linux/compile.h:include/asm/asm-offsets.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
link to explanation TBA&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Disabling GCC Plugins ===&lt;br /&gt;
&lt;br /&gt;
KConfig unselect HAVE_GCC_PLUGINS&lt;br /&gt;
&lt;br /&gt;
Some info is here in the troubleshooting part of the Arch Wiki&lt;br /&gt;
https://wiki.archlinux.org/title/Distcc#Troubleshooting&lt;br /&gt;
&lt;br /&gt;
=== Patches ===&lt;br /&gt;
&lt;br /&gt;
Other things (for 6.6LTS)&lt;br /&gt;
PCIe Stub patch&lt;br /&gt;
&lt;br /&gt;
=== Autoconf === &lt;br /&gt;
&lt;br /&gt;
No known setup examples&lt;br /&gt;
Add whatever it publishes in mdns&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== troubleshooting / analysis ==&lt;br /&gt;
&lt;br /&gt;
=== testing ===&lt;br /&gt;
&lt;br /&gt;
# turn off fallback DISTCC_FALLBACK=1&lt;br /&gt;
# set distcc up to point at specific system under test DISTCC_HOSTS=&amp;quot;mytestbox,cpp,lzo&amp;quot;&lt;br /&gt;
# GCC example compiles&lt;br /&gt;
## code example C&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example C++&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example ObjC&lt;br /&gt;
## same with included header&lt;br /&gt;
# Cmake example compiles&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docoument the thing with compile launcher ccache;distcc&lt;br /&gt;
there&#039;s some blog post, point to that&lt;br /&gt;
no ccache here yet&lt;br /&gt;
show $CC differences distcc vs gcc, what configure scripts see&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Latency ===&lt;br /&gt;
&lt;br /&gt;
Latency of pump mode startups and fallbacks needs to be investigated.&lt;br /&gt;
LZO is enforced even if you have faster network&lt;br /&gt;
DNS Requests, very old bug report from Gcode, one request per call, is it true? how to get rid of it?&lt;br /&gt;
TMPDIR is respected, make sure it&#039;s on ramdisk even on the remote nodes.&lt;br /&gt;
Compile ideally never goes to disk when it doesn&#039;t have to.&lt;br /&gt;
How efficient is the include server collection and unpacking?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== failed to distribute, running locally instead ===&lt;br /&gt;
&lt;br /&gt;
the curse of the ancient, wise bulgarian witch compildora nottherea has befallen people all over the world. only strict and mindless adherence to rituals passed down from generation to generation has given hope to those who are under her ages old spell. again and again it reemerges to prey on idealistic young men and women who spend so much time at their unholy computers that they try to spend less time there by spending a lot of time trying to optimize what the computer does, slowly, instead of reflecting on why they are there, while the computer is busy working, and why they try to solve this by adding a component that makes the computer be more error-prone at that same work, increasing the need of their presense at this idolized thinking machine to oversee and often repair, or worse, mindlessly restart its doing.&lt;br /&gt;
if the curse is not lifted, despair may befall them and all they see is the need to investigate and ruminate further on the workings of this tool, ignoring thereby the obivous flaws that stem from of its alchemic origins.&lt;br /&gt;
&lt;br /&gt;
just wait till you find out it has a backoff alghoritm deciding whether to call out to a remote server independent of that server functioning. graceful performance degradation is the goal, and degrading it is while we try to figure this out.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Node Selection algorithm ====&lt;br /&gt;
&lt;br /&gt;
as per my understanding, a flowchart goes here:&lt;br /&gt;
&lt;br /&gt;
# compile task&lt;br /&gt;
# evaluate whether to run locally by job nature&lt;br /&gt;
# determine if local host&#039;s load is notable&lt;br /&gt;
# look at distcc hosts list&lt;br /&gt;
# do something based off localhost entry if first&lt;br /&gt;
# filter for nodes with cpp flag&lt;br /&gt;
# do something based off localhost entry if not first&lt;br /&gt;
# further prioritize by server order, first is handled in some way&lt;br /&gt;
# skip nodes in backoff prisons&lt;br /&gt;
# balance and priotize by server thread number, if given&lt;br /&gt;
# send to suitable host&lt;br /&gt;
# if compile not successful, proceed on other node&lt;br /&gt;
# if nodes depleted, proceed on localhost&lt;br /&gt;
&lt;br /&gt;
== security ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== tcpwrapper style ip range filter ===&lt;br /&gt;
&lt;br /&gt;
the original security model consists of ip restrictions.&lt;br /&gt;
there seems to also be some GSSAPI user auth.&lt;br /&gt;
further, commands that can be called are restricted by name and location.&lt;br /&gt;
this appears to be a runtime whitelist lookup, meaning it&#039;s done and authorized by the same parts of the daemon as processes the compile request along with the intended compiler.&lt;br /&gt;
so the main weaknesses against malicious clients seem to be in sending things to compile, and in overriding the remote compiler to use.&lt;br /&gt;
it can be assumed that a malicious client able to exploit the compiler handshake can then run arbitrary stuff.&lt;br /&gt;
There&#039;s at least a github issue regarding this (link lost) suggesting running over ssh. That does only partitally alleviate this risk with regard  to a key based verfication of a client versus a the standard ip restrictions which always include some parsing.&lt;br /&gt;
So this protects against someone directly exploiting the TCP code of distcc.&lt;br /&gt;
It does not protect against malicious clients.&lt;br /&gt;
(ssh force command can&#039;t be used or you&#039;ll not compile anything)&lt;br /&gt;
&lt;br /&gt;
The basic step for protecting access should be filtering who can access the distcc server, so use nftables etc. to restrict access to port 3262 (??) set up the internal filter the same way.&lt;br /&gt;
&lt;br /&gt;
=== seccomp ===&lt;br /&gt;
&lt;br /&gt;
The next thing is to confine the compiler calls to only write in their temp directory and that they can only run compilers (using nsjail, apparmor, selinux etc)&lt;br /&gt;
&lt;br /&gt;
the above issue also references the second bit of security, namely a seccomp filter which will already cover a good bit of the above&lt;br /&gt;
https://github.com/distcc/distcc/pull/235&lt;br /&gt;
the commit got closed without merge, from what I see.&lt;br /&gt;
&lt;br /&gt;
I will update the entry once it&#039;s clear if the patch was later added or instead nothing was done.&lt;br /&gt;
&lt;br /&gt;
=== privs ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The other internal security bit is that they do some priviledge dropping. it runs as a dedicated user (distcc), so you can also have an audit policy, and can/could use something like iptables&#039; to ensure it can only connect to the other distcc/memcached hosts, but nothing else.&lt;br /&gt;
&lt;br /&gt;
=== compiler list ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
One needs to investigate when compiler_whitelist.sh is exactly called. as far as I recall it doesn&#039;t close stdin/stdout.&lt;br /&gt;
&lt;br /&gt;
=== distcc-hardened ===&lt;br /&gt;
&lt;br /&gt;
Alpine adds some hardening patch, idk what nature/origina that has.&lt;br /&gt;
&lt;br /&gt;
=== selinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
there&#039;s also a selinux policy for distcc from gentoo or liguros if one is so inclined.&lt;br /&gt;
https://repology.org/project/selinux-distcc/versions&lt;br /&gt;
&lt;br /&gt;
=== general posture ===&lt;br /&gt;
&lt;br /&gt;
Some security measures like the above should definitely be used since the project at its core relies on accepting foreign input over the network, has only a few part-time maintainers that cannot easily drive the project forward or do large refactors.&lt;br /&gt;
But the seccomp changes were done almost 10 years ago, so, if they were actually upstreamed, I&#039;d say they came through.&lt;br /&gt;
&lt;br /&gt;
A kind of overengineered solulion would be to use netlabel to ensure application integrity across hosts, meaning only a valid process would be able to send packets to the distcc nodes :-)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Arch wiki refers to a fork by SUSE&lt;br /&gt;
https://github.com/icecc/icecream&lt;br /&gt;
&lt;br /&gt;
It appears &#039;maybe better&#039; but hard to tell.&lt;br /&gt;
&lt;br /&gt;
A commercial alternative exists, but I have not tried it.&lt;br /&gt;
Architecturally it seems to be taking the ccache approach with a shared cache and smarter redistribution.&lt;br /&gt;
So anything that can call ccache is something they can scale out. I&#039;ll add a link later, for those whom it helps.&lt;br /&gt;
Naturally it is out of scope for this article.&lt;br /&gt;
Nonetheless it&#039;s interesting since the ordering of how to run ccache and how to run distcc is an issue that also exists in the OSS world. Not just that we don&#039;t have an automatic setup and integration of the tools (ccache, redis, distccd, distcc-pump) but we also don&#039;t have collected sufficient data to aid in deciding which aproach is the best.&lt;br /&gt;
Integrating into CIs (gitlab-runner specifically) is another item where cache persistence becomes very fragile.&lt;br /&gt;
Having an alpine build container that knows how to use ccache with redis and distcc-pump would be a possible step forward.&lt;/div&gt;</summary>
		<author><name>Darkfader</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32179</id>
		<title>User:Darkfader/distcc</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32179"/>
		<updated>2026-03-26T01:01:43Z</updated>

		<summary type="html">&lt;p&gt;Darkfader: /* tcpwrapper style ip range filter */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi,&lt;br /&gt;
&lt;br /&gt;
I&#039;m preparing this page. It can take a long time till I finish.&lt;br /&gt;
If you are also wishing to write on this topic, feel free to integrate the content.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Document overview ==&lt;br /&gt;
&lt;br /&gt;
I noticed that almost every distro has one partially complete, partially helpful document on how to use distcc on the distro.&lt;br /&gt;
Usually they also have one for ccache.&lt;br /&gt;
In either case, they&#039;re enough to get started, but not really a reliable watertight thing.&lt;br /&gt;
We definitely needed one of our own.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== goal ===&lt;br /&gt;
&lt;br /&gt;
to describe a working setup for building aports in easiest/fastests fashion&lt;br /&gt;
not planning to add versatility or features where it would make the setup more errorprone.&lt;br /&gt;
the page should describe enough of the steps to successfully compile an LTS kernel via aports and have that job be distributed over multiple nodes.&lt;br /&gt;
Logs should be set up and able to display errors, but not show any errors during the test compile.&lt;br /&gt;
&lt;br /&gt;
To include a path for analysis via testing components.&lt;br /&gt;
&lt;br /&gt;
distcc can greatly improve compile speeds for large software, it comes with a different set of features than ccache; it focusses not avoiding unneccessary compile work, but on a way to speed up the necessary one.&lt;br /&gt;
&lt;br /&gt;
There&#039;s valuable info in the docs of other distros, it should be referenced here (i.e. the arch wiki troubleshooting), when it makes sense, add a TOC for their content.&lt;br /&gt;
&lt;br /&gt;
=== audience ===&lt;br /&gt;
people running software builds on alpine and have multiple computers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This page will show a specific installation, specific configuration, and specific tests, resulting in a specific set of functionality that can be tested to be working.&lt;br /&gt;
&lt;br /&gt;
== installation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Packages ===&lt;br /&gt;
&lt;br /&gt;
you need, on each host&lt;br /&gt;
* distcc&lt;br /&gt;
* distccd-openrc&lt;br /&gt;
* distcc-pump&lt;br /&gt;
* distcc-pump-pyc&lt;br /&gt;
&lt;br /&gt;
the .pyc will speed up the invocations, without it &lt;br /&gt;
idk if one or both should be installed in that case. but it appears to be also automatically be precompiled in /usr/lib/python3.12/site-packages/include_server/__pycache__/ so what does the package do exactly?&lt;br /&gt;
&lt;br /&gt;
There&#039;s some references to cpython-312, so maybe it actually still uses classy python-c conversion or matbe that&#039;s just a component for reading C source code. I have zero idea.&lt;br /&gt;
&lt;br /&gt;
you also need stuff to do compiles&lt;br /&gt;
* alpine sdk&lt;br /&gt;
* clang&lt;br /&gt;
* binutils&lt;br /&gt;
...&lt;br /&gt;
* elfutils(-dev)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Settings ===&lt;br /&gt;
==== settings for distcc ====&lt;br /&gt;
&lt;br /&gt;
* there&#039;s /etc/default/distcc&lt;br /&gt;
* there&#039;s /etc/conf.d/distcc &lt;br /&gt;
&lt;br /&gt;
make all your settings here&lt;br /&gt;
take care with the listen address, if you specify an IP it&#039;ll not be on 127.0.0.1 in case you would have localhost in your list...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* command_whitelist.sh &lt;br /&gt;
&lt;br /&gt;
this is half functional, you need to set things here but you also need to maintain the symlinks that are collected under /usr/lib/distcc (for your compilers) and /usr/lib/distcc/bin (for itself)&lt;br /&gt;
&lt;br /&gt;
you MUST run the script to update the compilers!&lt;br /&gt;
Info for script and what files it will create&lt;br /&gt;
&lt;br /&gt;
/usr/sbin/update-distcc-symlinks&lt;br /&gt;
&lt;br /&gt;
tschike:/usr/bin# ls -l /usr/lib/distcc/&lt;br /&gt;
total 4&lt;br /&gt;
drwxr-xr-x 2 root root 4096 Mar  2 18:14 bin&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c89 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c99 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 cc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc-15.2.0 -&amp;gt; ../../bin/distcc&lt;br /&gt;
&lt;br /&gt;
distcc itself is in bin&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cpp -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 g++ -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 06:49 x86_64-alpine-linux-musl-gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
&lt;br /&gt;
the last symplink here is wrong, made by me and would not work...&lt;br /&gt;
BAD symlink.&lt;br /&gt;
&lt;br /&gt;
=== distcc hosts file ===&lt;br /&gt;
&lt;br /&gt;
idk about that thing it&#039;s odd&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== abuild.conf ===&lt;br /&gt;
&lt;br /&gt;
settings for aports&lt;br /&gt;
* cc=&lt;br /&gt;
* cxx=&lt;br /&gt;
* cpp=&lt;br /&gt;
* cflags=&lt;br /&gt;
* njobs&lt;br /&gt;
&lt;br /&gt;
== detail infos ==&lt;br /&gt;
&lt;br /&gt;
???&lt;br /&gt;
&lt;br /&gt;
=== hosts syntax ===&lt;br /&gt;
&lt;br /&gt;
* myhost otherhost&lt;br /&gt;
* myhost,cpp,lzo myotherhost,cpp,lzo&lt;br /&gt;
&lt;br /&gt;
==== the host ====&lt;br /&gt;
&lt;br /&gt;
hostname/ip&lt;br /&gt;
localhost&lt;br /&gt;
127.0.0.1&lt;br /&gt;
::1 - does not work&lt;br /&gt;
&lt;br /&gt;
==== protocol ====&lt;br /&gt;
&lt;br /&gt;
* no protocol given&lt;br /&gt;
* ,cpp,lzo protocol&lt;br /&gt;
&lt;br /&gt;
cpp implies lzo, it requires compression, even if you have 10gbit/s or more, it&#039;s just hardcoded&lt;br /&gt;
&lt;br /&gt;
=== threads ===&lt;br /&gt;
/number of workers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== architecture ==&lt;br /&gt;
it can handle C, C++, ObjC, maybe some other stuff&lt;br /&gt;
&lt;br /&gt;
* what happens with normal xmit&lt;br /&gt;
* what happens with pump mode&lt;br /&gt;
* at which step the include server is used and how it collects the includes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== distribution algorithm ===&lt;br /&gt;
honestly I simply don&#039;t get it&lt;br /&gt;
&lt;br /&gt;
* The order matters&lt;br /&gt;
* The number of threads matters&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== localhost ====&lt;br /&gt;
&lt;br /&gt;
* localhost precedence&lt;br /&gt;
* localhost fallback&lt;br /&gt;
&lt;br /&gt;
variable: DISTCC_FALLBACK&lt;br /&gt;
&lt;br /&gt;
0 = Fail to compile if it would need to fallback to a normal local gcc call&lt;br /&gt;
1 = If remote compile fails, just do it yourself&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Operation ==&lt;br /&gt;
&lt;br /&gt;
=== startup and shutdown ===&lt;br /&gt;
service distcc stop is not entirely reliable (it can take a minute after the stop until the processes are gone and sometimes it will never stop&lt;br /&gt;
this is very bad with openrc, the openrc script returns after a second and only relies on its service flags, not the process status.&lt;br /&gt;
manually check after stopping, wait a min, if needed, kill it all.&lt;br /&gt;
at some point the rc file needs to be rewritten, it can&#039;t stay like it is.&lt;br /&gt;
&lt;br /&gt;
if you used a pump mode session, that also needs a logout (pump --shutdown)&lt;br /&gt;
avoid running multiple startups without shutdown in one session. it&#039;s safe as far as I can tell but nothing cleans up these processes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== ccache and memcached ===&lt;br /&gt;
CCACHE is said to be conflicting with pump mode unless when you call them in the backend&lt;br /&gt;
so, where you start the compile, you don&#039;t use it&lt;br /&gt;
where the compile happens, you use it&lt;br /&gt;
they can share the cache via memcached, this is a nice trick for consistency&lt;br /&gt;
Upon looking at the ccache website, it seems the correct mechanism is not memcached but Redis. This would work just as well. Generally a cache shared in this way would be optimal for performance.&lt;br /&gt;
&lt;br /&gt;
=== dockerized / native ===&lt;br /&gt;
&lt;br /&gt;
it remains mostly the same, a container needs to make sure it monitors the right services (distccd, nginx, include_server)&lt;br /&gt;
if you&#039;re using zeroconf, you need to somehow expose the mdns service broadcasts &amp;amp; reception&lt;br /&gt;
&lt;br /&gt;
Processs list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
Workdir list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
=== alpine-chroot ===&lt;br /&gt;
&lt;br /&gt;
when using the &#039;official&#039; script there&#039;s still some odd pieces, seemed to be the processes died on logout. but not all of them.&lt;br /&gt;
&lt;br /&gt;
==== manual launch ====&lt;br /&gt;
&lt;br /&gt;
Starting the daemon would be using&lt;br /&gt;
/usr/bin/distccd --pid-file /var/run/distccd/distccd.pid -N 15 --user distcc --port 3632 --log-level=debug --log-file=/var/log/distccd.log --allow my-sub-net/24&lt;br /&gt;
&lt;br /&gt;
==== localhost? =====&lt;br /&gt;
unclear if you need to use --allow for 127.0.0.1/32 or something to allow the remote preproccesor.&lt;br /&gt;
&lt;br /&gt;
== Kernel specific settings ==&lt;br /&gt;
&lt;br /&gt;
currently (distcc 3.4-r9 on Alpine) you need a patch to build the kernel.&lt;br /&gt;
See &lt;br /&gt;
&lt;br /&gt;
=== Include server Settings ===&lt;br /&gt;
&lt;br /&gt;
cache reset triggers&lt;br /&gt;
This ought to be set before enabling pump mode.&lt;br /&gt;
&lt;br /&gt;
export INCLUDE_SERVER_ARGS=&amp;quot;--stat_reset_triggers=include/linux/compile.h:include/asm/asm-offsets.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
link to explanation TBA&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Disabling GCC Plugins ===&lt;br /&gt;
&lt;br /&gt;
KConfig unselect HAVE_GCC_PLUGINS&lt;br /&gt;
&lt;br /&gt;
Some info is here in the troubleshooting part of the Arch Wiki&lt;br /&gt;
https://wiki.archlinux.org/title/Distcc#Troubleshooting&lt;br /&gt;
&lt;br /&gt;
=== Patches ===&lt;br /&gt;
&lt;br /&gt;
Other things (for 6.6LTS)&lt;br /&gt;
PCIe Stub patch&lt;br /&gt;
&lt;br /&gt;
=== Autoconf === &lt;br /&gt;
&lt;br /&gt;
No known setup examples&lt;br /&gt;
Add whatever it publishes in mdns&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== troubleshooting / analysis ==&lt;br /&gt;
&lt;br /&gt;
=== testing ===&lt;br /&gt;
&lt;br /&gt;
# turn off fallback DISTCC_FALLBACK=1&lt;br /&gt;
# set distcc up to point at specific system under test DISTCC_HOSTS=&amp;quot;mytestbox,cpp,lzo&amp;quot;&lt;br /&gt;
# GCC example compiles&lt;br /&gt;
## code example C&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example C++&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example ObjC&lt;br /&gt;
## same with included header&lt;br /&gt;
# Cmake example compiles&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docoument the thing with compile launcher ccache;distcc&lt;br /&gt;
there&#039;s some blog post, point to that&lt;br /&gt;
no ccache here yet&lt;br /&gt;
show $CC differences distcc vs gcc, what configure scripts see&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Latency ===&lt;br /&gt;
&lt;br /&gt;
Latency of pump mode startups and fallbacks needs to be investigated.&lt;br /&gt;
LZO is enforced even if you have faster network&lt;br /&gt;
DNS Requests, very old bug report from Gcode, one request per call, is it true? how to get rid of it?&lt;br /&gt;
TMPDIR is respected, make sure it&#039;s on ramdisk even on the remote nodes.&lt;br /&gt;
Compile ideally never goes to disk when it doesn&#039;t have to.&lt;br /&gt;
How efficient is the include server collection and unpacking?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== failed to distribute, running locally instead ===&lt;br /&gt;
&lt;br /&gt;
the curse of the ancient, wise bulgarian witch compildora nottherea has befallen people all over the world. only strict and mindless adherence to rituals passed down from generation to generation has given hope to those who are under her ages old spell. again and again it reemerges to prey on idealistic young men and women who spend so much time at their unholy computers that they try to spend less time there by spending a lot of time trying to optimize what the computer does, slowly, instead of reflecting on why they are there, while the computer is busy working, and why they try to solve this by adding a component that makes the computer be more error-prone at that same work, increasing the need of their presense at this idolized thinking machine to oversee and often repair, or worse, mindlessly restart its doing.&lt;br /&gt;
if the curse is not lifted, despair may befall them and all they see is the need to investigate and ruminate further on the workings of this tool, ignoring thereby the obivous flaws that stem from of its alchemic origins.&lt;br /&gt;
&lt;br /&gt;
just wait till you find out it has a backoff alghoritm deciding whether to call out to a remote server independent of that server functioning. graceful performance degradation is the goal, and degrading it is while we try to figure this out.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Node Selection algorithm ====&lt;br /&gt;
&lt;br /&gt;
as per my understanding, a flowchart goes here:&lt;br /&gt;
&lt;br /&gt;
# compile task&lt;br /&gt;
# evaluate whether to run locally by job nature&lt;br /&gt;
# determine if local host&#039;s load is notable&lt;br /&gt;
# look at distcc hosts list&lt;br /&gt;
# do something based off localhost entry if first&lt;br /&gt;
# filter for nodes with cpp flag&lt;br /&gt;
# do something based off localhost entry if not first&lt;br /&gt;
# further prioritize by server order, first is handled in some way&lt;br /&gt;
# skip nodes in backoff prisons&lt;br /&gt;
# balance and priotize by server thread number, if given&lt;br /&gt;
# send to suitable host&lt;br /&gt;
# if compile not successful, proceed on other node&lt;br /&gt;
# if nodes depleted, proceed on localhost&lt;br /&gt;
&lt;br /&gt;
== security ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== tcpwrapper style ip range filter ===&lt;br /&gt;
&lt;br /&gt;
the original security model consists of ip restrictions.&lt;br /&gt;
there seems to also be some GSSAPI user auth.&lt;br /&gt;
further, commands that can be called are restricted by name and location.&lt;br /&gt;
this appears to be a runtime whitelist lookup, meaning it&#039;s done and authorized by the same parts of the daemon as processes the compile request along with the intended compiler.&lt;br /&gt;
so the main weaknesses against malicious clients seem to be in sending things to compile, and in overriding the remote compiler to use.&lt;br /&gt;
it can be assumed that a malicious client able to exploit the compiler handshake can then run arbitrary stuff.&lt;br /&gt;
There&#039;s at least a github issue regarding this (link lost) suggesting running over ssh. That does only partitally alleviate this risk with regard  to a key based verfication of a client versus a the standard ip restrictions which always include some parsing.&lt;br /&gt;
So this protects against someone directly exploiting the TCP code of distcc.&lt;br /&gt;
It does not protect against malicious clients.&lt;br /&gt;
(ssh force command can&#039;t be used or you&#039;ll not compile anything)&lt;br /&gt;
&lt;br /&gt;
The basic step for protecting access should be filtering who can access the distcc server, so use nftables etc. to restrict access to port 3262 (??) set up the internal filter the same way.&lt;br /&gt;
&lt;br /&gt;
=== seccomp ===&lt;br /&gt;
&lt;br /&gt;
The next thing is to confine the compiler calls to only write in their temp directory and that they can only run compilers (using nsjail, apparmor, selinux etc)&lt;br /&gt;
&lt;br /&gt;
the above issue also references the second bit of security, namely a seccomp filter which will already cover a good bit of the above&lt;br /&gt;
https://github.com/distcc/distcc/pull/235&lt;br /&gt;
the commit got closed without merge, from what I see.&lt;br /&gt;
&lt;br /&gt;
I will update the entry once it&#039;s clear if the patch was later added or instead nothing was done.&lt;br /&gt;
&lt;br /&gt;
=== privs ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The other internal security bit is that they do some priviledge dropping. it runs as a dedicated user (distcc), so you can also have an audit policy, and can/could use something like iptables&#039; to ensure it can only connect to the other distcc/memcached hosts, but nothing else.&lt;br /&gt;
&lt;br /&gt;
=== compiler list ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
One needs to investigate when compiler_whitelist.sh is exactly called. as far as I recall it doesn&#039;t close stdin/stdout.&lt;br /&gt;
&lt;br /&gt;
=== distcc-hardened ===&lt;br /&gt;
&lt;br /&gt;
Alpine adds some hardening patch, idk what nature/origina that has.&lt;br /&gt;
&lt;br /&gt;
=== selinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
there&#039;s also a selinux policy for distcc from gentoo or liguros if one is so inclined.&lt;br /&gt;
https://repology.org/project/selinux-distcc/versions&lt;br /&gt;
&lt;br /&gt;
=== general posture ===&lt;br /&gt;
&lt;br /&gt;
Some security measures like the above should definitely be used since the project at its core relies on accepting foreign input over the network, has only a few part-time maintainers that cannot easily drive the project forward or do large refactors.&lt;br /&gt;
But the seccomp changes were done almost 10 years ago, so, if they were actually upstreamed, I&#039;d say they came through.&lt;br /&gt;
&lt;br /&gt;
A kind of overengineered solulion would be to use netlabel to ensure application integrity across hosts, meaning only a valid process would be able to send packets to the distcc nodes :-)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Arch wiki refers to a fork by SUSE&lt;br /&gt;
https://github.com/icecc/icecream&lt;br /&gt;
&lt;br /&gt;
It appears &#039;maybe better&#039; but hard to tell.&lt;/div&gt;</summary>
		<author><name>Darkfader</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32146</id>
		<title>User:Darkfader/distcc</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32146"/>
		<updated>2026-03-03T19:25:12Z</updated>

		<summary type="html">&lt;p&gt;Darkfader: /* ccache and memcached */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi,&lt;br /&gt;
&lt;br /&gt;
I&#039;m preparing this page. It can take a long time till I finish.&lt;br /&gt;
If you are also wishing to write on this topic, feel free to integrate the content.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Document overview ==&lt;br /&gt;
&lt;br /&gt;
I noticed that almost every distro has one partially complete, partially helpful document on how to use distcc on the distro.&lt;br /&gt;
Usually they also have one for ccache.&lt;br /&gt;
In either case, they&#039;re enough to get started, but not really a reliable watertight thing.&lt;br /&gt;
We definitely needed one of our own.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== goal ===&lt;br /&gt;
&lt;br /&gt;
to describe a working setup for building aports in easiest/fastests fashion&lt;br /&gt;
not planning to add versatility or features where it would make the setup more errorprone.&lt;br /&gt;
the page should describe enough of the steps to successfully compile an LTS kernel via aports and have that job be distributed over multiple nodes.&lt;br /&gt;
Logs should be set up and able to display errors, but not show any errors during the test compile.&lt;br /&gt;
&lt;br /&gt;
To include a path for analysis via testing components.&lt;br /&gt;
&lt;br /&gt;
distcc can greatly improve compile speeds for large software, it comes with a different set of features than ccache; it focusses not avoiding unneccessary compile work, but on a way to speed up the necessary one.&lt;br /&gt;
&lt;br /&gt;
There&#039;s valuable info in the docs of other distros, it should be referenced here (i.e. the arch wiki troubleshooting), when it makes sense, add a TOC for their content.&lt;br /&gt;
&lt;br /&gt;
=== audience ===&lt;br /&gt;
people running software builds on alpine and have multiple computers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This page will show a specific installation, specific configuration, and specific tests, resulting in a specific set of functionality that can be tested to be working.&lt;br /&gt;
&lt;br /&gt;
== installation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Packages ===&lt;br /&gt;
&lt;br /&gt;
you need, on each host&lt;br /&gt;
* distcc&lt;br /&gt;
* distccd-openrc&lt;br /&gt;
* distcc-pump&lt;br /&gt;
* distcc-pump-pyc&lt;br /&gt;
&lt;br /&gt;
the .pyc will speed up the invocations, without it &lt;br /&gt;
idk if one or both should be installed in that case. but it appears to be also automatically be precompiled in /usr/lib/python3.12/site-packages/include_server/__pycache__/ so what does the package do exactly?&lt;br /&gt;
&lt;br /&gt;
There&#039;s some references to cpython-312, so maybe it actually still uses classy python-c conversion or matbe that&#039;s just a component for reading C source code. I have zero idea.&lt;br /&gt;
&lt;br /&gt;
you also need stuff to do compiles&lt;br /&gt;
* alpine sdk&lt;br /&gt;
* clang&lt;br /&gt;
* binutils&lt;br /&gt;
...&lt;br /&gt;
* elfutils(-dev)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Settings ===&lt;br /&gt;
==== settings for distcc ====&lt;br /&gt;
&lt;br /&gt;
* there&#039;s /etc/default/distcc&lt;br /&gt;
* there&#039;s /etc/conf.d/distcc &lt;br /&gt;
&lt;br /&gt;
make all your settings here&lt;br /&gt;
take care with the listen address, if you specify an IP it&#039;ll not be on 127.0.0.1 in case you would have localhost in your list...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* command_whitelist.sh &lt;br /&gt;
&lt;br /&gt;
this is half functional, you need to set things here but you also need to maintain the symlinks that are collected under /usr/lib/distcc (for your compilers) and /usr/lib/distcc/bin (for itself)&lt;br /&gt;
&lt;br /&gt;
you MUST run the script to update the compilers!&lt;br /&gt;
Info for script and what files it will create&lt;br /&gt;
&lt;br /&gt;
/usr/sbin/update-distcc-symlinks&lt;br /&gt;
&lt;br /&gt;
tschike:/usr/bin# ls -l /usr/lib/distcc/&lt;br /&gt;
total 4&lt;br /&gt;
drwxr-xr-x 2 root root 4096 Mar  2 18:14 bin&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c89 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c99 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 cc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc-15.2.0 -&amp;gt; ../../bin/distcc&lt;br /&gt;
&lt;br /&gt;
distcc itself is in bin&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cpp -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 g++ -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 06:49 x86_64-alpine-linux-musl-gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
&lt;br /&gt;
the last symplink here is wrong, made by me and would not work...&lt;br /&gt;
BAD symlink.&lt;br /&gt;
&lt;br /&gt;
=== distcc hosts file ===&lt;br /&gt;
&lt;br /&gt;
idk about that thing it&#039;s odd&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== abuild.conf ===&lt;br /&gt;
&lt;br /&gt;
settings for aports&lt;br /&gt;
* cc=&lt;br /&gt;
* cxx=&lt;br /&gt;
* cpp=&lt;br /&gt;
* cflags=&lt;br /&gt;
* njobs&lt;br /&gt;
&lt;br /&gt;
== detail infos ==&lt;br /&gt;
&lt;br /&gt;
???&lt;br /&gt;
&lt;br /&gt;
=== hosts syntax ===&lt;br /&gt;
&lt;br /&gt;
* myhost otherhost&lt;br /&gt;
* myhost,cpp,lzo myotherhost,cpp,lzo&lt;br /&gt;
&lt;br /&gt;
==== the host ====&lt;br /&gt;
&lt;br /&gt;
hostname/ip&lt;br /&gt;
localhost&lt;br /&gt;
127.0.0.1&lt;br /&gt;
::1 - does not work&lt;br /&gt;
&lt;br /&gt;
==== protocol ====&lt;br /&gt;
&lt;br /&gt;
* no protocol given&lt;br /&gt;
* ,cpp,lzo protocol&lt;br /&gt;
&lt;br /&gt;
cpp implies lzo, it requires compression, even if you have 10gbit/s or more, it&#039;s just hardcoded&lt;br /&gt;
&lt;br /&gt;
=== threads ===&lt;br /&gt;
/number of workers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== architecture ==&lt;br /&gt;
it can handle C, C++, ObjC, maybe some other stuff&lt;br /&gt;
&lt;br /&gt;
* what happens with normal xmit&lt;br /&gt;
* what happens with pump mode&lt;br /&gt;
* at which step the include server is used and how it collects the includes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== distribution algorithm ===&lt;br /&gt;
honestly I simply don&#039;t get it&lt;br /&gt;
&lt;br /&gt;
* The order matters&lt;br /&gt;
* The number of threads matters&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== localhost ====&lt;br /&gt;
&lt;br /&gt;
* localhost precedence&lt;br /&gt;
* localhost fallback&lt;br /&gt;
&lt;br /&gt;
variable: DISTCC_FALLBACK&lt;br /&gt;
&lt;br /&gt;
0 = Fail to compile if it would need to fallback to a normal local gcc call&lt;br /&gt;
1 = If remote compile fails, just do it yourself&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Operation ==&lt;br /&gt;
&lt;br /&gt;
=== startup and shutdown ===&lt;br /&gt;
service distcc stop is not entirely reliable (it can take a minute after the stop until the processes are gone and sometimes it will never stop&lt;br /&gt;
this is very bad with openrc, the openrc script returns after a second and only relies on its service flags, not the process status.&lt;br /&gt;
manually check after stopping, wait a min, if needed, kill it all.&lt;br /&gt;
at some point the rc file needs to be rewritten, it can&#039;t stay like it is.&lt;br /&gt;
&lt;br /&gt;
if you used a pump mode session, that also needs a logout (pump --shutdown)&lt;br /&gt;
avoid running multiple startups without shutdown in one session. it&#039;s safe as far as I can tell but nothing cleans up these processes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== ccache and memcached ===&lt;br /&gt;
CCACHE is said to be conflicting with pump mode unless when you call them in the backend&lt;br /&gt;
so, where you start the compile, you don&#039;t use it&lt;br /&gt;
where the compile happens, you use it&lt;br /&gt;
they can share the cache via memcached, this is a nice trick for consistency&lt;br /&gt;
Upon looking at the ccache website, it seems the correct mechanism is not memcached but Redis. This would work just as well. Generally a cache shared in this way would be optimal for performance.&lt;br /&gt;
&lt;br /&gt;
=== dockerized / native ===&lt;br /&gt;
&lt;br /&gt;
it remains mostly the same, a container needs to make sure it monitors the right services (distccd, nginx, include_server)&lt;br /&gt;
if you&#039;re using zeroconf, you need to somehow expose the mdns service broadcasts &amp;amp; reception&lt;br /&gt;
&lt;br /&gt;
Processs list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
Workdir list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
=== alpine-chroot ===&lt;br /&gt;
&lt;br /&gt;
when using the &#039;official&#039; script there&#039;s still some odd pieces, seemed to be the processes died on logout. but not all of them.&lt;br /&gt;
&lt;br /&gt;
==== manual launch ====&lt;br /&gt;
&lt;br /&gt;
Starting the daemon would be using&lt;br /&gt;
/usr/bin/distccd --pid-file /var/run/distccd/distccd.pid -N 15 --user distcc --port 3632 --log-level=debug --log-file=/var/log/distccd.log --allow my-sub-net/24&lt;br /&gt;
&lt;br /&gt;
==== localhost? =====&lt;br /&gt;
unclear if you need to use --allow for 127.0.0.1/32 or something to allow the remote preproccesor.&lt;br /&gt;
&lt;br /&gt;
== Kernel specific settings ==&lt;br /&gt;
&lt;br /&gt;
currently (distcc 3.4-r9 on Alpine) you need a patch to build the kernel.&lt;br /&gt;
See &lt;br /&gt;
&lt;br /&gt;
=== Include server Settings ===&lt;br /&gt;
&lt;br /&gt;
cache reset triggers&lt;br /&gt;
This ought to be set before enabling pump mode.&lt;br /&gt;
&lt;br /&gt;
export INCLUDE_SERVER_ARGS=&amp;quot;--stat_reset_triggers=include/linux/compile.h:include/asm/asm-offsets.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
link to explanation TBA&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Disabling GCC Plugins ===&lt;br /&gt;
&lt;br /&gt;
KConfig unselect HAVE_GCC_PLUGINS&lt;br /&gt;
&lt;br /&gt;
Some info is here in the troubleshooting part of the Arch Wiki&lt;br /&gt;
https://wiki.archlinux.org/title/Distcc#Troubleshooting&lt;br /&gt;
&lt;br /&gt;
=== Patches ===&lt;br /&gt;
&lt;br /&gt;
Other things (for 6.6LTS)&lt;br /&gt;
PCIe Stub patch&lt;br /&gt;
&lt;br /&gt;
=== Autoconf === &lt;br /&gt;
&lt;br /&gt;
No known setup examples&lt;br /&gt;
Add whatever it publishes in mdns&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== troubleshooting / analysis ==&lt;br /&gt;
&lt;br /&gt;
=== testing ===&lt;br /&gt;
&lt;br /&gt;
# turn off fallback DISTCC_FALLBACK=1&lt;br /&gt;
# set distcc up to point at specific system under test DISTCC_HOSTS=&amp;quot;mytestbox,cpp,lzo&amp;quot;&lt;br /&gt;
# GCC example compiles&lt;br /&gt;
## code example C&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example C++&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example ObjC&lt;br /&gt;
## same with included header&lt;br /&gt;
# Cmake example compiles&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docoument the thing with compile launcher ccache;distcc&lt;br /&gt;
there&#039;s some blog post, point to that&lt;br /&gt;
no ccache here yet&lt;br /&gt;
show $CC differences distcc vs gcc, what configure scripts see&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Latency ===&lt;br /&gt;
&lt;br /&gt;
Latency of pump mode startups and fallbacks needs to be investigated.&lt;br /&gt;
LZO is enforced even if you have faster network&lt;br /&gt;
DNS Requests, very old bug report from Gcode, one request per call, is it true? how to get rid of it?&lt;br /&gt;
TMPDIR is respected, make sure it&#039;s on ramdisk even on the remote nodes.&lt;br /&gt;
Compile ideally never goes to disk when it doesn&#039;t have to.&lt;br /&gt;
How efficient is the include server collection and unpacking?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== failed to distribute, running locally instead ===&lt;br /&gt;
&lt;br /&gt;
the curse of the ancient, wise bulgarian witch compildora nottherea has befallen people all over the world. only strict and mindless adherence to rituals passed down from generation to generation has given hope to those who are under her ages old spell. again and again it reemerges to prey on idealistic young men and women who spend so much time at their unholy computers that they try to spend less time there by spending a lot of time trying to optimize what the computer does, slowly, instead of reflecting on why they are there, while the computer is busy working, and why they try to solve this by adding a component that makes the computer be more error-prone at that same work, increasing the need of their presense at this idolized thinking machine to oversee and often repair, or worse, mindlessly restart its doing.&lt;br /&gt;
if the curse is not lifted, despair may befall them and all they see is the need to investigate and ruminate further on the workings of this tool, ignoring thereby the obivous flaws that stem from of its alchemic origins.&lt;br /&gt;
&lt;br /&gt;
just wait till you find out it has a backoff alghoritm deciding whether to call out to a remote server independent of that server functioning. graceful performance degradation is the goal, and degrading it is while we try to figure this out.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Node Selection algorithm ====&lt;br /&gt;
&lt;br /&gt;
as per my understanding, a flowchart goes here:&lt;br /&gt;
&lt;br /&gt;
# compile task&lt;br /&gt;
# evaluate whether to run locally by job nature&lt;br /&gt;
# determine if local host&#039;s load is notable&lt;br /&gt;
# look at distcc hosts list&lt;br /&gt;
# do something based off localhost entry if first&lt;br /&gt;
# filter for nodes with cpp flag&lt;br /&gt;
# do something based off localhost entry if not first&lt;br /&gt;
# further prioritize by server order, first is handled in some way&lt;br /&gt;
# skip nodes in backoff prisons&lt;br /&gt;
# balance and priotize by server thread number, if given&lt;br /&gt;
# send to suitable host&lt;br /&gt;
# if compile not successful, proceed on other node&lt;br /&gt;
# if nodes depleted, proceed on localhost&lt;br /&gt;
&lt;br /&gt;
== security ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== tcpwrapper style ip range filter ===&lt;br /&gt;
&lt;br /&gt;
the original security model consists of ip restrictions.&lt;br /&gt;
there seems to also be some GSSAPI user auth.&lt;br /&gt;
further, commands that can be called are restricted by name and location.&lt;br /&gt;
this appears to be a runtime whitelist lookup, meaning it&#039;s done and authorized by the same parts of the daemon as processes the compile request along with the intended compiler.&lt;br /&gt;
so the main weaknesses against malicious clients seem to be in sending things to compile, and in overriding the remote compiler to use.&lt;br /&gt;
it can be assumed that a malicious client able to exploit the compiler handshake can then run arbitrary stuff.&lt;br /&gt;
There&#039;s at least a github issue regarding this google.com/search?q=distcc+seccomp&amp;amp;rlz=1C5CHFA_enDE1121DE1121&amp;amp;oq=distcc+seccomp&amp;amp;gs_lcrp=EgZjaHJvbWUyBggAEEUYOTIHCAEQIRigATIHCAIQIRigAdIBCDM1NjRqMGo3qAIAsAIA&amp;amp;sourceid=chrome&amp;amp;ie=UTF-8 suggesting running over ssh. That does only partitally alleviate this risk with regard  to a key based verfication of a client versus a the standard ip restrictions which always include some parsing.&lt;br /&gt;
So this protects against someone directly exploiting the TCP code of distcc.&lt;br /&gt;
It does not protect against malicious clients.&lt;br /&gt;
(ssh force command can&#039;t be used or you&#039;ll not compile anything)&lt;br /&gt;
&lt;br /&gt;
The basic step for protecting access should be filtering who can access the distcc server, so use nftables etc. to restrict access to port 3262 (??) set up the internal filter the same way.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== seccomp ===&lt;br /&gt;
&lt;br /&gt;
The next thing is to confine the compiler calls to only write in their temp directory and that they can only run compilers (using nsjail, apparmor, selinux etc)&lt;br /&gt;
&lt;br /&gt;
the above issue also references the second bit of security, namely a seccomp filter which will already cover a good bit of the above&lt;br /&gt;
https://github.com/distcc/distcc/pull/235&lt;br /&gt;
the commit got closed without merge, from what I see.&lt;br /&gt;
&lt;br /&gt;
I will update the entry once it&#039;s clear if the patch was later added or instead nothing was done.&lt;br /&gt;
&lt;br /&gt;
=== privs ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The other internal security bit is that they do some priviledge dropping. it runs as a dedicated user (distcc), so you can also have an audit policy, and can/could use something like iptables&#039; to ensure it can only connect to the other distcc/memcached hosts, but nothing else.&lt;br /&gt;
&lt;br /&gt;
=== compiler list ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
One needs to investigate when compiler_whitelist.sh is exactly called. as far as I recall it doesn&#039;t close stdin/stdout.&lt;br /&gt;
&lt;br /&gt;
=== distcc-hardened ===&lt;br /&gt;
&lt;br /&gt;
Alpine adds some hardening patch, idk what nature/origina that has.&lt;br /&gt;
&lt;br /&gt;
=== selinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
there&#039;s also a selinux policy for distcc from gentoo or liguros if one is so inclined.&lt;br /&gt;
https://repology.org/project/selinux-distcc/versions&lt;br /&gt;
&lt;br /&gt;
=== general posture ===&lt;br /&gt;
&lt;br /&gt;
Some security measures like the above should definitely be used since the project at its core relies on accepting foreign input over the network, has only a few part-time maintainers that cannot easily drive the project forward or do large refactors.&lt;br /&gt;
But the seccomp changes were done almost 10 years ago, so, if they were actually upstreamed, I&#039;d say they came through.&lt;br /&gt;
&lt;br /&gt;
A kind of overengineered solulion would be to use netlabel to ensure application integrity across hosts, meaning only a valid process would be able to send packets to the distcc nodes :-)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Arch wiki refers to a fork by SUSE&lt;br /&gt;
https://github.com/icecc/icecream&lt;br /&gt;
&lt;br /&gt;
It appears &#039;maybe better&#039; but hard to tell.&lt;/div&gt;</summary>
		<author><name>Darkfader</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32145</id>
		<title>User:Darkfader/distcc</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32145"/>
		<updated>2026-03-03T19:22:39Z</updated>

		<summary type="html">&lt;p&gt;Darkfader: /* seccomp */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi,&lt;br /&gt;
&lt;br /&gt;
I&#039;m preparing this page. It can take a long time till I finish.&lt;br /&gt;
If you are also wishing to write on this topic, feel free to integrate the content.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Document overview ==&lt;br /&gt;
&lt;br /&gt;
I noticed that almost every distro has one partially complete, partially helpful document on how to use distcc on the distro.&lt;br /&gt;
Usually they also have one for ccache.&lt;br /&gt;
In either case, they&#039;re enough to get started, but not really a reliable watertight thing.&lt;br /&gt;
We definitely needed one of our own.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== goal ===&lt;br /&gt;
&lt;br /&gt;
to describe a working setup for building aports in easiest/fastests fashion&lt;br /&gt;
not planning to add versatility or features where it would make the setup more errorprone.&lt;br /&gt;
the page should describe enough of the steps to successfully compile an LTS kernel via aports and have that job be distributed over multiple nodes.&lt;br /&gt;
Logs should be set up and able to display errors, but not show any errors during the test compile.&lt;br /&gt;
&lt;br /&gt;
To include a path for analysis via testing components.&lt;br /&gt;
&lt;br /&gt;
distcc can greatly improve compile speeds for large software, it comes with a different set of features than ccache; it focusses not avoiding unneccessary compile work, but on a way to speed up the necessary one.&lt;br /&gt;
&lt;br /&gt;
There&#039;s valuable info in the docs of other distros, it should be referenced here (i.e. the arch wiki troubleshooting), when it makes sense, add a TOC for their content.&lt;br /&gt;
&lt;br /&gt;
=== audience ===&lt;br /&gt;
people running software builds on alpine and have multiple computers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This page will show a specific installation, specific configuration, and specific tests, resulting in a specific set of functionality that can be tested to be working.&lt;br /&gt;
&lt;br /&gt;
== installation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Packages ===&lt;br /&gt;
&lt;br /&gt;
you need, on each host&lt;br /&gt;
* distcc&lt;br /&gt;
* distccd-openrc&lt;br /&gt;
* distcc-pump&lt;br /&gt;
* distcc-pump-pyc&lt;br /&gt;
&lt;br /&gt;
the .pyc will speed up the invocations, without it &lt;br /&gt;
idk if one or both should be installed in that case. but it appears to be also automatically be precompiled in /usr/lib/python3.12/site-packages/include_server/__pycache__/ so what does the package do exactly?&lt;br /&gt;
&lt;br /&gt;
There&#039;s some references to cpython-312, so maybe it actually still uses classy python-c conversion or matbe that&#039;s just a component for reading C source code. I have zero idea.&lt;br /&gt;
&lt;br /&gt;
you also need stuff to do compiles&lt;br /&gt;
* alpine sdk&lt;br /&gt;
* clang&lt;br /&gt;
* binutils&lt;br /&gt;
...&lt;br /&gt;
* elfutils(-dev)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Settings ===&lt;br /&gt;
==== settings for distcc ====&lt;br /&gt;
&lt;br /&gt;
* there&#039;s /etc/default/distcc&lt;br /&gt;
* there&#039;s /etc/conf.d/distcc &lt;br /&gt;
&lt;br /&gt;
make all your settings here&lt;br /&gt;
take care with the listen address, if you specify an IP it&#039;ll not be on 127.0.0.1 in case you would have localhost in your list...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* command_whitelist.sh &lt;br /&gt;
&lt;br /&gt;
this is half functional, you need to set things here but you also need to maintain the symlinks that are collected under /usr/lib/distcc (for your compilers) and /usr/lib/distcc/bin (for itself)&lt;br /&gt;
&lt;br /&gt;
you MUST run the script to update the compilers!&lt;br /&gt;
Info for script and what files it will create&lt;br /&gt;
&lt;br /&gt;
/usr/sbin/update-distcc-symlinks&lt;br /&gt;
&lt;br /&gt;
tschike:/usr/bin# ls -l /usr/lib/distcc/&lt;br /&gt;
total 4&lt;br /&gt;
drwxr-xr-x 2 root root 4096 Mar  2 18:14 bin&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c89 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c99 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 cc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc-15.2.0 -&amp;gt; ../../bin/distcc&lt;br /&gt;
&lt;br /&gt;
distcc itself is in bin&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cpp -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 g++ -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 06:49 x86_64-alpine-linux-musl-gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
&lt;br /&gt;
the last symplink here is wrong, made by me and would not work...&lt;br /&gt;
BAD symlink.&lt;br /&gt;
&lt;br /&gt;
=== distcc hosts file ===&lt;br /&gt;
&lt;br /&gt;
idk about that thing it&#039;s odd&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== abuild.conf ===&lt;br /&gt;
&lt;br /&gt;
settings for aports&lt;br /&gt;
* cc=&lt;br /&gt;
* cxx=&lt;br /&gt;
* cpp=&lt;br /&gt;
* cflags=&lt;br /&gt;
* njobs&lt;br /&gt;
&lt;br /&gt;
== detail infos ==&lt;br /&gt;
&lt;br /&gt;
???&lt;br /&gt;
&lt;br /&gt;
=== hosts syntax ===&lt;br /&gt;
&lt;br /&gt;
* myhost otherhost&lt;br /&gt;
* myhost,cpp,lzo myotherhost,cpp,lzo&lt;br /&gt;
&lt;br /&gt;
==== the host ====&lt;br /&gt;
&lt;br /&gt;
hostname/ip&lt;br /&gt;
localhost&lt;br /&gt;
127.0.0.1&lt;br /&gt;
::1 - does not work&lt;br /&gt;
&lt;br /&gt;
==== protocol ====&lt;br /&gt;
&lt;br /&gt;
* no protocol given&lt;br /&gt;
* ,cpp,lzo protocol&lt;br /&gt;
&lt;br /&gt;
cpp implies lzo, it requires compression, even if you have 10gbit/s or more, it&#039;s just hardcoded&lt;br /&gt;
&lt;br /&gt;
=== threads ===&lt;br /&gt;
/number of workers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== architecture ==&lt;br /&gt;
it can handle C, C++, ObjC, maybe some other stuff&lt;br /&gt;
&lt;br /&gt;
* what happens with normal xmit&lt;br /&gt;
* what happens with pump mode&lt;br /&gt;
* at which step the include server is used and how it collects the includes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== distribution algorithm ===&lt;br /&gt;
honestly I simply don&#039;t get it&lt;br /&gt;
&lt;br /&gt;
* The order matters&lt;br /&gt;
* The number of threads matters&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== localhost ====&lt;br /&gt;
&lt;br /&gt;
* localhost precedence&lt;br /&gt;
* localhost fallback&lt;br /&gt;
&lt;br /&gt;
variable: DISTCC_FALLBACK&lt;br /&gt;
&lt;br /&gt;
0 = Fail to compile if it would need to fallback to a normal local gcc call&lt;br /&gt;
1 = If remote compile fails, just do it yourself&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Operation ==&lt;br /&gt;
&lt;br /&gt;
=== startup and shutdown ===&lt;br /&gt;
service distcc stop is not entirely reliable (it can take a minute after the stop until the processes are gone and sometimes it will never stop&lt;br /&gt;
this is very bad with openrc, the openrc script returns after a second and only relies on its service flags, not the process status.&lt;br /&gt;
manually check after stopping, wait a min, if needed, kill it all.&lt;br /&gt;
at some point the rc file needs to be rewritten, it can&#039;t stay like it is.&lt;br /&gt;
&lt;br /&gt;
if you used a pump mode session, that also needs a logout (pump --shutdown)&lt;br /&gt;
avoid running multiple startups without shutdown in one session. it&#039;s safe as far as I can tell but nothing cleans up these processes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== ccache and memcached ===&lt;br /&gt;
CCACHE is said to be conflicting with pump mode unless when you call them in the backend&lt;br /&gt;
so, where you start the compile, you don&#039;t use it&lt;br /&gt;
where the compile happens, you use it&lt;br /&gt;
they can share the cache via memcached, this is a nice trick for consistency&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== dockerized / native ===&lt;br /&gt;
&lt;br /&gt;
it remains mostly the same, a container needs to make sure it monitors the right services (distccd, nginx, include_server)&lt;br /&gt;
if you&#039;re using zeroconf, you need to somehow expose the mdns service broadcasts &amp;amp; reception&lt;br /&gt;
&lt;br /&gt;
Processs list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
Workdir list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
=== alpine-chroot ===&lt;br /&gt;
&lt;br /&gt;
when using the &#039;official&#039; script there&#039;s still some odd pieces, seemed to be the processes died on logout. but not all of them.&lt;br /&gt;
&lt;br /&gt;
==== manual launch ====&lt;br /&gt;
&lt;br /&gt;
Starting the daemon would be using&lt;br /&gt;
/usr/bin/distccd --pid-file /var/run/distccd/distccd.pid -N 15 --user distcc --port 3632 --log-level=debug --log-file=/var/log/distccd.log --allow my-sub-net/24&lt;br /&gt;
&lt;br /&gt;
==== localhost? =====&lt;br /&gt;
unclear if you need to use --allow for 127.0.0.1/32 or something to allow the remote preproccesor.&lt;br /&gt;
&lt;br /&gt;
== Kernel specific settings ==&lt;br /&gt;
&lt;br /&gt;
currently (distcc 3.4-r9 on Alpine) you need a patch to build the kernel.&lt;br /&gt;
See &lt;br /&gt;
&lt;br /&gt;
=== Include server Settings ===&lt;br /&gt;
&lt;br /&gt;
cache reset triggers&lt;br /&gt;
This ought to be set before enabling pump mode.&lt;br /&gt;
&lt;br /&gt;
export INCLUDE_SERVER_ARGS=&amp;quot;--stat_reset_triggers=include/linux/compile.h:include/asm/asm-offsets.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
link to explanation TBA&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Disabling GCC Plugins ===&lt;br /&gt;
&lt;br /&gt;
KConfig unselect HAVE_GCC_PLUGINS&lt;br /&gt;
&lt;br /&gt;
Some info is here in the troubleshooting part of the Arch Wiki&lt;br /&gt;
https://wiki.archlinux.org/title/Distcc#Troubleshooting&lt;br /&gt;
&lt;br /&gt;
=== Patches ===&lt;br /&gt;
&lt;br /&gt;
Other things (for 6.6LTS)&lt;br /&gt;
PCIe Stub patch&lt;br /&gt;
&lt;br /&gt;
=== Autoconf === &lt;br /&gt;
&lt;br /&gt;
No known setup examples&lt;br /&gt;
Add whatever it publishes in mdns&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== troubleshooting / analysis ==&lt;br /&gt;
&lt;br /&gt;
=== testing ===&lt;br /&gt;
&lt;br /&gt;
# turn off fallback DISTCC_FALLBACK=1&lt;br /&gt;
# set distcc up to point at specific system under test DISTCC_HOSTS=&amp;quot;mytestbox,cpp,lzo&amp;quot;&lt;br /&gt;
# GCC example compiles&lt;br /&gt;
## code example C&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example C++&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example ObjC&lt;br /&gt;
## same with included header&lt;br /&gt;
# Cmake example compiles&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docoument the thing with compile launcher ccache;distcc&lt;br /&gt;
there&#039;s some blog post, point to that&lt;br /&gt;
no ccache here yet&lt;br /&gt;
show $CC differences distcc vs gcc, what configure scripts see&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Latency ===&lt;br /&gt;
&lt;br /&gt;
Latency of pump mode startups and fallbacks needs to be investigated.&lt;br /&gt;
LZO is enforced even if you have faster network&lt;br /&gt;
DNS Requests, very old bug report from Gcode, one request per call, is it true? how to get rid of it?&lt;br /&gt;
TMPDIR is respected, make sure it&#039;s on ramdisk even on the remote nodes.&lt;br /&gt;
Compile ideally never goes to disk when it doesn&#039;t have to.&lt;br /&gt;
How efficient is the include server collection and unpacking?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== failed to distribute, running locally instead ===&lt;br /&gt;
&lt;br /&gt;
the curse of the ancient, wise bulgarian witch compildora nottherea has befallen people all over the world. only strict and mindless adherence to rituals passed down from generation to generation has given hope to those who are under her ages old spell. again and again it reemerges to prey on idealistic young men and women who spend so much time at their unholy computers that they try to spend less time there by spending a lot of time trying to optimize what the computer does, slowly, instead of reflecting on why they are there, while the computer is busy working, and why they try to solve this by adding a component that makes the computer be more error-prone at that same work, increasing the need of their presense at this idolized thinking machine to oversee and often repair, or worse, mindlessly restart its doing.&lt;br /&gt;
if the curse is not lifted, despair may befall them and all they see is the need to investigate and ruminate further on the workings of this tool, ignoring thereby the obivous flaws that stem from of its alchemic origins.&lt;br /&gt;
&lt;br /&gt;
just wait till you find out it has a backoff alghoritm deciding whether to call out to a remote server independent of that server functioning. graceful performance degradation is the goal, and degrading it is while we try to figure this out.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Node Selection algorithm ====&lt;br /&gt;
&lt;br /&gt;
as per my understanding, a flowchart goes here:&lt;br /&gt;
&lt;br /&gt;
# compile task&lt;br /&gt;
# evaluate whether to run locally by job nature&lt;br /&gt;
# determine if local host&#039;s load is notable&lt;br /&gt;
# look at distcc hosts list&lt;br /&gt;
# do something based off localhost entry if first&lt;br /&gt;
# filter for nodes with cpp flag&lt;br /&gt;
# do something based off localhost entry if not first&lt;br /&gt;
# further prioritize by server order, first is handled in some way&lt;br /&gt;
# skip nodes in backoff prisons&lt;br /&gt;
# balance and priotize by server thread number, if given&lt;br /&gt;
# send to suitable host&lt;br /&gt;
# if compile not successful, proceed on other node&lt;br /&gt;
# if nodes depleted, proceed on localhost&lt;br /&gt;
&lt;br /&gt;
== security ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== tcpwrapper style ip range filter ===&lt;br /&gt;
&lt;br /&gt;
the original security model consists of ip restrictions.&lt;br /&gt;
there seems to also be some GSSAPI user auth.&lt;br /&gt;
further, commands that can be called are restricted by name and location.&lt;br /&gt;
this appears to be a runtime whitelist lookup, meaning it&#039;s done and authorized by the same parts of the daemon as processes the compile request along with the intended compiler.&lt;br /&gt;
so the main weaknesses against malicious clients seem to be in sending things to compile, and in overriding the remote compiler to use.&lt;br /&gt;
it can be assumed that a malicious client able to exploit the compiler handshake can then run arbitrary stuff.&lt;br /&gt;
There&#039;s at least a github issue regarding this google.com/search?q=distcc+seccomp&amp;amp;rlz=1C5CHFA_enDE1121DE1121&amp;amp;oq=distcc+seccomp&amp;amp;gs_lcrp=EgZjaHJvbWUyBggAEEUYOTIHCAEQIRigATIHCAIQIRigAdIBCDM1NjRqMGo3qAIAsAIA&amp;amp;sourceid=chrome&amp;amp;ie=UTF-8 suggesting running over ssh. That does only partitally alleviate this risk with regard  to a key based verfication of a client versus a the standard ip restrictions which always include some parsing.&lt;br /&gt;
So this protects against someone directly exploiting the TCP code of distcc.&lt;br /&gt;
It does not protect against malicious clients.&lt;br /&gt;
(ssh force command can&#039;t be used or you&#039;ll not compile anything)&lt;br /&gt;
&lt;br /&gt;
The basic step for protecting access should be filtering who can access the distcc server, so use nftables etc. to restrict access to port 3262 (??) set up the internal filter the same way.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== seccomp ===&lt;br /&gt;
&lt;br /&gt;
The next thing is to confine the compiler calls to only write in their temp directory and that they can only run compilers (using nsjail, apparmor, selinux etc)&lt;br /&gt;
&lt;br /&gt;
the above issue also references the second bit of security, namely a seccomp filter which will already cover a good bit of the above&lt;br /&gt;
https://github.com/distcc/distcc/pull/235&lt;br /&gt;
the commit got closed without merge, from what I see.&lt;br /&gt;
&lt;br /&gt;
I will update the entry once it&#039;s clear if the patch was later added or instead nothing was done.&lt;br /&gt;
&lt;br /&gt;
=== privs ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The other internal security bit is that they do some priviledge dropping. it runs as a dedicated user (distcc), so you can also have an audit policy, and can/could use something like iptables&#039; to ensure it can only connect to the other distcc/memcached hosts, but nothing else.&lt;br /&gt;
&lt;br /&gt;
=== compiler list ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
One needs to investigate when compiler_whitelist.sh is exactly called. as far as I recall it doesn&#039;t close stdin/stdout.&lt;br /&gt;
&lt;br /&gt;
=== distcc-hardened ===&lt;br /&gt;
&lt;br /&gt;
Alpine adds some hardening patch, idk what nature/origina that has.&lt;br /&gt;
&lt;br /&gt;
=== selinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
there&#039;s also a selinux policy for distcc from gentoo or liguros if one is so inclined.&lt;br /&gt;
https://repology.org/project/selinux-distcc/versions&lt;br /&gt;
&lt;br /&gt;
=== general posture ===&lt;br /&gt;
&lt;br /&gt;
Some security measures like the above should definitely be used since the project at its core relies on accepting foreign input over the network, has only a few part-time maintainers that cannot easily drive the project forward or do large refactors.&lt;br /&gt;
But the seccomp changes were done almost 10 years ago, so, if they were actually upstreamed, I&#039;d say they came through.&lt;br /&gt;
&lt;br /&gt;
A kind of overengineered solulion would be to use netlabel to ensure application integrity across hosts, meaning only a valid process would be able to send packets to the distcc nodes :-)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Arch wiki refers to a fork by SUSE&lt;br /&gt;
https://github.com/icecc/icecream&lt;br /&gt;
&lt;br /&gt;
It appears &#039;maybe better&#039; but hard to tell.&lt;/div&gt;</summary>
		<author><name>Darkfader</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32144</id>
		<title>User:Darkfader/distcc</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32144"/>
		<updated>2026-03-03T19:21:39Z</updated>

		<summary type="html">&lt;p&gt;Darkfader: /* general posture */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi,&lt;br /&gt;
&lt;br /&gt;
I&#039;m preparing this page. It can take a long time till I finish.&lt;br /&gt;
If you are also wishing to write on this topic, feel free to integrate the content.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Document overview ==&lt;br /&gt;
&lt;br /&gt;
I noticed that almost every distro has one partially complete, partially helpful document on how to use distcc on the distro.&lt;br /&gt;
Usually they also have one for ccache.&lt;br /&gt;
In either case, they&#039;re enough to get started, but not really a reliable watertight thing.&lt;br /&gt;
We definitely needed one of our own.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== goal ===&lt;br /&gt;
&lt;br /&gt;
to describe a working setup for building aports in easiest/fastests fashion&lt;br /&gt;
not planning to add versatility or features where it would make the setup more errorprone.&lt;br /&gt;
the page should describe enough of the steps to successfully compile an LTS kernel via aports and have that job be distributed over multiple nodes.&lt;br /&gt;
Logs should be set up and able to display errors, but not show any errors during the test compile.&lt;br /&gt;
&lt;br /&gt;
To include a path for analysis via testing components.&lt;br /&gt;
&lt;br /&gt;
distcc can greatly improve compile speeds for large software, it comes with a different set of features than ccache; it focusses not avoiding unneccessary compile work, but on a way to speed up the necessary one.&lt;br /&gt;
&lt;br /&gt;
There&#039;s valuable info in the docs of other distros, it should be referenced here (i.e. the arch wiki troubleshooting), when it makes sense, add a TOC for their content.&lt;br /&gt;
&lt;br /&gt;
=== audience ===&lt;br /&gt;
people running software builds on alpine and have multiple computers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This page will show a specific installation, specific configuration, and specific tests, resulting in a specific set of functionality that can be tested to be working.&lt;br /&gt;
&lt;br /&gt;
== installation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Packages ===&lt;br /&gt;
&lt;br /&gt;
you need, on each host&lt;br /&gt;
* distcc&lt;br /&gt;
* distccd-openrc&lt;br /&gt;
* distcc-pump&lt;br /&gt;
* distcc-pump-pyc&lt;br /&gt;
&lt;br /&gt;
the .pyc will speed up the invocations, without it &lt;br /&gt;
idk if one or both should be installed in that case. but it appears to be also automatically be precompiled in /usr/lib/python3.12/site-packages/include_server/__pycache__/ so what does the package do exactly?&lt;br /&gt;
&lt;br /&gt;
There&#039;s some references to cpython-312, so maybe it actually still uses classy python-c conversion or matbe that&#039;s just a component for reading C source code. I have zero idea.&lt;br /&gt;
&lt;br /&gt;
you also need stuff to do compiles&lt;br /&gt;
* alpine sdk&lt;br /&gt;
* clang&lt;br /&gt;
* binutils&lt;br /&gt;
...&lt;br /&gt;
* elfutils(-dev)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Settings ===&lt;br /&gt;
==== settings for distcc ====&lt;br /&gt;
&lt;br /&gt;
* there&#039;s /etc/default/distcc&lt;br /&gt;
* there&#039;s /etc/conf.d/distcc &lt;br /&gt;
&lt;br /&gt;
make all your settings here&lt;br /&gt;
take care with the listen address, if you specify an IP it&#039;ll not be on 127.0.0.1 in case you would have localhost in your list...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* command_whitelist.sh &lt;br /&gt;
&lt;br /&gt;
this is half functional, you need to set things here but you also need to maintain the symlinks that are collected under /usr/lib/distcc (for your compilers) and /usr/lib/distcc/bin (for itself)&lt;br /&gt;
&lt;br /&gt;
you MUST run the script to update the compilers!&lt;br /&gt;
Info for script and what files it will create&lt;br /&gt;
&lt;br /&gt;
/usr/sbin/update-distcc-symlinks&lt;br /&gt;
&lt;br /&gt;
tschike:/usr/bin# ls -l /usr/lib/distcc/&lt;br /&gt;
total 4&lt;br /&gt;
drwxr-xr-x 2 root root 4096 Mar  2 18:14 bin&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c89 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c99 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 cc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc-15.2.0 -&amp;gt; ../../bin/distcc&lt;br /&gt;
&lt;br /&gt;
distcc itself is in bin&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cpp -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 g++ -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 06:49 x86_64-alpine-linux-musl-gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
&lt;br /&gt;
the last symplink here is wrong, made by me and would not work...&lt;br /&gt;
BAD symlink.&lt;br /&gt;
&lt;br /&gt;
=== distcc hosts file ===&lt;br /&gt;
&lt;br /&gt;
idk about that thing it&#039;s odd&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== abuild.conf ===&lt;br /&gt;
&lt;br /&gt;
settings for aports&lt;br /&gt;
* cc=&lt;br /&gt;
* cxx=&lt;br /&gt;
* cpp=&lt;br /&gt;
* cflags=&lt;br /&gt;
* njobs&lt;br /&gt;
&lt;br /&gt;
== detail infos ==&lt;br /&gt;
&lt;br /&gt;
???&lt;br /&gt;
&lt;br /&gt;
=== hosts syntax ===&lt;br /&gt;
&lt;br /&gt;
* myhost otherhost&lt;br /&gt;
* myhost,cpp,lzo myotherhost,cpp,lzo&lt;br /&gt;
&lt;br /&gt;
==== the host ====&lt;br /&gt;
&lt;br /&gt;
hostname/ip&lt;br /&gt;
localhost&lt;br /&gt;
127.0.0.1&lt;br /&gt;
::1 - does not work&lt;br /&gt;
&lt;br /&gt;
==== protocol ====&lt;br /&gt;
&lt;br /&gt;
* no protocol given&lt;br /&gt;
* ,cpp,lzo protocol&lt;br /&gt;
&lt;br /&gt;
cpp implies lzo, it requires compression, even if you have 10gbit/s or more, it&#039;s just hardcoded&lt;br /&gt;
&lt;br /&gt;
=== threads ===&lt;br /&gt;
/number of workers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== architecture ==&lt;br /&gt;
it can handle C, C++, ObjC, maybe some other stuff&lt;br /&gt;
&lt;br /&gt;
* what happens with normal xmit&lt;br /&gt;
* what happens with pump mode&lt;br /&gt;
* at which step the include server is used and how it collects the includes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== distribution algorithm ===&lt;br /&gt;
honestly I simply don&#039;t get it&lt;br /&gt;
&lt;br /&gt;
* The order matters&lt;br /&gt;
* The number of threads matters&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== localhost ====&lt;br /&gt;
&lt;br /&gt;
* localhost precedence&lt;br /&gt;
* localhost fallback&lt;br /&gt;
&lt;br /&gt;
variable: DISTCC_FALLBACK&lt;br /&gt;
&lt;br /&gt;
0 = Fail to compile if it would need to fallback to a normal local gcc call&lt;br /&gt;
1 = If remote compile fails, just do it yourself&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Operation ==&lt;br /&gt;
&lt;br /&gt;
=== startup and shutdown ===&lt;br /&gt;
service distcc stop is not entirely reliable (it can take a minute after the stop until the processes are gone and sometimes it will never stop&lt;br /&gt;
this is very bad with openrc, the openrc script returns after a second and only relies on its service flags, not the process status.&lt;br /&gt;
manually check after stopping, wait a min, if needed, kill it all.&lt;br /&gt;
at some point the rc file needs to be rewritten, it can&#039;t stay like it is.&lt;br /&gt;
&lt;br /&gt;
if you used a pump mode session, that also needs a logout (pump --shutdown)&lt;br /&gt;
avoid running multiple startups without shutdown in one session. it&#039;s safe as far as I can tell but nothing cleans up these processes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== ccache and memcached ===&lt;br /&gt;
CCACHE is said to be conflicting with pump mode unless when you call them in the backend&lt;br /&gt;
so, where you start the compile, you don&#039;t use it&lt;br /&gt;
where the compile happens, you use it&lt;br /&gt;
they can share the cache via memcached, this is a nice trick for consistency&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== dockerized / native ===&lt;br /&gt;
&lt;br /&gt;
it remains mostly the same, a container needs to make sure it monitors the right services (distccd, nginx, include_server)&lt;br /&gt;
if you&#039;re using zeroconf, you need to somehow expose the mdns service broadcasts &amp;amp; reception&lt;br /&gt;
&lt;br /&gt;
Processs list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
Workdir list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
=== alpine-chroot ===&lt;br /&gt;
&lt;br /&gt;
when using the &#039;official&#039; script there&#039;s still some odd pieces, seemed to be the processes died on logout. but not all of them.&lt;br /&gt;
&lt;br /&gt;
==== manual launch ====&lt;br /&gt;
&lt;br /&gt;
Starting the daemon would be using&lt;br /&gt;
/usr/bin/distccd --pid-file /var/run/distccd/distccd.pid -N 15 --user distcc --port 3632 --log-level=debug --log-file=/var/log/distccd.log --allow my-sub-net/24&lt;br /&gt;
&lt;br /&gt;
==== localhost? =====&lt;br /&gt;
unclear if you need to use --allow for 127.0.0.1/32 or something to allow the remote preproccesor.&lt;br /&gt;
&lt;br /&gt;
== Kernel specific settings ==&lt;br /&gt;
&lt;br /&gt;
currently (distcc 3.4-r9 on Alpine) you need a patch to build the kernel.&lt;br /&gt;
See &lt;br /&gt;
&lt;br /&gt;
=== Include server Settings ===&lt;br /&gt;
&lt;br /&gt;
cache reset triggers&lt;br /&gt;
This ought to be set before enabling pump mode.&lt;br /&gt;
&lt;br /&gt;
export INCLUDE_SERVER_ARGS=&amp;quot;--stat_reset_triggers=include/linux/compile.h:include/asm/asm-offsets.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
link to explanation TBA&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Disabling GCC Plugins ===&lt;br /&gt;
&lt;br /&gt;
KConfig unselect HAVE_GCC_PLUGINS&lt;br /&gt;
&lt;br /&gt;
Some info is here in the troubleshooting part of the Arch Wiki&lt;br /&gt;
https://wiki.archlinux.org/title/Distcc#Troubleshooting&lt;br /&gt;
&lt;br /&gt;
=== Patches ===&lt;br /&gt;
&lt;br /&gt;
Other things (for 6.6LTS)&lt;br /&gt;
PCIe Stub patch&lt;br /&gt;
&lt;br /&gt;
=== Autoconf === &lt;br /&gt;
&lt;br /&gt;
No known setup examples&lt;br /&gt;
Add whatever it publishes in mdns&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== troubleshooting / analysis ==&lt;br /&gt;
&lt;br /&gt;
=== testing ===&lt;br /&gt;
&lt;br /&gt;
# turn off fallback DISTCC_FALLBACK=1&lt;br /&gt;
# set distcc up to point at specific system under test DISTCC_HOSTS=&amp;quot;mytestbox,cpp,lzo&amp;quot;&lt;br /&gt;
# GCC example compiles&lt;br /&gt;
## code example C&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example C++&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example ObjC&lt;br /&gt;
## same with included header&lt;br /&gt;
# Cmake example compiles&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docoument the thing with compile launcher ccache;distcc&lt;br /&gt;
there&#039;s some blog post, point to that&lt;br /&gt;
no ccache here yet&lt;br /&gt;
show $CC differences distcc vs gcc, what configure scripts see&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Latency ===&lt;br /&gt;
&lt;br /&gt;
Latency of pump mode startups and fallbacks needs to be investigated.&lt;br /&gt;
LZO is enforced even if you have faster network&lt;br /&gt;
DNS Requests, very old bug report from Gcode, one request per call, is it true? how to get rid of it?&lt;br /&gt;
TMPDIR is respected, make sure it&#039;s on ramdisk even on the remote nodes.&lt;br /&gt;
Compile ideally never goes to disk when it doesn&#039;t have to.&lt;br /&gt;
How efficient is the include server collection and unpacking?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== failed to distribute, running locally instead ===&lt;br /&gt;
&lt;br /&gt;
the curse of the ancient, wise bulgarian witch compildora nottherea has befallen people all over the world. only strict and mindless adherence to rituals passed down from generation to generation has given hope to those who are under her ages old spell. again and again it reemerges to prey on idealistic young men and women who spend so much time at their unholy computers that they try to spend less time there by spending a lot of time trying to optimize what the computer does, slowly, instead of reflecting on why they are there, while the computer is busy working, and why they try to solve this by adding a component that makes the computer be more error-prone at that same work, increasing the need of their presense at this idolized thinking machine to oversee and often repair, or worse, mindlessly restart its doing.&lt;br /&gt;
if the curse is not lifted, despair may befall them and all they see is the need to investigate and ruminate further on the workings of this tool, ignoring thereby the obivous flaws that stem from of its alchemic origins.&lt;br /&gt;
&lt;br /&gt;
just wait till you find out it has a backoff alghoritm deciding whether to call out to a remote server independent of that server functioning. graceful performance degradation is the goal, and degrading it is while we try to figure this out.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Node Selection algorithm ====&lt;br /&gt;
&lt;br /&gt;
as per my understanding, a flowchart goes here:&lt;br /&gt;
&lt;br /&gt;
# compile task&lt;br /&gt;
# evaluate whether to run locally by job nature&lt;br /&gt;
# determine if local host&#039;s load is notable&lt;br /&gt;
# look at distcc hosts list&lt;br /&gt;
# do something based off localhost entry if first&lt;br /&gt;
# filter for nodes with cpp flag&lt;br /&gt;
# do something based off localhost entry if not first&lt;br /&gt;
# further prioritize by server order, first is handled in some way&lt;br /&gt;
# skip nodes in backoff prisons&lt;br /&gt;
# balance and priotize by server thread number, if given&lt;br /&gt;
# send to suitable host&lt;br /&gt;
# if compile not successful, proceed on other node&lt;br /&gt;
# if nodes depleted, proceed on localhost&lt;br /&gt;
&lt;br /&gt;
== security ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== tcpwrapper style ip range filter ===&lt;br /&gt;
&lt;br /&gt;
the original security model consists of ip restrictions.&lt;br /&gt;
there seems to also be some GSSAPI user auth.&lt;br /&gt;
further, commands that can be called are restricted by name and location.&lt;br /&gt;
this appears to be a runtime whitelist lookup, meaning it&#039;s done and authorized by the same parts of the daemon as processes the compile request along with the intended compiler.&lt;br /&gt;
so the main weaknesses against malicious clients seem to be in sending things to compile, and in overriding the remote compiler to use.&lt;br /&gt;
it can be assumed that a malicious client able to exploit the compiler handshake can then run arbitrary stuff.&lt;br /&gt;
There&#039;s at least a github issue regarding this google.com/search?q=distcc+seccomp&amp;amp;rlz=1C5CHFA_enDE1121DE1121&amp;amp;oq=distcc+seccomp&amp;amp;gs_lcrp=EgZjaHJvbWUyBggAEEUYOTIHCAEQIRigATIHCAIQIRigAdIBCDM1NjRqMGo3qAIAsAIA&amp;amp;sourceid=chrome&amp;amp;ie=UTF-8 suggesting running over ssh. That does only partitally alleviate this risk with regard  to a key based verfication of a client versus a the standard ip restrictions which always include some parsing.&lt;br /&gt;
So this protects against someone directly exploiting the TCP code of distcc.&lt;br /&gt;
It does not protect against malicious clients.&lt;br /&gt;
(ssh force command can&#039;t be used or you&#039;ll not compile anything)&lt;br /&gt;
&lt;br /&gt;
The basic step for protecting access should be filtering who can access the distcc server, so use nftables etc. to restrict access to port 3262 (??) set up the internal filter the same way.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== seccomp ===&lt;br /&gt;
&lt;br /&gt;
The next thing is to confine the compiler calls to only write in their temp directory and that they can only run compilers (using nsjail, apparmor, selinux etc)&lt;br /&gt;
&lt;br /&gt;
the above issue also references the second bit of security, namely a seccomp filter which will already cover a good bit of the above&lt;br /&gt;
https://github.com/distcc/distcc/pull/235&lt;br /&gt;
the commit got closed without merge, from what I see.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== privs ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The other internal security bit is that they do some priviledge dropping. it runs as a dedicated user (distcc), so you can also have an audit policy, and can/could use something like iptables&#039; to ensure it can only connect to the other distcc/memcached hosts, but nothing else.&lt;br /&gt;
&lt;br /&gt;
=== compiler list ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
One needs to investigate when compiler_whitelist.sh is exactly called. as far as I recall it doesn&#039;t close stdin/stdout.&lt;br /&gt;
&lt;br /&gt;
=== distcc-hardened ===&lt;br /&gt;
&lt;br /&gt;
Alpine adds some hardening patch, idk what nature/origina that has.&lt;br /&gt;
&lt;br /&gt;
=== selinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
there&#039;s also a selinux policy for distcc from gentoo or liguros if one is so inclined.&lt;br /&gt;
https://repology.org/project/selinux-distcc/versions&lt;br /&gt;
&lt;br /&gt;
=== general posture ===&lt;br /&gt;
&lt;br /&gt;
Some security measures like the above should definitely be used since the project at its core relies on accepting foreign input over the network, has only a few part-time maintainers that cannot easily drive the project forward or do large refactors.&lt;br /&gt;
But the seccomp changes were done almost 10 years ago, so, if they were actually upstreamed, I&#039;d say they came through.&lt;br /&gt;
&lt;br /&gt;
A kind of overengineered solulion would be to use netlabel to ensure application integrity across hosts, meaning only a valid process would be able to send packets to the distcc nodes :-)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Arch wiki refers to a fork by SUSE&lt;br /&gt;
https://github.com/icecc/icecream&lt;br /&gt;
&lt;br /&gt;
It appears &#039;maybe better&#039; but hard to tell.&lt;/div&gt;</summary>
		<author><name>Darkfader</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32143</id>
		<title>User:Darkfader/distcc</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32143"/>
		<updated>2026-03-03T11:37:01Z</updated>

		<summary type="html">&lt;p&gt;Darkfader: /* troubleshooting / analysis */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi,&lt;br /&gt;
&lt;br /&gt;
I&#039;m preparing this page. It can take a long time till I finish.&lt;br /&gt;
If you are also wishing to write on this topic, feel free to integrate the content.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Document overview ==&lt;br /&gt;
&lt;br /&gt;
I noticed that almost every distro has one partially complete, partially helpful document on how to use distcc on the distro.&lt;br /&gt;
Usually they also have one for ccache.&lt;br /&gt;
In either case, they&#039;re enough to get started, but not really a reliable watertight thing.&lt;br /&gt;
We definitely needed one of our own.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== goal ===&lt;br /&gt;
&lt;br /&gt;
to describe a working setup for building aports in easiest/fastests fashion&lt;br /&gt;
not planning to add versatility or features where it would make the setup more errorprone.&lt;br /&gt;
the page should describe enough of the steps to successfully compile an LTS kernel via aports and have that job be distributed over multiple nodes.&lt;br /&gt;
Logs should be set up and able to display errors, but not show any errors during the test compile.&lt;br /&gt;
&lt;br /&gt;
To include a path for analysis via testing components.&lt;br /&gt;
&lt;br /&gt;
distcc can greatly improve compile speeds for large software, it comes with a different set of features than ccache; it focusses not avoiding unneccessary compile work, but on a way to speed up the necessary one.&lt;br /&gt;
&lt;br /&gt;
There&#039;s valuable info in the docs of other distros, it should be referenced here (i.e. the arch wiki troubleshooting), when it makes sense, add a TOC for their content.&lt;br /&gt;
&lt;br /&gt;
=== audience ===&lt;br /&gt;
people running software builds on alpine and have multiple computers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This page will show a specific installation, specific configuration, and specific tests, resulting in a specific set of functionality that can be tested to be working.&lt;br /&gt;
&lt;br /&gt;
== installation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Packages ===&lt;br /&gt;
&lt;br /&gt;
you need, on each host&lt;br /&gt;
* distcc&lt;br /&gt;
* distccd-openrc&lt;br /&gt;
* distcc-pump&lt;br /&gt;
* distcc-pump-pyc&lt;br /&gt;
&lt;br /&gt;
the .pyc will speed up the invocations, without it &lt;br /&gt;
idk if one or both should be installed in that case. but it appears to be also automatically be precompiled in /usr/lib/python3.12/site-packages/include_server/__pycache__/ so what does the package do exactly?&lt;br /&gt;
&lt;br /&gt;
There&#039;s some references to cpython-312, so maybe it actually still uses classy python-c conversion or matbe that&#039;s just a component for reading C source code. I have zero idea.&lt;br /&gt;
&lt;br /&gt;
you also need stuff to do compiles&lt;br /&gt;
* alpine sdk&lt;br /&gt;
* clang&lt;br /&gt;
* binutils&lt;br /&gt;
...&lt;br /&gt;
* elfutils(-dev)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Settings ===&lt;br /&gt;
==== settings for distcc ====&lt;br /&gt;
&lt;br /&gt;
* there&#039;s /etc/default/distcc&lt;br /&gt;
* there&#039;s /etc/conf.d/distcc &lt;br /&gt;
&lt;br /&gt;
make all your settings here&lt;br /&gt;
take care with the listen address, if you specify an IP it&#039;ll not be on 127.0.0.1 in case you would have localhost in your list...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* command_whitelist.sh &lt;br /&gt;
&lt;br /&gt;
this is half functional, you need to set things here but you also need to maintain the symlinks that are collected under /usr/lib/distcc (for your compilers) and /usr/lib/distcc/bin (for itself)&lt;br /&gt;
&lt;br /&gt;
you MUST run the script to update the compilers!&lt;br /&gt;
Info for script and what files it will create&lt;br /&gt;
&lt;br /&gt;
/usr/sbin/update-distcc-symlinks&lt;br /&gt;
&lt;br /&gt;
tschike:/usr/bin# ls -l /usr/lib/distcc/&lt;br /&gt;
total 4&lt;br /&gt;
drwxr-xr-x 2 root root 4096 Mar  2 18:14 bin&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c89 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c99 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 cc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc-15.2.0 -&amp;gt; ../../bin/distcc&lt;br /&gt;
&lt;br /&gt;
distcc itself is in bin&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cpp -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 g++ -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 06:49 x86_64-alpine-linux-musl-gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
&lt;br /&gt;
the last symplink here is wrong, made by me and would not work...&lt;br /&gt;
BAD symlink.&lt;br /&gt;
&lt;br /&gt;
=== distcc hosts file ===&lt;br /&gt;
&lt;br /&gt;
idk about that thing it&#039;s odd&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== abuild.conf ===&lt;br /&gt;
&lt;br /&gt;
settings for aports&lt;br /&gt;
* cc=&lt;br /&gt;
* cxx=&lt;br /&gt;
* cpp=&lt;br /&gt;
* cflags=&lt;br /&gt;
* njobs&lt;br /&gt;
&lt;br /&gt;
== detail infos ==&lt;br /&gt;
&lt;br /&gt;
???&lt;br /&gt;
&lt;br /&gt;
=== hosts syntax ===&lt;br /&gt;
&lt;br /&gt;
* myhost otherhost&lt;br /&gt;
* myhost,cpp,lzo myotherhost,cpp,lzo&lt;br /&gt;
&lt;br /&gt;
==== the host ====&lt;br /&gt;
&lt;br /&gt;
hostname/ip&lt;br /&gt;
localhost&lt;br /&gt;
127.0.0.1&lt;br /&gt;
::1 - does not work&lt;br /&gt;
&lt;br /&gt;
==== protocol ====&lt;br /&gt;
&lt;br /&gt;
* no protocol given&lt;br /&gt;
* ,cpp,lzo protocol&lt;br /&gt;
&lt;br /&gt;
cpp implies lzo, it requires compression, even if you have 10gbit/s or more, it&#039;s just hardcoded&lt;br /&gt;
&lt;br /&gt;
=== threads ===&lt;br /&gt;
/number of workers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== architecture ==&lt;br /&gt;
it can handle C, C++, ObjC, maybe some other stuff&lt;br /&gt;
&lt;br /&gt;
* what happens with normal xmit&lt;br /&gt;
* what happens with pump mode&lt;br /&gt;
* at which step the include server is used and how it collects the includes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== distribution algorithm ===&lt;br /&gt;
honestly I simply don&#039;t get it&lt;br /&gt;
&lt;br /&gt;
* The order matters&lt;br /&gt;
* The number of threads matters&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== localhost ====&lt;br /&gt;
&lt;br /&gt;
* localhost precedence&lt;br /&gt;
* localhost fallback&lt;br /&gt;
&lt;br /&gt;
variable: DISTCC_FALLBACK&lt;br /&gt;
&lt;br /&gt;
0 = Fail to compile if it would need to fallback to a normal local gcc call&lt;br /&gt;
1 = If remote compile fails, just do it yourself&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Operation ==&lt;br /&gt;
&lt;br /&gt;
=== startup and shutdown ===&lt;br /&gt;
service distcc stop is not entirely reliable (it can take a minute after the stop until the processes are gone and sometimes it will never stop&lt;br /&gt;
this is very bad with openrc, the openrc script returns after a second and only relies on its service flags, not the process status.&lt;br /&gt;
manually check after stopping, wait a min, if needed, kill it all.&lt;br /&gt;
at some point the rc file needs to be rewritten, it can&#039;t stay like it is.&lt;br /&gt;
&lt;br /&gt;
if you used a pump mode session, that also needs a logout (pump --shutdown)&lt;br /&gt;
avoid running multiple startups without shutdown in one session. it&#039;s safe as far as I can tell but nothing cleans up these processes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== ccache and memcached ===&lt;br /&gt;
CCACHE is said to be conflicting with pump mode unless when you call them in the backend&lt;br /&gt;
so, where you start the compile, you don&#039;t use it&lt;br /&gt;
where the compile happens, you use it&lt;br /&gt;
they can share the cache via memcached, this is a nice trick for consistency&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== dockerized / native ===&lt;br /&gt;
&lt;br /&gt;
it remains mostly the same, a container needs to make sure it monitors the right services (distccd, nginx, include_server)&lt;br /&gt;
if you&#039;re using zeroconf, you need to somehow expose the mdns service broadcasts &amp;amp; reception&lt;br /&gt;
&lt;br /&gt;
Processs list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
Workdir list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
=== alpine-chroot ===&lt;br /&gt;
&lt;br /&gt;
when using the &#039;official&#039; script there&#039;s still some odd pieces, seemed to be the processes died on logout. but not all of them.&lt;br /&gt;
&lt;br /&gt;
==== manual launch ====&lt;br /&gt;
&lt;br /&gt;
Starting the daemon would be using&lt;br /&gt;
/usr/bin/distccd --pid-file /var/run/distccd/distccd.pid -N 15 --user distcc --port 3632 --log-level=debug --log-file=/var/log/distccd.log --allow my-sub-net/24&lt;br /&gt;
&lt;br /&gt;
==== localhost? =====&lt;br /&gt;
unclear if you need to use --allow for 127.0.0.1/32 or something to allow the remote preproccesor.&lt;br /&gt;
&lt;br /&gt;
== Kernel specific settings ==&lt;br /&gt;
&lt;br /&gt;
currently (distcc 3.4-r9 on Alpine) you need a patch to build the kernel.&lt;br /&gt;
See &lt;br /&gt;
&lt;br /&gt;
=== Include server Settings ===&lt;br /&gt;
&lt;br /&gt;
cache reset triggers&lt;br /&gt;
This ought to be set before enabling pump mode.&lt;br /&gt;
&lt;br /&gt;
export INCLUDE_SERVER_ARGS=&amp;quot;--stat_reset_triggers=include/linux/compile.h:include/asm/asm-offsets.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
link to explanation TBA&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Disabling GCC Plugins ===&lt;br /&gt;
&lt;br /&gt;
KConfig unselect HAVE_GCC_PLUGINS&lt;br /&gt;
&lt;br /&gt;
Some info is here in the troubleshooting part of the Arch Wiki&lt;br /&gt;
https://wiki.archlinux.org/title/Distcc#Troubleshooting&lt;br /&gt;
&lt;br /&gt;
=== Patches ===&lt;br /&gt;
&lt;br /&gt;
Other things (for 6.6LTS)&lt;br /&gt;
PCIe Stub patch&lt;br /&gt;
&lt;br /&gt;
=== Autoconf === &lt;br /&gt;
&lt;br /&gt;
No known setup examples&lt;br /&gt;
Add whatever it publishes in mdns&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== troubleshooting / analysis ==&lt;br /&gt;
&lt;br /&gt;
=== testing ===&lt;br /&gt;
&lt;br /&gt;
# turn off fallback DISTCC_FALLBACK=1&lt;br /&gt;
# set distcc up to point at specific system under test DISTCC_HOSTS=&amp;quot;mytestbox,cpp,lzo&amp;quot;&lt;br /&gt;
# GCC example compiles&lt;br /&gt;
## code example C&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example C++&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example ObjC&lt;br /&gt;
## same with included header&lt;br /&gt;
# Cmake example compiles&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docoument the thing with compile launcher ccache;distcc&lt;br /&gt;
there&#039;s some blog post, point to that&lt;br /&gt;
no ccache here yet&lt;br /&gt;
show $CC differences distcc vs gcc, what configure scripts see&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Latency ===&lt;br /&gt;
&lt;br /&gt;
Latency of pump mode startups and fallbacks needs to be investigated.&lt;br /&gt;
LZO is enforced even if you have faster network&lt;br /&gt;
DNS Requests, very old bug report from Gcode, one request per call, is it true? how to get rid of it?&lt;br /&gt;
TMPDIR is respected, make sure it&#039;s on ramdisk even on the remote nodes.&lt;br /&gt;
Compile ideally never goes to disk when it doesn&#039;t have to.&lt;br /&gt;
How efficient is the include server collection and unpacking?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== failed to distribute, running locally instead ===&lt;br /&gt;
&lt;br /&gt;
the curse of the ancient, wise bulgarian witch compildora nottherea has befallen people all over the world. only strict and mindless adherence to rituals passed down from generation to generation has given hope to those who are under her ages old spell. again and again it reemerges to prey on idealistic young men and women who spend so much time at their unholy computers that they try to spend less time there by spending a lot of time trying to optimize what the computer does, slowly, instead of reflecting on why they are there, while the computer is busy working, and why they try to solve this by adding a component that makes the computer be more error-prone at that same work, increasing the need of their presense at this idolized thinking machine to oversee and often repair, or worse, mindlessly restart its doing.&lt;br /&gt;
if the curse is not lifted, despair may befall them and all they see is the need to investigate and ruminate further on the workings of this tool, ignoring thereby the obivous flaws that stem from of its alchemic origins.&lt;br /&gt;
&lt;br /&gt;
just wait till you find out it has a backoff alghoritm deciding whether to call out to a remote server independent of that server functioning. graceful performance degradation is the goal, and degrading it is while we try to figure this out.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Node Selection algorithm ====&lt;br /&gt;
&lt;br /&gt;
as per my understanding, a flowchart goes here:&lt;br /&gt;
&lt;br /&gt;
# compile task&lt;br /&gt;
# evaluate whether to run locally by job nature&lt;br /&gt;
# determine if local host&#039;s load is notable&lt;br /&gt;
# look at distcc hosts list&lt;br /&gt;
# do something based off localhost entry if first&lt;br /&gt;
# filter for nodes with cpp flag&lt;br /&gt;
# do something based off localhost entry if not first&lt;br /&gt;
# further prioritize by server order, first is handled in some way&lt;br /&gt;
# skip nodes in backoff prisons&lt;br /&gt;
# balance and priotize by server thread number, if given&lt;br /&gt;
# send to suitable host&lt;br /&gt;
# if compile not successful, proceed on other node&lt;br /&gt;
# if nodes depleted, proceed on localhost&lt;br /&gt;
&lt;br /&gt;
== security ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== tcpwrapper style ip range filter ===&lt;br /&gt;
&lt;br /&gt;
the original security model consists of ip restrictions.&lt;br /&gt;
there seems to also be some GSSAPI user auth.&lt;br /&gt;
further, commands that can be called are restricted by name and location.&lt;br /&gt;
this appears to be a runtime whitelist lookup, meaning it&#039;s done and authorized by the same parts of the daemon as processes the compile request along with the intended compiler.&lt;br /&gt;
so the main weaknesses against malicious clients seem to be in sending things to compile, and in overriding the remote compiler to use.&lt;br /&gt;
it can be assumed that a malicious client able to exploit the compiler handshake can then run arbitrary stuff.&lt;br /&gt;
There&#039;s at least a github issue regarding this google.com/search?q=distcc+seccomp&amp;amp;rlz=1C5CHFA_enDE1121DE1121&amp;amp;oq=distcc+seccomp&amp;amp;gs_lcrp=EgZjaHJvbWUyBggAEEUYOTIHCAEQIRigATIHCAIQIRigAdIBCDM1NjRqMGo3qAIAsAIA&amp;amp;sourceid=chrome&amp;amp;ie=UTF-8 suggesting running over ssh. That does only partitally alleviate this risk with regard  to a key based verfication of a client versus a the standard ip restrictions which always include some parsing.&lt;br /&gt;
So this protects against someone directly exploiting the TCP code of distcc.&lt;br /&gt;
It does not protect against malicious clients.&lt;br /&gt;
(ssh force command can&#039;t be used or you&#039;ll not compile anything)&lt;br /&gt;
&lt;br /&gt;
The basic step for protecting access should be filtering who can access the distcc server, so use nftables etc. to restrict access to port 3262 (??) set up the internal filter the same way.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== seccomp ===&lt;br /&gt;
&lt;br /&gt;
The next thing is to confine the compiler calls to only write in their temp directory and that they can only run compilers (using nsjail, apparmor, selinux etc)&lt;br /&gt;
&lt;br /&gt;
the above issue also references the second bit of security, namely a seccomp filter which will already cover a good bit of the above&lt;br /&gt;
https://github.com/distcc/distcc/pull/235&lt;br /&gt;
the commit got closed without merge, from what I see.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== privs ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The other internal security bit is that they do some priviledge dropping. it runs as a dedicated user (distcc), so you can also have an audit policy, and can/could use something like iptables&#039; to ensure it can only connect to the other distcc/memcached hosts, but nothing else.&lt;br /&gt;
&lt;br /&gt;
=== compiler list ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
One needs to investigate when compiler_whitelist.sh is exactly called. as far as I recall it doesn&#039;t close stdin/stdout.&lt;br /&gt;
&lt;br /&gt;
=== distcc-hardened ===&lt;br /&gt;
&lt;br /&gt;
Alpine adds some hardening patch, idk what nature/origina that has.&lt;br /&gt;
&lt;br /&gt;
=== selinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
there&#039;s also a selinux policy for distcc from gentoo or liguros if one is so inclined.&lt;br /&gt;
https://repology.org/project/selinux-distcc/versions&lt;br /&gt;
&lt;br /&gt;
=== general posture ===&lt;br /&gt;
&lt;br /&gt;
Some security measures like the above should definitely be used since the project has only a few part-time maintainers that cannot easily drive the project forward or do large refactors.&lt;br /&gt;
But the seccomp changes were done almost 10 years ago, so, to be fair, they still came through.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Arch wiki refers to a fork by SUSE&lt;br /&gt;
https://github.com/icecc/icecream&lt;br /&gt;
&lt;br /&gt;
It appears &#039;maybe better&#039; but hard to tell.&lt;/div&gt;</summary>
		<author><name>Darkfader</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32142</id>
		<title>User:Darkfader/distcc</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32142"/>
		<updated>2026-03-03T11:36:29Z</updated>

		<summary type="html">&lt;p&gt;Darkfader: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi,&lt;br /&gt;
&lt;br /&gt;
I&#039;m preparing this page. It can take a long time till I finish.&lt;br /&gt;
If you are also wishing to write on this topic, feel free to integrate the content.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Document overview ==&lt;br /&gt;
&lt;br /&gt;
I noticed that almost every distro has one partially complete, partially helpful document on how to use distcc on the distro.&lt;br /&gt;
Usually they also have one for ccache.&lt;br /&gt;
In either case, they&#039;re enough to get started, but not really a reliable watertight thing.&lt;br /&gt;
We definitely needed one of our own.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== goal ===&lt;br /&gt;
&lt;br /&gt;
to describe a working setup for building aports in easiest/fastests fashion&lt;br /&gt;
not planning to add versatility or features where it would make the setup more errorprone.&lt;br /&gt;
the page should describe enough of the steps to successfully compile an LTS kernel via aports and have that job be distributed over multiple nodes.&lt;br /&gt;
Logs should be set up and able to display errors, but not show any errors during the test compile.&lt;br /&gt;
&lt;br /&gt;
To include a path for analysis via testing components.&lt;br /&gt;
&lt;br /&gt;
distcc can greatly improve compile speeds for large software, it comes with a different set of features than ccache; it focusses not avoiding unneccessary compile work, but on a way to speed up the necessary one.&lt;br /&gt;
&lt;br /&gt;
There&#039;s valuable info in the docs of other distros, it should be referenced here (i.e. the arch wiki troubleshooting), when it makes sense, add a TOC for their content.&lt;br /&gt;
&lt;br /&gt;
=== audience ===&lt;br /&gt;
people running software builds on alpine and have multiple computers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This page will show a specific installation, specific configuration, and specific tests, resulting in a specific set of functionality that can be tested to be working.&lt;br /&gt;
&lt;br /&gt;
== installation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Packages ===&lt;br /&gt;
&lt;br /&gt;
you need, on each host&lt;br /&gt;
* distcc&lt;br /&gt;
* distccd-openrc&lt;br /&gt;
* distcc-pump&lt;br /&gt;
* distcc-pump-pyc&lt;br /&gt;
&lt;br /&gt;
the .pyc will speed up the invocations, without it &lt;br /&gt;
idk if one or both should be installed in that case. but it appears to be also automatically be precompiled in /usr/lib/python3.12/site-packages/include_server/__pycache__/ so what does the package do exactly?&lt;br /&gt;
&lt;br /&gt;
There&#039;s some references to cpython-312, so maybe it actually still uses classy python-c conversion or matbe that&#039;s just a component for reading C source code. I have zero idea.&lt;br /&gt;
&lt;br /&gt;
you also need stuff to do compiles&lt;br /&gt;
* alpine sdk&lt;br /&gt;
* clang&lt;br /&gt;
* binutils&lt;br /&gt;
...&lt;br /&gt;
* elfutils(-dev)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Settings ===&lt;br /&gt;
==== settings for distcc ====&lt;br /&gt;
&lt;br /&gt;
* there&#039;s /etc/default/distcc&lt;br /&gt;
* there&#039;s /etc/conf.d/distcc &lt;br /&gt;
&lt;br /&gt;
make all your settings here&lt;br /&gt;
take care with the listen address, if you specify an IP it&#039;ll not be on 127.0.0.1 in case you would have localhost in your list...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* command_whitelist.sh &lt;br /&gt;
&lt;br /&gt;
this is half functional, you need to set things here but you also need to maintain the symlinks that are collected under /usr/lib/distcc (for your compilers) and /usr/lib/distcc/bin (for itself)&lt;br /&gt;
&lt;br /&gt;
you MUST run the script to update the compilers!&lt;br /&gt;
Info for script and what files it will create&lt;br /&gt;
&lt;br /&gt;
/usr/sbin/update-distcc-symlinks&lt;br /&gt;
&lt;br /&gt;
tschike:/usr/bin# ls -l /usr/lib/distcc/&lt;br /&gt;
total 4&lt;br /&gt;
drwxr-xr-x 2 root root 4096 Mar  2 18:14 bin&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c89 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c99 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 cc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc-15.2.0 -&amp;gt; ../../bin/distcc&lt;br /&gt;
&lt;br /&gt;
distcc itself is in bin&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cpp -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 g++ -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 06:49 x86_64-alpine-linux-musl-gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
&lt;br /&gt;
the last symplink here is wrong, made by me and would not work...&lt;br /&gt;
BAD symlink.&lt;br /&gt;
&lt;br /&gt;
=== distcc hosts file ===&lt;br /&gt;
&lt;br /&gt;
idk about that thing it&#039;s odd&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== abuild.conf ===&lt;br /&gt;
&lt;br /&gt;
settings for aports&lt;br /&gt;
* cc=&lt;br /&gt;
* cxx=&lt;br /&gt;
* cpp=&lt;br /&gt;
* cflags=&lt;br /&gt;
* njobs&lt;br /&gt;
&lt;br /&gt;
== detail infos ==&lt;br /&gt;
&lt;br /&gt;
???&lt;br /&gt;
&lt;br /&gt;
=== hosts syntax ===&lt;br /&gt;
&lt;br /&gt;
* myhost otherhost&lt;br /&gt;
* myhost,cpp,lzo myotherhost,cpp,lzo&lt;br /&gt;
&lt;br /&gt;
==== the host ====&lt;br /&gt;
&lt;br /&gt;
hostname/ip&lt;br /&gt;
localhost&lt;br /&gt;
127.0.0.1&lt;br /&gt;
::1 - does not work&lt;br /&gt;
&lt;br /&gt;
==== protocol ====&lt;br /&gt;
&lt;br /&gt;
* no protocol given&lt;br /&gt;
* ,cpp,lzo protocol&lt;br /&gt;
&lt;br /&gt;
cpp implies lzo, it requires compression, even if you have 10gbit/s or more, it&#039;s just hardcoded&lt;br /&gt;
&lt;br /&gt;
=== threads ===&lt;br /&gt;
/number of workers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== architecture ==&lt;br /&gt;
it can handle C, C++, ObjC, maybe some other stuff&lt;br /&gt;
&lt;br /&gt;
* what happens with normal xmit&lt;br /&gt;
* what happens with pump mode&lt;br /&gt;
* at which step the include server is used and how it collects the includes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== distribution algorithm ===&lt;br /&gt;
honestly I simply don&#039;t get it&lt;br /&gt;
&lt;br /&gt;
* The order matters&lt;br /&gt;
* The number of threads matters&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== localhost ====&lt;br /&gt;
&lt;br /&gt;
* localhost precedence&lt;br /&gt;
* localhost fallback&lt;br /&gt;
&lt;br /&gt;
variable: DISTCC_FALLBACK&lt;br /&gt;
&lt;br /&gt;
0 = Fail to compile if it would need to fallback to a normal local gcc call&lt;br /&gt;
1 = If remote compile fails, just do it yourself&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Operation ==&lt;br /&gt;
&lt;br /&gt;
=== startup and shutdown ===&lt;br /&gt;
service distcc stop is not entirely reliable (it can take a minute after the stop until the processes are gone and sometimes it will never stop&lt;br /&gt;
this is very bad with openrc, the openrc script returns after a second and only relies on its service flags, not the process status.&lt;br /&gt;
manually check after stopping, wait a min, if needed, kill it all.&lt;br /&gt;
at some point the rc file needs to be rewritten, it can&#039;t stay like it is.&lt;br /&gt;
&lt;br /&gt;
if you used a pump mode session, that also needs a logout (pump --shutdown)&lt;br /&gt;
avoid running multiple startups without shutdown in one session. it&#039;s safe as far as I can tell but nothing cleans up these processes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== ccache and memcached ===&lt;br /&gt;
CCACHE is said to be conflicting with pump mode unless when you call them in the backend&lt;br /&gt;
so, where you start the compile, you don&#039;t use it&lt;br /&gt;
where the compile happens, you use it&lt;br /&gt;
they can share the cache via memcached, this is a nice trick for consistency&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== dockerized / native ===&lt;br /&gt;
&lt;br /&gt;
it remains mostly the same, a container needs to make sure it monitors the right services (distccd, nginx, include_server)&lt;br /&gt;
if you&#039;re using zeroconf, you need to somehow expose the mdns service broadcasts &amp;amp; reception&lt;br /&gt;
&lt;br /&gt;
Processs list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
Workdir list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
=== alpine-chroot ===&lt;br /&gt;
&lt;br /&gt;
when using the &#039;official&#039; script there&#039;s still some odd pieces, seemed to be the processes died on logout. but not all of them.&lt;br /&gt;
&lt;br /&gt;
==== manual launch ====&lt;br /&gt;
&lt;br /&gt;
Starting the daemon would be using&lt;br /&gt;
/usr/bin/distccd --pid-file /var/run/distccd/distccd.pid -N 15 --user distcc --port 3632 --log-level=debug --log-file=/var/log/distccd.log --allow my-sub-net/24&lt;br /&gt;
&lt;br /&gt;
==== localhost? =====&lt;br /&gt;
unclear if you need to use --allow for 127.0.0.1/32 or something to allow the remote preproccesor.&lt;br /&gt;
&lt;br /&gt;
== Kernel specific settings ==&lt;br /&gt;
&lt;br /&gt;
currently (distcc 3.4-r9 on Alpine) you need a patch to build the kernel.&lt;br /&gt;
See &lt;br /&gt;
&lt;br /&gt;
=== Include server Settings ===&lt;br /&gt;
&lt;br /&gt;
cache reset triggers&lt;br /&gt;
This ought to be set before enabling pump mode.&lt;br /&gt;
&lt;br /&gt;
export INCLUDE_SERVER_ARGS=&amp;quot;--stat_reset_triggers=include/linux/compile.h:include/asm/asm-offsets.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
link to explanation TBA&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Disabling GCC Plugins ===&lt;br /&gt;
&lt;br /&gt;
KConfig unselect HAVE_GCC_PLUGINS&lt;br /&gt;
&lt;br /&gt;
Some info is here in the troubleshooting part of the Arch Wiki&lt;br /&gt;
https://wiki.archlinux.org/title/Distcc#Troubleshooting&lt;br /&gt;
&lt;br /&gt;
=== Patches ===&lt;br /&gt;
&lt;br /&gt;
Other things (for 6.6LTS)&lt;br /&gt;
PCIe Stub patch&lt;br /&gt;
&lt;br /&gt;
=== Autoconf === &lt;br /&gt;
&lt;br /&gt;
No known setup examples&lt;br /&gt;
Add whatever it publishes in mdns&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== troubleshooting / analysis ==&lt;br /&gt;
&lt;br /&gt;
=== testing ===&lt;br /&gt;
&lt;br /&gt;
# turn off fallback DISTCC_FALLBACK=1&lt;br /&gt;
# set distcc up to point at specific system under test DISTCC_HOSTS=&amp;quot;mytestbox,cpp,lzo&amp;quot;&lt;br /&gt;
# GCC example compiles&lt;br /&gt;
## code example C&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example C++&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example ObjC&lt;br /&gt;
## same with included header&lt;br /&gt;
# Cmake example compiles&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docoument the thing with compile launcher ccache;distcc&lt;br /&gt;
there&#039;s some blog post, point to that&lt;br /&gt;
no ccache here yet&lt;br /&gt;
show $CC differences distcc vs gcc, what configure scripts see&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Latency ===&lt;br /&gt;
&lt;br /&gt;
Latency of pump mode startups and fallbacks needs to be investigated.&lt;br /&gt;
LZO is enforced even if you have faster network&lt;br /&gt;
DNS Requests, very old bug report from Gcode, one request per call, is it true? how to get rid of it?&lt;br /&gt;
TMPDIR is respected, make sure it&#039;s on ramdisk even on the remote nodes.&lt;br /&gt;
Compile ideally never goes to disk when it doesn&#039;t have to.&lt;br /&gt;
How efficient is the include server collection and unpacking?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== failed to distribute, running locally instead ===&lt;br /&gt;
&lt;br /&gt;
the curse of the ancient, wise bulgarian witch compildora nottherea has befallen people all over the world. only strict and mindless adherence to rituals passed down from generation to generation has given hope to those who are under her ages old spell. again and again it reemerges to prey on idealistic young men and women who spend so much time at their unholy computers that they try to spend less time there by spending a lot of time trying to optimize what the computer does, slowly, instead of reflecting on why they are there, while the computer is busy working, and why they try to solve this by adding a component that makes the computer be more error-prone at that same work, increasing the need of their presense at this idolized thinking machine to oversee and often repair, or worse, mindlessly restart its doing.&lt;br /&gt;
if the curse is not lifted, despair may befall them and all they see is the need to investigate and ruminate further on the workings of this tool, ignoring thereby the obivous flaws that stem from of its alchemic origins.&lt;br /&gt;
&lt;br /&gt;
just wait till you find out it has a backoff alghoritm deciding whether to call out to a remote server independent of that server functioning. graceful performance degradation is the goal, and degrading it is while we try to figure this out.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Node Selection algorithm ===&lt;br /&gt;
&lt;br /&gt;
as per my understanding, a flowchart goes here:&lt;br /&gt;
&lt;br /&gt;
# compile task&lt;br /&gt;
# evaluate whether to run locally by job nature&lt;br /&gt;
# determine if local host&#039;s load is notable&lt;br /&gt;
# look at distcc hosts list&lt;br /&gt;
# do something based off localhost entry if first&lt;br /&gt;
# filter for nodes with cpp flag&lt;br /&gt;
# do something based off localhost entry if not first&lt;br /&gt;
# further prioritize by server order, first is handled in some way&lt;br /&gt;
# skip nodes in backoff prisons&lt;br /&gt;
# balance and priotize by server thread number, if given&lt;br /&gt;
# send to suitable host&lt;br /&gt;
# if compile not successful, proceed on other node&lt;br /&gt;
# if nodes depleted, proceed on localhost&lt;br /&gt;
&lt;br /&gt;
== security ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== tcpwrapper style ip range filter ===&lt;br /&gt;
&lt;br /&gt;
the original security model consists of ip restrictions.&lt;br /&gt;
there seems to also be some GSSAPI user auth.&lt;br /&gt;
further, commands that can be called are restricted by name and location.&lt;br /&gt;
this appears to be a runtime whitelist lookup, meaning it&#039;s done and authorized by the same parts of the daemon as processes the compile request along with the intended compiler.&lt;br /&gt;
so the main weaknesses against malicious clients seem to be in sending things to compile, and in overriding the remote compiler to use.&lt;br /&gt;
it can be assumed that a malicious client able to exploit the compiler handshake can then run arbitrary stuff.&lt;br /&gt;
There&#039;s at least a github issue regarding this google.com/search?q=distcc+seccomp&amp;amp;rlz=1C5CHFA_enDE1121DE1121&amp;amp;oq=distcc+seccomp&amp;amp;gs_lcrp=EgZjaHJvbWUyBggAEEUYOTIHCAEQIRigATIHCAIQIRigAdIBCDM1NjRqMGo3qAIAsAIA&amp;amp;sourceid=chrome&amp;amp;ie=UTF-8 suggesting running over ssh. That does only partitally alleviate this risk with regard  to a key based verfication of a client versus a the standard ip restrictions which always include some parsing.&lt;br /&gt;
So this protects against someone directly exploiting the TCP code of distcc.&lt;br /&gt;
It does not protect against malicious clients.&lt;br /&gt;
(ssh force command can&#039;t be used or you&#039;ll not compile anything)&lt;br /&gt;
&lt;br /&gt;
The basic step for protecting access should be filtering who can access the distcc server, so use nftables etc. to restrict access to port 3262 (??) set up the internal filter the same way.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== seccomp ===&lt;br /&gt;
&lt;br /&gt;
The next thing is to confine the compiler calls to only write in their temp directory and that they can only run compilers (using nsjail, apparmor, selinux etc)&lt;br /&gt;
&lt;br /&gt;
the above issue also references the second bit of security, namely a seccomp filter which will already cover a good bit of the above&lt;br /&gt;
https://github.com/distcc/distcc/pull/235&lt;br /&gt;
the commit got closed without merge, from what I see.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== privs ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The other internal security bit is that they do some priviledge dropping. it runs as a dedicated user (distcc), so you can also have an audit policy, and can/could use something like iptables&#039; to ensure it can only connect to the other distcc/memcached hosts, but nothing else.&lt;br /&gt;
&lt;br /&gt;
=== compiler list ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
One needs to investigate when compiler_whitelist.sh is exactly called. as far as I recall it doesn&#039;t close stdin/stdout.&lt;br /&gt;
&lt;br /&gt;
=== distcc-hardened ===&lt;br /&gt;
&lt;br /&gt;
Alpine adds some hardening patch, idk what nature/origina that has.&lt;br /&gt;
&lt;br /&gt;
=== selinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
there&#039;s also a selinux policy for distcc from gentoo or liguros if one is so inclined.&lt;br /&gt;
https://repology.org/project/selinux-distcc/versions&lt;br /&gt;
&lt;br /&gt;
=== general posture ===&lt;br /&gt;
&lt;br /&gt;
Some security measures like the above should definitely be used since the project has only a few part-time maintainers that cannot easily drive the project forward or do large refactors.&lt;br /&gt;
But the seccomp changes were done almost 10 years ago, so, to be fair, they still came through.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Arch wiki refers to a fork by SUSE&lt;br /&gt;
https://github.com/icecc/icecream&lt;br /&gt;
&lt;br /&gt;
It appears &#039;maybe better&#039; but hard to tell.&lt;/div&gt;</summary>
		<author><name>Darkfader</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32141</id>
		<title>User:Darkfader/distcc</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32141"/>
		<updated>2026-03-03T11:35:29Z</updated>

		<summary type="html">&lt;p&gt;Darkfader: /* failed to distribute, running locally instead */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi,&lt;br /&gt;
&lt;br /&gt;
I&#039;m preparing this page. It can take a long time till I finish.&lt;br /&gt;
If you are also wishing to write on this topic, feel free to integrate the content.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Document overview ==&lt;br /&gt;
&lt;br /&gt;
I noticed that almost every distro has one partially complete, partially helpful document on how to use distcc on the distro.&lt;br /&gt;
Usually they also have one for ccache.&lt;br /&gt;
In either case, they&#039;re enough to get started, but not really a reliable watertight thing.&lt;br /&gt;
We definitely needed one of our own.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== goal ===&lt;br /&gt;
&lt;br /&gt;
to describe a working setup for building aports in easiest/fastests fashion&lt;br /&gt;
not planning to add versatility or features where it would make the setup more errorprone.&lt;br /&gt;
the page should describe enough of the steps to successfully compile an LTS kernel via aports and have that job be distributed over multiple nodes.&lt;br /&gt;
Logs should be set up and able to display errors, but not show any errors during the test compile.&lt;br /&gt;
&lt;br /&gt;
To include a path for analysis via testing components.&lt;br /&gt;
&lt;br /&gt;
distcc can greatly improve compile speeds for large software, it comes with a different set of features than ccache; it focusses not avoiding unneccessary compile work, but on a way to speed up the necessary one.&lt;br /&gt;
&lt;br /&gt;
There&#039;s valuable info in the docs of other distros, it should be referenced here (i.e. the arch wiki troubleshooting), when it makes sense, add a TOC for their content.&lt;br /&gt;
&lt;br /&gt;
=== audience ===&lt;br /&gt;
people running software builds on alpine and have multiple computers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This page will show a specific installation, specific configuration, and specific tests, resulting in a specific set of functionality that can be tested to be working.&lt;br /&gt;
&lt;br /&gt;
== installation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Packages ===&lt;br /&gt;
&lt;br /&gt;
you need, on each host&lt;br /&gt;
* distcc&lt;br /&gt;
* distccd-openrc&lt;br /&gt;
* distcc-pump&lt;br /&gt;
* distcc-pump-pyc&lt;br /&gt;
&lt;br /&gt;
the .pyc will speed up the invocations, without it &lt;br /&gt;
idk if one or both should be installed in that case. but it appears to be also automatically be precompiled in /usr/lib/python3.12/site-packages/include_server/__pycache__/ so what does the package do exactly?&lt;br /&gt;
&lt;br /&gt;
There&#039;s some references to cpython-312, so maybe it actually still uses classy python-c conversion or matbe that&#039;s just a component for reading C source code. I have zero idea.&lt;br /&gt;
&lt;br /&gt;
you also need stuff to do compiles&lt;br /&gt;
* alpine sdk&lt;br /&gt;
* clang&lt;br /&gt;
* binutils&lt;br /&gt;
...&lt;br /&gt;
* elfutils(-dev)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Settings ===&lt;br /&gt;
==== settings for distcc ====&lt;br /&gt;
&lt;br /&gt;
* there&#039;s /etc/default/distcc&lt;br /&gt;
* there&#039;s /etc/conf.d/distcc &lt;br /&gt;
&lt;br /&gt;
make all your settings here&lt;br /&gt;
take care with the listen address, if you specify an IP it&#039;ll not be on 127.0.0.1 in case you would have localhost in your list...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* command_whitelist.sh &lt;br /&gt;
&lt;br /&gt;
this is half functional, you need to set things here but you also need to maintain the symlinks that are collected under /usr/lib/distcc (for your compilers) and /usr/lib/distcc/bin (for itself)&lt;br /&gt;
&lt;br /&gt;
you MUST run the script to update the compilers!&lt;br /&gt;
Info for script and what files it will create&lt;br /&gt;
&lt;br /&gt;
/usr/sbin/update-distcc-symlinks&lt;br /&gt;
&lt;br /&gt;
tschike:/usr/bin# ls -l /usr/lib/distcc/&lt;br /&gt;
total 4&lt;br /&gt;
drwxr-xr-x 2 root root 4096 Mar  2 18:14 bin&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c89 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c99 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 cc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc-15.2.0 -&amp;gt; ../../bin/distcc&lt;br /&gt;
&lt;br /&gt;
distcc itself is in bin&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cpp -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 g++ -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 06:49 x86_64-alpine-linux-musl-gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
&lt;br /&gt;
the last symplink here is wrong, made by me and would not work...&lt;br /&gt;
BAD symlink.&lt;br /&gt;
&lt;br /&gt;
=== distcc hosts file ===&lt;br /&gt;
&lt;br /&gt;
idk about that thing it&#039;s odd&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== abuild.conf ===&lt;br /&gt;
&lt;br /&gt;
settings for aports&lt;br /&gt;
* cc=&lt;br /&gt;
* cxx=&lt;br /&gt;
* cpp=&lt;br /&gt;
* cflags=&lt;br /&gt;
* njobs&lt;br /&gt;
&lt;br /&gt;
== detail infos ==&lt;br /&gt;
&lt;br /&gt;
???&lt;br /&gt;
&lt;br /&gt;
=== hosts syntax ===&lt;br /&gt;
&lt;br /&gt;
* myhost otherhost&lt;br /&gt;
* myhost,cpp,lzo myotherhost,cpp,lzo&lt;br /&gt;
&lt;br /&gt;
==== the host ====&lt;br /&gt;
&lt;br /&gt;
hostname/ip&lt;br /&gt;
localhost&lt;br /&gt;
127.0.0.1&lt;br /&gt;
::1 - does not work&lt;br /&gt;
&lt;br /&gt;
==== protocol ====&lt;br /&gt;
&lt;br /&gt;
* no protocol given&lt;br /&gt;
* ,cpp,lzo protocol&lt;br /&gt;
&lt;br /&gt;
cpp implies lzo, it requires compression, even if you have 10gbit/s or more, it&#039;s just hardcoded&lt;br /&gt;
&lt;br /&gt;
=== threads ===&lt;br /&gt;
/number of workers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== architecture ==&lt;br /&gt;
it can handle C, C++, ObjC, maybe some other stuff&lt;br /&gt;
&lt;br /&gt;
* what happens with normal xmit&lt;br /&gt;
* what happens with pump mode&lt;br /&gt;
* at which step the include server is used and how it collects the includes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== distribution algorithm ===&lt;br /&gt;
honestly I simply don&#039;t get it&lt;br /&gt;
&lt;br /&gt;
* The order matters&lt;br /&gt;
* The number of threads matters&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== localhost ====&lt;br /&gt;
&lt;br /&gt;
* localhost precedence&lt;br /&gt;
* localhost fallback&lt;br /&gt;
&lt;br /&gt;
variable: DISTCC_FALLBACK&lt;br /&gt;
&lt;br /&gt;
0 = Fail to compile if it would need to fallback to a normal local gcc call&lt;br /&gt;
1 = If remote compile fails, just do it yourself&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Operation ==&lt;br /&gt;
&lt;br /&gt;
=== startup and shutdown ===&lt;br /&gt;
service distcc stop is not entirely reliable (it can take a minute after the stop until the processes are gone and sometimes it will never stop&lt;br /&gt;
this is very bad with openrc, the openrc script returns after a second and only relies on its service flags, not the process status.&lt;br /&gt;
manually check after stopping, wait a min, if needed, kill it all.&lt;br /&gt;
at some point the rc file needs to be rewritten, it can&#039;t stay like it is.&lt;br /&gt;
&lt;br /&gt;
if you used a pump mode session, that also needs a logout (pump --shutdown)&lt;br /&gt;
avoid running multiple startups without shutdown in one session. it&#039;s safe as far as I can tell but nothing cleans up these processes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== ccache and memcached ===&lt;br /&gt;
CCACHE is said to be conflicting with pump mode unless when you call them in the backend&lt;br /&gt;
so, where you start the compile, you don&#039;t use it&lt;br /&gt;
where the compile happens, you use it&lt;br /&gt;
they can share the cache via memcached, this is a nice trick for consistency&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== dockerized / native ===&lt;br /&gt;
&lt;br /&gt;
it remains mostly the same, a container needs to make sure it monitors the right services (distccd, nginx, include_server)&lt;br /&gt;
if you&#039;re using zeroconf, you need to somehow expose the mdns service broadcasts &amp;amp; reception&lt;br /&gt;
&lt;br /&gt;
Processs list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
Workdir list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
=== alpine-chroot ===&lt;br /&gt;
&lt;br /&gt;
when using the &#039;official&#039; script there&#039;s still some odd pieces, seemed to be the processes died on logout. but not all of them.&lt;br /&gt;
&lt;br /&gt;
==== manual launch ====&lt;br /&gt;
&lt;br /&gt;
Starting the daemon would be using&lt;br /&gt;
/usr/bin/distccd --pid-file /var/run/distccd/distccd.pid -N 15 --user distcc --port 3632 --log-level=debug --log-file=/var/log/distccd.log --allow my-sub-net/24&lt;br /&gt;
&lt;br /&gt;
==== localhost? =====&lt;br /&gt;
unclear if you need to use --allow for 127.0.0.1/32 or something to allow the remote preproccesor.&lt;br /&gt;
&lt;br /&gt;
== Kernel specific settings ==&lt;br /&gt;
&lt;br /&gt;
currently (distcc 3.4-r9 on Alpine) you need a patch to build the kernel.&lt;br /&gt;
See &lt;br /&gt;
&lt;br /&gt;
=== Include server Settings ===&lt;br /&gt;
&lt;br /&gt;
cache reset triggers&lt;br /&gt;
This ought to be set before enabling pump mode.&lt;br /&gt;
&lt;br /&gt;
export INCLUDE_SERVER_ARGS=&amp;quot;--stat_reset_triggers=include/linux/compile.h:include/asm/asm-offsets.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
link to explanation TBA&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Disabling GCC Plugins ===&lt;br /&gt;
&lt;br /&gt;
KConfig unselect HAVE_GCC_PLUGINS&lt;br /&gt;
&lt;br /&gt;
Some info is here in the troubleshooting part of the Arch Wiki&lt;br /&gt;
https://wiki.archlinux.org/title/Distcc#Troubleshooting&lt;br /&gt;
&lt;br /&gt;
=== Patches ===&lt;br /&gt;
&lt;br /&gt;
Other things (for 6.6LTS)&lt;br /&gt;
PCIe Stub patch&lt;br /&gt;
&lt;br /&gt;
=== Autoconf === &lt;br /&gt;
&lt;br /&gt;
No known setup examples&lt;br /&gt;
Add whatever it publishes in mdns&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== troubleshooting / analysis ==&lt;br /&gt;
&lt;br /&gt;
=== testing ===&lt;br /&gt;
&lt;br /&gt;
# turn off fallback DISTCC_FALLBACK=1&lt;br /&gt;
# set distcc up to point at specific system under test DISTCC_HOSTS=&amp;quot;mytestbox,cpp,lzo&amp;quot;&lt;br /&gt;
# GCC example compiles&lt;br /&gt;
## code example C&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example C++&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example ObjC&lt;br /&gt;
## same with included header&lt;br /&gt;
# Cmake example compiles&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docoument the thing with compile launcher ccache;distcc&lt;br /&gt;
there&#039;s some blog post, point to that&lt;br /&gt;
no ccache here yet&lt;br /&gt;
show $CC differences distcc vs gcc, what configure scripts see&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Latency ===&lt;br /&gt;
&lt;br /&gt;
Latency of pump mode startups and fallbacks needs to be investigated.&lt;br /&gt;
LZO is enforced even if you have faster network&lt;br /&gt;
DNS Requests, very old bug report from Gcode, one request per call, is it true? how to get rid of it?&lt;br /&gt;
TMPDIR is respected, make sure it&#039;s on ramdisk even on the remote nodes.&lt;br /&gt;
Compile ideally never goes to disk when it doesn&#039;t have to.&lt;br /&gt;
How efficient is the include server collection and unpacking?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== failed to distribute, running locally instead ===&lt;br /&gt;
&lt;br /&gt;
the curse of the ancient, wise bulgarian witch compildora nottherea has befallen people all over the world. only strict and mindless adherence to rituals passed down from generation to generation has given hope to those who are under her ages old spell. again and again it reemerges to prey on idealistic young men and women who spend so much time at their unholy computers that they try to spend less time there by spending a lot of time trying to optimize what the computer does, slowly, instead of reflecting on why they are there, while the computer is busy working, and why they try to solve this by adding a component that makes the computer be more error-prone at that same work, increasing the need of their presense at this idolized thinking machine to oversee and often repair, or worse, mindlessly restart its doing.&lt;br /&gt;
if the curse is not lifted, despair may befall them and all they see is the need to investigate and ruminate further on the workings of this tool, ignoring thereby the obivous flaws that stem from of its alchemic origins.&lt;br /&gt;
&lt;br /&gt;
just wait till you find out it has a backoff alghoritm deciding whether to call out to a remote server independent of that server functioning. graceful performance degradation is the goal, and degrading it is while we try to figure this out.&lt;br /&gt;
&lt;br /&gt;
A flowchart goes here:&lt;br /&gt;
&lt;br /&gt;
1. compile task&lt;br /&gt;
2. evaluate whether to run locally by job nature&lt;br /&gt;
3. determine if local host&#039;s load is notable&lt;br /&gt;
4. look at distcc hosts list&lt;br /&gt;
5. do something based off localhost entry if first&lt;br /&gt;
6. filter for nodes with cpp flag&lt;br /&gt;
7. do something based off localhost entry if not first&lt;br /&gt;
8. further prioritize by server order, first is handled in some way&lt;br /&gt;
9. skip nodes in backoff prisons&lt;br /&gt;
10. balance and priotize by server thread number, if given&lt;br /&gt;
11. send to suitable host&lt;br /&gt;
12. if compile not successful, proceed on other node&lt;br /&gt;
13. if nodes depleted, proceed on localhost&lt;br /&gt;
&lt;br /&gt;
== security ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== tcpwrapper style ip range filter ===&lt;br /&gt;
&lt;br /&gt;
the original security model consists of ip restrictions.&lt;br /&gt;
there seems to also be some GSSAPI user auth.&lt;br /&gt;
further, commands that can be called are restricted by name and location.&lt;br /&gt;
this appears to be a runtime whitelist lookup, meaning it&#039;s done and authorized by the same parts of the daemon as processes the compile request along with the intended compiler.&lt;br /&gt;
so the main weaknesses against malicious clients seem to be in sending things to compile, and in overriding the remote compiler to use.&lt;br /&gt;
it can be assumed that a malicious client able to exploit the compiler handshake can then run arbitrary stuff.&lt;br /&gt;
There&#039;s at least a github issue regarding this google.com/search?q=distcc+seccomp&amp;amp;rlz=1C5CHFA_enDE1121DE1121&amp;amp;oq=distcc+seccomp&amp;amp;gs_lcrp=EgZjaHJvbWUyBggAEEUYOTIHCAEQIRigATIHCAIQIRigAdIBCDM1NjRqMGo3qAIAsAIA&amp;amp;sourceid=chrome&amp;amp;ie=UTF-8 suggesting running over ssh. That does only partitally alleviate this risk with regard  to a key based verfication of a client versus a the standard ip restrictions which always include some parsing.&lt;br /&gt;
So this protects against someone directly exploiting the TCP code of distcc.&lt;br /&gt;
It does not protect against malicious clients.&lt;br /&gt;
(ssh force command can&#039;t be used or you&#039;ll not compile anything)&lt;br /&gt;
&lt;br /&gt;
The basic step for protecting access should be filtering who can access the distcc server, so use nftables etc. to restrict access to port 3262 (??) set up the internal filter the same way.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== seccomp ===&lt;br /&gt;
&lt;br /&gt;
The next thing is to confine the compiler calls to only write in their temp directory and that they can only run compilers (using nsjail, apparmor, selinux etc)&lt;br /&gt;
&lt;br /&gt;
the above issue also references the second bit of security, namely a seccomp filter which will already cover a good bit of the above&lt;br /&gt;
https://github.com/distcc/distcc/pull/235&lt;br /&gt;
the commit got closed without merge, from what I see.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== privs ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The other internal security bit is that they do some priviledge dropping. it runs as a dedicated user (distcc), so you can also have an audit policy, and can/could use something like iptables&#039; to ensure it can only connect to the other distcc/memcached hosts, but nothing else.&lt;br /&gt;
&lt;br /&gt;
=== compiler list ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
One needs to investigate when compiler_whitelist.sh is exactly called. as far as I recall it doesn&#039;t close stdin/stdout.&lt;br /&gt;
&lt;br /&gt;
=== distcc-hardened ===&lt;br /&gt;
&lt;br /&gt;
Alpine adds some hardening patch, idk what nature/origina that has.&lt;br /&gt;
&lt;br /&gt;
=== selinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
there&#039;s also a selinux policy for distcc from gentoo or liguros if one is so inclined.&lt;br /&gt;
https://repology.org/project/selinux-distcc/versions&lt;br /&gt;
&lt;br /&gt;
=== general posture ===&lt;br /&gt;
&lt;br /&gt;
Some security measures like the above should definitely be used since the project has only a few part-time maintainers that cannot easily drive the project forward or do large refactors.&lt;br /&gt;
But the seccomp changes were done almost 10 years ago, so, to be fair, they still came through.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Arch wiki refers to a fork by SUSE&lt;br /&gt;
https://github.com/icecc/icecream&lt;br /&gt;
&lt;br /&gt;
It appears &#039;maybe better&#039; but hard to tell.&lt;/div&gt;</summary>
		<author><name>Darkfader</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32140</id>
		<title>User:Darkfader/distcc</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32140"/>
		<updated>2026-03-03T11:29:49Z</updated>

		<summary type="html">&lt;p&gt;Darkfader: /* failed to distribute, running locally instead */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi,&lt;br /&gt;
&lt;br /&gt;
I&#039;m preparing this page. It can take a long time till I finish.&lt;br /&gt;
If you are also wishing to write on this topic, feel free to integrate the content.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Document overview ==&lt;br /&gt;
&lt;br /&gt;
I noticed that almost every distro has one partially complete, partially helpful document on how to use distcc on the distro.&lt;br /&gt;
Usually they also have one for ccache.&lt;br /&gt;
In either case, they&#039;re enough to get started, but not really a reliable watertight thing.&lt;br /&gt;
We definitely needed one of our own.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== goal ===&lt;br /&gt;
&lt;br /&gt;
to describe a working setup for building aports in easiest/fastests fashion&lt;br /&gt;
not planning to add versatility or features where it would make the setup more errorprone.&lt;br /&gt;
the page should describe enough of the steps to successfully compile an LTS kernel via aports and have that job be distributed over multiple nodes.&lt;br /&gt;
Logs should be set up and able to display errors, but not show any errors during the test compile.&lt;br /&gt;
&lt;br /&gt;
To include a path for analysis via testing components.&lt;br /&gt;
&lt;br /&gt;
distcc can greatly improve compile speeds for large software, it comes with a different set of features than ccache; it focusses not avoiding unneccessary compile work, but on a way to speed up the necessary one.&lt;br /&gt;
&lt;br /&gt;
There&#039;s valuable info in the docs of other distros, it should be referenced here (i.e. the arch wiki troubleshooting), when it makes sense, add a TOC for their content.&lt;br /&gt;
&lt;br /&gt;
=== audience ===&lt;br /&gt;
people running software builds on alpine and have multiple computers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This page will show a specific installation, specific configuration, and specific tests, resulting in a specific set of functionality that can be tested to be working.&lt;br /&gt;
&lt;br /&gt;
== installation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Packages ===&lt;br /&gt;
&lt;br /&gt;
you need, on each host&lt;br /&gt;
* distcc&lt;br /&gt;
* distccd-openrc&lt;br /&gt;
* distcc-pump&lt;br /&gt;
* distcc-pump-pyc&lt;br /&gt;
&lt;br /&gt;
the .pyc will speed up the invocations, without it &lt;br /&gt;
idk if one or both should be installed in that case. but it appears to be also automatically be precompiled in /usr/lib/python3.12/site-packages/include_server/__pycache__/ so what does the package do exactly?&lt;br /&gt;
&lt;br /&gt;
There&#039;s some references to cpython-312, so maybe it actually still uses classy python-c conversion or matbe that&#039;s just a component for reading C source code. I have zero idea.&lt;br /&gt;
&lt;br /&gt;
you also need stuff to do compiles&lt;br /&gt;
* alpine sdk&lt;br /&gt;
* clang&lt;br /&gt;
* binutils&lt;br /&gt;
...&lt;br /&gt;
* elfutils(-dev)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Settings ===&lt;br /&gt;
==== settings for distcc ====&lt;br /&gt;
&lt;br /&gt;
* there&#039;s /etc/default/distcc&lt;br /&gt;
* there&#039;s /etc/conf.d/distcc &lt;br /&gt;
&lt;br /&gt;
make all your settings here&lt;br /&gt;
take care with the listen address, if you specify an IP it&#039;ll not be on 127.0.0.1 in case you would have localhost in your list...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* command_whitelist.sh &lt;br /&gt;
&lt;br /&gt;
this is half functional, you need to set things here but you also need to maintain the symlinks that are collected under /usr/lib/distcc (for your compilers) and /usr/lib/distcc/bin (for itself)&lt;br /&gt;
&lt;br /&gt;
you MUST run the script to update the compilers!&lt;br /&gt;
Info for script and what files it will create&lt;br /&gt;
&lt;br /&gt;
/usr/sbin/update-distcc-symlinks&lt;br /&gt;
&lt;br /&gt;
tschike:/usr/bin# ls -l /usr/lib/distcc/&lt;br /&gt;
total 4&lt;br /&gt;
drwxr-xr-x 2 root root 4096 Mar  2 18:14 bin&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c89 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c99 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 cc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc-15.2.0 -&amp;gt; ../../bin/distcc&lt;br /&gt;
&lt;br /&gt;
distcc itself is in bin&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cpp -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 g++ -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 06:49 x86_64-alpine-linux-musl-gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
&lt;br /&gt;
the last symplink here is wrong, made by me and would not work...&lt;br /&gt;
BAD symlink.&lt;br /&gt;
&lt;br /&gt;
=== distcc hosts file ===&lt;br /&gt;
&lt;br /&gt;
idk about that thing it&#039;s odd&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== abuild.conf ===&lt;br /&gt;
&lt;br /&gt;
settings for aports&lt;br /&gt;
* cc=&lt;br /&gt;
* cxx=&lt;br /&gt;
* cpp=&lt;br /&gt;
* cflags=&lt;br /&gt;
* njobs&lt;br /&gt;
&lt;br /&gt;
== detail infos ==&lt;br /&gt;
&lt;br /&gt;
???&lt;br /&gt;
&lt;br /&gt;
=== hosts syntax ===&lt;br /&gt;
&lt;br /&gt;
* myhost otherhost&lt;br /&gt;
* myhost,cpp,lzo myotherhost,cpp,lzo&lt;br /&gt;
&lt;br /&gt;
==== the host ====&lt;br /&gt;
&lt;br /&gt;
hostname/ip&lt;br /&gt;
localhost&lt;br /&gt;
127.0.0.1&lt;br /&gt;
::1 - does not work&lt;br /&gt;
&lt;br /&gt;
==== protocol ====&lt;br /&gt;
&lt;br /&gt;
* no protocol given&lt;br /&gt;
* ,cpp,lzo protocol&lt;br /&gt;
&lt;br /&gt;
cpp implies lzo, it requires compression, even if you have 10gbit/s or more, it&#039;s just hardcoded&lt;br /&gt;
&lt;br /&gt;
=== threads ===&lt;br /&gt;
/number of workers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== architecture ==&lt;br /&gt;
it can handle C, C++, ObjC, maybe some other stuff&lt;br /&gt;
&lt;br /&gt;
* what happens with normal xmit&lt;br /&gt;
* what happens with pump mode&lt;br /&gt;
* at which step the include server is used and how it collects the includes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== distribution algorithm ===&lt;br /&gt;
honestly I simply don&#039;t get it&lt;br /&gt;
&lt;br /&gt;
* The order matters&lt;br /&gt;
* The number of threads matters&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== localhost ====&lt;br /&gt;
&lt;br /&gt;
* localhost precedence&lt;br /&gt;
* localhost fallback&lt;br /&gt;
&lt;br /&gt;
variable: DISTCC_FALLBACK&lt;br /&gt;
&lt;br /&gt;
0 = Fail to compile if it would need to fallback to a normal local gcc call&lt;br /&gt;
1 = If remote compile fails, just do it yourself&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Operation ==&lt;br /&gt;
&lt;br /&gt;
=== startup and shutdown ===&lt;br /&gt;
service distcc stop is not entirely reliable (it can take a minute after the stop until the processes are gone and sometimes it will never stop&lt;br /&gt;
this is very bad with openrc, the openrc script returns after a second and only relies on its service flags, not the process status.&lt;br /&gt;
manually check after stopping, wait a min, if needed, kill it all.&lt;br /&gt;
at some point the rc file needs to be rewritten, it can&#039;t stay like it is.&lt;br /&gt;
&lt;br /&gt;
if you used a pump mode session, that also needs a logout (pump --shutdown)&lt;br /&gt;
avoid running multiple startups without shutdown in one session. it&#039;s safe as far as I can tell but nothing cleans up these processes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== ccache and memcached ===&lt;br /&gt;
CCACHE is said to be conflicting with pump mode unless when you call them in the backend&lt;br /&gt;
so, where you start the compile, you don&#039;t use it&lt;br /&gt;
where the compile happens, you use it&lt;br /&gt;
they can share the cache via memcached, this is a nice trick for consistency&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== dockerized / native ===&lt;br /&gt;
&lt;br /&gt;
it remains mostly the same, a container needs to make sure it monitors the right services (distccd, nginx, include_server)&lt;br /&gt;
if you&#039;re using zeroconf, you need to somehow expose the mdns service broadcasts &amp;amp; reception&lt;br /&gt;
&lt;br /&gt;
Processs list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
Workdir list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
=== alpine-chroot ===&lt;br /&gt;
&lt;br /&gt;
when using the &#039;official&#039; script there&#039;s still some odd pieces, seemed to be the processes died on logout. but not all of them.&lt;br /&gt;
&lt;br /&gt;
==== manual launch ====&lt;br /&gt;
&lt;br /&gt;
Starting the daemon would be using&lt;br /&gt;
/usr/bin/distccd --pid-file /var/run/distccd/distccd.pid -N 15 --user distcc --port 3632 --log-level=debug --log-file=/var/log/distccd.log --allow my-sub-net/24&lt;br /&gt;
&lt;br /&gt;
==== localhost? =====&lt;br /&gt;
unclear if you need to use --allow for 127.0.0.1/32 or something to allow the remote preproccesor.&lt;br /&gt;
&lt;br /&gt;
== Kernel specific settings ==&lt;br /&gt;
&lt;br /&gt;
currently (distcc 3.4-r9 on Alpine) you need a patch to build the kernel.&lt;br /&gt;
See &lt;br /&gt;
&lt;br /&gt;
=== Include server Settings ===&lt;br /&gt;
&lt;br /&gt;
cache reset triggers&lt;br /&gt;
This ought to be set before enabling pump mode.&lt;br /&gt;
&lt;br /&gt;
export INCLUDE_SERVER_ARGS=&amp;quot;--stat_reset_triggers=include/linux/compile.h:include/asm/asm-offsets.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
link to explanation TBA&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Disabling GCC Plugins ===&lt;br /&gt;
&lt;br /&gt;
KConfig unselect HAVE_GCC_PLUGINS&lt;br /&gt;
&lt;br /&gt;
Some info is here in the troubleshooting part of the Arch Wiki&lt;br /&gt;
https://wiki.archlinux.org/title/Distcc#Troubleshooting&lt;br /&gt;
&lt;br /&gt;
=== Patches ===&lt;br /&gt;
&lt;br /&gt;
Other things (for 6.6LTS)&lt;br /&gt;
PCIe Stub patch&lt;br /&gt;
&lt;br /&gt;
=== Autoconf === &lt;br /&gt;
&lt;br /&gt;
No known setup examples&lt;br /&gt;
Add whatever it publishes in mdns&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== troubleshooting / analysis ==&lt;br /&gt;
&lt;br /&gt;
=== testing ===&lt;br /&gt;
&lt;br /&gt;
# turn off fallback DISTCC_FALLBACK=1&lt;br /&gt;
# set distcc up to point at specific system under test DISTCC_HOSTS=&amp;quot;mytestbox,cpp,lzo&amp;quot;&lt;br /&gt;
# GCC example compiles&lt;br /&gt;
## code example C&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example C++&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example ObjC&lt;br /&gt;
## same with included header&lt;br /&gt;
# Cmake example compiles&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docoument the thing with compile launcher ccache;distcc&lt;br /&gt;
there&#039;s some blog post, point to that&lt;br /&gt;
no ccache here yet&lt;br /&gt;
show $CC differences distcc vs gcc, what configure scripts see&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Latency ===&lt;br /&gt;
&lt;br /&gt;
Latency of pump mode startups and fallbacks needs to be investigated.&lt;br /&gt;
LZO is enforced even if you have faster network&lt;br /&gt;
DNS Requests, very old bug report from Gcode, one request per call, is it true? how to get rid of it?&lt;br /&gt;
TMPDIR is respected, make sure it&#039;s on ramdisk even on the remote nodes.&lt;br /&gt;
Compile ideally never goes to disk when it doesn&#039;t have to.&lt;br /&gt;
How efficient is the include server collection and unpacking?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== failed to distribute, running locally instead ===&lt;br /&gt;
&lt;br /&gt;
the curse of the ancient, wise bulgarian witch compildora nottherea has befallen people all over the world. only strict and mindless adherence to rituals passed down from generation to generation has given hope to those who are under her ages old spell. again and again it reemerges to prey on idealistic young men and women who spend so much time at their unholy computers that they try to spend less time there by spending a lot of time trying to optimize what the computer does, slowly, instead of reflecting on why they are there, while the computer is busy working, and why they try to solve this by adding a component that makes the computer be more error-prone at that same work, increasing the need of their presense at this idolized thinking machine to oversee and often repair, or worse, mindlessly restart its doing.&lt;br /&gt;
if the curse is not lifted, despair may befall them and all they see is the need to investigate and ruminate further on the workings of this tool, ignoring thereby the obivous flaws that stem from of its alchemic origins.&lt;br /&gt;
&lt;br /&gt;
just wait till you find out it has a backoff alghoritm deciding whether to call out to a remote server independent of that server functioning.&lt;br /&gt;
&lt;br /&gt;
== security ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== tcpwrapper style ip range filter ===&lt;br /&gt;
&lt;br /&gt;
the original security model consists of ip restrictions.&lt;br /&gt;
there seems to also be some GSSAPI user auth.&lt;br /&gt;
further, commands that can be called are restricted by name and location.&lt;br /&gt;
this appears to be a runtime whitelist lookup, meaning it&#039;s done and authorized by the same parts of the daemon as processes the compile request along with the intended compiler.&lt;br /&gt;
so the main weaknesses against malicious clients seem to be in sending things to compile, and in overriding the remote compiler to use.&lt;br /&gt;
it can be assumed that a malicious client able to exploit the compiler handshake can then run arbitrary stuff.&lt;br /&gt;
There&#039;s at least a github issue regarding this google.com/search?q=distcc+seccomp&amp;amp;rlz=1C5CHFA_enDE1121DE1121&amp;amp;oq=distcc+seccomp&amp;amp;gs_lcrp=EgZjaHJvbWUyBggAEEUYOTIHCAEQIRigATIHCAIQIRigAdIBCDM1NjRqMGo3qAIAsAIA&amp;amp;sourceid=chrome&amp;amp;ie=UTF-8 suggesting running over ssh. That does only partitally alleviate this risk with regard  to a key based verfication of a client versus a the standard ip restrictions which always include some parsing.&lt;br /&gt;
So this protects against someone directly exploiting the TCP code of distcc.&lt;br /&gt;
It does not protect against malicious clients.&lt;br /&gt;
(ssh force command can&#039;t be used or you&#039;ll not compile anything)&lt;br /&gt;
&lt;br /&gt;
The basic step for protecting access should be filtering who can access the distcc server, so use nftables etc. to restrict access to port 3262 (??) set up the internal filter the same way.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== seccomp ===&lt;br /&gt;
&lt;br /&gt;
The next thing is to confine the compiler calls to only write in their temp directory and that they can only run compilers (using nsjail, apparmor, selinux etc)&lt;br /&gt;
&lt;br /&gt;
the above issue also references the second bit of security, namely a seccomp filter which will already cover a good bit of the above&lt;br /&gt;
https://github.com/distcc/distcc/pull/235&lt;br /&gt;
the commit got closed without merge, from what I see.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== privs ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The other internal security bit is that they do some priviledge dropping. it runs as a dedicated user (distcc), so you can also have an audit policy, and can/could use something like iptables&#039; to ensure it can only connect to the other distcc/memcached hosts, but nothing else.&lt;br /&gt;
&lt;br /&gt;
=== compiler list ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
One needs to investigate when compiler_whitelist.sh is exactly called. as far as I recall it doesn&#039;t close stdin/stdout.&lt;br /&gt;
&lt;br /&gt;
=== distcc-hardened ===&lt;br /&gt;
&lt;br /&gt;
Alpine adds some hardening patch, idk what nature/origina that has.&lt;br /&gt;
&lt;br /&gt;
=== selinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
there&#039;s also a selinux policy for distcc from gentoo or liguros if one is so inclined.&lt;br /&gt;
https://repology.org/project/selinux-distcc/versions&lt;br /&gt;
&lt;br /&gt;
=== general posture ===&lt;br /&gt;
&lt;br /&gt;
Some security measures like the above should definitely be used since the project has only a few part-time maintainers that cannot easily drive the project forward or do large refactors.&lt;br /&gt;
But the seccomp changes were done almost 10 years ago, so, to be fair, they still came through.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Arch wiki refers to a fork by SUSE&lt;br /&gt;
https://github.com/icecc/icecream&lt;br /&gt;
&lt;br /&gt;
It appears &#039;maybe better&#039; but hard to tell.&lt;/div&gt;</summary>
		<author><name>Darkfader</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32139</id>
		<title>User:Darkfader/distcc</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32139"/>
		<updated>2026-03-03T11:25:52Z</updated>

		<summary type="html">&lt;p&gt;Darkfader: /* failed to distribute, running locally instead */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi,&lt;br /&gt;
&lt;br /&gt;
I&#039;m preparing this page. It can take a long time till I finish.&lt;br /&gt;
If you are also wishing to write on this topic, feel free to integrate the content.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Document overview ==&lt;br /&gt;
&lt;br /&gt;
I noticed that almost every distro has one partially complete, partially helpful document on how to use distcc on the distro.&lt;br /&gt;
Usually they also have one for ccache.&lt;br /&gt;
In either case, they&#039;re enough to get started, but not really a reliable watertight thing.&lt;br /&gt;
We definitely needed one of our own.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== goal ===&lt;br /&gt;
&lt;br /&gt;
to describe a working setup for building aports in easiest/fastests fashion&lt;br /&gt;
not planning to add versatility or features where it would make the setup more errorprone.&lt;br /&gt;
the page should describe enough of the steps to successfully compile an LTS kernel via aports and have that job be distributed over multiple nodes.&lt;br /&gt;
Logs should be set up and able to display errors, but not show any errors during the test compile.&lt;br /&gt;
&lt;br /&gt;
To include a path for analysis via testing components.&lt;br /&gt;
&lt;br /&gt;
distcc can greatly improve compile speeds for large software, it comes with a different set of features than ccache; it focusses not avoiding unneccessary compile work, but on a way to speed up the necessary one.&lt;br /&gt;
&lt;br /&gt;
There&#039;s valuable info in the docs of other distros, it should be referenced here (i.e. the arch wiki troubleshooting), when it makes sense, add a TOC for their content.&lt;br /&gt;
&lt;br /&gt;
=== audience ===&lt;br /&gt;
people running software builds on alpine and have multiple computers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This page will show a specific installation, specific configuration, and specific tests, resulting in a specific set of functionality that can be tested to be working.&lt;br /&gt;
&lt;br /&gt;
== installation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Packages ===&lt;br /&gt;
&lt;br /&gt;
you need, on each host&lt;br /&gt;
* distcc&lt;br /&gt;
* distccd-openrc&lt;br /&gt;
* distcc-pump&lt;br /&gt;
* distcc-pump-pyc&lt;br /&gt;
&lt;br /&gt;
the .pyc will speed up the invocations, without it &lt;br /&gt;
idk if one or both should be installed in that case. but it appears to be also automatically be precompiled in /usr/lib/python3.12/site-packages/include_server/__pycache__/ so what does the package do exactly?&lt;br /&gt;
&lt;br /&gt;
There&#039;s some references to cpython-312, so maybe it actually still uses classy python-c conversion or matbe that&#039;s just a component for reading C source code. I have zero idea.&lt;br /&gt;
&lt;br /&gt;
you also need stuff to do compiles&lt;br /&gt;
* alpine sdk&lt;br /&gt;
* clang&lt;br /&gt;
* binutils&lt;br /&gt;
...&lt;br /&gt;
* elfutils(-dev)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Settings ===&lt;br /&gt;
==== settings for distcc ====&lt;br /&gt;
&lt;br /&gt;
* there&#039;s /etc/default/distcc&lt;br /&gt;
* there&#039;s /etc/conf.d/distcc &lt;br /&gt;
&lt;br /&gt;
make all your settings here&lt;br /&gt;
take care with the listen address, if you specify an IP it&#039;ll not be on 127.0.0.1 in case you would have localhost in your list...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* command_whitelist.sh &lt;br /&gt;
&lt;br /&gt;
this is half functional, you need to set things here but you also need to maintain the symlinks that are collected under /usr/lib/distcc (for your compilers) and /usr/lib/distcc/bin (for itself)&lt;br /&gt;
&lt;br /&gt;
you MUST run the script to update the compilers!&lt;br /&gt;
Info for script and what files it will create&lt;br /&gt;
&lt;br /&gt;
/usr/sbin/update-distcc-symlinks&lt;br /&gt;
&lt;br /&gt;
tschike:/usr/bin# ls -l /usr/lib/distcc/&lt;br /&gt;
total 4&lt;br /&gt;
drwxr-xr-x 2 root root 4096 Mar  2 18:14 bin&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c89 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c99 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 cc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc-15.2.0 -&amp;gt; ../../bin/distcc&lt;br /&gt;
&lt;br /&gt;
distcc itself is in bin&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cpp -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 g++ -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 06:49 x86_64-alpine-linux-musl-gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
&lt;br /&gt;
the last symplink here is wrong, made by me and would not work...&lt;br /&gt;
BAD symlink.&lt;br /&gt;
&lt;br /&gt;
=== distcc hosts file ===&lt;br /&gt;
&lt;br /&gt;
idk about that thing it&#039;s odd&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== abuild.conf ===&lt;br /&gt;
&lt;br /&gt;
settings for aports&lt;br /&gt;
* cc=&lt;br /&gt;
* cxx=&lt;br /&gt;
* cpp=&lt;br /&gt;
* cflags=&lt;br /&gt;
* njobs&lt;br /&gt;
&lt;br /&gt;
== detail infos ==&lt;br /&gt;
&lt;br /&gt;
???&lt;br /&gt;
&lt;br /&gt;
=== hosts syntax ===&lt;br /&gt;
&lt;br /&gt;
* myhost otherhost&lt;br /&gt;
* myhost,cpp,lzo myotherhost,cpp,lzo&lt;br /&gt;
&lt;br /&gt;
==== the host ====&lt;br /&gt;
&lt;br /&gt;
hostname/ip&lt;br /&gt;
localhost&lt;br /&gt;
127.0.0.1&lt;br /&gt;
::1 - does not work&lt;br /&gt;
&lt;br /&gt;
==== protocol ====&lt;br /&gt;
&lt;br /&gt;
* no protocol given&lt;br /&gt;
* ,cpp,lzo protocol&lt;br /&gt;
&lt;br /&gt;
cpp implies lzo, it requires compression, even if you have 10gbit/s or more, it&#039;s just hardcoded&lt;br /&gt;
&lt;br /&gt;
=== threads ===&lt;br /&gt;
/number of workers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== architecture ==&lt;br /&gt;
it can handle C, C++, ObjC, maybe some other stuff&lt;br /&gt;
&lt;br /&gt;
* what happens with normal xmit&lt;br /&gt;
* what happens with pump mode&lt;br /&gt;
* at which step the include server is used and how it collects the includes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== distribution algorithm ===&lt;br /&gt;
honestly I simply don&#039;t get it&lt;br /&gt;
&lt;br /&gt;
* The order matters&lt;br /&gt;
* The number of threads matters&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== localhost ====&lt;br /&gt;
&lt;br /&gt;
* localhost precedence&lt;br /&gt;
* localhost fallback&lt;br /&gt;
&lt;br /&gt;
variable: DISTCC_FALLBACK&lt;br /&gt;
&lt;br /&gt;
0 = Fail to compile if it would need to fallback to a normal local gcc call&lt;br /&gt;
1 = If remote compile fails, just do it yourself&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Operation ==&lt;br /&gt;
&lt;br /&gt;
=== startup and shutdown ===&lt;br /&gt;
service distcc stop is not entirely reliable (it can take a minute after the stop until the processes are gone and sometimes it will never stop&lt;br /&gt;
this is very bad with openrc, the openrc script returns after a second and only relies on its service flags, not the process status.&lt;br /&gt;
manually check after stopping, wait a min, if needed, kill it all.&lt;br /&gt;
at some point the rc file needs to be rewritten, it can&#039;t stay like it is.&lt;br /&gt;
&lt;br /&gt;
if you used a pump mode session, that also needs a logout (pump --shutdown)&lt;br /&gt;
avoid running multiple startups without shutdown in one session. it&#039;s safe as far as I can tell but nothing cleans up these processes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== ccache and memcached ===&lt;br /&gt;
CCACHE is said to be conflicting with pump mode unless when you call them in the backend&lt;br /&gt;
so, where you start the compile, you don&#039;t use it&lt;br /&gt;
where the compile happens, you use it&lt;br /&gt;
they can share the cache via memcached, this is a nice trick for consistency&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== dockerized / native ===&lt;br /&gt;
&lt;br /&gt;
it remains mostly the same, a container needs to make sure it monitors the right services (distccd, nginx, include_server)&lt;br /&gt;
if you&#039;re using zeroconf, you need to somehow expose the mdns service broadcasts &amp;amp; reception&lt;br /&gt;
&lt;br /&gt;
Processs list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
Workdir list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
=== alpine-chroot ===&lt;br /&gt;
&lt;br /&gt;
when using the &#039;official&#039; script there&#039;s still some odd pieces, seemed to be the processes died on logout. but not all of them.&lt;br /&gt;
&lt;br /&gt;
==== manual launch ====&lt;br /&gt;
&lt;br /&gt;
Starting the daemon would be using&lt;br /&gt;
/usr/bin/distccd --pid-file /var/run/distccd/distccd.pid -N 15 --user distcc --port 3632 --log-level=debug --log-file=/var/log/distccd.log --allow my-sub-net/24&lt;br /&gt;
&lt;br /&gt;
==== localhost? =====&lt;br /&gt;
unclear if you need to use --allow for 127.0.0.1/32 or something to allow the remote preproccesor.&lt;br /&gt;
&lt;br /&gt;
== Kernel specific settings ==&lt;br /&gt;
&lt;br /&gt;
currently (distcc 3.4-r9 on Alpine) you need a patch to build the kernel.&lt;br /&gt;
See &lt;br /&gt;
&lt;br /&gt;
=== Include server Settings ===&lt;br /&gt;
&lt;br /&gt;
cache reset triggers&lt;br /&gt;
This ought to be set before enabling pump mode.&lt;br /&gt;
&lt;br /&gt;
export INCLUDE_SERVER_ARGS=&amp;quot;--stat_reset_triggers=include/linux/compile.h:include/asm/asm-offsets.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
link to explanation TBA&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Disabling GCC Plugins ===&lt;br /&gt;
&lt;br /&gt;
KConfig unselect HAVE_GCC_PLUGINS&lt;br /&gt;
&lt;br /&gt;
Some info is here in the troubleshooting part of the Arch Wiki&lt;br /&gt;
https://wiki.archlinux.org/title/Distcc#Troubleshooting&lt;br /&gt;
&lt;br /&gt;
=== Patches ===&lt;br /&gt;
&lt;br /&gt;
Other things (for 6.6LTS)&lt;br /&gt;
PCIe Stub patch&lt;br /&gt;
&lt;br /&gt;
=== Autoconf === &lt;br /&gt;
&lt;br /&gt;
No known setup examples&lt;br /&gt;
Add whatever it publishes in mdns&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== troubleshooting / analysis ==&lt;br /&gt;
&lt;br /&gt;
=== testing ===&lt;br /&gt;
&lt;br /&gt;
# turn off fallback DISTCC_FALLBACK=1&lt;br /&gt;
# set distcc up to point at specific system under test DISTCC_HOSTS=&amp;quot;mytestbox,cpp,lzo&amp;quot;&lt;br /&gt;
# GCC example compiles&lt;br /&gt;
## code example C&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example C++&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example ObjC&lt;br /&gt;
## same with included header&lt;br /&gt;
# Cmake example compiles&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docoument the thing with compile launcher ccache;distcc&lt;br /&gt;
there&#039;s some blog post, point to that&lt;br /&gt;
no ccache here yet&lt;br /&gt;
show $CC differences distcc vs gcc, what configure scripts see&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Latency ===&lt;br /&gt;
&lt;br /&gt;
Latency of pump mode startups and fallbacks needs to be investigated.&lt;br /&gt;
LZO is enforced even if you have faster network&lt;br /&gt;
DNS Requests, very old bug report from Gcode, one request per call, is it true? how to get rid of it?&lt;br /&gt;
TMPDIR is respected, make sure it&#039;s on ramdisk even on the remote nodes.&lt;br /&gt;
Compile ideally never goes to disk when it doesn&#039;t have to.&lt;br /&gt;
How efficient is the include server collection and unpacking?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== failed to distribute, running locally instead ===&lt;br /&gt;
&lt;br /&gt;
the curse of the ancient, wise bulgarian witch compildora nottherea has befallen people all over the world. only strict and mindless adherence to rituals passed down from generation to generation has given hope to those who are under her ages old spell. again and again it reemerges to prey on idealistic young men and women who spend so much time at their unholy computers that they try to spend less time there by spending a lot of time trying to optimize what the computer does, slowly, instead of reflecting on why they are there, while the computer is busy working, and why they try to solve this by adding a component that makes the computer be more error-prone at that same work, increasing the need of their presense at this idolized thinking machine to oversee and often repair, or worse, mindlessly restart its doing.&lt;br /&gt;
&lt;br /&gt;
== security ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== tcpwrapper style ip range filter ===&lt;br /&gt;
&lt;br /&gt;
the original security model consists of ip restrictions.&lt;br /&gt;
there seems to also be some GSSAPI user auth.&lt;br /&gt;
further, commands that can be called are restricted by name and location.&lt;br /&gt;
this appears to be a runtime whitelist lookup, meaning it&#039;s done and authorized by the same parts of the daemon as processes the compile request along with the intended compiler.&lt;br /&gt;
so the main weaknesses against malicious clients seem to be in sending things to compile, and in overriding the remote compiler to use.&lt;br /&gt;
it can be assumed that a malicious client able to exploit the compiler handshake can then run arbitrary stuff.&lt;br /&gt;
There&#039;s at least a github issue regarding this google.com/search?q=distcc+seccomp&amp;amp;rlz=1C5CHFA_enDE1121DE1121&amp;amp;oq=distcc+seccomp&amp;amp;gs_lcrp=EgZjaHJvbWUyBggAEEUYOTIHCAEQIRigATIHCAIQIRigAdIBCDM1NjRqMGo3qAIAsAIA&amp;amp;sourceid=chrome&amp;amp;ie=UTF-8 suggesting running over ssh. That does only partitally alleviate this risk with regard  to a key based verfication of a client versus a the standard ip restrictions which always include some parsing.&lt;br /&gt;
So this protects against someone directly exploiting the TCP code of distcc.&lt;br /&gt;
It does not protect against malicious clients.&lt;br /&gt;
(ssh force command can&#039;t be used or you&#039;ll not compile anything)&lt;br /&gt;
&lt;br /&gt;
The basic step for protecting access should be filtering who can access the distcc server, so use nftables etc. to restrict access to port 3262 (??) set up the internal filter the same way.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== seccomp ===&lt;br /&gt;
&lt;br /&gt;
The next thing is to confine the compiler calls to only write in their temp directory and that they can only run compilers (using nsjail, apparmor, selinux etc)&lt;br /&gt;
&lt;br /&gt;
the above issue also references the second bit of security, namely a seccomp filter which will already cover a good bit of the above&lt;br /&gt;
https://github.com/distcc/distcc/pull/235&lt;br /&gt;
the commit got closed without merge, from what I see.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== privs ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The other internal security bit is that they do some priviledge dropping. it runs as a dedicated user (distcc), so you can also have an audit policy, and can/could use something like iptables&#039; to ensure it can only connect to the other distcc/memcached hosts, but nothing else.&lt;br /&gt;
&lt;br /&gt;
=== compiler list ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
One needs to investigate when compiler_whitelist.sh is exactly called. as far as I recall it doesn&#039;t close stdin/stdout.&lt;br /&gt;
&lt;br /&gt;
=== distcc-hardened ===&lt;br /&gt;
&lt;br /&gt;
Alpine adds some hardening patch, idk what nature/origina that has.&lt;br /&gt;
&lt;br /&gt;
=== selinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
there&#039;s also a selinux policy for distcc from gentoo or liguros if one is so inclined.&lt;br /&gt;
https://repology.org/project/selinux-distcc/versions&lt;br /&gt;
&lt;br /&gt;
=== general posture ===&lt;br /&gt;
&lt;br /&gt;
Some security measures like the above should definitely be used since the project has only a few part-time maintainers that cannot easily drive the project forward or do large refactors.&lt;br /&gt;
But the seccomp changes were done almost 10 years ago, so, to be fair, they still came through.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Arch wiki refers to a fork by SUSE&lt;br /&gt;
https://github.com/icecc/icecream&lt;br /&gt;
&lt;br /&gt;
It appears &#039;maybe better&#039; but hard to tell.&lt;/div&gt;</summary>
		<author><name>Darkfader</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32138</id>
		<title>User:Darkfader/distcc</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32138"/>
		<updated>2026-03-03T11:25:19Z</updated>

		<summary type="html">&lt;p&gt;Darkfader: /* failed to distribute, running locally instead */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi,&lt;br /&gt;
&lt;br /&gt;
I&#039;m preparing this page. It can take a long time till I finish.&lt;br /&gt;
If you are also wishing to write on this topic, feel free to integrate the content.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Document overview ==&lt;br /&gt;
&lt;br /&gt;
I noticed that almost every distro has one partially complete, partially helpful document on how to use distcc on the distro.&lt;br /&gt;
Usually they also have one for ccache.&lt;br /&gt;
In either case, they&#039;re enough to get started, but not really a reliable watertight thing.&lt;br /&gt;
We definitely needed one of our own.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== goal ===&lt;br /&gt;
&lt;br /&gt;
to describe a working setup for building aports in easiest/fastests fashion&lt;br /&gt;
not planning to add versatility or features where it would make the setup more errorprone.&lt;br /&gt;
the page should describe enough of the steps to successfully compile an LTS kernel via aports and have that job be distributed over multiple nodes.&lt;br /&gt;
Logs should be set up and able to display errors, but not show any errors during the test compile.&lt;br /&gt;
&lt;br /&gt;
To include a path for analysis via testing components.&lt;br /&gt;
&lt;br /&gt;
distcc can greatly improve compile speeds for large software, it comes with a different set of features than ccache; it focusses not avoiding unneccessary compile work, but on a way to speed up the necessary one.&lt;br /&gt;
&lt;br /&gt;
There&#039;s valuable info in the docs of other distros, it should be referenced here (i.e. the arch wiki troubleshooting), when it makes sense, add a TOC for their content.&lt;br /&gt;
&lt;br /&gt;
=== audience ===&lt;br /&gt;
people running software builds on alpine and have multiple computers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This page will show a specific installation, specific configuration, and specific tests, resulting in a specific set of functionality that can be tested to be working.&lt;br /&gt;
&lt;br /&gt;
== installation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Packages ===&lt;br /&gt;
&lt;br /&gt;
you need, on each host&lt;br /&gt;
* distcc&lt;br /&gt;
* distccd-openrc&lt;br /&gt;
* distcc-pump&lt;br /&gt;
* distcc-pump-pyc&lt;br /&gt;
&lt;br /&gt;
the .pyc will speed up the invocations, without it &lt;br /&gt;
idk if one or both should be installed in that case. but it appears to be also automatically be precompiled in /usr/lib/python3.12/site-packages/include_server/__pycache__/ so what does the package do exactly?&lt;br /&gt;
&lt;br /&gt;
There&#039;s some references to cpython-312, so maybe it actually still uses classy python-c conversion or matbe that&#039;s just a component for reading C source code. I have zero idea.&lt;br /&gt;
&lt;br /&gt;
you also need stuff to do compiles&lt;br /&gt;
* alpine sdk&lt;br /&gt;
* clang&lt;br /&gt;
* binutils&lt;br /&gt;
...&lt;br /&gt;
* elfutils(-dev)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Settings ===&lt;br /&gt;
==== settings for distcc ====&lt;br /&gt;
&lt;br /&gt;
* there&#039;s /etc/default/distcc&lt;br /&gt;
* there&#039;s /etc/conf.d/distcc &lt;br /&gt;
&lt;br /&gt;
make all your settings here&lt;br /&gt;
take care with the listen address, if you specify an IP it&#039;ll not be on 127.0.0.1 in case you would have localhost in your list...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* command_whitelist.sh &lt;br /&gt;
&lt;br /&gt;
this is half functional, you need to set things here but you also need to maintain the symlinks that are collected under /usr/lib/distcc (for your compilers) and /usr/lib/distcc/bin (for itself)&lt;br /&gt;
&lt;br /&gt;
you MUST run the script to update the compilers!&lt;br /&gt;
Info for script and what files it will create&lt;br /&gt;
&lt;br /&gt;
/usr/sbin/update-distcc-symlinks&lt;br /&gt;
&lt;br /&gt;
tschike:/usr/bin# ls -l /usr/lib/distcc/&lt;br /&gt;
total 4&lt;br /&gt;
drwxr-xr-x 2 root root 4096 Mar  2 18:14 bin&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c89 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c99 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 cc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc-15.2.0 -&amp;gt; ../../bin/distcc&lt;br /&gt;
&lt;br /&gt;
distcc itself is in bin&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cpp -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 g++ -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 06:49 x86_64-alpine-linux-musl-gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
&lt;br /&gt;
the last symplink here is wrong, made by me and would not work...&lt;br /&gt;
BAD symlink.&lt;br /&gt;
&lt;br /&gt;
=== distcc hosts file ===&lt;br /&gt;
&lt;br /&gt;
idk about that thing it&#039;s odd&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== abuild.conf ===&lt;br /&gt;
&lt;br /&gt;
settings for aports&lt;br /&gt;
* cc=&lt;br /&gt;
* cxx=&lt;br /&gt;
* cpp=&lt;br /&gt;
* cflags=&lt;br /&gt;
* njobs&lt;br /&gt;
&lt;br /&gt;
== detail infos ==&lt;br /&gt;
&lt;br /&gt;
???&lt;br /&gt;
&lt;br /&gt;
=== hosts syntax ===&lt;br /&gt;
&lt;br /&gt;
* myhost otherhost&lt;br /&gt;
* myhost,cpp,lzo myotherhost,cpp,lzo&lt;br /&gt;
&lt;br /&gt;
==== the host ====&lt;br /&gt;
&lt;br /&gt;
hostname/ip&lt;br /&gt;
localhost&lt;br /&gt;
127.0.0.1&lt;br /&gt;
::1 - does not work&lt;br /&gt;
&lt;br /&gt;
==== protocol ====&lt;br /&gt;
&lt;br /&gt;
* no protocol given&lt;br /&gt;
* ,cpp,lzo protocol&lt;br /&gt;
&lt;br /&gt;
cpp implies lzo, it requires compression, even if you have 10gbit/s or more, it&#039;s just hardcoded&lt;br /&gt;
&lt;br /&gt;
=== threads ===&lt;br /&gt;
/number of workers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== architecture ==&lt;br /&gt;
it can handle C, C++, ObjC, maybe some other stuff&lt;br /&gt;
&lt;br /&gt;
* what happens with normal xmit&lt;br /&gt;
* what happens with pump mode&lt;br /&gt;
* at which step the include server is used and how it collects the includes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== distribution algorithm ===&lt;br /&gt;
honestly I simply don&#039;t get it&lt;br /&gt;
&lt;br /&gt;
* The order matters&lt;br /&gt;
* The number of threads matters&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== localhost ====&lt;br /&gt;
&lt;br /&gt;
* localhost precedence&lt;br /&gt;
* localhost fallback&lt;br /&gt;
&lt;br /&gt;
variable: DISTCC_FALLBACK&lt;br /&gt;
&lt;br /&gt;
0 = Fail to compile if it would need to fallback to a normal local gcc call&lt;br /&gt;
1 = If remote compile fails, just do it yourself&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Operation ==&lt;br /&gt;
&lt;br /&gt;
=== startup and shutdown ===&lt;br /&gt;
service distcc stop is not entirely reliable (it can take a minute after the stop until the processes are gone and sometimes it will never stop&lt;br /&gt;
this is very bad with openrc, the openrc script returns after a second and only relies on its service flags, not the process status.&lt;br /&gt;
manually check after stopping, wait a min, if needed, kill it all.&lt;br /&gt;
at some point the rc file needs to be rewritten, it can&#039;t stay like it is.&lt;br /&gt;
&lt;br /&gt;
if you used a pump mode session, that also needs a logout (pump --shutdown)&lt;br /&gt;
avoid running multiple startups without shutdown in one session. it&#039;s safe as far as I can tell but nothing cleans up these processes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== ccache and memcached ===&lt;br /&gt;
CCACHE is said to be conflicting with pump mode unless when you call them in the backend&lt;br /&gt;
so, where you start the compile, you don&#039;t use it&lt;br /&gt;
where the compile happens, you use it&lt;br /&gt;
they can share the cache via memcached, this is a nice trick for consistency&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== dockerized / native ===&lt;br /&gt;
&lt;br /&gt;
it remains mostly the same, a container needs to make sure it monitors the right services (distccd, nginx, include_server)&lt;br /&gt;
if you&#039;re using zeroconf, you need to somehow expose the mdns service broadcasts &amp;amp; reception&lt;br /&gt;
&lt;br /&gt;
Processs list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
Workdir list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
=== alpine-chroot ===&lt;br /&gt;
&lt;br /&gt;
when using the &#039;official&#039; script there&#039;s still some odd pieces, seemed to be the processes died on logout. but not all of them.&lt;br /&gt;
&lt;br /&gt;
==== manual launch ====&lt;br /&gt;
&lt;br /&gt;
Starting the daemon would be using&lt;br /&gt;
/usr/bin/distccd --pid-file /var/run/distccd/distccd.pid -N 15 --user distcc --port 3632 --log-level=debug --log-file=/var/log/distccd.log --allow my-sub-net/24&lt;br /&gt;
&lt;br /&gt;
==== localhost? =====&lt;br /&gt;
unclear if you need to use --allow for 127.0.0.1/32 or something to allow the remote preproccesor.&lt;br /&gt;
&lt;br /&gt;
== Kernel specific settings ==&lt;br /&gt;
&lt;br /&gt;
currently (distcc 3.4-r9 on Alpine) you need a patch to build the kernel.&lt;br /&gt;
See &lt;br /&gt;
&lt;br /&gt;
=== Include server Settings ===&lt;br /&gt;
&lt;br /&gt;
cache reset triggers&lt;br /&gt;
This ought to be set before enabling pump mode.&lt;br /&gt;
&lt;br /&gt;
export INCLUDE_SERVER_ARGS=&amp;quot;--stat_reset_triggers=include/linux/compile.h:include/asm/asm-offsets.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
link to explanation TBA&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Disabling GCC Plugins ===&lt;br /&gt;
&lt;br /&gt;
KConfig unselect HAVE_GCC_PLUGINS&lt;br /&gt;
&lt;br /&gt;
Some info is here in the troubleshooting part of the Arch Wiki&lt;br /&gt;
https://wiki.archlinux.org/title/Distcc#Troubleshooting&lt;br /&gt;
&lt;br /&gt;
=== Patches ===&lt;br /&gt;
&lt;br /&gt;
Other things (for 6.6LTS)&lt;br /&gt;
PCIe Stub patch&lt;br /&gt;
&lt;br /&gt;
=== Autoconf === &lt;br /&gt;
&lt;br /&gt;
No known setup examples&lt;br /&gt;
Add whatever it publishes in mdns&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== troubleshooting / analysis ==&lt;br /&gt;
&lt;br /&gt;
=== testing ===&lt;br /&gt;
&lt;br /&gt;
# turn off fallback DISTCC_FALLBACK=1&lt;br /&gt;
# set distcc up to point at specific system under test DISTCC_HOSTS=&amp;quot;mytestbox,cpp,lzo&amp;quot;&lt;br /&gt;
# GCC example compiles&lt;br /&gt;
## code example C&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example C++&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example ObjC&lt;br /&gt;
## same with included header&lt;br /&gt;
# Cmake example compiles&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docoument the thing with compile launcher ccache;distcc&lt;br /&gt;
there&#039;s some blog post, point to that&lt;br /&gt;
no ccache here yet&lt;br /&gt;
show $CC differences distcc vs gcc, what configure scripts see&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Latency ===&lt;br /&gt;
&lt;br /&gt;
Latency of pump mode startups and fallbacks needs to be investigated.&lt;br /&gt;
LZO is enforced even if you have faster network&lt;br /&gt;
DNS Requests, very old bug report from Gcode, one request per call, is it true? how to get rid of it?&lt;br /&gt;
TMPDIR is respected, make sure it&#039;s on ramdisk even on the remote nodes.&lt;br /&gt;
Compile ideally never goes to disk when it doesn&#039;t have to.&lt;br /&gt;
How efficient is the include server collection and unpacking?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== failed to distribute, running locally instead ===&lt;br /&gt;
&lt;br /&gt;
the curse of the ancient, wise bulgarian witch compildora nottherea has befallen people all over the world. only strict and mindless adherence to rituals passed down from generation to generation has given hope to those who are under her ages old spell. again and again it reemerges to prey on idealistic young men and women who spend so much time at their unholy computers that they try to spend less time there by spending a lot of time trying to optimize what the computer does, slowly, instead of reflecting on why they are there, while the computer is busy working, and why they try to solve this by adding a component that makes the computer be more fragile at that, increasing the need of their presense at this idolized thinking machine to oversee and often repair, or worse, mindlessly restart its doing.&lt;br /&gt;
&lt;br /&gt;
== security ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== tcpwrapper style ip range filter ===&lt;br /&gt;
&lt;br /&gt;
the original security model consists of ip restrictions.&lt;br /&gt;
there seems to also be some GSSAPI user auth.&lt;br /&gt;
further, commands that can be called are restricted by name and location.&lt;br /&gt;
this appears to be a runtime whitelist lookup, meaning it&#039;s done and authorized by the same parts of the daemon as processes the compile request along with the intended compiler.&lt;br /&gt;
so the main weaknesses against malicious clients seem to be in sending things to compile, and in overriding the remote compiler to use.&lt;br /&gt;
it can be assumed that a malicious client able to exploit the compiler handshake can then run arbitrary stuff.&lt;br /&gt;
There&#039;s at least a github issue regarding this google.com/search?q=distcc+seccomp&amp;amp;rlz=1C5CHFA_enDE1121DE1121&amp;amp;oq=distcc+seccomp&amp;amp;gs_lcrp=EgZjaHJvbWUyBggAEEUYOTIHCAEQIRigATIHCAIQIRigAdIBCDM1NjRqMGo3qAIAsAIA&amp;amp;sourceid=chrome&amp;amp;ie=UTF-8 suggesting running over ssh. That does only partitally alleviate this risk with regard  to a key based verfication of a client versus a the standard ip restrictions which always include some parsing.&lt;br /&gt;
So this protects against someone directly exploiting the TCP code of distcc.&lt;br /&gt;
It does not protect against malicious clients.&lt;br /&gt;
(ssh force command can&#039;t be used or you&#039;ll not compile anything)&lt;br /&gt;
&lt;br /&gt;
The basic step for protecting access should be filtering who can access the distcc server, so use nftables etc. to restrict access to port 3262 (??) set up the internal filter the same way.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== seccomp ===&lt;br /&gt;
&lt;br /&gt;
The next thing is to confine the compiler calls to only write in their temp directory and that they can only run compilers (using nsjail, apparmor, selinux etc)&lt;br /&gt;
&lt;br /&gt;
the above issue also references the second bit of security, namely a seccomp filter which will already cover a good bit of the above&lt;br /&gt;
https://github.com/distcc/distcc/pull/235&lt;br /&gt;
the commit got closed without merge, from what I see.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== privs ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The other internal security bit is that they do some priviledge dropping. it runs as a dedicated user (distcc), so you can also have an audit policy, and can/could use something like iptables&#039; to ensure it can only connect to the other distcc/memcached hosts, but nothing else.&lt;br /&gt;
&lt;br /&gt;
=== compiler list ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
One needs to investigate when compiler_whitelist.sh is exactly called. as far as I recall it doesn&#039;t close stdin/stdout.&lt;br /&gt;
&lt;br /&gt;
=== distcc-hardened ===&lt;br /&gt;
&lt;br /&gt;
Alpine adds some hardening patch, idk what nature/origina that has.&lt;br /&gt;
&lt;br /&gt;
=== selinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
there&#039;s also a selinux policy for distcc from gentoo or liguros if one is so inclined.&lt;br /&gt;
https://repology.org/project/selinux-distcc/versions&lt;br /&gt;
&lt;br /&gt;
=== general posture ===&lt;br /&gt;
&lt;br /&gt;
Some security measures like the above should definitely be used since the project has only a few part-time maintainers that cannot easily drive the project forward or do large refactors.&lt;br /&gt;
But the seccomp changes were done almost 10 years ago, so, to be fair, they still came through.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Arch wiki refers to a fork by SUSE&lt;br /&gt;
https://github.com/icecc/icecream&lt;br /&gt;
&lt;br /&gt;
It appears &#039;maybe better&#039; but hard to tell.&lt;/div&gt;</summary>
		<author><name>Darkfader</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32137</id>
		<title>User:Darkfader/distcc</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32137"/>
		<updated>2026-03-03T11:24:44Z</updated>

		<summary type="html">&lt;p&gt;Darkfader: /* failed to distribute, running locally instead */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi,&lt;br /&gt;
&lt;br /&gt;
I&#039;m preparing this page. It can take a long time till I finish.&lt;br /&gt;
If you are also wishing to write on this topic, feel free to integrate the content.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Document overview ==&lt;br /&gt;
&lt;br /&gt;
I noticed that almost every distro has one partially complete, partially helpful document on how to use distcc on the distro.&lt;br /&gt;
Usually they also have one for ccache.&lt;br /&gt;
In either case, they&#039;re enough to get started, but not really a reliable watertight thing.&lt;br /&gt;
We definitely needed one of our own.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== goal ===&lt;br /&gt;
&lt;br /&gt;
to describe a working setup for building aports in easiest/fastests fashion&lt;br /&gt;
not planning to add versatility or features where it would make the setup more errorprone.&lt;br /&gt;
the page should describe enough of the steps to successfully compile an LTS kernel via aports and have that job be distributed over multiple nodes.&lt;br /&gt;
Logs should be set up and able to display errors, but not show any errors during the test compile.&lt;br /&gt;
&lt;br /&gt;
To include a path for analysis via testing components.&lt;br /&gt;
&lt;br /&gt;
distcc can greatly improve compile speeds for large software, it comes with a different set of features than ccache; it focusses not avoiding unneccessary compile work, but on a way to speed up the necessary one.&lt;br /&gt;
&lt;br /&gt;
There&#039;s valuable info in the docs of other distros, it should be referenced here (i.e. the arch wiki troubleshooting), when it makes sense, add a TOC for their content.&lt;br /&gt;
&lt;br /&gt;
=== audience ===&lt;br /&gt;
people running software builds on alpine and have multiple computers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This page will show a specific installation, specific configuration, and specific tests, resulting in a specific set of functionality that can be tested to be working.&lt;br /&gt;
&lt;br /&gt;
== installation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Packages ===&lt;br /&gt;
&lt;br /&gt;
you need, on each host&lt;br /&gt;
* distcc&lt;br /&gt;
* distccd-openrc&lt;br /&gt;
* distcc-pump&lt;br /&gt;
* distcc-pump-pyc&lt;br /&gt;
&lt;br /&gt;
the .pyc will speed up the invocations, without it &lt;br /&gt;
idk if one or both should be installed in that case. but it appears to be also automatically be precompiled in /usr/lib/python3.12/site-packages/include_server/__pycache__/ so what does the package do exactly?&lt;br /&gt;
&lt;br /&gt;
There&#039;s some references to cpython-312, so maybe it actually still uses classy python-c conversion or matbe that&#039;s just a component for reading C source code. I have zero idea.&lt;br /&gt;
&lt;br /&gt;
you also need stuff to do compiles&lt;br /&gt;
* alpine sdk&lt;br /&gt;
* clang&lt;br /&gt;
* binutils&lt;br /&gt;
...&lt;br /&gt;
* elfutils(-dev)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Settings ===&lt;br /&gt;
==== settings for distcc ====&lt;br /&gt;
&lt;br /&gt;
* there&#039;s /etc/default/distcc&lt;br /&gt;
* there&#039;s /etc/conf.d/distcc &lt;br /&gt;
&lt;br /&gt;
make all your settings here&lt;br /&gt;
take care with the listen address, if you specify an IP it&#039;ll not be on 127.0.0.1 in case you would have localhost in your list...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* command_whitelist.sh &lt;br /&gt;
&lt;br /&gt;
this is half functional, you need to set things here but you also need to maintain the symlinks that are collected under /usr/lib/distcc (for your compilers) and /usr/lib/distcc/bin (for itself)&lt;br /&gt;
&lt;br /&gt;
you MUST run the script to update the compilers!&lt;br /&gt;
Info for script and what files it will create&lt;br /&gt;
&lt;br /&gt;
/usr/sbin/update-distcc-symlinks&lt;br /&gt;
&lt;br /&gt;
tschike:/usr/bin# ls -l /usr/lib/distcc/&lt;br /&gt;
total 4&lt;br /&gt;
drwxr-xr-x 2 root root 4096 Mar  2 18:14 bin&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c89 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c99 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 cc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc-15.2.0 -&amp;gt; ../../bin/distcc&lt;br /&gt;
&lt;br /&gt;
distcc itself is in bin&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cpp -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 g++ -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 06:49 x86_64-alpine-linux-musl-gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
&lt;br /&gt;
the last symplink here is wrong, made by me and would not work...&lt;br /&gt;
BAD symlink.&lt;br /&gt;
&lt;br /&gt;
=== distcc hosts file ===&lt;br /&gt;
&lt;br /&gt;
idk about that thing it&#039;s odd&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== abuild.conf ===&lt;br /&gt;
&lt;br /&gt;
settings for aports&lt;br /&gt;
* cc=&lt;br /&gt;
* cxx=&lt;br /&gt;
* cpp=&lt;br /&gt;
* cflags=&lt;br /&gt;
* njobs&lt;br /&gt;
&lt;br /&gt;
== detail infos ==&lt;br /&gt;
&lt;br /&gt;
???&lt;br /&gt;
&lt;br /&gt;
=== hosts syntax ===&lt;br /&gt;
&lt;br /&gt;
* myhost otherhost&lt;br /&gt;
* myhost,cpp,lzo myotherhost,cpp,lzo&lt;br /&gt;
&lt;br /&gt;
==== the host ====&lt;br /&gt;
&lt;br /&gt;
hostname/ip&lt;br /&gt;
localhost&lt;br /&gt;
127.0.0.1&lt;br /&gt;
::1 - does not work&lt;br /&gt;
&lt;br /&gt;
==== protocol ====&lt;br /&gt;
&lt;br /&gt;
* no protocol given&lt;br /&gt;
* ,cpp,lzo protocol&lt;br /&gt;
&lt;br /&gt;
cpp implies lzo, it requires compression, even if you have 10gbit/s or more, it&#039;s just hardcoded&lt;br /&gt;
&lt;br /&gt;
=== threads ===&lt;br /&gt;
/number of workers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== architecture ==&lt;br /&gt;
it can handle C, C++, ObjC, maybe some other stuff&lt;br /&gt;
&lt;br /&gt;
* what happens with normal xmit&lt;br /&gt;
* what happens with pump mode&lt;br /&gt;
* at which step the include server is used and how it collects the includes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== distribution algorithm ===&lt;br /&gt;
honestly I simply don&#039;t get it&lt;br /&gt;
&lt;br /&gt;
* The order matters&lt;br /&gt;
* The number of threads matters&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== localhost ====&lt;br /&gt;
&lt;br /&gt;
* localhost precedence&lt;br /&gt;
* localhost fallback&lt;br /&gt;
&lt;br /&gt;
variable: DISTCC_FALLBACK&lt;br /&gt;
&lt;br /&gt;
0 = Fail to compile if it would need to fallback to a normal local gcc call&lt;br /&gt;
1 = If remote compile fails, just do it yourself&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Operation ==&lt;br /&gt;
&lt;br /&gt;
=== startup and shutdown ===&lt;br /&gt;
service distcc stop is not entirely reliable (it can take a minute after the stop until the processes are gone and sometimes it will never stop&lt;br /&gt;
this is very bad with openrc, the openrc script returns after a second and only relies on its service flags, not the process status.&lt;br /&gt;
manually check after stopping, wait a min, if needed, kill it all.&lt;br /&gt;
at some point the rc file needs to be rewritten, it can&#039;t stay like it is.&lt;br /&gt;
&lt;br /&gt;
if you used a pump mode session, that also needs a logout (pump --shutdown)&lt;br /&gt;
avoid running multiple startups without shutdown in one session. it&#039;s safe as far as I can tell but nothing cleans up these processes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== ccache and memcached ===&lt;br /&gt;
CCACHE is said to be conflicting with pump mode unless when you call them in the backend&lt;br /&gt;
so, where you start the compile, you don&#039;t use it&lt;br /&gt;
where the compile happens, you use it&lt;br /&gt;
they can share the cache via memcached, this is a nice trick for consistency&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== dockerized / native ===&lt;br /&gt;
&lt;br /&gt;
it remains mostly the same, a container needs to make sure it monitors the right services (distccd, nginx, include_server)&lt;br /&gt;
if you&#039;re using zeroconf, you need to somehow expose the mdns service broadcasts &amp;amp; reception&lt;br /&gt;
&lt;br /&gt;
Processs list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
Workdir list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
=== alpine-chroot ===&lt;br /&gt;
&lt;br /&gt;
when using the &#039;official&#039; script there&#039;s still some odd pieces, seemed to be the processes died on logout. but not all of them.&lt;br /&gt;
&lt;br /&gt;
==== manual launch ====&lt;br /&gt;
&lt;br /&gt;
Starting the daemon would be using&lt;br /&gt;
/usr/bin/distccd --pid-file /var/run/distccd/distccd.pid -N 15 --user distcc --port 3632 --log-level=debug --log-file=/var/log/distccd.log --allow my-sub-net/24&lt;br /&gt;
&lt;br /&gt;
==== localhost? =====&lt;br /&gt;
unclear if you need to use --allow for 127.0.0.1/32 or something to allow the remote preproccesor.&lt;br /&gt;
&lt;br /&gt;
== Kernel specific settings ==&lt;br /&gt;
&lt;br /&gt;
currently (distcc 3.4-r9 on Alpine) you need a patch to build the kernel.&lt;br /&gt;
See &lt;br /&gt;
&lt;br /&gt;
=== Include server Settings ===&lt;br /&gt;
&lt;br /&gt;
cache reset triggers&lt;br /&gt;
This ought to be set before enabling pump mode.&lt;br /&gt;
&lt;br /&gt;
export INCLUDE_SERVER_ARGS=&amp;quot;--stat_reset_triggers=include/linux/compile.h:include/asm/asm-offsets.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
link to explanation TBA&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Disabling GCC Plugins ===&lt;br /&gt;
&lt;br /&gt;
KConfig unselect HAVE_GCC_PLUGINS&lt;br /&gt;
&lt;br /&gt;
Some info is here in the troubleshooting part of the Arch Wiki&lt;br /&gt;
https://wiki.archlinux.org/title/Distcc#Troubleshooting&lt;br /&gt;
&lt;br /&gt;
=== Patches ===&lt;br /&gt;
&lt;br /&gt;
Other things (for 6.6LTS)&lt;br /&gt;
PCIe Stub patch&lt;br /&gt;
&lt;br /&gt;
=== Autoconf === &lt;br /&gt;
&lt;br /&gt;
No known setup examples&lt;br /&gt;
Add whatever it publishes in mdns&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== troubleshooting / analysis ==&lt;br /&gt;
&lt;br /&gt;
=== testing ===&lt;br /&gt;
&lt;br /&gt;
# turn off fallback DISTCC_FALLBACK=1&lt;br /&gt;
# set distcc up to point at specific system under test DISTCC_HOSTS=&amp;quot;mytestbox,cpp,lzo&amp;quot;&lt;br /&gt;
# GCC example compiles&lt;br /&gt;
## code example C&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example C++&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example ObjC&lt;br /&gt;
## same with included header&lt;br /&gt;
# Cmake example compiles&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docoument the thing with compile launcher ccache;distcc&lt;br /&gt;
there&#039;s some blog post, point to that&lt;br /&gt;
no ccache here yet&lt;br /&gt;
show $CC differences distcc vs gcc, what configure scripts see&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Latency ===&lt;br /&gt;
&lt;br /&gt;
Latency of pump mode startups and fallbacks needs to be investigated.&lt;br /&gt;
LZO is enforced even if you have faster network&lt;br /&gt;
DNS Requests, very old bug report from Gcode, one request per call, is it true? how to get rid of it?&lt;br /&gt;
TMPDIR is respected, make sure it&#039;s on ramdisk even on the remote nodes.&lt;br /&gt;
Compile ideally never goes to disk when it doesn&#039;t have to.&lt;br /&gt;
How efficient is the include server collection and unpacking?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== failed to distribute, running locally instead ===&lt;br /&gt;
&lt;br /&gt;
the curse of the ancient, wise bulgarian witch compildora nottherea has befallen people all over the world. only strict and mindless adherence to rituals passed down from generation to generation has given hope to those who are under her ages old spell. again and again it reemerges on idealistic young men and women who spend so much time at their unholy computers that they try to spend less time there by spending a lot of time trying to optimize what the computer does, slowly, instead of reflecting on why they are there, while the computer is busy working, and why they try to solve this by adding a component that makes the computer be more fragile at that, increasing the need of their presense at this idolized thinking machine to oversee and often repair, or worse, mindlessly restart its doing.&lt;br /&gt;
&lt;br /&gt;
== security ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== tcpwrapper style ip range filter ===&lt;br /&gt;
&lt;br /&gt;
the original security model consists of ip restrictions.&lt;br /&gt;
there seems to also be some GSSAPI user auth.&lt;br /&gt;
further, commands that can be called are restricted by name and location.&lt;br /&gt;
this appears to be a runtime whitelist lookup, meaning it&#039;s done and authorized by the same parts of the daemon as processes the compile request along with the intended compiler.&lt;br /&gt;
so the main weaknesses against malicious clients seem to be in sending things to compile, and in overriding the remote compiler to use.&lt;br /&gt;
it can be assumed that a malicious client able to exploit the compiler handshake can then run arbitrary stuff.&lt;br /&gt;
There&#039;s at least a github issue regarding this google.com/search?q=distcc+seccomp&amp;amp;rlz=1C5CHFA_enDE1121DE1121&amp;amp;oq=distcc+seccomp&amp;amp;gs_lcrp=EgZjaHJvbWUyBggAEEUYOTIHCAEQIRigATIHCAIQIRigAdIBCDM1NjRqMGo3qAIAsAIA&amp;amp;sourceid=chrome&amp;amp;ie=UTF-8 suggesting running over ssh. That does only partitally alleviate this risk with regard  to a key based verfication of a client versus a the standard ip restrictions which always include some parsing.&lt;br /&gt;
So this protects against someone directly exploiting the TCP code of distcc.&lt;br /&gt;
It does not protect against malicious clients.&lt;br /&gt;
(ssh force command can&#039;t be used or you&#039;ll not compile anything)&lt;br /&gt;
&lt;br /&gt;
The basic step for protecting access should be filtering who can access the distcc server, so use nftables etc. to restrict access to port 3262 (??) set up the internal filter the same way.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== seccomp ===&lt;br /&gt;
&lt;br /&gt;
The next thing is to confine the compiler calls to only write in their temp directory and that they can only run compilers (using nsjail, apparmor, selinux etc)&lt;br /&gt;
&lt;br /&gt;
the above issue also references the second bit of security, namely a seccomp filter which will already cover a good bit of the above&lt;br /&gt;
https://github.com/distcc/distcc/pull/235&lt;br /&gt;
the commit got closed without merge, from what I see.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== privs ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The other internal security bit is that they do some priviledge dropping. it runs as a dedicated user (distcc), so you can also have an audit policy, and can/could use something like iptables&#039; to ensure it can only connect to the other distcc/memcached hosts, but nothing else.&lt;br /&gt;
&lt;br /&gt;
=== compiler list ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
One needs to investigate when compiler_whitelist.sh is exactly called. as far as I recall it doesn&#039;t close stdin/stdout.&lt;br /&gt;
&lt;br /&gt;
=== distcc-hardened ===&lt;br /&gt;
&lt;br /&gt;
Alpine adds some hardening patch, idk what nature/origina that has.&lt;br /&gt;
&lt;br /&gt;
=== selinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
there&#039;s also a selinux policy for distcc from gentoo or liguros if one is so inclined.&lt;br /&gt;
https://repology.org/project/selinux-distcc/versions&lt;br /&gt;
&lt;br /&gt;
=== general posture ===&lt;br /&gt;
&lt;br /&gt;
Some security measures like the above should definitely be used since the project has only a few part-time maintainers that cannot easily drive the project forward or do large refactors.&lt;br /&gt;
But the seccomp changes were done almost 10 years ago, so, to be fair, they still came through.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Arch wiki refers to a fork by SUSE&lt;br /&gt;
https://github.com/icecc/icecream&lt;br /&gt;
&lt;br /&gt;
It appears &#039;maybe better&#039; but hard to tell.&lt;/div&gt;</summary>
		<author><name>Darkfader</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32136</id>
		<title>User:Darkfader/distcc</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32136"/>
		<updated>2026-03-03T11:24:19Z</updated>

		<summary type="html">&lt;p&gt;Darkfader: /* failed to distribute, running locally instead */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi,&lt;br /&gt;
&lt;br /&gt;
I&#039;m preparing this page. It can take a long time till I finish.&lt;br /&gt;
If you are also wishing to write on this topic, feel free to integrate the content.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Document overview ==&lt;br /&gt;
&lt;br /&gt;
I noticed that almost every distro has one partially complete, partially helpful document on how to use distcc on the distro.&lt;br /&gt;
Usually they also have one for ccache.&lt;br /&gt;
In either case, they&#039;re enough to get started, but not really a reliable watertight thing.&lt;br /&gt;
We definitely needed one of our own.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== goal ===&lt;br /&gt;
&lt;br /&gt;
to describe a working setup for building aports in easiest/fastests fashion&lt;br /&gt;
not planning to add versatility or features where it would make the setup more errorprone.&lt;br /&gt;
the page should describe enough of the steps to successfully compile an LTS kernel via aports and have that job be distributed over multiple nodes.&lt;br /&gt;
Logs should be set up and able to display errors, but not show any errors during the test compile.&lt;br /&gt;
&lt;br /&gt;
To include a path for analysis via testing components.&lt;br /&gt;
&lt;br /&gt;
distcc can greatly improve compile speeds for large software, it comes with a different set of features than ccache; it focusses not avoiding unneccessary compile work, but on a way to speed up the necessary one.&lt;br /&gt;
&lt;br /&gt;
There&#039;s valuable info in the docs of other distros, it should be referenced here (i.e. the arch wiki troubleshooting), when it makes sense, add a TOC for their content.&lt;br /&gt;
&lt;br /&gt;
=== audience ===&lt;br /&gt;
people running software builds on alpine and have multiple computers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This page will show a specific installation, specific configuration, and specific tests, resulting in a specific set of functionality that can be tested to be working.&lt;br /&gt;
&lt;br /&gt;
== installation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Packages ===&lt;br /&gt;
&lt;br /&gt;
you need, on each host&lt;br /&gt;
* distcc&lt;br /&gt;
* distccd-openrc&lt;br /&gt;
* distcc-pump&lt;br /&gt;
* distcc-pump-pyc&lt;br /&gt;
&lt;br /&gt;
the .pyc will speed up the invocations, without it &lt;br /&gt;
idk if one or both should be installed in that case. but it appears to be also automatically be precompiled in /usr/lib/python3.12/site-packages/include_server/__pycache__/ so what does the package do exactly?&lt;br /&gt;
&lt;br /&gt;
There&#039;s some references to cpython-312, so maybe it actually still uses classy python-c conversion or matbe that&#039;s just a component for reading C source code. I have zero idea.&lt;br /&gt;
&lt;br /&gt;
you also need stuff to do compiles&lt;br /&gt;
* alpine sdk&lt;br /&gt;
* clang&lt;br /&gt;
* binutils&lt;br /&gt;
...&lt;br /&gt;
* elfutils(-dev)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Settings ===&lt;br /&gt;
==== settings for distcc ====&lt;br /&gt;
&lt;br /&gt;
* there&#039;s /etc/default/distcc&lt;br /&gt;
* there&#039;s /etc/conf.d/distcc &lt;br /&gt;
&lt;br /&gt;
make all your settings here&lt;br /&gt;
take care with the listen address, if you specify an IP it&#039;ll not be on 127.0.0.1 in case you would have localhost in your list...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* command_whitelist.sh &lt;br /&gt;
&lt;br /&gt;
this is half functional, you need to set things here but you also need to maintain the symlinks that are collected under /usr/lib/distcc (for your compilers) and /usr/lib/distcc/bin (for itself)&lt;br /&gt;
&lt;br /&gt;
you MUST run the script to update the compilers!&lt;br /&gt;
Info for script and what files it will create&lt;br /&gt;
&lt;br /&gt;
/usr/sbin/update-distcc-symlinks&lt;br /&gt;
&lt;br /&gt;
tschike:/usr/bin# ls -l /usr/lib/distcc/&lt;br /&gt;
total 4&lt;br /&gt;
drwxr-xr-x 2 root root 4096 Mar  2 18:14 bin&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c89 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c99 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 cc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc-15.2.0 -&amp;gt; ../../bin/distcc&lt;br /&gt;
&lt;br /&gt;
distcc itself is in bin&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cpp -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 g++ -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 06:49 x86_64-alpine-linux-musl-gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
&lt;br /&gt;
the last symplink here is wrong, made by me and would not work...&lt;br /&gt;
BAD symlink.&lt;br /&gt;
&lt;br /&gt;
=== distcc hosts file ===&lt;br /&gt;
&lt;br /&gt;
idk about that thing it&#039;s odd&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== abuild.conf ===&lt;br /&gt;
&lt;br /&gt;
settings for aports&lt;br /&gt;
* cc=&lt;br /&gt;
* cxx=&lt;br /&gt;
* cpp=&lt;br /&gt;
* cflags=&lt;br /&gt;
* njobs&lt;br /&gt;
&lt;br /&gt;
== detail infos ==&lt;br /&gt;
&lt;br /&gt;
???&lt;br /&gt;
&lt;br /&gt;
=== hosts syntax ===&lt;br /&gt;
&lt;br /&gt;
* myhost otherhost&lt;br /&gt;
* myhost,cpp,lzo myotherhost,cpp,lzo&lt;br /&gt;
&lt;br /&gt;
==== the host ====&lt;br /&gt;
&lt;br /&gt;
hostname/ip&lt;br /&gt;
localhost&lt;br /&gt;
127.0.0.1&lt;br /&gt;
::1 - does not work&lt;br /&gt;
&lt;br /&gt;
==== protocol ====&lt;br /&gt;
&lt;br /&gt;
* no protocol given&lt;br /&gt;
* ,cpp,lzo protocol&lt;br /&gt;
&lt;br /&gt;
cpp implies lzo, it requires compression, even if you have 10gbit/s or more, it&#039;s just hardcoded&lt;br /&gt;
&lt;br /&gt;
=== threads ===&lt;br /&gt;
/number of workers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== architecture ==&lt;br /&gt;
it can handle C, C++, ObjC, maybe some other stuff&lt;br /&gt;
&lt;br /&gt;
* what happens with normal xmit&lt;br /&gt;
* what happens with pump mode&lt;br /&gt;
* at which step the include server is used and how it collects the includes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== distribution algorithm ===&lt;br /&gt;
honestly I simply don&#039;t get it&lt;br /&gt;
&lt;br /&gt;
* The order matters&lt;br /&gt;
* The number of threads matters&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== localhost ====&lt;br /&gt;
&lt;br /&gt;
* localhost precedence&lt;br /&gt;
* localhost fallback&lt;br /&gt;
&lt;br /&gt;
variable: DISTCC_FALLBACK&lt;br /&gt;
&lt;br /&gt;
0 = Fail to compile if it would need to fallback to a normal local gcc call&lt;br /&gt;
1 = If remote compile fails, just do it yourself&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Operation ==&lt;br /&gt;
&lt;br /&gt;
=== startup and shutdown ===&lt;br /&gt;
service distcc stop is not entirely reliable (it can take a minute after the stop until the processes are gone and sometimes it will never stop&lt;br /&gt;
this is very bad with openrc, the openrc script returns after a second and only relies on its service flags, not the process status.&lt;br /&gt;
manually check after stopping, wait a min, if needed, kill it all.&lt;br /&gt;
at some point the rc file needs to be rewritten, it can&#039;t stay like it is.&lt;br /&gt;
&lt;br /&gt;
if you used a pump mode session, that also needs a logout (pump --shutdown)&lt;br /&gt;
avoid running multiple startups without shutdown in one session. it&#039;s safe as far as I can tell but nothing cleans up these processes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== ccache and memcached ===&lt;br /&gt;
CCACHE is said to be conflicting with pump mode unless when you call them in the backend&lt;br /&gt;
so, where you start the compile, you don&#039;t use it&lt;br /&gt;
where the compile happens, you use it&lt;br /&gt;
they can share the cache via memcached, this is a nice trick for consistency&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== dockerized / native ===&lt;br /&gt;
&lt;br /&gt;
it remains mostly the same, a container needs to make sure it monitors the right services (distccd, nginx, include_server)&lt;br /&gt;
if you&#039;re using zeroconf, you need to somehow expose the mdns service broadcasts &amp;amp; reception&lt;br /&gt;
&lt;br /&gt;
Processs list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
Workdir list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
=== alpine-chroot ===&lt;br /&gt;
&lt;br /&gt;
when using the &#039;official&#039; script there&#039;s still some odd pieces, seemed to be the processes died on logout. but not all of them.&lt;br /&gt;
&lt;br /&gt;
==== manual launch ====&lt;br /&gt;
&lt;br /&gt;
Starting the daemon would be using&lt;br /&gt;
/usr/bin/distccd --pid-file /var/run/distccd/distccd.pid -N 15 --user distcc --port 3632 --log-level=debug --log-file=/var/log/distccd.log --allow my-sub-net/24&lt;br /&gt;
&lt;br /&gt;
==== localhost? =====&lt;br /&gt;
unclear if you need to use --allow for 127.0.0.1/32 or something to allow the remote preproccesor.&lt;br /&gt;
&lt;br /&gt;
== Kernel specific settings ==&lt;br /&gt;
&lt;br /&gt;
currently (distcc 3.4-r9 on Alpine) you need a patch to build the kernel.&lt;br /&gt;
See &lt;br /&gt;
&lt;br /&gt;
=== Include server Settings ===&lt;br /&gt;
&lt;br /&gt;
cache reset triggers&lt;br /&gt;
This ought to be set before enabling pump mode.&lt;br /&gt;
&lt;br /&gt;
export INCLUDE_SERVER_ARGS=&amp;quot;--stat_reset_triggers=include/linux/compile.h:include/asm/asm-offsets.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
link to explanation TBA&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Disabling GCC Plugins ===&lt;br /&gt;
&lt;br /&gt;
KConfig unselect HAVE_GCC_PLUGINS&lt;br /&gt;
&lt;br /&gt;
Some info is here in the troubleshooting part of the Arch Wiki&lt;br /&gt;
https://wiki.archlinux.org/title/Distcc#Troubleshooting&lt;br /&gt;
&lt;br /&gt;
=== Patches ===&lt;br /&gt;
&lt;br /&gt;
Other things (for 6.6LTS)&lt;br /&gt;
PCIe Stub patch&lt;br /&gt;
&lt;br /&gt;
=== Autoconf === &lt;br /&gt;
&lt;br /&gt;
No known setup examples&lt;br /&gt;
Add whatever it publishes in mdns&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== troubleshooting / analysis ==&lt;br /&gt;
&lt;br /&gt;
=== testing ===&lt;br /&gt;
&lt;br /&gt;
# turn off fallback DISTCC_FALLBACK=1&lt;br /&gt;
# set distcc up to point at specific system under test DISTCC_HOSTS=&amp;quot;mytestbox,cpp,lzo&amp;quot;&lt;br /&gt;
# GCC example compiles&lt;br /&gt;
## code example C&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example C++&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example ObjC&lt;br /&gt;
## same with included header&lt;br /&gt;
# Cmake example compiles&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docoument the thing with compile launcher ccache;distcc&lt;br /&gt;
there&#039;s some blog post, point to that&lt;br /&gt;
no ccache here yet&lt;br /&gt;
show $CC differences distcc vs gcc, what configure scripts see&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Latency ===&lt;br /&gt;
&lt;br /&gt;
Latency of pump mode startups and fallbacks needs to be investigated.&lt;br /&gt;
LZO is enforced even if you have faster network&lt;br /&gt;
DNS Requests, very old bug report from Gcode, one request per call, is it true? how to get rid of it?&lt;br /&gt;
TMPDIR is respected, make sure it&#039;s on ramdisk even on the remote nodes.&lt;br /&gt;
Compile ideally never goes to disk when it doesn&#039;t have to.&lt;br /&gt;
How efficient is the include server collection and unpacking?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== failed to distribute, running locally instead ===&lt;br /&gt;
&lt;br /&gt;
the curse of the ancient and wise bulgarian witch compildora nottherea has befallen people all over the world. only strict and mindless adherence to rituals passed down from generation to generation has given hope to those who are under her ages old spell. again and again it reemerges on idealistic young men and women who spend so much time at their unholy computers that they try to spend less time there by spending a lot of time trying to optimize what the computer does, slowly, instead of reflecting on why they are there, while the computer is busy working, and why they try to solve this by adding a component that makes the computer be more fragile at that, increasing the need of their presense at this idolized thinking machine to oversee and often repair, or worse, mindlessly restart its doing.&lt;br /&gt;
&lt;br /&gt;
== security ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== tcpwrapper style ip range filter ===&lt;br /&gt;
&lt;br /&gt;
the original security model consists of ip restrictions.&lt;br /&gt;
there seems to also be some GSSAPI user auth.&lt;br /&gt;
further, commands that can be called are restricted by name and location.&lt;br /&gt;
this appears to be a runtime whitelist lookup, meaning it&#039;s done and authorized by the same parts of the daemon as processes the compile request along with the intended compiler.&lt;br /&gt;
so the main weaknesses against malicious clients seem to be in sending things to compile, and in overriding the remote compiler to use.&lt;br /&gt;
it can be assumed that a malicious client able to exploit the compiler handshake can then run arbitrary stuff.&lt;br /&gt;
There&#039;s at least a github issue regarding this google.com/search?q=distcc+seccomp&amp;amp;rlz=1C5CHFA_enDE1121DE1121&amp;amp;oq=distcc+seccomp&amp;amp;gs_lcrp=EgZjaHJvbWUyBggAEEUYOTIHCAEQIRigATIHCAIQIRigAdIBCDM1NjRqMGo3qAIAsAIA&amp;amp;sourceid=chrome&amp;amp;ie=UTF-8 suggesting running over ssh. That does only partitally alleviate this risk with regard  to a key based verfication of a client versus a the standard ip restrictions which always include some parsing.&lt;br /&gt;
So this protects against someone directly exploiting the TCP code of distcc.&lt;br /&gt;
It does not protect against malicious clients.&lt;br /&gt;
(ssh force command can&#039;t be used or you&#039;ll not compile anything)&lt;br /&gt;
&lt;br /&gt;
The basic step for protecting access should be filtering who can access the distcc server, so use nftables etc. to restrict access to port 3262 (??) set up the internal filter the same way.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== seccomp ===&lt;br /&gt;
&lt;br /&gt;
The next thing is to confine the compiler calls to only write in their temp directory and that they can only run compilers (using nsjail, apparmor, selinux etc)&lt;br /&gt;
&lt;br /&gt;
the above issue also references the second bit of security, namely a seccomp filter which will already cover a good bit of the above&lt;br /&gt;
https://github.com/distcc/distcc/pull/235&lt;br /&gt;
the commit got closed without merge, from what I see.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== privs ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The other internal security bit is that they do some priviledge dropping. it runs as a dedicated user (distcc), so you can also have an audit policy, and can/could use something like iptables&#039; to ensure it can only connect to the other distcc/memcached hosts, but nothing else.&lt;br /&gt;
&lt;br /&gt;
=== compiler list ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
One needs to investigate when compiler_whitelist.sh is exactly called. as far as I recall it doesn&#039;t close stdin/stdout.&lt;br /&gt;
&lt;br /&gt;
=== distcc-hardened ===&lt;br /&gt;
&lt;br /&gt;
Alpine adds some hardening patch, idk what nature/origina that has.&lt;br /&gt;
&lt;br /&gt;
=== selinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
there&#039;s also a selinux policy for distcc from gentoo or liguros if one is so inclined.&lt;br /&gt;
https://repology.org/project/selinux-distcc/versions&lt;br /&gt;
&lt;br /&gt;
=== general posture ===&lt;br /&gt;
&lt;br /&gt;
Some security measures like the above should definitely be used since the project has only a few part-time maintainers that cannot easily drive the project forward or do large refactors.&lt;br /&gt;
But the seccomp changes were done almost 10 years ago, so, to be fair, they still came through.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Arch wiki refers to a fork by SUSE&lt;br /&gt;
https://github.com/icecc/icecream&lt;br /&gt;
&lt;br /&gt;
It appears &#039;maybe better&#039; but hard to tell.&lt;/div&gt;</summary>
		<author><name>Darkfader</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32135</id>
		<title>User:Darkfader/distcc</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32135"/>
		<updated>2026-03-03T11:19:59Z</updated>

		<summary type="html">&lt;p&gt;Darkfader: /* troubleshooting / analysis */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi,&lt;br /&gt;
&lt;br /&gt;
I&#039;m preparing this page. It can take a long time till I finish.&lt;br /&gt;
If you are also wishing to write on this topic, feel free to integrate the content.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Document overview ==&lt;br /&gt;
&lt;br /&gt;
I noticed that almost every distro has one partially complete, partially helpful document on how to use distcc on the distro.&lt;br /&gt;
Usually they also have one for ccache.&lt;br /&gt;
In either case, they&#039;re enough to get started, but not really a reliable watertight thing.&lt;br /&gt;
We definitely needed one of our own.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== goal ===&lt;br /&gt;
&lt;br /&gt;
to describe a working setup for building aports in easiest/fastests fashion&lt;br /&gt;
not planning to add versatility or features where it would make the setup more errorprone.&lt;br /&gt;
the page should describe enough of the steps to successfully compile an LTS kernel via aports and have that job be distributed over multiple nodes.&lt;br /&gt;
Logs should be set up and able to display errors, but not show any errors during the test compile.&lt;br /&gt;
&lt;br /&gt;
To include a path for analysis via testing components.&lt;br /&gt;
&lt;br /&gt;
distcc can greatly improve compile speeds for large software, it comes with a different set of features than ccache; it focusses not avoiding unneccessary compile work, but on a way to speed up the necessary one.&lt;br /&gt;
&lt;br /&gt;
There&#039;s valuable info in the docs of other distros, it should be referenced here (i.e. the arch wiki troubleshooting), when it makes sense, add a TOC for their content.&lt;br /&gt;
&lt;br /&gt;
=== audience ===&lt;br /&gt;
people running software builds on alpine and have multiple computers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This page will show a specific installation, specific configuration, and specific tests, resulting in a specific set of functionality that can be tested to be working.&lt;br /&gt;
&lt;br /&gt;
== installation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Packages ===&lt;br /&gt;
&lt;br /&gt;
you need, on each host&lt;br /&gt;
* distcc&lt;br /&gt;
* distccd-openrc&lt;br /&gt;
* distcc-pump&lt;br /&gt;
* distcc-pump-pyc&lt;br /&gt;
&lt;br /&gt;
the .pyc will speed up the invocations, without it &lt;br /&gt;
idk if one or both should be installed in that case. but it appears to be also automatically be precompiled in /usr/lib/python3.12/site-packages/include_server/__pycache__/ so what does the package do exactly?&lt;br /&gt;
&lt;br /&gt;
There&#039;s some references to cpython-312, so maybe it actually still uses classy python-c conversion or matbe that&#039;s just a component for reading C source code. I have zero idea.&lt;br /&gt;
&lt;br /&gt;
you also need stuff to do compiles&lt;br /&gt;
* alpine sdk&lt;br /&gt;
* clang&lt;br /&gt;
* binutils&lt;br /&gt;
...&lt;br /&gt;
* elfutils(-dev)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Settings ===&lt;br /&gt;
==== settings for distcc ====&lt;br /&gt;
&lt;br /&gt;
* there&#039;s /etc/default/distcc&lt;br /&gt;
* there&#039;s /etc/conf.d/distcc &lt;br /&gt;
&lt;br /&gt;
make all your settings here&lt;br /&gt;
take care with the listen address, if you specify an IP it&#039;ll not be on 127.0.0.1 in case you would have localhost in your list...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* command_whitelist.sh &lt;br /&gt;
&lt;br /&gt;
this is half functional, you need to set things here but you also need to maintain the symlinks that are collected under /usr/lib/distcc (for your compilers) and /usr/lib/distcc/bin (for itself)&lt;br /&gt;
&lt;br /&gt;
you MUST run the script to update the compilers!&lt;br /&gt;
Info for script and what files it will create&lt;br /&gt;
&lt;br /&gt;
/usr/sbin/update-distcc-symlinks&lt;br /&gt;
&lt;br /&gt;
tschike:/usr/bin# ls -l /usr/lib/distcc/&lt;br /&gt;
total 4&lt;br /&gt;
drwxr-xr-x 2 root root 4096 Mar  2 18:14 bin&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c89 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c99 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 cc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc-15.2.0 -&amp;gt; ../../bin/distcc&lt;br /&gt;
&lt;br /&gt;
distcc itself is in bin&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cpp -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 g++ -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 06:49 x86_64-alpine-linux-musl-gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
&lt;br /&gt;
the last symplink here is wrong, made by me and would not work...&lt;br /&gt;
BAD symlink.&lt;br /&gt;
&lt;br /&gt;
=== distcc hosts file ===&lt;br /&gt;
&lt;br /&gt;
idk about that thing it&#039;s odd&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== abuild.conf ===&lt;br /&gt;
&lt;br /&gt;
settings for aports&lt;br /&gt;
* cc=&lt;br /&gt;
* cxx=&lt;br /&gt;
* cpp=&lt;br /&gt;
* cflags=&lt;br /&gt;
* njobs&lt;br /&gt;
&lt;br /&gt;
== detail infos ==&lt;br /&gt;
&lt;br /&gt;
???&lt;br /&gt;
&lt;br /&gt;
=== hosts syntax ===&lt;br /&gt;
&lt;br /&gt;
* myhost otherhost&lt;br /&gt;
* myhost,cpp,lzo myotherhost,cpp,lzo&lt;br /&gt;
&lt;br /&gt;
==== the host ====&lt;br /&gt;
&lt;br /&gt;
hostname/ip&lt;br /&gt;
localhost&lt;br /&gt;
127.0.0.1&lt;br /&gt;
::1 - does not work&lt;br /&gt;
&lt;br /&gt;
==== protocol ====&lt;br /&gt;
&lt;br /&gt;
* no protocol given&lt;br /&gt;
* ,cpp,lzo protocol&lt;br /&gt;
&lt;br /&gt;
cpp implies lzo, it requires compression, even if you have 10gbit/s or more, it&#039;s just hardcoded&lt;br /&gt;
&lt;br /&gt;
=== threads ===&lt;br /&gt;
/number of workers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== architecture ==&lt;br /&gt;
it can handle C, C++, ObjC, maybe some other stuff&lt;br /&gt;
&lt;br /&gt;
* what happens with normal xmit&lt;br /&gt;
* what happens with pump mode&lt;br /&gt;
* at which step the include server is used and how it collects the includes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== distribution algorithm ===&lt;br /&gt;
honestly I simply don&#039;t get it&lt;br /&gt;
&lt;br /&gt;
* The order matters&lt;br /&gt;
* The number of threads matters&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== localhost ====&lt;br /&gt;
&lt;br /&gt;
* localhost precedence&lt;br /&gt;
* localhost fallback&lt;br /&gt;
&lt;br /&gt;
variable: DISTCC_FALLBACK&lt;br /&gt;
&lt;br /&gt;
0 = Fail to compile if it would need to fallback to a normal local gcc call&lt;br /&gt;
1 = If remote compile fails, just do it yourself&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Operation ==&lt;br /&gt;
&lt;br /&gt;
=== startup and shutdown ===&lt;br /&gt;
service distcc stop is not entirely reliable (it can take a minute after the stop until the processes are gone and sometimes it will never stop&lt;br /&gt;
this is very bad with openrc, the openrc script returns after a second and only relies on its service flags, not the process status.&lt;br /&gt;
manually check after stopping, wait a min, if needed, kill it all.&lt;br /&gt;
at some point the rc file needs to be rewritten, it can&#039;t stay like it is.&lt;br /&gt;
&lt;br /&gt;
if you used a pump mode session, that also needs a logout (pump --shutdown)&lt;br /&gt;
avoid running multiple startups without shutdown in one session. it&#039;s safe as far as I can tell but nothing cleans up these processes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== ccache and memcached ===&lt;br /&gt;
CCACHE is said to be conflicting with pump mode unless when you call them in the backend&lt;br /&gt;
so, where you start the compile, you don&#039;t use it&lt;br /&gt;
where the compile happens, you use it&lt;br /&gt;
they can share the cache via memcached, this is a nice trick for consistency&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== dockerized / native ===&lt;br /&gt;
&lt;br /&gt;
it remains mostly the same, a container needs to make sure it monitors the right services (distccd, nginx, include_server)&lt;br /&gt;
if you&#039;re using zeroconf, you need to somehow expose the mdns service broadcasts &amp;amp; reception&lt;br /&gt;
&lt;br /&gt;
Processs list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
Workdir list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
=== alpine-chroot ===&lt;br /&gt;
&lt;br /&gt;
when using the &#039;official&#039; script there&#039;s still some odd pieces, seemed to be the processes died on logout. but not all of them.&lt;br /&gt;
&lt;br /&gt;
==== manual launch ====&lt;br /&gt;
&lt;br /&gt;
Starting the daemon would be using&lt;br /&gt;
/usr/bin/distccd --pid-file /var/run/distccd/distccd.pid -N 15 --user distcc --port 3632 --log-level=debug --log-file=/var/log/distccd.log --allow my-sub-net/24&lt;br /&gt;
&lt;br /&gt;
==== localhost? =====&lt;br /&gt;
unclear if you need to use --allow for 127.0.0.1/32 or something to allow the remote preproccesor.&lt;br /&gt;
&lt;br /&gt;
== Kernel specific settings ==&lt;br /&gt;
&lt;br /&gt;
currently (distcc 3.4-r9 on Alpine) you need a patch to build the kernel.&lt;br /&gt;
See &lt;br /&gt;
&lt;br /&gt;
=== Include server Settings ===&lt;br /&gt;
&lt;br /&gt;
cache reset triggers&lt;br /&gt;
This ought to be set before enabling pump mode.&lt;br /&gt;
&lt;br /&gt;
export INCLUDE_SERVER_ARGS=&amp;quot;--stat_reset_triggers=include/linux/compile.h:include/asm/asm-offsets.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
link to explanation TBA&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Disabling GCC Plugins ===&lt;br /&gt;
&lt;br /&gt;
KConfig unselect HAVE_GCC_PLUGINS&lt;br /&gt;
&lt;br /&gt;
Some info is here in the troubleshooting part of the Arch Wiki&lt;br /&gt;
https://wiki.archlinux.org/title/Distcc#Troubleshooting&lt;br /&gt;
&lt;br /&gt;
=== Patches ===&lt;br /&gt;
&lt;br /&gt;
Other things (for 6.6LTS)&lt;br /&gt;
PCIe Stub patch&lt;br /&gt;
&lt;br /&gt;
=== Autoconf === &lt;br /&gt;
&lt;br /&gt;
No known setup examples&lt;br /&gt;
Add whatever it publishes in mdns&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== troubleshooting / analysis ==&lt;br /&gt;
&lt;br /&gt;
=== testing ===&lt;br /&gt;
&lt;br /&gt;
# turn off fallback DISTCC_FALLBACK=1&lt;br /&gt;
# set distcc up to point at specific system under test DISTCC_HOSTS=&amp;quot;mytestbox,cpp,lzo&amp;quot;&lt;br /&gt;
# GCC example compiles&lt;br /&gt;
## code example C&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example C++&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example ObjC&lt;br /&gt;
## same with included header&lt;br /&gt;
# Cmake example compiles&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docoument the thing with compile launcher ccache;distcc&lt;br /&gt;
there&#039;s some blog post, point to that&lt;br /&gt;
no ccache here yet&lt;br /&gt;
show $CC differences distcc vs gcc, what configure scripts see&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Latency ===&lt;br /&gt;
&lt;br /&gt;
Latency of pump mode startups and fallbacks needs to be investigated.&lt;br /&gt;
LZO is enforced even if you have faster network&lt;br /&gt;
DNS Requests, very old bug report from Gcode, one request per call, is it true? how to get rid of it?&lt;br /&gt;
TMPDIR is respected, make sure it&#039;s on ramdisk even on the remote nodes.&lt;br /&gt;
Compile ideally never goes to disk when it doesn&#039;t have to.&lt;br /&gt;
How efficient is the include server collection and unpacking?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== failed to distribute, running locally instead ===&lt;br /&gt;
&lt;br /&gt;
the curse&lt;br /&gt;
&lt;br /&gt;
== security ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== tcpwrapper style ip range filter ===&lt;br /&gt;
&lt;br /&gt;
the original security model consists of ip restrictions.&lt;br /&gt;
there seems to also be some GSSAPI user auth.&lt;br /&gt;
further, commands that can be called are restricted by name and location.&lt;br /&gt;
this appears to be a runtime whitelist lookup, meaning it&#039;s done and authorized by the same parts of the daemon as processes the compile request along with the intended compiler.&lt;br /&gt;
so the main weaknesses against malicious clients seem to be in sending things to compile, and in overriding the remote compiler to use.&lt;br /&gt;
it can be assumed that a malicious client able to exploit the compiler handshake can then run arbitrary stuff.&lt;br /&gt;
There&#039;s at least a github issue regarding this google.com/search?q=distcc+seccomp&amp;amp;rlz=1C5CHFA_enDE1121DE1121&amp;amp;oq=distcc+seccomp&amp;amp;gs_lcrp=EgZjaHJvbWUyBggAEEUYOTIHCAEQIRigATIHCAIQIRigAdIBCDM1NjRqMGo3qAIAsAIA&amp;amp;sourceid=chrome&amp;amp;ie=UTF-8 suggesting running over ssh. That does only partitally alleviate this risk with regard  to a key based verfication of a client versus a the standard ip restrictions which always include some parsing.&lt;br /&gt;
So this protects against someone directly exploiting the TCP code of distcc.&lt;br /&gt;
It does not protect against malicious clients.&lt;br /&gt;
(ssh force command can&#039;t be used or you&#039;ll not compile anything)&lt;br /&gt;
&lt;br /&gt;
The basic step for protecting access should be filtering who can access the distcc server, so use nftables etc. to restrict access to port 3262 (??) set up the internal filter the same way.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== seccomp ===&lt;br /&gt;
&lt;br /&gt;
The next thing is to confine the compiler calls to only write in their temp directory and that they can only run compilers (using nsjail, apparmor, selinux etc)&lt;br /&gt;
&lt;br /&gt;
the above issue also references the second bit of security, namely a seccomp filter which will already cover a good bit of the above&lt;br /&gt;
https://github.com/distcc/distcc/pull/235&lt;br /&gt;
the commit got closed without merge, from what I see.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== privs ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The other internal security bit is that they do some priviledge dropping. it runs as a dedicated user (distcc), so you can also have an audit policy, and can/could use something like iptables&#039; to ensure it can only connect to the other distcc/memcached hosts, but nothing else.&lt;br /&gt;
&lt;br /&gt;
=== compiler list ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
One needs to investigate when compiler_whitelist.sh is exactly called. as far as I recall it doesn&#039;t close stdin/stdout.&lt;br /&gt;
&lt;br /&gt;
=== distcc-hardened ===&lt;br /&gt;
&lt;br /&gt;
Alpine adds some hardening patch, idk what nature/origina that has.&lt;br /&gt;
&lt;br /&gt;
=== selinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
there&#039;s also a selinux policy for distcc from gentoo or liguros if one is so inclined.&lt;br /&gt;
https://repology.org/project/selinux-distcc/versions&lt;br /&gt;
&lt;br /&gt;
=== general posture ===&lt;br /&gt;
&lt;br /&gt;
Some security measures like the above should definitely be used since the project has only a few part-time maintainers that cannot easily drive the project forward or do large refactors.&lt;br /&gt;
But the seccomp changes were done almost 10 years ago, so, to be fair, they still came through.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Arch wiki refers to a fork by SUSE&lt;br /&gt;
https://github.com/icecc/icecream&lt;br /&gt;
&lt;br /&gt;
It appears &#039;maybe better&#039; but hard to tell.&lt;/div&gt;</summary>
		<author><name>Darkfader</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32134</id>
		<title>User:Darkfader/distcc</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32134"/>
		<updated>2026-03-03T11:08:42Z</updated>

		<summary type="html">&lt;p&gt;Darkfader: /* goal */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi,&lt;br /&gt;
&lt;br /&gt;
I&#039;m preparing this page. It can take a long time till I finish.&lt;br /&gt;
If you are also wishing to write on this topic, feel free to integrate the content.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Document overview ==&lt;br /&gt;
&lt;br /&gt;
I noticed that almost every distro has one partially complete, partially helpful document on how to use distcc on the distro.&lt;br /&gt;
Usually they also have one for ccache.&lt;br /&gt;
In either case, they&#039;re enough to get started, but not really a reliable watertight thing.&lt;br /&gt;
We definitely needed one of our own.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== goal ===&lt;br /&gt;
&lt;br /&gt;
to describe a working setup for building aports in easiest/fastests fashion&lt;br /&gt;
not planning to add versatility or features where it would make the setup more errorprone.&lt;br /&gt;
the page should describe enough of the steps to successfully compile an LTS kernel via aports and have that job be distributed over multiple nodes.&lt;br /&gt;
Logs should be set up and able to display errors, but not show any errors during the test compile.&lt;br /&gt;
&lt;br /&gt;
To include a path for analysis via testing components.&lt;br /&gt;
&lt;br /&gt;
distcc can greatly improve compile speeds for large software, it comes with a different set of features than ccache; it focusses not avoiding unneccessary compile work, but on a way to speed up the necessary one.&lt;br /&gt;
&lt;br /&gt;
There&#039;s valuable info in the docs of other distros, it should be referenced here (i.e. the arch wiki troubleshooting), when it makes sense, add a TOC for their content.&lt;br /&gt;
&lt;br /&gt;
=== audience ===&lt;br /&gt;
people running software builds on alpine and have multiple computers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This page will show a specific installation, specific configuration, and specific tests, resulting in a specific set of functionality that can be tested to be working.&lt;br /&gt;
&lt;br /&gt;
== installation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Packages ===&lt;br /&gt;
&lt;br /&gt;
you need, on each host&lt;br /&gt;
* distcc&lt;br /&gt;
* distccd-openrc&lt;br /&gt;
* distcc-pump&lt;br /&gt;
* distcc-pump-pyc&lt;br /&gt;
&lt;br /&gt;
the .pyc will speed up the invocations, without it &lt;br /&gt;
idk if one or both should be installed in that case. but it appears to be also automatically be precompiled in /usr/lib/python3.12/site-packages/include_server/__pycache__/ so what does the package do exactly?&lt;br /&gt;
&lt;br /&gt;
There&#039;s some references to cpython-312, so maybe it actually still uses classy python-c conversion or matbe that&#039;s just a component for reading C source code. I have zero idea.&lt;br /&gt;
&lt;br /&gt;
you also need stuff to do compiles&lt;br /&gt;
* alpine sdk&lt;br /&gt;
* clang&lt;br /&gt;
* binutils&lt;br /&gt;
...&lt;br /&gt;
* elfutils(-dev)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Settings ===&lt;br /&gt;
==== settings for distcc ====&lt;br /&gt;
&lt;br /&gt;
* there&#039;s /etc/default/distcc&lt;br /&gt;
* there&#039;s /etc/conf.d/distcc &lt;br /&gt;
&lt;br /&gt;
make all your settings here&lt;br /&gt;
take care with the listen address, if you specify an IP it&#039;ll not be on 127.0.0.1 in case you would have localhost in your list...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* command_whitelist.sh &lt;br /&gt;
&lt;br /&gt;
this is half functional, you need to set things here but you also need to maintain the symlinks that are collected under /usr/lib/distcc (for your compilers) and /usr/lib/distcc/bin (for itself)&lt;br /&gt;
&lt;br /&gt;
you MUST run the script to update the compilers!&lt;br /&gt;
Info for script and what files it will create&lt;br /&gt;
&lt;br /&gt;
/usr/sbin/update-distcc-symlinks&lt;br /&gt;
&lt;br /&gt;
tschike:/usr/bin# ls -l /usr/lib/distcc/&lt;br /&gt;
total 4&lt;br /&gt;
drwxr-xr-x 2 root root 4096 Mar  2 18:14 bin&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c89 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c99 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 cc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc-15.2.0 -&amp;gt; ../../bin/distcc&lt;br /&gt;
&lt;br /&gt;
distcc itself is in bin&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cpp -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 g++ -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 06:49 x86_64-alpine-linux-musl-gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
&lt;br /&gt;
the last symplink here is wrong, made by me and would not work...&lt;br /&gt;
BAD symlink.&lt;br /&gt;
&lt;br /&gt;
=== distcc hosts file ===&lt;br /&gt;
&lt;br /&gt;
idk about that thing it&#039;s odd&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== abuild.conf ===&lt;br /&gt;
&lt;br /&gt;
settings for aports&lt;br /&gt;
* cc=&lt;br /&gt;
* cxx=&lt;br /&gt;
* cpp=&lt;br /&gt;
* cflags=&lt;br /&gt;
* njobs&lt;br /&gt;
&lt;br /&gt;
== detail infos ==&lt;br /&gt;
&lt;br /&gt;
???&lt;br /&gt;
&lt;br /&gt;
=== hosts syntax ===&lt;br /&gt;
&lt;br /&gt;
* myhost otherhost&lt;br /&gt;
* myhost,cpp,lzo myotherhost,cpp,lzo&lt;br /&gt;
&lt;br /&gt;
==== the host ====&lt;br /&gt;
&lt;br /&gt;
hostname/ip&lt;br /&gt;
localhost&lt;br /&gt;
127.0.0.1&lt;br /&gt;
::1 - does not work&lt;br /&gt;
&lt;br /&gt;
==== protocol ====&lt;br /&gt;
&lt;br /&gt;
* no protocol given&lt;br /&gt;
* ,cpp,lzo protocol&lt;br /&gt;
&lt;br /&gt;
cpp implies lzo, it requires compression, even if you have 10gbit/s or more, it&#039;s just hardcoded&lt;br /&gt;
&lt;br /&gt;
=== threads ===&lt;br /&gt;
/number of workers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== architecture ==&lt;br /&gt;
it can handle C, C++, ObjC, maybe some other stuff&lt;br /&gt;
&lt;br /&gt;
* what happens with normal xmit&lt;br /&gt;
* what happens with pump mode&lt;br /&gt;
* at which step the include server is used and how it collects the includes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== distribution algorithm ===&lt;br /&gt;
honestly I simply don&#039;t get it&lt;br /&gt;
&lt;br /&gt;
* The order matters&lt;br /&gt;
* The number of threads matters&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== localhost ====&lt;br /&gt;
&lt;br /&gt;
* localhost precedence&lt;br /&gt;
* localhost fallback&lt;br /&gt;
&lt;br /&gt;
variable: DISTCC_FALLBACK&lt;br /&gt;
&lt;br /&gt;
0 = Fail to compile if it would need to fallback to a normal local gcc call&lt;br /&gt;
1 = If remote compile fails, just do it yourself&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Operation ==&lt;br /&gt;
&lt;br /&gt;
=== startup and shutdown ===&lt;br /&gt;
service distcc stop is not entirely reliable (it can take a minute after the stop until the processes are gone and sometimes it will never stop&lt;br /&gt;
this is very bad with openrc, the openrc script returns after a second and only relies on its service flags, not the process status.&lt;br /&gt;
manually check after stopping, wait a min, if needed, kill it all.&lt;br /&gt;
at some point the rc file needs to be rewritten, it can&#039;t stay like it is.&lt;br /&gt;
&lt;br /&gt;
if you used a pump mode session, that also needs a logout (pump --shutdown)&lt;br /&gt;
avoid running multiple startups without shutdown in one session. it&#039;s safe as far as I can tell but nothing cleans up these processes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== ccache and memcached ===&lt;br /&gt;
CCACHE is said to be conflicting with pump mode unless when you call them in the backend&lt;br /&gt;
so, where you start the compile, you don&#039;t use it&lt;br /&gt;
where the compile happens, you use it&lt;br /&gt;
they can share the cache via memcached, this is a nice trick for consistency&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== dockerized / native ===&lt;br /&gt;
&lt;br /&gt;
it remains mostly the same, a container needs to make sure it monitors the right services (distccd, nginx, include_server)&lt;br /&gt;
if you&#039;re using zeroconf, you need to somehow expose the mdns service broadcasts &amp;amp; reception&lt;br /&gt;
&lt;br /&gt;
Processs list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
Workdir list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
=== alpine-chroot ===&lt;br /&gt;
&lt;br /&gt;
when using the &#039;official&#039; script there&#039;s still some odd pieces, seemed to be the processes died on logout. but not all of them.&lt;br /&gt;
&lt;br /&gt;
==== manual launch ====&lt;br /&gt;
&lt;br /&gt;
Starting the daemon would be using&lt;br /&gt;
/usr/bin/distccd --pid-file /var/run/distccd/distccd.pid -N 15 --user distcc --port 3632 --log-level=debug --log-file=/var/log/distccd.log --allow my-sub-net/24&lt;br /&gt;
&lt;br /&gt;
==== localhost? =====&lt;br /&gt;
unclear if you need to use --allow for 127.0.0.1/32 or something to allow the remote preproccesor.&lt;br /&gt;
&lt;br /&gt;
== Kernel specific settings ==&lt;br /&gt;
&lt;br /&gt;
currently (distcc 3.4-r9 on Alpine) you need a patch to build the kernel.&lt;br /&gt;
See &lt;br /&gt;
&lt;br /&gt;
=== Include server Settings ===&lt;br /&gt;
&lt;br /&gt;
cache reset triggers&lt;br /&gt;
This ought to be set before enabling pump mode.&lt;br /&gt;
&lt;br /&gt;
export INCLUDE_SERVER_ARGS=&amp;quot;--stat_reset_triggers=include/linux/compile.h:include/asm/asm-offsets.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
link to explanation TBA&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Disabling GCC Plugins ===&lt;br /&gt;
&lt;br /&gt;
KConfig unselect HAVE_GCC_PLUGINS&lt;br /&gt;
&lt;br /&gt;
Some info is here in the troubleshooting part of the Arch Wiki&lt;br /&gt;
https://wiki.archlinux.org/title/Distcc#Troubleshooting&lt;br /&gt;
&lt;br /&gt;
=== Patches ===&lt;br /&gt;
&lt;br /&gt;
Other things (for 6.6LTS)&lt;br /&gt;
PCIe Stub patch&lt;br /&gt;
&lt;br /&gt;
=== Autoconf === &lt;br /&gt;
&lt;br /&gt;
No known setup examples&lt;br /&gt;
Add whatever it publishes in mdns&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== troubleshooting / analysis ==&lt;br /&gt;
&lt;br /&gt;
=== testing ===&lt;br /&gt;
&lt;br /&gt;
# turn off fallback DISTCC_FALLBACK=1&lt;br /&gt;
# set distcc up to point at specific system under test DISTCC_HOSTS=&amp;quot;mytestbox,cpp,lzo&amp;quot;&lt;br /&gt;
# GCC example compiles&lt;br /&gt;
## code example C&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example C++&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example ObjC&lt;br /&gt;
## same with included header&lt;br /&gt;
# Cmake example compiles&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docoument the thing with compile launcher ccache;distcc&lt;br /&gt;
there&#039;s some blog post, point to that&lt;br /&gt;
no ccache here yet&lt;br /&gt;
show $CC differences distcc vs gcc, what configure scripts see&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Latency ===&lt;br /&gt;
&lt;br /&gt;
Latency of pump mode startups and fallbacks needs to be investigated.&lt;br /&gt;
LZO is enforced even if you have faster network&lt;br /&gt;
DNS Requests, very old bug report from Gcode, one request per call, is it true? how to get rid of it?&lt;br /&gt;
TMPDIR is respected, make sure it&#039;s on ramdisk even on the remote nodes.&lt;br /&gt;
Compile ideally never goes to disk when it doesn&#039;t have to.&lt;br /&gt;
How efficient is the include server collection and unpacking?&lt;br /&gt;
&lt;br /&gt;
== security ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== tcpwrapper style ip range filter ===&lt;br /&gt;
&lt;br /&gt;
the original security model consists of ip restrictions.&lt;br /&gt;
there seems to also be some GSSAPI user auth.&lt;br /&gt;
further, commands that can be called are restricted by name and location.&lt;br /&gt;
this appears to be a runtime whitelist lookup, meaning it&#039;s done and authorized by the same parts of the daemon as processes the compile request along with the intended compiler.&lt;br /&gt;
so the main weaknesses against malicious clients seem to be in sending things to compile, and in overriding the remote compiler to use.&lt;br /&gt;
it can be assumed that a malicious client able to exploit the compiler handshake can then run arbitrary stuff.&lt;br /&gt;
There&#039;s at least a github issue regarding this google.com/search?q=distcc+seccomp&amp;amp;rlz=1C5CHFA_enDE1121DE1121&amp;amp;oq=distcc+seccomp&amp;amp;gs_lcrp=EgZjaHJvbWUyBggAEEUYOTIHCAEQIRigATIHCAIQIRigAdIBCDM1NjRqMGo3qAIAsAIA&amp;amp;sourceid=chrome&amp;amp;ie=UTF-8 suggesting running over ssh. That does only partitally alleviate this risk with regard  to a key based verfication of a client versus a the standard ip restrictions which always include some parsing.&lt;br /&gt;
So this protects against someone directly exploiting the TCP code of distcc.&lt;br /&gt;
It does not protect against malicious clients.&lt;br /&gt;
(ssh force command can&#039;t be used or you&#039;ll not compile anything)&lt;br /&gt;
&lt;br /&gt;
The basic step for protecting access should be filtering who can access the distcc server, so use nftables etc. to restrict access to port 3262 (??) set up the internal filter the same way.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== seccomp ===&lt;br /&gt;
&lt;br /&gt;
The next thing is to confine the compiler calls to only write in their temp directory and that they can only run compilers (using nsjail, apparmor, selinux etc)&lt;br /&gt;
&lt;br /&gt;
the above issue also references the second bit of security, namely a seccomp filter which will already cover a good bit of the above&lt;br /&gt;
https://github.com/distcc/distcc/pull/235&lt;br /&gt;
the commit got closed without merge, from what I see.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== privs ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The other internal security bit is that they do some priviledge dropping. it runs as a dedicated user (distcc), so you can also have an audit policy, and can/could use something like iptables&#039; to ensure it can only connect to the other distcc/memcached hosts, but nothing else.&lt;br /&gt;
&lt;br /&gt;
=== compiler list ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
One needs to investigate when compiler_whitelist.sh is exactly called. as far as I recall it doesn&#039;t close stdin/stdout.&lt;br /&gt;
&lt;br /&gt;
=== distcc-hardened ===&lt;br /&gt;
&lt;br /&gt;
Alpine adds some hardening patch, idk what nature/origina that has.&lt;br /&gt;
&lt;br /&gt;
=== selinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
there&#039;s also a selinux policy for distcc from gentoo or liguros if one is so inclined.&lt;br /&gt;
https://repology.org/project/selinux-distcc/versions&lt;br /&gt;
&lt;br /&gt;
=== general posture ===&lt;br /&gt;
&lt;br /&gt;
Some security measures like the above should definitely be used since the project has only a few part-time maintainers that cannot easily drive the project forward or do large refactors.&lt;br /&gt;
But the seccomp changes were done almost 10 years ago, so, to be fair, they still came through.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Arch wiki refers to a fork by SUSE&lt;br /&gt;
https://github.com/icecc/icecream&lt;br /&gt;
&lt;br /&gt;
It appears &#039;maybe better&#039; but hard to tell.&lt;/div&gt;</summary>
		<author><name>Darkfader</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32133</id>
		<title>User:Darkfader/distcc</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32133"/>
		<updated>2026-03-03T11:08:08Z</updated>

		<summary type="html">&lt;p&gt;Darkfader: /* goal */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi,&lt;br /&gt;
&lt;br /&gt;
I&#039;m preparing this page. It can take a long time till I finish.&lt;br /&gt;
If you are also wishing to write on this topic, feel free to integrate the content.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Document overview ==&lt;br /&gt;
&lt;br /&gt;
I noticed that almost every distro has one partially complete, partially helpful document on how to use distcc on the distro.&lt;br /&gt;
Usually they also have one for ccache.&lt;br /&gt;
In either case, they&#039;re enough to get started, but not really a reliable watertight thing.&lt;br /&gt;
We definitely needed one of our own.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== goal ===&lt;br /&gt;
&lt;br /&gt;
to describe a working setup for building aports in easiest/fastests fashion&lt;br /&gt;
not planning to add versatility or features where it would make the setup more errorprone.&lt;br /&gt;
the page should describe enough of the steps to successfully compile an LTS kernel via aports and have that job be distributed over multiple nodes.&lt;br /&gt;
Logs should be set up and able to display errors, but not show any errors during the test compile.&lt;br /&gt;
&lt;br /&gt;
To include a path for analysis via testing components.&lt;br /&gt;
&lt;br /&gt;
distcc can greatly improve compile speeds for large software, it comes with a different set of features than ccache; it focusses not avoiding unneccessary compile work, but on a way to speed up the necessary one.&lt;br /&gt;
&lt;br /&gt;
There&#039;s valuable info in the docs of other distros, it should be referenced here (i.e. the arch wiki troubleshooting).&lt;br /&gt;
&lt;br /&gt;
=== audience ===&lt;br /&gt;
people running software builds on alpine and have multiple computers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This page will show a specific installation, specific configuration, and specific tests, resulting in a specific set of functionality that can be tested to be working.&lt;br /&gt;
&lt;br /&gt;
== installation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Packages ===&lt;br /&gt;
&lt;br /&gt;
you need, on each host&lt;br /&gt;
* distcc&lt;br /&gt;
* distccd-openrc&lt;br /&gt;
* distcc-pump&lt;br /&gt;
* distcc-pump-pyc&lt;br /&gt;
&lt;br /&gt;
the .pyc will speed up the invocations, without it &lt;br /&gt;
idk if one or both should be installed in that case. but it appears to be also automatically be precompiled in /usr/lib/python3.12/site-packages/include_server/__pycache__/ so what does the package do exactly?&lt;br /&gt;
&lt;br /&gt;
There&#039;s some references to cpython-312, so maybe it actually still uses classy python-c conversion or matbe that&#039;s just a component for reading C source code. I have zero idea.&lt;br /&gt;
&lt;br /&gt;
you also need stuff to do compiles&lt;br /&gt;
* alpine sdk&lt;br /&gt;
* clang&lt;br /&gt;
* binutils&lt;br /&gt;
...&lt;br /&gt;
* elfutils(-dev)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Settings ===&lt;br /&gt;
==== settings for distcc ====&lt;br /&gt;
&lt;br /&gt;
* there&#039;s /etc/default/distcc&lt;br /&gt;
* there&#039;s /etc/conf.d/distcc &lt;br /&gt;
&lt;br /&gt;
make all your settings here&lt;br /&gt;
take care with the listen address, if you specify an IP it&#039;ll not be on 127.0.0.1 in case you would have localhost in your list...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* command_whitelist.sh &lt;br /&gt;
&lt;br /&gt;
this is half functional, you need to set things here but you also need to maintain the symlinks that are collected under /usr/lib/distcc (for your compilers) and /usr/lib/distcc/bin (for itself)&lt;br /&gt;
&lt;br /&gt;
you MUST run the script to update the compilers!&lt;br /&gt;
Info for script and what files it will create&lt;br /&gt;
&lt;br /&gt;
/usr/sbin/update-distcc-symlinks&lt;br /&gt;
&lt;br /&gt;
tschike:/usr/bin# ls -l /usr/lib/distcc/&lt;br /&gt;
total 4&lt;br /&gt;
drwxr-xr-x 2 root root 4096 Mar  2 18:14 bin&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c89 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c99 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 cc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc-15.2.0 -&amp;gt; ../../bin/distcc&lt;br /&gt;
&lt;br /&gt;
distcc itself is in bin&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cpp -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 g++ -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 06:49 x86_64-alpine-linux-musl-gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
&lt;br /&gt;
the last symplink here is wrong, made by me and would not work...&lt;br /&gt;
BAD symlink.&lt;br /&gt;
&lt;br /&gt;
=== distcc hosts file ===&lt;br /&gt;
&lt;br /&gt;
idk about that thing it&#039;s odd&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== abuild.conf ===&lt;br /&gt;
&lt;br /&gt;
settings for aports&lt;br /&gt;
* cc=&lt;br /&gt;
* cxx=&lt;br /&gt;
* cpp=&lt;br /&gt;
* cflags=&lt;br /&gt;
* njobs&lt;br /&gt;
&lt;br /&gt;
== detail infos ==&lt;br /&gt;
&lt;br /&gt;
???&lt;br /&gt;
&lt;br /&gt;
=== hosts syntax ===&lt;br /&gt;
&lt;br /&gt;
* myhost otherhost&lt;br /&gt;
* myhost,cpp,lzo myotherhost,cpp,lzo&lt;br /&gt;
&lt;br /&gt;
==== the host ====&lt;br /&gt;
&lt;br /&gt;
hostname/ip&lt;br /&gt;
localhost&lt;br /&gt;
127.0.0.1&lt;br /&gt;
::1 - does not work&lt;br /&gt;
&lt;br /&gt;
==== protocol ====&lt;br /&gt;
&lt;br /&gt;
* no protocol given&lt;br /&gt;
* ,cpp,lzo protocol&lt;br /&gt;
&lt;br /&gt;
cpp implies lzo, it requires compression, even if you have 10gbit/s or more, it&#039;s just hardcoded&lt;br /&gt;
&lt;br /&gt;
=== threads ===&lt;br /&gt;
/number of workers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== architecture ==&lt;br /&gt;
it can handle C, C++, ObjC, maybe some other stuff&lt;br /&gt;
&lt;br /&gt;
* what happens with normal xmit&lt;br /&gt;
* what happens with pump mode&lt;br /&gt;
* at which step the include server is used and how it collects the includes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== distribution algorithm ===&lt;br /&gt;
honestly I simply don&#039;t get it&lt;br /&gt;
&lt;br /&gt;
* The order matters&lt;br /&gt;
* The number of threads matters&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== localhost ====&lt;br /&gt;
&lt;br /&gt;
* localhost precedence&lt;br /&gt;
* localhost fallback&lt;br /&gt;
&lt;br /&gt;
variable: DISTCC_FALLBACK&lt;br /&gt;
&lt;br /&gt;
0 = Fail to compile if it would need to fallback to a normal local gcc call&lt;br /&gt;
1 = If remote compile fails, just do it yourself&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Operation ==&lt;br /&gt;
&lt;br /&gt;
=== startup and shutdown ===&lt;br /&gt;
service distcc stop is not entirely reliable (it can take a minute after the stop until the processes are gone and sometimes it will never stop&lt;br /&gt;
this is very bad with openrc, the openrc script returns after a second and only relies on its service flags, not the process status.&lt;br /&gt;
manually check after stopping, wait a min, if needed, kill it all.&lt;br /&gt;
at some point the rc file needs to be rewritten, it can&#039;t stay like it is.&lt;br /&gt;
&lt;br /&gt;
if you used a pump mode session, that also needs a logout (pump --shutdown)&lt;br /&gt;
avoid running multiple startups without shutdown in one session. it&#039;s safe as far as I can tell but nothing cleans up these processes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== ccache and memcached ===&lt;br /&gt;
CCACHE is said to be conflicting with pump mode unless when you call them in the backend&lt;br /&gt;
so, where you start the compile, you don&#039;t use it&lt;br /&gt;
where the compile happens, you use it&lt;br /&gt;
they can share the cache via memcached, this is a nice trick for consistency&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== dockerized / native ===&lt;br /&gt;
&lt;br /&gt;
it remains mostly the same, a container needs to make sure it monitors the right services (distccd, nginx, include_server)&lt;br /&gt;
if you&#039;re using zeroconf, you need to somehow expose the mdns service broadcasts &amp;amp; reception&lt;br /&gt;
&lt;br /&gt;
Processs list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
Workdir list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
=== alpine-chroot ===&lt;br /&gt;
&lt;br /&gt;
when using the &#039;official&#039; script there&#039;s still some odd pieces, seemed to be the processes died on logout. but not all of them.&lt;br /&gt;
&lt;br /&gt;
==== manual launch ====&lt;br /&gt;
&lt;br /&gt;
Starting the daemon would be using&lt;br /&gt;
/usr/bin/distccd --pid-file /var/run/distccd/distccd.pid -N 15 --user distcc --port 3632 --log-level=debug --log-file=/var/log/distccd.log --allow my-sub-net/24&lt;br /&gt;
&lt;br /&gt;
==== localhost? =====&lt;br /&gt;
unclear if you need to use --allow for 127.0.0.1/32 or something to allow the remote preproccesor.&lt;br /&gt;
&lt;br /&gt;
== Kernel specific settings ==&lt;br /&gt;
&lt;br /&gt;
currently (distcc 3.4-r9 on Alpine) you need a patch to build the kernel.&lt;br /&gt;
See &lt;br /&gt;
&lt;br /&gt;
=== Include server Settings ===&lt;br /&gt;
&lt;br /&gt;
cache reset triggers&lt;br /&gt;
This ought to be set before enabling pump mode.&lt;br /&gt;
&lt;br /&gt;
export INCLUDE_SERVER_ARGS=&amp;quot;--stat_reset_triggers=include/linux/compile.h:include/asm/asm-offsets.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
link to explanation TBA&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Disabling GCC Plugins ===&lt;br /&gt;
&lt;br /&gt;
KConfig unselect HAVE_GCC_PLUGINS&lt;br /&gt;
&lt;br /&gt;
Some info is here in the troubleshooting part of the Arch Wiki&lt;br /&gt;
https://wiki.archlinux.org/title/Distcc#Troubleshooting&lt;br /&gt;
&lt;br /&gt;
=== Patches ===&lt;br /&gt;
&lt;br /&gt;
Other things (for 6.6LTS)&lt;br /&gt;
PCIe Stub patch&lt;br /&gt;
&lt;br /&gt;
=== Autoconf === &lt;br /&gt;
&lt;br /&gt;
No known setup examples&lt;br /&gt;
Add whatever it publishes in mdns&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== troubleshooting / analysis ==&lt;br /&gt;
&lt;br /&gt;
=== testing ===&lt;br /&gt;
&lt;br /&gt;
# turn off fallback DISTCC_FALLBACK=1&lt;br /&gt;
# set distcc up to point at specific system under test DISTCC_HOSTS=&amp;quot;mytestbox,cpp,lzo&amp;quot;&lt;br /&gt;
# GCC example compiles&lt;br /&gt;
## code example C&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example C++&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example ObjC&lt;br /&gt;
## same with included header&lt;br /&gt;
# Cmake example compiles&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docoument the thing with compile launcher ccache;distcc&lt;br /&gt;
there&#039;s some blog post, point to that&lt;br /&gt;
no ccache here yet&lt;br /&gt;
show $CC differences distcc vs gcc, what configure scripts see&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Latency ===&lt;br /&gt;
&lt;br /&gt;
Latency of pump mode startups and fallbacks needs to be investigated.&lt;br /&gt;
LZO is enforced even if you have faster network&lt;br /&gt;
DNS Requests, very old bug report from Gcode, one request per call, is it true? how to get rid of it?&lt;br /&gt;
TMPDIR is respected, make sure it&#039;s on ramdisk even on the remote nodes.&lt;br /&gt;
Compile ideally never goes to disk when it doesn&#039;t have to.&lt;br /&gt;
How efficient is the include server collection and unpacking?&lt;br /&gt;
&lt;br /&gt;
== security ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== tcpwrapper style ip range filter ===&lt;br /&gt;
&lt;br /&gt;
the original security model consists of ip restrictions.&lt;br /&gt;
there seems to also be some GSSAPI user auth.&lt;br /&gt;
further, commands that can be called are restricted by name and location.&lt;br /&gt;
this appears to be a runtime whitelist lookup, meaning it&#039;s done and authorized by the same parts of the daemon as processes the compile request along with the intended compiler.&lt;br /&gt;
so the main weaknesses against malicious clients seem to be in sending things to compile, and in overriding the remote compiler to use.&lt;br /&gt;
it can be assumed that a malicious client able to exploit the compiler handshake can then run arbitrary stuff.&lt;br /&gt;
There&#039;s at least a github issue regarding this google.com/search?q=distcc+seccomp&amp;amp;rlz=1C5CHFA_enDE1121DE1121&amp;amp;oq=distcc+seccomp&amp;amp;gs_lcrp=EgZjaHJvbWUyBggAEEUYOTIHCAEQIRigATIHCAIQIRigAdIBCDM1NjRqMGo3qAIAsAIA&amp;amp;sourceid=chrome&amp;amp;ie=UTF-8 suggesting running over ssh. That does only partitally alleviate this risk with regard  to a key based verfication of a client versus a the standard ip restrictions which always include some parsing.&lt;br /&gt;
So this protects against someone directly exploiting the TCP code of distcc.&lt;br /&gt;
It does not protect against malicious clients.&lt;br /&gt;
(ssh force command can&#039;t be used or you&#039;ll not compile anything)&lt;br /&gt;
&lt;br /&gt;
The basic step for protecting access should be filtering who can access the distcc server, so use nftables etc. to restrict access to port 3262 (??) set up the internal filter the same way.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== seccomp ===&lt;br /&gt;
&lt;br /&gt;
The next thing is to confine the compiler calls to only write in their temp directory and that they can only run compilers (using nsjail, apparmor, selinux etc)&lt;br /&gt;
&lt;br /&gt;
the above issue also references the second bit of security, namely a seccomp filter which will already cover a good bit of the above&lt;br /&gt;
https://github.com/distcc/distcc/pull/235&lt;br /&gt;
the commit got closed without merge, from what I see.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== privs ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The other internal security bit is that they do some priviledge dropping. it runs as a dedicated user (distcc), so you can also have an audit policy, and can/could use something like iptables&#039; to ensure it can only connect to the other distcc/memcached hosts, but nothing else.&lt;br /&gt;
&lt;br /&gt;
=== compiler list ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
One needs to investigate when compiler_whitelist.sh is exactly called. as far as I recall it doesn&#039;t close stdin/stdout.&lt;br /&gt;
&lt;br /&gt;
=== distcc-hardened ===&lt;br /&gt;
&lt;br /&gt;
Alpine adds some hardening patch, idk what nature/origina that has.&lt;br /&gt;
&lt;br /&gt;
=== selinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
there&#039;s also a selinux policy for distcc from gentoo or liguros if one is so inclined.&lt;br /&gt;
https://repology.org/project/selinux-distcc/versions&lt;br /&gt;
&lt;br /&gt;
=== general posture ===&lt;br /&gt;
&lt;br /&gt;
Some security measures like the above should definitely be used since the project has only a few part-time maintainers that cannot easily drive the project forward or do large refactors.&lt;br /&gt;
But the seccomp changes were done almost 10 years ago, so, to be fair, they still came through.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Arch wiki refers to a fork by SUSE&lt;br /&gt;
https://github.com/icecc/icecream&lt;br /&gt;
&lt;br /&gt;
It appears &#039;maybe better&#039; but hard to tell.&lt;/div&gt;</summary>
		<author><name>Darkfader</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32132</id>
		<title>User:Darkfader/distcc</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32132"/>
		<updated>2026-03-03T11:07:13Z</updated>

		<summary type="html">&lt;p&gt;Darkfader: /* general posture */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi,&lt;br /&gt;
&lt;br /&gt;
I&#039;m preparing this page. It can take a long time till I finish.&lt;br /&gt;
If you are also wishing to write on this topic, feel free to integrate the content.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Document overview ==&lt;br /&gt;
&lt;br /&gt;
I noticed that almost every distro has one partially complete, partially helpful document on how to use distcc on the distro.&lt;br /&gt;
Usually they also have one for ccache.&lt;br /&gt;
In either case, they&#039;re enough to get started, but not really a reliable watertight thing.&lt;br /&gt;
We definitely needed one of our own.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== goal ===&lt;br /&gt;
&lt;br /&gt;
to describe a working setup for building aports in easiest/fastests fashion&lt;br /&gt;
not planning to add versatility or features where it would make the setup more errorprone.&lt;br /&gt;
the page should describe enough of the steps to successfully compile an LTS kernel via aports and have that job be distributed over multiple nodes.&lt;br /&gt;
Logs should be set up and able to display errors, but not show any errors during the test compile.&lt;br /&gt;
&lt;br /&gt;
To include a path for analysis via testing components.&lt;br /&gt;
&lt;br /&gt;
distcc can greatly improve compile speeds for large software, it comes with a different set of features than ccache; it focusses not avoiding unneccessary compile work, but on a way to speed up the necessary one.&lt;br /&gt;
&lt;br /&gt;
=== audience ===&lt;br /&gt;
people running software builds on alpine and have multiple computers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This page will show a specific installation, specific configuration, and specific tests, resulting in a specific set of functionality that can be tested to be working.&lt;br /&gt;
&lt;br /&gt;
== installation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Packages ===&lt;br /&gt;
&lt;br /&gt;
you need, on each host&lt;br /&gt;
* distcc&lt;br /&gt;
* distccd-openrc&lt;br /&gt;
* distcc-pump&lt;br /&gt;
* distcc-pump-pyc&lt;br /&gt;
&lt;br /&gt;
the .pyc will speed up the invocations, without it &lt;br /&gt;
idk if one or both should be installed in that case. but it appears to be also automatically be precompiled in /usr/lib/python3.12/site-packages/include_server/__pycache__/ so what does the package do exactly?&lt;br /&gt;
&lt;br /&gt;
There&#039;s some references to cpython-312, so maybe it actually still uses classy python-c conversion or matbe that&#039;s just a component for reading C source code. I have zero idea.&lt;br /&gt;
&lt;br /&gt;
you also need stuff to do compiles&lt;br /&gt;
* alpine sdk&lt;br /&gt;
* clang&lt;br /&gt;
* binutils&lt;br /&gt;
...&lt;br /&gt;
* elfutils(-dev)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Settings ===&lt;br /&gt;
==== settings for distcc ====&lt;br /&gt;
&lt;br /&gt;
* there&#039;s /etc/default/distcc&lt;br /&gt;
* there&#039;s /etc/conf.d/distcc &lt;br /&gt;
&lt;br /&gt;
make all your settings here&lt;br /&gt;
take care with the listen address, if you specify an IP it&#039;ll not be on 127.0.0.1 in case you would have localhost in your list...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* command_whitelist.sh &lt;br /&gt;
&lt;br /&gt;
this is half functional, you need to set things here but you also need to maintain the symlinks that are collected under /usr/lib/distcc (for your compilers) and /usr/lib/distcc/bin (for itself)&lt;br /&gt;
&lt;br /&gt;
you MUST run the script to update the compilers!&lt;br /&gt;
Info for script and what files it will create&lt;br /&gt;
&lt;br /&gt;
/usr/sbin/update-distcc-symlinks&lt;br /&gt;
&lt;br /&gt;
tschike:/usr/bin# ls -l /usr/lib/distcc/&lt;br /&gt;
total 4&lt;br /&gt;
drwxr-xr-x 2 root root 4096 Mar  2 18:14 bin&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c89 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c99 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 cc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc-15.2.0 -&amp;gt; ../../bin/distcc&lt;br /&gt;
&lt;br /&gt;
distcc itself is in bin&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cpp -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 g++ -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 06:49 x86_64-alpine-linux-musl-gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
&lt;br /&gt;
the last symplink here is wrong, made by me and would not work...&lt;br /&gt;
BAD symlink.&lt;br /&gt;
&lt;br /&gt;
=== distcc hosts file ===&lt;br /&gt;
&lt;br /&gt;
idk about that thing it&#039;s odd&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== abuild.conf ===&lt;br /&gt;
&lt;br /&gt;
settings for aports&lt;br /&gt;
* cc=&lt;br /&gt;
* cxx=&lt;br /&gt;
* cpp=&lt;br /&gt;
* cflags=&lt;br /&gt;
* njobs&lt;br /&gt;
&lt;br /&gt;
== detail infos ==&lt;br /&gt;
&lt;br /&gt;
???&lt;br /&gt;
&lt;br /&gt;
=== hosts syntax ===&lt;br /&gt;
&lt;br /&gt;
* myhost otherhost&lt;br /&gt;
* myhost,cpp,lzo myotherhost,cpp,lzo&lt;br /&gt;
&lt;br /&gt;
==== the host ====&lt;br /&gt;
&lt;br /&gt;
hostname/ip&lt;br /&gt;
localhost&lt;br /&gt;
127.0.0.1&lt;br /&gt;
::1 - does not work&lt;br /&gt;
&lt;br /&gt;
==== protocol ====&lt;br /&gt;
&lt;br /&gt;
* no protocol given&lt;br /&gt;
* ,cpp,lzo protocol&lt;br /&gt;
&lt;br /&gt;
cpp implies lzo, it requires compression, even if you have 10gbit/s or more, it&#039;s just hardcoded&lt;br /&gt;
&lt;br /&gt;
=== threads ===&lt;br /&gt;
/number of workers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== architecture ==&lt;br /&gt;
it can handle C, C++, ObjC, maybe some other stuff&lt;br /&gt;
&lt;br /&gt;
* what happens with normal xmit&lt;br /&gt;
* what happens with pump mode&lt;br /&gt;
* at which step the include server is used and how it collects the includes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== distribution algorithm ===&lt;br /&gt;
honestly I simply don&#039;t get it&lt;br /&gt;
&lt;br /&gt;
* The order matters&lt;br /&gt;
* The number of threads matters&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== localhost ====&lt;br /&gt;
&lt;br /&gt;
* localhost precedence&lt;br /&gt;
* localhost fallback&lt;br /&gt;
&lt;br /&gt;
variable: DISTCC_FALLBACK&lt;br /&gt;
&lt;br /&gt;
0 = Fail to compile if it would need to fallback to a normal local gcc call&lt;br /&gt;
1 = If remote compile fails, just do it yourself&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Operation ==&lt;br /&gt;
&lt;br /&gt;
=== startup and shutdown ===&lt;br /&gt;
service distcc stop is not entirely reliable (it can take a minute after the stop until the processes are gone and sometimes it will never stop&lt;br /&gt;
this is very bad with openrc, the openrc script returns after a second and only relies on its service flags, not the process status.&lt;br /&gt;
manually check after stopping, wait a min, if needed, kill it all.&lt;br /&gt;
at some point the rc file needs to be rewritten, it can&#039;t stay like it is.&lt;br /&gt;
&lt;br /&gt;
if you used a pump mode session, that also needs a logout (pump --shutdown)&lt;br /&gt;
avoid running multiple startups without shutdown in one session. it&#039;s safe as far as I can tell but nothing cleans up these processes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== ccache and memcached ===&lt;br /&gt;
CCACHE is said to be conflicting with pump mode unless when you call them in the backend&lt;br /&gt;
so, where you start the compile, you don&#039;t use it&lt;br /&gt;
where the compile happens, you use it&lt;br /&gt;
they can share the cache via memcached, this is a nice trick for consistency&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== dockerized / native ===&lt;br /&gt;
&lt;br /&gt;
it remains mostly the same, a container needs to make sure it monitors the right services (distccd, nginx, include_server)&lt;br /&gt;
if you&#039;re using zeroconf, you need to somehow expose the mdns service broadcasts &amp;amp; reception&lt;br /&gt;
&lt;br /&gt;
Processs list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
Workdir list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
=== alpine-chroot ===&lt;br /&gt;
&lt;br /&gt;
when using the &#039;official&#039; script there&#039;s still some odd pieces, seemed to be the processes died on logout. but not all of them.&lt;br /&gt;
&lt;br /&gt;
==== manual launch ====&lt;br /&gt;
&lt;br /&gt;
Starting the daemon would be using&lt;br /&gt;
/usr/bin/distccd --pid-file /var/run/distccd/distccd.pid -N 15 --user distcc --port 3632 --log-level=debug --log-file=/var/log/distccd.log --allow my-sub-net/24&lt;br /&gt;
&lt;br /&gt;
==== localhost? =====&lt;br /&gt;
unclear if you need to use --allow for 127.0.0.1/32 or something to allow the remote preproccesor.&lt;br /&gt;
&lt;br /&gt;
== Kernel specific settings ==&lt;br /&gt;
&lt;br /&gt;
currently (distcc 3.4-r9 on Alpine) you need a patch to build the kernel.&lt;br /&gt;
See &lt;br /&gt;
&lt;br /&gt;
=== Include server Settings ===&lt;br /&gt;
&lt;br /&gt;
cache reset triggers&lt;br /&gt;
This ought to be set before enabling pump mode.&lt;br /&gt;
&lt;br /&gt;
export INCLUDE_SERVER_ARGS=&amp;quot;--stat_reset_triggers=include/linux/compile.h:include/asm/asm-offsets.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
link to explanation TBA&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Disabling GCC Plugins ===&lt;br /&gt;
&lt;br /&gt;
KConfig unselect HAVE_GCC_PLUGINS&lt;br /&gt;
&lt;br /&gt;
Some info is here in the troubleshooting part of the Arch Wiki&lt;br /&gt;
https://wiki.archlinux.org/title/Distcc#Troubleshooting&lt;br /&gt;
&lt;br /&gt;
=== Patches ===&lt;br /&gt;
&lt;br /&gt;
Other things (for 6.6LTS)&lt;br /&gt;
PCIe Stub patch&lt;br /&gt;
&lt;br /&gt;
=== Autoconf === &lt;br /&gt;
&lt;br /&gt;
No known setup examples&lt;br /&gt;
Add whatever it publishes in mdns&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== troubleshooting / analysis ==&lt;br /&gt;
&lt;br /&gt;
=== testing ===&lt;br /&gt;
&lt;br /&gt;
# turn off fallback DISTCC_FALLBACK=1&lt;br /&gt;
# set distcc up to point at specific system under test DISTCC_HOSTS=&amp;quot;mytestbox,cpp,lzo&amp;quot;&lt;br /&gt;
# GCC example compiles&lt;br /&gt;
## code example C&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example C++&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example ObjC&lt;br /&gt;
## same with included header&lt;br /&gt;
# Cmake example compiles&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docoument the thing with compile launcher ccache;distcc&lt;br /&gt;
there&#039;s some blog post, point to that&lt;br /&gt;
no ccache here yet&lt;br /&gt;
show $CC differences distcc vs gcc, what configure scripts see&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Latency ===&lt;br /&gt;
&lt;br /&gt;
Latency of pump mode startups and fallbacks needs to be investigated.&lt;br /&gt;
LZO is enforced even if you have faster network&lt;br /&gt;
DNS Requests, very old bug report from Gcode, one request per call, is it true? how to get rid of it?&lt;br /&gt;
TMPDIR is respected, make sure it&#039;s on ramdisk even on the remote nodes.&lt;br /&gt;
Compile ideally never goes to disk when it doesn&#039;t have to.&lt;br /&gt;
How efficient is the include server collection and unpacking?&lt;br /&gt;
&lt;br /&gt;
== security ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== tcpwrapper style ip range filter ===&lt;br /&gt;
&lt;br /&gt;
the original security model consists of ip restrictions.&lt;br /&gt;
there seems to also be some GSSAPI user auth.&lt;br /&gt;
further, commands that can be called are restricted by name and location.&lt;br /&gt;
this appears to be a runtime whitelist lookup, meaning it&#039;s done and authorized by the same parts of the daemon as processes the compile request along with the intended compiler.&lt;br /&gt;
so the main weaknesses against malicious clients seem to be in sending things to compile, and in overriding the remote compiler to use.&lt;br /&gt;
it can be assumed that a malicious client able to exploit the compiler handshake can then run arbitrary stuff.&lt;br /&gt;
There&#039;s at least a github issue regarding this google.com/search?q=distcc+seccomp&amp;amp;rlz=1C5CHFA_enDE1121DE1121&amp;amp;oq=distcc+seccomp&amp;amp;gs_lcrp=EgZjaHJvbWUyBggAEEUYOTIHCAEQIRigATIHCAIQIRigAdIBCDM1NjRqMGo3qAIAsAIA&amp;amp;sourceid=chrome&amp;amp;ie=UTF-8 suggesting running over ssh. That does only partitally alleviate this risk with regard  to a key based verfication of a client versus a the standard ip restrictions which always include some parsing.&lt;br /&gt;
So this protects against someone directly exploiting the TCP code of distcc.&lt;br /&gt;
It does not protect against malicious clients.&lt;br /&gt;
(ssh force command can&#039;t be used or you&#039;ll not compile anything)&lt;br /&gt;
&lt;br /&gt;
The basic step for protecting access should be filtering who can access the distcc server, so use nftables etc. to restrict access to port 3262 (??) set up the internal filter the same way.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== seccomp ===&lt;br /&gt;
&lt;br /&gt;
The next thing is to confine the compiler calls to only write in their temp directory and that they can only run compilers (using nsjail, apparmor, selinux etc)&lt;br /&gt;
&lt;br /&gt;
the above issue also references the second bit of security, namely a seccomp filter which will already cover a good bit of the above&lt;br /&gt;
https://github.com/distcc/distcc/pull/235&lt;br /&gt;
the commit got closed without merge, from what I see.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== privs ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The other internal security bit is that they do some priviledge dropping. it runs as a dedicated user (distcc), so you can also have an audit policy, and can/could use something like iptables&#039; to ensure it can only connect to the other distcc/memcached hosts, but nothing else.&lt;br /&gt;
&lt;br /&gt;
=== compiler list ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
One needs to investigate when compiler_whitelist.sh is exactly called. as far as I recall it doesn&#039;t close stdin/stdout.&lt;br /&gt;
&lt;br /&gt;
=== distcc-hardened ===&lt;br /&gt;
&lt;br /&gt;
Alpine adds some hardening patch, idk what nature/origina that has.&lt;br /&gt;
&lt;br /&gt;
=== selinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
there&#039;s also a selinux policy for distcc from gentoo or liguros if one is so inclined.&lt;br /&gt;
https://repology.org/project/selinux-distcc/versions&lt;br /&gt;
&lt;br /&gt;
=== general posture ===&lt;br /&gt;
&lt;br /&gt;
Some security measures like the above should definitely be used since the project has only a few part-time maintainers that cannot easily drive the project forward or do large refactors.&lt;br /&gt;
But the seccomp changes were done almost 10 years ago, so, to be fair, they still came through.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Arch wiki refers to a fork by SUSE&lt;br /&gt;
https://github.com/icecc/icecream&lt;br /&gt;
&lt;br /&gt;
It appears &#039;maybe better&#039; but hard to tell.&lt;/div&gt;</summary>
		<author><name>Darkfader</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32131</id>
		<title>User:Darkfader/distcc</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32131"/>
		<updated>2026-03-03T11:04:53Z</updated>

		<summary type="html">&lt;p&gt;Darkfader: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi,&lt;br /&gt;
&lt;br /&gt;
I&#039;m preparing this page. It can take a long time till I finish.&lt;br /&gt;
If you are also wishing to write on this topic, feel free to integrate the content.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Document overview ==&lt;br /&gt;
&lt;br /&gt;
I noticed that almost every distro has one partially complete, partially helpful document on how to use distcc on the distro.&lt;br /&gt;
Usually they also have one for ccache.&lt;br /&gt;
In either case, they&#039;re enough to get started, but not really a reliable watertight thing.&lt;br /&gt;
We definitely needed one of our own.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== goal ===&lt;br /&gt;
&lt;br /&gt;
to describe a working setup for building aports in easiest/fastests fashion&lt;br /&gt;
not planning to add versatility or features where it would make the setup more errorprone.&lt;br /&gt;
the page should describe enough of the steps to successfully compile an LTS kernel via aports and have that job be distributed over multiple nodes.&lt;br /&gt;
Logs should be set up and able to display errors, but not show any errors during the test compile.&lt;br /&gt;
&lt;br /&gt;
To include a path for analysis via testing components.&lt;br /&gt;
&lt;br /&gt;
distcc can greatly improve compile speeds for large software, it comes with a different set of features than ccache; it focusses not avoiding unneccessary compile work, but on a way to speed up the necessary one.&lt;br /&gt;
&lt;br /&gt;
=== audience ===&lt;br /&gt;
people running software builds on alpine and have multiple computers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This page will show a specific installation, specific configuration, and specific tests, resulting in a specific set of functionality that can be tested to be working.&lt;br /&gt;
&lt;br /&gt;
== installation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Packages ===&lt;br /&gt;
&lt;br /&gt;
you need, on each host&lt;br /&gt;
* distcc&lt;br /&gt;
* distccd-openrc&lt;br /&gt;
* distcc-pump&lt;br /&gt;
* distcc-pump-pyc&lt;br /&gt;
&lt;br /&gt;
the .pyc will speed up the invocations, without it &lt;br /&gt;
idk if one or both should be installed in that case. but it appears to be also automatically be precompiled in /usr/lib/python3.12/site-packages/include_server/__pycache__/ so what does the package do exactly?&lt;br /&gt;
&lt;br /&gt;
There&#039;s some references to cpython-312, so maybe it actually still uses classy python-c conversion or matbe that&#039;s just a component for reading C source code. I have zero idea.&lt;br /&gt;
&lt;br /&gt;
you also need stuff to do compiles&lt;br /&gt;
* alpine sdk&lt;br /&gt;
* clang&lt;br /&gt;
* binutils&lt;br /&gt;
...&lt;br /&gt;
* elfutils(-dev)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Settings ===&lt;br /&gt;
==== settings for distcc ====&lt;br /&gt;
&lt;br /&gt;
* there&#039;s /etc/default/distcc&lt;br /&gt;
* there&#039;s /etc/conf.d/distcc &lt;br /&gt;
&lt;br /&gt;
make all your settings here&lt;br /&gt;
take care with the listen address, if you specify an IP it&#039;ll not be on 127.0.0.1 in case you would have localhost in your list...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* command_whitelist.sh &lt;br /&gt;
&lt;br /&gt;
this is half functional, you need to set things here but you also need to maintain the symlinks that are collected under /usr/lib/distcc (for your compilers) and /usr/lib/distcc/bin (for itself)&lt;br /&gt;
&lt;br /&gt;
you MUST run the script to update the compilers!&lt;br /&gt;
Info for script and what files it will create&lt;br /&gt;
&lt;br /&gt;
/usr/sbin/update-distcc-symlinks&lt;br /&gt;
&lt;br /&gt;
tschike:/usr/bin# ls -l /usr/lib/distcc/&lt;br /&gt;
total 4&lt;br /&gt;
drwxr-xr-x 2 root root 4096 Mar  2 18:14 bin&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c89 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c99 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 cc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc-15.2.0 -&amp;gt; ../../bin/distcc&lt;br /&gt;
&lt;br /&gt;
distcc itself is in bin&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cpp -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 g++ -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 06:49 x86_64-alpine-linux-musl-gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
&lt;br /&gt;
the last symplink here is wrong, made by me and would not work...&lt;br /&gt;
BAD symlink.&lt;br /&gt;
&lt;br /&gt;
=== distcc hosts file ===&lt;br /&gt;
&lt;br /&gt;
idk about that thing it&#039;s odd&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== abuild.conf ===&lt;br /&gt;
&lt;br /&gt;
settings for aports&lt;br /&gt;
* cc=&lt;br /&gt;
* cxx=&lt;br /&gt;
* cpp=&lt;br /&gt;
* cflags=&lt;br /&gt;
* njobs&lt;br /&gt;
&lt;br /&gt;
== detail infos ==&lt;br /&gt;
&lt;br /&gt;
???&lt;br /&gt;
&lt;br /&gt;
=== hosts syntax ===&lt;br /&gt;
&lt;br /&gt;
* myhost otherhost&lt;br /&gt;
* myhost,cpp,lzo myotherhost,cpp,lzo&lt;br /&gt;
&lt;br /&gt;
==== the host ====&lt;br /&gt;
&lt;br /&gt;
hostname/ip&lt;br /&gt;
localhost&lt;br /&gt;
127.0.0.1&lt;br /&gt;
::1 - does not work&lt;br /&gt;
&lt;br /&gt;
==== protocol ====&lt;br /&gt;
&lt;br /&gt;
* no protocol given&lt;br /&gt;
* ,cpp,lzo protocol&lt;br /&gt;
&lt;br /&gt;
cpp implies lzo, it requires compression, even if you have 10gbit/s or more, it&#039;s just hardcoded&lt;br /&gt;
&lt;br /&gt;
=== threads ===&lt;br /&gt;
/number of workers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== architecture ==&lt;br /&gt;
it can handle C, C++, ObjC, maybe some other stuff&lt;br /&gt;
&lt;br /&gt;
* what happens with normal xmit&lt;br /&gt;
* what happens with pump mode&lt;br /&gt;
* at which step the include server is used and how it collects the includes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== distribution algorithm ===&lt;br /&gt;
honestly I simply don&#039;t get it&lt;br /&gt;
&lt;br /&gt;
* The order matters&lt;br /&gt;
* The number of threads matters&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== localhost ====&lt;br /&gt;
&lt;br /&gt;
* localhost precedence&lt;br /&gt;
* localhost fallback&lt;br /&gt;
&lt;br /&gt;
variable: DISTCC_FALLBACK&lt;br /&gt;
&lt;br /&gt;
0 = Fail to compile if it would need to fallback to a normal local gcc call&lt;br /&gt;
1 = If remote compile fails, just do it yourself&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Operation ==&lt;br /&gt;
&lt;br /&gt;
=== startup and shutdown ===&lt;br /&gt;
service distcc stop is not entirely reliable (it can take a minute after the stop until the processes are gone and sometimes it will never stop&lt;br /&gt;
this is very bad with openrc, the openrc script returns after a second and only relies on its service flags, not the process status.&lt;br /&gt;
manually check after stopping, wait a min, if needed, kill it all.&lt;br /&gt;
at some point the rc file needs to be rewritten, it can&#039;t stay like it is.&lt;br /&gt;
&lt;br /&gt;
if you used a pump mode session, that also needs a logout (pump --shutdown)&lt;br /&gt;
avoid running multiple startups without shutdown in one session. it&#039;s safe as far as I can tell but nothing cleans up these processes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== ccache and memcached ===&lt;br /&gt;
CCACHE is said to be conflicting with pump mode unless when you call them in the backend&lt;br /&gt;
so, where you start the compile, you don&#039;t use it&lt;br /&gt;
where the compile happens, you use it&lt;br /&gt;
they can share the cache via memcached, this is a nice trick for consistency&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== dockerized / native ===&lt;br /&gt;
&lt;br /&gt;
it remains mostly the same, a container needs to make sure it monitors the right services (distccd, nginx, include_server)&lt;br /&gt;
if you&#039;re using zeroconf, you need to somehow expose the mdns service broadcasts &amp;amp; reception&lt;br /&gt;
&lt;br /&gt;
Processs list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
Workdir list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
=== alpine-chroot ===&lt;br /&gt;
&lt;br /&gt;
when using the &#039;official&#039; script there&#039;s still some odd pieces, seemed to be the processes died on logout. but not all of them.&lt;br /&gt;
&lt;br /&gt;
==== manual launch ====&lt;br /&gt;
&lt;br /&gt;
Starting the daemon would be using&lt;br /&gt;
/usr/bin/distccd --pid-file /var/run/distccd/distccd.pid -N 15 --user distcc --port 3632 --log-level=debug --log-file=/var/log/distccd.log --allow my-sub-net/24&lt;br /&gt;
&lt;br /&gt;
==== localhost? =====&lt;br /&gt;
unclear if you need to use --allow for 127.0.0.1/32 or something to allow the remote preproccesor.&lt;br /&gt;
&lt;br /&gt;
== Kernel specific settings ==&lt;br /&gt;
&lt;br /&gt;
currently (distcc 3.4-r9 on Alpine) you need a patch to build the kernel.&lt;br /&gt;
See &lt;br /&gt;
&lt;br /&gt;
=== Include server Settings ===&lt;br /&gt;
&lt;br /&gt;
cache reset triggers&lt;br /&gt;
This ought to be set before enabling pump mode.&lt;br /&gt;
&lt;br /&gt;
export INCLUDE_SERVER_ARGS=&amp;quot;--stat_reset_triggers=include/linux/compile.h:include/asm/asm-offsets.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
link to explanation TBA&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Disabling GCC Plugins ===&lt;br /&gt;
&lt;br /&gt;
KConfig unselect HAVE_GCC_PLUGINS&lt;br /&gt;
&lt;br /&gt;
Some info is here in the troubleshooting part of the Arch Wiki&lt;br /&gt;
https://wiki.archlinux.org/title/Distcc#Troubleshooting&lt;br /&gt;
&lt;br /&gt;
=== Patches ===&lt;br /&gt;
&lt;br /&gt;
Other things (for 6.6LTS)&lt;br /&gt;
PCIe Stub patch&lt;br /&gt;
&lt;br /&gt;
=== Autoconf === &lt;br /&gt;
&lt;br /&gt;
No known setup examples&lt;br /&gt;
Add whatever it publishes in mdns&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== troubleshooting / analysis ==&lt;br /&gt;
&lt;br /&gt;
=== testing ===&lt;br /&gt;
&lt;br /&gt;
# turn off fallback DISTCC_FALLBACK=1&lt;br /&gt;
# set distcc up to point at specific system under test DISTCC_HOSTS=&amp;quot;mytestbox,cpp,lzo&amp;quot;&lt;br /&gt;
# GCC example compiles&lt;br /&gt;
## code example C&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example C++&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example ObjC&lt;br /&gt;
## same with included header&lt;br /&gt;
# Cmake example compiles&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docoument the thing with compile launcher ccache;distcc&lt;br /&gt;
there&#039;s some blog post, point to that&lt;br /&gt;
no ccache here yet&lt;br /&gt;
show $CC differences distcc vs gcc, what configure scripts see&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Latency ===&lt;br /&gt;
&lt;br /&gt;
Latency of pump mode startups and fallbacks needs to be investigated.&lt;br /&gt;
LZO is enforced even if you have faster network&lt;br /&gt;
DNS Requests, very old bug report from Gcode, one request per call, is it true? how to get rid of it?&lt;br /&gt;
TMPDIR is respected, make sure it&#039;s on ramdisk even on the remote nodes.&lt;br /&gt;
Compile ideally never goes to disk when it doesn&#039;t have to.&lt;br /&gt;
How efficient is the include server collection and unpacking?&lt;br /&gt;
&lt;br /&gt;
== security ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== tcpwrapper style ip range filter ===&lt;br /&gt;
&lt;br /&gt;
the original security model consists of ip restrictions.&lt;br /&gt;
there seems to also be some GSSAPI user auth.&lt;br /&gt;
further, commands that can be called are restricted by name and location.&lt;br /&gt;
this appears to be a runtime whitelist lookup, meaning it&#039;s done and authorized by the same parts of the daemon as processes the compile request along with the intended compiler.&lt;br /&gt;
so the main weaknesses against malicious clients seem to be in sending things to compile, and in overriding the remote compiler to use.&lt;br /&gt;
it can be assumed that a malicious client able to exploit the compiler handshake can then run arbitrary stuff.&lt;br /&gt;
There&#039;s at least a github issue regarding this google.com/search?q=distcc+seccomp&amp;amp;rlz=1C5CHFA_enDE1121DE1121&amp;amp;oq=distcc+seccomp&amp;amp;gs_lcrp=EgZjaHJvbWUyBggAEEUYOTIHCAEQIRigATIHCAIQIRigAdIBCDM1NjRqMGo3qAIAsAIA&amp;amp;sourceid=chrome&amp;amp;ie=UTF-8 suggesting running over ssh. That does only partitally alleviate this risk with regard  to a key based verfication of a client versus a the standard ip restrictions which always include some parsing.&lt;br /&gt;
So this protects against someone directly exploiting the TCP code of distcc.&lt;br /&gt;
It does not protect against malicious clients.&lt;br /&gt;
(ssh force command can&#039;t be used or you&#039;ll not compile anything)&lt;br /&gt;
&lt;br /&gt;
The basic step for protecting access should be filtering who can access the distcc server, so use nftables etc. to restrict access to port 3262 (??) set up the internal filter the same way.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== seccomp ===&lt;br /&gt;
&lt;br /&gt;
The next thing is to confine the compiler calls to only write in their temp directory and that they can only run compilers (using nsjail, apparmor, selinux etc)&lt;br /&gt;
&lt;br /&gt;
the above issue also references the second bit of security, namely a seccomp filter which will already cover a good bit of the above&lt;br /&gt;
https://github.com/distcc/distcc/pull/235&lt;br /&gt;
the commit got closed without merge, from what I see.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== privs ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The other internal security bit is that they do some priviledge dropping. it runs as a dedicated user (distcc), so you can also have an audit policy, and can/could use something like iptables&#039; to ensure it can only connect to the other distcc/memcached hosts, but nothing else.&lt;br /&gt;
&lt;br /&gt;
=== compiler list ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
One needs to investigate when compiler_whitelist.sh is exactly called. as far as I recall it doesn&#039;t close stdin/stdout.&lt;br /&gt;
&lt;br /&gt;
=== distcc-hardened ===&lt;br /&gt;
&lt;br /&gt;
Alpine adds some hardening patch, idk what nature/origina that has.&lt;br /&gt;
&lt;br /&gt;
=== selinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
there&#039;s also a selinux policy for distcc from gentoo or liguros if one is so inclined.&lt;br /&gt;
https://repology.org/project/selinux-distcc/versions&lt;br /&gt;
&lt;br /&gt;
=== general posture ===&lt;br /&gt;
&lt;br /&gt;
Some security measures like the above should definitely be used since the project has only a few part-time maintainers that cannot easily drive the project forward or do large refactors.&lt;br /&gt;
But the seccomp changes were done almost 10 years ago, so, to be fair, they still came through.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Arch wiki refers to a fork by SUSE&lt;br /&gt;
https://github.com/icecc/icecream&lt;/div&gt;</summary>
		<author><name>Darkfader</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32130</id>
		<title>User:Darkfader/distcc</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32130"/>
		<updated>2026-03-03T11:03:03Z</updated>

		<summary type="html">&lt;p&gt;Darkfader: /* troubleshooting / analysis */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi,&lt;br /&gt;
&lt;br /&gt;
I&#039;m preparing this page. It can take a long time till I finish.&lt;br /&gt;
If you are also wishing to write on this topic, feel free to integrate the content.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Document overview ==&lt;br /&gt;
&lt;br /&gt;
I noticed that almost every distro has one partially complete, partially helpful document on how to use distcc on the distro.&lt;br /&gt;
Usually they also have one for ccache.&lt;br /&gt;
In either case, they&#039;re enough to get started, but not really a reliable watertight thing.&lt;br /&gt;
We definitely needed one of our own.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== goal ===&lt;br /&gt;
&lt;br /&gt;
to describe a working setup for building aports in easiest/fastests fashion&lt;br /&gt;
not planning to add versatility or features where it would make the setup more errorprone.&lt;br /&gt;
the page should describe enough of the steps to successfully compile an LTS kernel via aports and have that job be distributed over multiple nodes.&lt;br /&gt;
Logs should be set up and able to display errors, but not show any errors during the test compile.&lt;br /&gt;
&lt;br /&gt;
To include a path for analysis via testing components.&lt;br /&gt;
&lt;br /&gt;
distcc can greatly improve compile speeds for large software, it comes with a different set of features than ccache; it focusses not avoiding unneccessary compile work, but on a way to speed up the necessary one.&lt;br /&gt;
&lt;br /&gt;
=== audience ===&lt;br /&gt;
people running software builds on alpine and have multiple computers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This page will show a specific installation, specific configuration, and specific tests, resulting in a specific set of functionality that can be tested to be working.&lt;br /&gt;
&lt;br /&gt;
== installation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Packages ===&lt;br /&gt;
&lt;br /&gt;
you need, on each host&lt;br /&gt;
* distcc&lt;br /&gt;
* distccd-openrc&lt;br /&gt;
* distcc-pump&lt;br /&gt;
* distcc-pump-pyc&lt;br /&gt;
&lt;br /&gt;
the .pyc will speed up the invocations, without it &lt;br /&gt;
idk if one or both should be installed in that case. but it appears to be also automatically be precompiled in /usr/lib/python3.12/site-packages/include_server/__pycache__/ so what does the package do exactly?&lt;br /&gt;
&lt;br /&gt;
There&#039;s some references to cpython-312, so maybe it actually still uses classy python-c conversion or matbe that&#039;s just a component for reading C source code. I have zero idea.&lt;br /&gt;
&lt;br /&gt;
you also need stuff to do compiles&lt;br /&gt;
* alpine sdk&lt;br /&gt;
* clang&lt;br /&gt;
* binutils&lt;br /&gt;
...&lt;br /&gt;
* elfutils(-dev)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Settings ===&lt;br /&gt;
==== settings for distcc ====&lt;br /&gt;
&lt;br /&gt;
* there&#039;s /etc/default/distcc&lt;br /&gt;
* there&#039;s /etc/conf.d/distcc &lt;br /&gt;
&lt;br /&gt;
make all your settings here&lt;br /&gt;
take care with the listen address, if you specify an IP it&#039;ll not be on 127.0.0.1 in case you would have localhost in your list...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* command_whitelist.sh &lt;br /&gt;
&lt;br /&gt;
this is half functional, you need to set things here but you also need to maintain the symlinks that are collected under /usr/lib/distcc (for your compilers) and /usr/lib/distcc/bin (for itself)&lt;br /&gt;
&lt;br /&gt;
you MUST run the script to update the compilers!&lt;br /&gt;
Info for script and what files it will create&lt;br /&gt;
&lt;br /&gt;
/usr/sbin/update-distcc-symlinks&lt;br /&gt;
&lt;br /&gt;
tschike:/usr/bin# ls -l /usr/lib/distcc/&lt;br /&gt;
total 4&lt;br /&gt;
drwxr-xr-x 2 root root 4096 Mar  2 18:14 bin&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c89 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c99 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 cc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc-15.2.0 -&amp;gt; ../../bin/distcc&lt;br /&gt;
&lt;br /&gt;
distcc itself is in bin&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cpp -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 g++ -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 06:49 x86_64-alpine-linux-musl-gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
&lt;br /&gt;
the last symplink here is wrong, made by me and would not work...&lt;br /&gt;
BAD symlink.&lt;br /&gt;
&lt;br /&gt;
=== distcc hosts file ===&lt;br /&gt;
&lt;br /&gt;
idk about that thing it&#039;s odd&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== abuild.conf ===&lt;br /&gt;
&lt;br /&gt;
settings for aports&lt;br /&gt;
* cc=&lt;br /&gt;
* cxx=&lt;br /&gt;
* cpp=&lt;br /&gt;
* cflags=&lt;br /&gt;
* njobs&lt;br /&gt;
&lt;br /&gt;
== detail infos ==&lt;br /&gt;
&lt;br /&gt;
???&lt;br /&gt;
&lt;br /&gt;
=== hosts syntax ===&lt;br /&gt;
&lt;br /&gt;
* myhost otherhost&lt;br /&gt;
* myhost,cpp,lzo myotherhost,cpp,lzo&lt;br /&gt;
&lt;br /&gt;
==== the host ====&lt;br /&gt;
&lt;br /&gt;
hostname/ip&lt;br /&gt;
localhost&lt;br /&gt;
127.0.0.1&lt;br /&gt;
::1 - does not work&lt;br /&gt;
&lt;br /&gt;
==== protocol ====&lt;br /&gt;
&lt;br /&gt;
* no protocol given&lt;br /&gt;
* ,cpp,lzo protocol&lt;br /&gt;
&lt;br /&gt;
cpp implies lzo, it requires compression, even if you have 10gbit/s or more, it&#039;s just hardcoded&lt;br /&gt;
&lt;br /&gt;
=== threads ===&lt;br /&gt;
/number of workers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== architecture ==&lt;br /&gt;
it can handle C, C++, ObjC, maybe some other stuff&lt;br /&gt;
&lt;br /&gt;
* what happens with normal xmit&lt;br /&gt;
* what happens with pump mode&lt;br /&gt;
* at which step the include server is used and how it collects the includes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== distribution algorithm ===&lt;br /&gt;
honestly I simply don&#039;t get it&lt;br /&gt;
&lt;br /&gt;
* The order matters&lt;br /&gt;
* The number of threads matters&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== localhost ====&lt;br /&gt;
&lt;br /&gt;
* localhost precedence&lt;br /&gt;
* localhost fallback&lt;br /&gt;
&lt;br /&gt;
variable: DISTCC_FALLBACK&lt;br /&gt;
&lt;br /&gt;
0 = Fail to compile if it would need to fallback to a normal local gcc call&lt;br /&gt;
1 = If remote compile fails, just do it yourself&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Operation ==&lt;br /&gt;
&lt;br /&gt;
=== startup and shutdown ===&lt;br /&gt;
service distcc stop is not entirely reliable (it can take a minute after the stop until the processes are gone and sometimes it will never stop&lt;br /&gt;
this is very bad with openrc, the openrc script returns after a second and only relies on its service flags, not the process status.&lt;br /&gt;
manually check after stopping, wait a min, if needed, kill it all.&lt;br /&gt;
at some point the rc file needs to be rewritten, it can&#039;t stay like it is.&lt;br /&gt;
&lt;br /&gt;
if you used a pump mode session, that also needs a logout (pump --shutdown)&lt;br /&gt;
avoid running multiple startups without shutdown in one session. it&#039;s safe as far as I can tell but nothing cleans up these processes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== ccache and memcached ===&lt;br /&gt;
CCACHE is said to be conflicting with pump mode unless when you call them in the backend&lt;br /&gt;
so, where you start the compile, you don&#039;t use it&lt;br /&gt;
where the compile happens, you use it&lt;br /&gt;
they can share the cache via memcached, this is a nice trick for consistency&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== dockerized / native ===&lt;br /&gt;
&lt;br /&gt;
it remains mostly the same, a container needs to make sure it monitors the right services (distccd, nginx, include_server)&lt;br /&gt;
if you&#039;re using zeroconf, you need to somehow expose the mdns service broadcasts &amp;amp; reception&lt;br /&gt;
&lt;br /&gt;
Processs list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
Workdir list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
=== alpine-chroot ===&lt;br /&gt;
&lt;br /&gt;
when using the &#039;official&#039; script there&#039;s still some odd pieces, seemed to be the processes died on logout. but not all of them.&lt;br /&gt;
&lt;br /&gt;
==== manual launch ====&lt;br /&gt;
&lt;br /&gt;
Starting the daemon would be using&lt;br /&gt;
/usr/bin/distccd --pid-file /var/run/distccd/distccd.pid -N 15 --user distcc --port 3632 --log-level=debug --log-file=/var/log/distccd.log --allow my-sub-net/24&lt;br /&gt;
&lt;br /&gt;
==== localhost? =====&lt;br /&gt;
unclear if you need to use --allow for 127.0.0.1/32 or something to allow the remote preproccesor.&lt;br /&gt;
&lt;br /&gt;
== Kernel specific settings ==&lt;br /&gt;
&lt;br /&gt;
currently (distcc 3.4-r9 on Alpine) you need a patch to build the kernel.&lt;br /&gt;
See &lt;br /&gt;
&lt;br /&gt;
=== Include server Settings ===&lt;br /&gt;
&lt;br /&gt;
cache reset triggers&lt;br /&gt;
This ought to be set before enabling pump mode.&lt;br /&gt;
&lt;br /&gt;
export INCLUDE_SERVER_ARGS=&amp;quot;--stat_reset_triggers=include/linux/compile.h:include/asm/asm-offsets.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
link to explanation TBA&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Disabling GCC Plugins ===&lt;br /&gt;
&lt;br /&gt;
KConfig unselect HAVE_GCC_PLUGINS&lt;br /&gt;
&lt;br /&gt;
Some info is here in the troubleshooting part of the Arch Wiki&lt;br /&gt;
https://wiki.archlinux.org/title/Distcc#Troubleshooting&lt;br /&gt;
&lt;br /&gt;
=== Patches ===&lt;br /&gt;
&lt;br /&gt;
Other things (for 6.6LTS)&lt;br /&gt;
PCIe Stub patch&lt;br /&gt;
&lt;br /&gt;
=== Autoconf === &lt;br /&gt;
&lt;br /&gt;
No known setup examples&lt;br /&gt;
Add whatever it publishes in mdns&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== troubleshooting / analysis ==&lt;br /&gt;
&lt;br /&gt;
=== testing ===&lt;br /&gt;
&lt;br /&gt;
# turn off fallback DISTCC_FALLBACK=1&lt;br /&gt;
# set distcc up to point at specific system under test DISTCC_HOSTS=&amp;quot;mytestbox,cpp,lzo&amp;quot;&lt;br /&gt;
# GCC example compiles&lt;br /&gt;
## code example C&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example C++&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example ObjC&lt;br /&gt;
## same with included header&lt;br /&gt;
# Cmake example compiles&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docoument the thing with compile launcher ccache;distcc&lt;br /&gt;
there&#039;s some blog post, point to that&lt;br /&gt;
no ccache here yet&lt;br /&gt;
show $CC differences distcc vs gcc, what configure scripts see&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Latency ===&lt;br /&gt;
&lt;br /&gt;
Latency of pump mode startups and fallbacks needs to be investigated.&lt;br /&gt;
LZO is enforced even if you have faster network&lt;br /&gt;
DNS Requests, very old bug report from Gcode, one request per call, is it true? how to get rid of it?&lt;br /&gt;
TMPDIR is respected, make sure it&#039;s on ramdisk even on the remote nodes.&lt;br /&gt;
Compile ideally never goes to disk when it doesn&#039;t have to.&lt;br /&gt;
How efficient is the include server collection and unpacking?&lt;br /&gt;
&lt;br /&gt;
== security ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== tcpwrapper style ip range filter ===&lt;br /&gt;
&lt;br /&gt;
the original security model consists of ip restrictions.&lt;br /&gt;
there seems to also be some GSSAPI user auth.&lt;br /&gt;
further, commands that can be called are restricted by name and location.&lt;br /&gt;
this appears to be a runtime whitelist lookup, meaning it&#039;s done and authorized by the same parts of the daemon as processes the compile request along with the intended compiler.&lt;br /&gt;
so the main weaknesses against malicious clients seem to be in sending things to compile, and in overriding the remote compiler to use.&lt;br /&gt;
it can be assumed that a malicious client able to exploit the compiler handshake can then run arbitrary stuff.&lt;br /&gt;
There&#039;s at least a github issue regarding this google.com/search?q=distcc+seccomp&amp;amp;rlz=1C5CHFA_enDE1121DE1121&amp;amp;oq=distcc+seccomp&amp;amp;gs_lcrp=EgZjaHJvbWUyBggAEEUYOTIHCAEQIRigATIHCAIQIRigAdIBCDM1NjRqMGo3qAIAsAIA&amp;amp;sourceid=chrome&amp;amp;ie=UTF-8 suggesting running over ssh. That does only partitally alleviate this risk with regard  to a key based verfication of a client versus a the standard ip restrictions which always include some parsing.&lt;br /&gt;
So this protects against someone directly exploiting the TCP code of distcc.&lt;br /&gt;
It does not protect against malicious clients.&lt;br /&gt;
(ssh force command can&#039;t be used or you&#039;ll not compile anything)&lt;br /&gt;
&lt;br /&gt;
The basic step for protecting access should be filtering who can access the distcc server, so use nftables etc. to restrict access to port 3262 (??) set up the internal filter the same way.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== seccomp ===&lt;br /&gt;
&lt;br /&gt;
The next thing is to confine the compiler calls to only write in their temp directory and that they can only run compilers (using nsjail, apparmor, selinux etc)&lt;br /&gt;
&lt;br /&gt;
the above issue also references the second bit of security, namely a seccomp filter which will already cover a good bit of the above&lt;br /&gt;
https://github.com/distcc/distcc/pull/235&lt;br /&gt;
the commit got closed without merge, from what I see.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== privs ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The other internal security bit is that they do some priviledge dropping. it runs as a dedicated user (distcc), so you can also have an audit policy, and can/could use something like iptables&#039; to ensure it can only connect to the other distcc/memcached hosts, but nothing else.&lt;br /&gt;
&lt;br /&gt;
=== compiler list ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
One needs to investigate when compiler_whitelist.sh is exactly called. as far as I recall it doesn&#039;t close stdin/stdout.&lt;br /&gt;
&lt;br /&gt;
=== distcc-hardened ===&lt;br /&gt;
&lt;br /&gt;
Alpine adds some hardening patch, idk what nature/origina that has.&lt;br /&gt;
&lt;br /&gt;
=== selinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
there&#039;s also a selinux policy for distcc from gentoo or liguros if one is so inclined.&lt;br /&gt;
https://repology.org/project/selinux-distcc/versions&lt;br /&gt;
&lt;br /&gt;
=== general posture ===&lt;br /&gt;
&lt;br /&gt;
Some security measures like the above should definitely be used since the project has only a few part-time maintainers that cannot easily drive the project forward or do large refactors.&lt;br /&gt;
But the seccomp changes were done almost 10 years ago, so, to be fair, they still came through.&lt;/div&gt;</summary>
		<author><name>Darkfader</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32129</id>
		<title>User:Darkfader/distcc</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32129"/>
		<updated>2026-03-03T11:01:34Z</updated>

		<summary type="html">&lt;p&gt;Darkfader: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi,&lt;br /&gt;
&lt;br /&gt;
I&#039;m preparing this page. It can take a long time till I finish.&lt;br /&gt;
If you are also wishing to write on this topic, feel free to integrate the content.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Document overview ==&lt;br /&gt;
&lt;br /&gt;
I noticed that almost every distro has one partially complete, partially helpful document on how to use distcc on the distro.&lt;br /&gt;
Usually they also have one for ccache.&lt;br /&gt;
In either case, they&#039;re enough to get started, but not really a reliable watertight thing.&lt;br /&gt;
We definitely needed one of our own.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== goal ===&lt;br /&gt;
&lt;br /&gt;
to describe a working setup for building aports in easiest/fastests fashion&lt;br /&gt;
not planning to add versatility or features where it would make the setup more errorprone.&lt;br /&gt;
the page should describe enough of the steps to successfully compile an LTS kernel via aports and have that job be distributed over multiple nodes.&lt;br /&gt;
Logs should be set up and able to display errors, but not show any errors during the test compile.&lt;br /&gt;
&lt;br /&gt;
To include a path for analysis via testing components.&lt;br /&gt;
&lt;br /&gt;
distcc can greatly improve compile speeds for large software, it comes with a different set of features than ccache; it focusses not avoiding unneccessary compile work, but on a way to speed up the necessary one.&lt;br /&gt;
&lt;br /&gt;
=== audience ===&lt;br /&gt;
people running software builds on alpine and have multiple computers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This page will show a specific installation, specific configuration, and specific tests, resulting in a specific set of functionality that can be tested to be working.&lt;br /&gt;
&lt;br /&gt;
== installation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Packages ===&lt;br /&gt;
&lt;br /&gt;
you need, on each host&lt;br /&gt;
* distcc&lt;br /&gt;
* distccd-openrc&lt;br /&gt;
* distcc-pump&lt;br /&gt;
* distcc-pump-pyc&lt;br /&gt;
&lt;br /&gt;
the .pyc will speed up the invocations, without it &lt;br /&gt;
idk if one or both should be installed in that case. but it appears to be also automatically be precompiled in /usr/lib/python3.12/site-packages/include_server/__pycache__/ so what does the package do exactly?&lt;br /&gt;
&lt;br /&gt;
There&#039;s some references to cpython-312, so maybe it actually still uses classy python-c conversion or matbe that&#039;s just a component for reading C source code. I have zero idea.&lt;br /&gt;
&lt;br /&gt;
you also need stuff to do compiles&lt;br /&gt;
* alpine sdk&lt;br /&gt;
* clang&lt;br /&gt;
* binutils&lt;br /&gt;
...&lt;br /&gt;
* elfutils(-dev)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Settings ===&lt;br /&gt;
==== settings for distcc ====&lt;br /&gt;
&lt;br /&gt;
* there&#039;s /etc/default/distcc&lt;br /&gt;
* there&#039;s /etc/conf.d/distcc &lt;br /&gt;
&lt;br /&gt;
make all your settings here&lt;br /&gt;
take care with the listen address, if you specify an IP it&#039;ll not be on 127.0.0.1 in case you would have localhost in your list...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* command_whitelist.sh &lt;br /&gt;
&lt;br /&gt;
this is half functional, you need to set things here but you also need to maintain the symlinks that are collected under /usr/lib/distcc (for your compilers) and /usr/lib/distcc/bin (for itself)&lt;br /&gt;
&lt;br /&gt;
you MUST run the script to update the compilers!&lt;br /&gt;
Info for script and what files it will create&lt;br /&gt;
&lt;br /&gt;
/usr/sbin/update-distcc-symlinks&lt;br /&gt;
&lt;br /&gt;
tschike:/usr/bin# ls -l /usr/lib/distcc/&lt;br /&gt;
total 4&lt;br /&gt;
drwxr-xr-x 2 root root 4096 Mar  2 18:14 bin&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c89 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c99 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 cc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc-15.2.0 -&amp;gt; ../../bin/distcc&lt;br /&gt;
&lt;br /&gt;
distcc itself is in bin&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cpp -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 g++ -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 06:49 x86_64-alpine-linux-musl-gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
&lt;br /&gt;
the last symplink here is wrong, made by me and would not work...&lt;br /&gt;
BAD symlink.&lt;br /&gt;
&lt;br /&gt;
=== distcc hosts file ===&lt;br /&gt;
&lt;br /&gt;
idk about that thing it&#039;s odd&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== abuild.conf ===&lt;br /&gt;
&lt;br /&gt;
settings for aports&lt;br /&gt;
* cc=&lt;br /&gt;
* cxx=&lt;br /&gt;
* cpp=&lt;br /&gt;
* cflags=&lt;br /&gt;
* njobs&lt;br /&gt;
&lt;br /&gt;
== detail infos ==&lt;br /&gt;
&lt;br /&gt;
???&lt;br /&gt;
&lt;br /&gt;
=== hosts syntax ===&lt;br /&gt;
&lt;br /&gt;
* myhost otherhost&lt;br /&gt;
* myhost,cpp,lzo myotherhost,cpp,lzo&lt;br /&gt;
&lt;br /&gt;
==== the host ====&lt;br /&gt;
&lt;br /&gt;
hostname/ip&lt;br /&gt;
localhost&lt;br /&gt;
127.0.0.1&lt;br /&gt;
::1 - does not work&lt;br /&gt;
&lt;br /&gt;
==== protocol ====&lt;br /&gt;
&lt;br /&gt;
* no protocol given&lt;br /&gt;
* ,cpp,lzo protocol&lt;br /&gt;
&lt;br /&gt;
cpp implies lzo, it requires compression, even if you have 10gbit/s or more, it&#039;s just hardcoded&lt;br /&gt;
&lt;br /&gt;
=== threads ===&lt;br /&gt;
/number of workers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== architecture ==&lt;br /&gt;
it can handle C, C++, ObjC, maybe some other stuff&lt;br /&gt;
&lt;br /&gt;
* what happens with normal xmit&lt;br /&gt;
* what happens with pump mode&lt;br /&gt;
* at which step the include server is used and how it collects the includes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== distribution algorithm ===&lt;br /&gt;
honestly I simply don&#039;t get it&lt;br /&gt;
&lt;br /&gt;
* The order matters&lt;br /&gt;
* The number of threads matters&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== localhost ====&lt;br /&gt;
&lt;br /&gt;
* localhost precedence&lt;br /&gt;
* localhost fallback&lt;br /&gt;
&lt;br /&gt;
variable: DISTCC_FALLBACK&lt;br /&gt;
&lt;br /&gt;
0 = Fail to compile if it would need to fallback to a normal local gcc call&lt;br /&gt;
1 = If remote compile fails, just do it yourself&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Operation ==&lt;br /&gt;
&lt;br /&gt;
=== startup and shutdown ===&lt;br /&gt;
service distcc stop is not entirely reliable (it can take a minute after the stop until the processes are gone and sometimes it will never stop&lt;br /&gt;
this is very bad with openrc, the openrc script returns after a second and only relies on its service flags, not the process status.&lt;br /&gt;
manually check after stopping, wait a min, if needed, kill it all.&lt;br /&gt;
at some point the rc file needs to be rewritten, it can&#039;t stay like it is.&lt;br /&gt;
&lt;br /&gt;
if you used a pump mode session, that also needs a logout (pump --shutdown)&lt;br /&gt;
avoid running multiple startups without shutdown in one session. it&#039;s safe as far as I can tell but nothing cleans up these processes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== ccache and memcached ===&lt;br /&gt;
CCACHE is said to be conflicting with pump mode unless when you call them in the backend&lt;br /&gt;
so, where you start the compile, you don&#039;t use it&lt;br /&gt;
where the compile happens, you use it&lt;br /&gt;
they can share the cache via memcached, this is a nice trick for consistency&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== dockerized / native ===&lt;br /&gt;
&lt;br /&gt;
it remains mostly the same, a container needs to make sure it monitors the right services (distccd, nginx, include_server)&lt;br /&gt;
if you&#039;re using zeroconf, you need to somehow expose the mdns service broadcasts &amp;amp; reception&lt;br /&gt;
&lt;br /&gt;
Processs list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
Workdir list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
=== alpine-chroot ===&lt;br /&gt;
&lt;br /&gt;
when using the &#039;official&#039; script there&#039;s still some odd pieces, seemed to be the processes died on logout. but not all of them.&lt;br /&gt;
&lt;br /&gt;
==== manual launch ====&lt;br /&gt;
&lt;br /&gt;
Starting the daemon would be using&lt;br /&gt;
/usr/bin/distccd --pid-file /var/run/distccd/distccd.pid -N 15 --user distcc --port 3632 --log-level=debug --log-file=/var/log/distccd.log --allow my-sub-net/24&lt;br /&gt;
&lt;br /&gt;
==== localhost? =====&lt;br /&gt;
unclear if you need to use --allow for 127.0.0.1/32 or something to allow the remote preproccesor.&lt;br /&gt;
&lt;br /&gt;
== Kernel specific settings ==&lt;br /&gt;
&lt;br /&gt;
currently (distcc 3.4-r9 on Alpine) you need a patch to build the kernel.&lt;br /&gt;
See &lt;br /&gt;
&lt;br /&gt;
=== Include server Settings ===&lt;br /&gt;
&lt;br /&gt;
cache reset triggers&lt;br /&gt;
This ought to be set before enabling pump mode.&lt;br /&gt;
&lt;br /&gt;
export INCLUDE_SERVER_ARGS=&amp;quot;--stat_reset_triggers=include/linux/compile.h:include/asm/asm-offsets.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
link to explanation TBA&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Disabling GCC Plugins ===&lt;br /&gt;
&lt;br /&gt;
KConfig unselect HAVE_GCC_PLUGINS&lt;br /&gt;
&lt;br /&gt;
Some info is here in the troubleshooting part of the Arch Wiki&lt;br /&gt;
https://wiki.archlinux.org/title/Distcc#Troubleshooting&lt;br /&gt;
&lt;br /&gt;
=== Patches ===&lt;br /&gt;
&lt;br /&gt;
Other things (for 6.6LTS)&lt;br /&gt;
PCIe Stub patch&lt;br /&gt;
&lt;br /&gt;
=== Autoconf === &lt;br /&gt;
&lt;br /&gt;
No known setup examples&lt;br /&gt;
Add whatever it publishes in mdns&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== troubleshooting / analysis ==&lt;br /&gt;
&lt;br /&gt;
=== testing ===&lt;br /&gt;
&lt;br /&gt;
# turn off fallback DISTCC_FALLBACK=1&lt;br /&gt;
# set distcc up to point at specific system under test DISTCC_HOSTS=&amp;quot;mytestbox,cpp,lzo&amp;quot;&lt;br /&gt;
# GCC example compiles&lt;br /&gt;
## code example C&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example C++&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example ObjC&lt;br /&gt;
## same with included header&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
no ccache here yet&lt;br /&gt;
&lt;br /&gt;
# Cmake example compiles&lt;br /&gt;
the thing with compile launcher ccache;distcc&lt;br /&gt;
&lt;br /&gt;
=== Latency ===&lt;br /&gt;
&lt;br /&gt;
Latency of pump mode startups and fallbacks needs to be investigated.&lt;br /&gt;
LZO is enforced even if you have faster network&lt;br /&gt;
DNS Requests, very old bug report from Gcode, one request per call, is it true? how to get rid of it?&lt;br /&gt;
TMPDIR is respected, make sure it&#039;s on ramdisk even on the remote nodes.&lt;br /&gt;
Compile ideally never goes to disk when it doesn&#039;t have to.&lt;br /&gt;
How efficient is the include server collection and unpacking?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== security ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== tcpwrapper style ip range filter ===&lt;br /&gt;
&lt;br /&gt;
the original security model consists of ip restrictions.&lt;br /&gt;
there seems to also be some GSSAPI user auth.&lt;br /&gt;
further, commands that can be called are restricted by name and location.&lt;br /&gt;
this appears to be a runtime whitelist lookup, meaning it&#039;s done and authorized by the same parts of the daemon as processes the compile request along with the intended compiler.&lt;br /&gt;
so the main weaknesses against malicious clients seem to be in sending things to compile, and in overriding the remote compiler to use.&lt;br /&gt;
it can be assumed that a malicious client able to exploit the compiler handshake can then run arbitrary stuff.&lt;br /&gt;
There&#039;s at least a github issue regarding this google.com/search?q=distcc+seccomp&amp;amp;rlz=1C5CHFA_enDE1121DE1121&amp;amp;oq=distcc+seccomp&amp;amp;gs_lcrp=EgZjaHJvbWUyBggAEEUYOTIHCAEQIRigATIHCAIQIRigAdIBCDM1NjRqMGo3qAIAsAIA&amp;amp;sourceid=chrome&amp;amp;ie=UTF-8 suggesting running over ssh. That does only partitally alleviate this risk with regard  to a key based verfication of a client versus a the standard ip restrictions which always include some parsing.&lt;br /&gt;
So this protects against someone directly exploiting the TCP code of distcc.&lt;br /&gt;
It does not protect against malicious clients.&lt;br /&gt;
(ssh force command can&#039;t be used or you&#039;ll not compile anything)&lt;br /&gt;
&lt;br /&gt;
The basic step for protecting access should be filtering who can access the distcc server, so use nftables etc. to restrict access to port 3262 (??) set up the internal filter the same way.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== seccomp ===&lt;br /&gt;
&lt;br /&gt;
The next thing is to confine the compiler calls to only write in their temp directory and that they can only run compilers (using nsjail, apparmor, selinux etc)&lt;br /&gt;
&lt;br /&gt;
the above issue also references the second bit of security, namely a seccomp filter which will already cover a good bit of the above&lt;br /&gt;
https://github.com/distcc/distcc/pull/235&lt;br /&gt;
the commit got closed without merge, from what I see.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== privs ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The other internal security bit is that they do some priviledge dropping. it runs as a dedicated user (distcc), so you can also have an audit policy, and can/could use something like iptables&#039; to ensure it can only connect to the other distcc/memcached hosts, but nothing else.&lt;br /&gt;
&lt;br /&gt;
=== compiler list ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
One needs to investigate when compiler_whitelist.sh is exactly called. as far as I recall it doesn&#039;t close stdin/stdout.&lt;br /&gt;
&lt;br /&gt;
=== distcc-hardened ===&lt;br /&gt;
&lt;br /&gt;
Alpine adds some hardening patch, idk what nature/origina that has.&lt;br /&gt;
&lt;br /&gt;
=== selinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
there&#039;s also a selinux policy for distcc from gentoo or liguros if one is so inclined.&lt;br /&gt;
https://repology.org/project/selinux-distcc/versions&lt;br /&gt;
&lt;br /&gt;
=== general posture ===&lt;br /&gt;
&lt;br /&gt;
Some security measures like the above should definitely be used since the project has only a few part-time maintainers that cannot easily drive the project forward or do large refactors.&lt;br /&gt;
But the seccomp changes were done almost 10 years ago, so, to be fair, they still came through.&lt;/div&gt;</summary>
		<author><name>Darkfader</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32128</id>
		<title>User:Darkfader/distcc</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32128"/>
		<updated>2026-03-03T10:49:52Z</updated>

		<summary type="html">&lt;p&gt;Darkfader: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi,&lt;br /&gt;
&lt;br /&gt;
I&#039;m preparing this page. It can take a long time till I finish.&lt;br /&gt;
If you are also wishing to write on this topic, feel free to integrate the content.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Document overview ==&lt;br /&gt;
&lt;br /&gt;
I noticed that almost every distro has one partially complete, partially helpful document on how to use distcc on the distro.&lt;br /&gt;
Usually they also have one for ccache.&lt;br /&gt;
In either case, they&#039;re enough to get started, but not really a reliable watertight thing.&lt;br /&gt;
We definitely needed one of our own.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== goal ===&lt;br /&gt;
&lt;br /&gt;
to describe a working setup for building aports in easiest/fastests fashion&lt;br /&gt;
not planning to add versatility or features where it would make the setup more errorprone.&lt;br /&gt;
the page should describe enough of the steps to successfully compile an LTS kernel via aports and have that job be distributed over multiple nodes.&lt;br /&gt;
Logs should be set up and able to display errors, but not show any errors during the test compile.&lt;br /&gt;
&lt;br /&gt;
To include a path for analysis via testing components.&lt;br /&gt;
&lt;br /&gt;
distcc can greatly improve compile speeds for large software, it comes with a different set of features than ccache; it focusses not avoiding unneccessary compile work, but on a way to speed up the necessary one.&lt;br /&gt;
&lt;br /&gt;
=== audience ===&lt;br /&gt;
people running software builds on alpine and have multiple computers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This page will show a specific installation, specific configuration, and specific tests, resulting in a specific set of functionality that can be tested to be working.&lt;br /&gt;
&lt;br /&gt;
== installation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Packages ===&lt;br /&gt;
&lt;br /&gt;
you need, on each host&lt;br /&gt;
* distcc&lt;br /&gt;
* distccd-openrc&lt;br /&gt;
* distcc-pump&lt;br /&gt;
* distcc-pump-pyc&lt;br /&gt;
&lt;br /&gt;
the .pyc will speed up the invocations, without it &lt;br /&gt;
idk if one or both should be installed in that case. but it appears to be also automatically be precompiled in /usr/lib/python3.12/site-packages/include_server/__pycache__/ so what does the package do exactly?&lt;br /&gt;
&lt;br /&gt;
There&#039;s some references to cpython-312, so maybe it actually still uses classy python-c conversion or matbe that&#039;s just a component for reading C source code. I have zero idea.&lt;br /&gt;
&lt;br /&gt;
you also need stuff to do compiles&lt;br /&gt;
* alpine sdk&lt;br /&gt;
* clang&lt;br /&gt;
* binutils&lt;br /&gt;
...&lt;br /&gt;
* elfutils(-dev)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Settings ===&lt;br /&gt;
==== settings for distcc ====&lt;br /&gt;
&lt;br /&gt;
* there&#039;s /etc/default/distcc&lt;br /&gt;
* there&#039;s /etc/conf.d/distcc &lt;br /&gt;
&lt;br /&gt;
make all your settings here&lt;br /&gt;
* command_whitelist.sh &lt;br /&gt;
&lt;br /&gt;
this is half functional, you need to set things here but you also need to maintain the symlinks that are collected under /usr/lib/distcc (for your compilers) and /usr/lib/distcc/bin (for itself)&lt;br /&gt;
&lt;br /&gt;
you MUST run the script to update the compilers!&lt;br /&gt;
Info for script and what files it will create&lt;br /&gt;
&lt;br /&gt;
/usr/sbin/update-distcc-symlinks&lt;br /&gt;
&lt;br /&gt;
tschike:/usr/bin# ls -l /usr/lib/distcc/&lt;br /&gt;
total 4&lt;br /&gt;
drwxr-xr-x 2 root root 4096 Mar  2 18:14 bin&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c89 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c99 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 cc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc-15.2.0 -&amp;gt; ../../bin/distcc&lt;br /&gt;
&lt;br /&gt;
distcc itself is in bin&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cpp -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 g++ -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 06:49 x86_64-alpine-linux-musl-gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
&lt;br /&gt;
the last symplink here is wrong, made by me and would not work...&lt;br /&gt;
BAD symlink.&lt;br /&gt;
&lt;br /&gt;
=== distcc hosts file ===&lt;br /&gt;
&lt;br /&gt;
idk about that thing it&#039;s odd&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== abuild.conf ===&lt;br /&gt;
&lt;br /&gt;
settings for aports&lt;br /&gt;
* cc=&lt;br /&gt;
* cxx=&lt;br /&gt;
* cpp=&lt;br /&gt;
* cflags=&lt;br /&gt;
* njobs&lt;br /&gt;
&lt;br /&gt;
== detail infos ==&lt;br /&gt;
&lt;br /&gt;
???&lt;br /&gt;
&lt;br /&gt;
=== hosts syntax ===&lt;br /&gt;
&lt;br /&gt;
* myhost otherhost&lt;br /&gt;
* myhost,cpp,lzo myotherhost,cpp,lzo&lt;br /&gt;
&lt;br /&gt;
==== the host ====&lt;br /&gt;
&lt;br /&gt;
hostname/ip&lt;br /&gt;
localhost&lt;br /&gt;
127.0.0.1&lt;br /&gt;
::1 - does not work&lt;br /&gt;
&lt;br /&gt;
==== protocol ====&lt;br /&gt;
&lt;br /&gt;
* no protocol given&lt;br /&gt;
* ,cpp,lzo protocol&lt;br /&gt;
&lt;br /&gt;
cpp implies lzo, it requires compression, even if you have 10gbit/s or more, it&#039;s just hardcoded&lt;br /&gt;
&lt;br /&gt;
=== threads ===&lt;br /&gt;
/number of workers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== architecture ==&lt;br /&gt;
it can handle C, C++, ObjC, maybe some other stuff&lt;br /&gt;
&lt;br /&gt;
* what happens with normal xmit&lt;br /&gt;
* what happens with pump mode&lt;br /&gt;
* at which step the include server is used and how it collects the includes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== distribution algorithm ===&lt;br /&gt;
honestly I simply don&#039;t get it&lt;br /&gt;
&lt;br /&gt;
* The order matters&lt;br /&gt;
* The number of threads matters&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== localhost ====&lt;br /&gt;
&lt;br /&gt;
* localhost precedence&lt;br /&gt;
* localhost fallback&lt;br /&gt;
&lt;br /&gt;
variable: DISTCC_FALLBACK&lt;br /&gt;
&lt;br /&gt;
0 = Fail to compile if it would need to fallback to a normal local gcc call&lt;br /&gt;
1 = If remote compile fails, just do it yourself&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Operation ==&lt;br /&gt;
&lt;br /&gt;
=== startup and shutdown ===&lt;br /&gt;
service distcc stop is not entirely reliable (it can take a minute after the stop until the processes are gone and sometimes it will never stop&lt;br /&gt;
this is very bad with openrc, the openrc script returns after a second and only relies on its service flags, not the process status.&lt;br /&gt;
manually check after stopping, wait a min, if needed, kill it all.&lt;br /&gt;
at some point the rc file needs to be rewritten, it can&#039;t stay like it is.&lt;br /&gt;
&lt;br /&gt;
if you used a pump mode session, that also needs a logout (pump --shutdown)&lt;br /&gt;
avoid running multiple startups without shutdown in one session. it&#039;s safe as far as I can tell but nothing cleans up these processes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== ccache and memcached ===&lt;br /&gt;
CCACHE is said to be conflicting with pump mode unless when you call them in the backend&lt;br /&gt;
so, where you start the compile, you don&#039;t use it&lt;br /&gt;
where the compile happens, you use it&lt;br /&gt;
they can share the cache via memcached, this is a nice trick for consistency&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== dockerized / native ===&lt;br /&gt;
&lt;br /&gt;
it remains mostly the same, a container needs to make sure it monitors the right services (distccd, nginx, include_server)&lt;br /&gt;
if you&#039;re using zeroconf, you need to somehow expose the mdns service broadcasts &amp;amp; reception&lt;br /&gt;
&lt;br /&gt;
Processs list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
Workdir list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
=== alpine-chroot ===&lt;br /&gt;
&lt;br /&gt;
when using the &#039;official&#039; script there&#039;s still some odd pieces, seemed to be the processes died on logout. but not all of them.&lt;br /&gt;
&lt;br /&gt;
==== manual launch ====&lt;br /&gt;
&lt;br /&gt;
Starting the daemon would be using&lt;br /&gt;
/usr/bin/distccd --pid-file /var/run/distccd/distccd.pid -N 15 --user distcc --port 3632 --log-level=debug --log-file=/var/log/distccd.log --allow my-sub-net/24&lt;br /&gt;
&lt;br /&gt;
==== localhost? =====&lt;br /&gt;
unclear if you need to use --allow for 127.0.0.1/32 or something to allow the remote preproccesor.&lt;br /&gt;
&lt;br /&gt;
== Kernel specific settings ==&lt;br /&gt;
&lt;br /&gt;
currently (distcc 3.4-r9 on Alpine) you need a patch to build the kernel.&lt;br /&gt;
See &lt;br /&gt;
&lt;br /&gt;
=== Include server Settings ===&lt;br /&gt;
&lt;br /&gt;
cache reset triggers&lt;br /&gt;
This ought to be set before enabling pump mode.&lt;br /&gt;
&lt;br /&gt;
export INCLUDE_SERVER_ARGS=&amp;quot;--stat_reset_triggers=include/linux/compile.h:include/asm/asm-offsets.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
link to explanation TBA&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Disabling GCC Plugins ===&lt;br /&gt;
&lt;br /&gt;
KConfig unselect HAVE_GCC_PLUGINS&lt;br /&gt;
&lt;br /&gt;
Some info is here in the troubleshooting part of the Arch Wiki&lt;br /&gt;
https://wiki.archlinux.org/title/Distcc#Troubleshooting&lt;br /&gt;
&lt;br /&gt;
=== Patches ===&lt;br /&gt;
&lt;br /&gt;
Other things (for 6.6LTS)&lt;br /&gt;
PCIe Stub patch&lt;br /&gt;
&lt;br /&gt;
=== Autoconf === &lt;br /&gt;
&lt;br /&gt;
No known setup examples&lt;br /&gt;
Add whatever it publishes in mdns&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== troubleshooting / analysis ==&lt;br /&gt;
&lt;br /&gt;
=== testing ===&lt;br /&gt;
&lt;br /&gt;
# turn off fallback&lt;br /&gt;
&lt;br /&gt;
# GCC example compiles&lt;br /&gt;
## code example C&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example C++&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example ObjC&lt;br /&gt;
## same with included header&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
no ccache here yet&lt;br /&gt;
&lt;br /&gt;
# Cmake example compiles&lt;br /&gt;
the thing with compile launcher ccache;distcc&lt;br /&gt;
&lt;br /&gt;
=== Latency ===&lt;br /&gt;
&lt;br /&gt;
Latency of pump mode startups and fallbacks needs to be investigated.&lt;br /&gt;
LZO is enforced even if you have faster network&lt;br /&gt;
DNS Requests, very old bug report from Gcode, one request per call, is it true? how to get rid of it?&lt;br /&gt;
TMPDIR is respected, make sure it&#039;s on ramdisk even on the remote nodes.&lt;br /&gt;
Compile ideally never goes to disk when it doesn&#039;t have to.&lt;br /&gt;
How efficient is the include server collection and unpacking?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== security ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== tcpwrapper style ip range filter ===&lt;br /&gt;
&lt;br /&gt;
the original security model consists of ip restrictions.&lt;br /&gt;
there seems to also be some GSSAPI user auth.&lt;br /&gt;
further, commands that can be called are restricted by name and location.&lt;br /&gt;
this appears to be a runtime whitelist lookup, meaning it&#039;s done and authorized by the same parts of the daemon as processes the compile request along with the intended compiler.&lt;br /&gt;
so the main weaknesses against malicious clients seem to be in sending things to compile, and in overriding the remote compiler to use.&lt;br /&gt;
it can be assumed that a malicious client able to exploit the compiler handshake can then run arbitrary stuff.&lt;br /&gt;
There&#039;s at least a github issue regarding this google.com/search?q=distcc+seccomp&amp;amp;rlz=1C5CHFA_enDE1121DE1121&amp;amp;oq=distcc+seccomp&amp;amp;gs_lcrp=EgZjaHJvbWUyBggAEEUYOTIHCAEQIRigATIHCAIQIRigAdIBCDM1NjRqMGo3qAIAsAIA&amp;amp;sourceid=chrome&amp;amp;ie=UTF-8 suggesting running over ssh. That does only partitally alleviate this risk with regard  to a key based verfication of a client versus a the standard ip restrictions which always include some parsing.&lt;br /&gt;
So this protects against someone directly exploiting the TCP code of distcc.&lt;br /&gt;
It does not protect against malicious clients.&lt;br /&gt;
(ssh force command can&#039;t be used or you&#039;ll not compile anything)&lt;br /&gt;
&lt;br /&gt;
The basic step for protecting access should be filtering who can access the distcc server, so use nftables etc. to restrict access to port 3262 (??) set up the internal filter the same way.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== seccomp ===&lt;br /&gt;
&lt;br /&gt;
The next thing is to confine the compiler calls to only write in their temp directory and that they can only run compilers (using nsjail, apparmor, selinux etc)&lt;br /&gt;
&lt;br /&gt;
the above issue also references the second bit of security, namely a seccomp filter which will already cover a good bit of the above&lt;br /&gt;
https://github.com/distcc/distcc/pull/235&lt;br /&gt;
the commit got closed without merge, from what I see.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== privs ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The other internal security bit is that they do some priviledge dropping. it runs as a dedicated user (distcc), so you can also have an audit policy, and can/could use something like iptables&#039; to ensure it can only connect to the other distcc/memcached hosts, but nothing else.&lt;br /&gt;
&lt;br /&gt;
=== compiler list ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
One needs to investigate when compiler_whitelist.sh is exactly called. as far as I recall it doesn&#039;t close stdin/stdout.&lt;br /&gt;
&lt;br /&gt;
=== distcc-hardened ===&lt;br /&gt;
&lt;br /&gt;
Alpine adds some hardening patch, idk what nature/origina that has.&lt;br /&gt;
&lt;br /&gt;
=== selinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
there&#039;s also a selinux policy for distcc from gentoo or liguros if one is so inclined.&lt;br /&gt;
https://repology.org/project/selinux-distcc/versions&lt;br /&gt;
&lt;br /&gt;
=== general posture ===&lt;br /&gt;
&lt;br /&gt;
Some security measures like the above should definitely be used since the project has only a few part-time maintainers that cannot easily drive the project forward or do large refactors.&lt;br /&gt;
But the seccomp changes were done almost 10 years ago, so, to be fair, they still came through.&lt;/div&gt;</summary>
		<author><name>Darkfader</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32127</id>
		<title>User:Darkfader/distcc</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32127"/>
		<updated>2026-03-03T10:46:28Z</updated>

		<summary type="html">&lt;p&gt;Darkfader: /* general posture */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi,&lt;br /&gt;
&lt;br /&gt;
I&#039;m preparing this page. It can take a long time till I finish.&lt;br /&gt;
If you are also wishing to write on this topic, feel free to integrate the content.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Document overview ==&lt;br /&gt;
&lt;br /&gt;
I noticed that almost every distro has one partially complete, partially helpful document on how to use distcc on the distro.&lt;br /&gt;
Usually they also have one for ccache.&lt;br /&gt;
In either case, they&#039;re enough to get started, but not really a reliable watertight thing.&lt;br /&gt;
We definitely needed one of our own.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== goal ===&lt;br /&gt;
&lt;br /&gt;
to describe a working setup for building aports in easiest/fastests fashion&lt;br /&gt;
not planning to add versatility or features where it would make the setup more errorprone.&lt;br /&gt;
the page should describe enough of the steps to successfully compile an LTS kernel via aports and have that job be distributed over multiple nodes.&lt;br /&gt;
Logs should be set up and able to display errors, but not show any errors during the test compile.&lt;br /&gt;
&lt;br /&gt;
To include a path for analysis via testing components.&lt;br /&gt;
&lt;br /&gt;
distcc can greatly improve compile speeds for large software, it comes with a different set of features than ccache; it focusses not avoiding unneccessary compile work, but on a way to speed up the necessary one.&lt;br /&gt;
&lt;br /&gt;
=== audience ===&lt;br /&gt;
people running software builds on alpine and have multiple computers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This page will show a specific installation, specific configuration, and specific tests, resulting in a specific set of functionality that can be tested to be working.&lt;br /&gt;
&lt;br /&gt;
== installation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Packages ===&lt;br /&gt;
&lt;br /&gt;
you need, on each host&lt;br /&gt;
* distcc&lt;br /&gt;
* distccd-openrc&lt;br /&gt;
* distcc-pump&lt;br /&gt;
* distcc-pump-pyc&lt;br /&gt;
&lt;br /&gt;
the .pyc will speed up the invocations, without it &lt;br /&gt;
idk if one or both should be installed in that case. but it appears to be also automatically be precompiled in /usr/lib/python3.12/site-packages/include_server/__pycache__/ so what does the package do exactly?&lt;br /&gt;
&lt;br /&gt;
There&#039;s some references to cpython-312, so maybe it actually still uses classy python-c conversion or matbe that&#039;s just a component for reading C source code. I have zero idea.&lt;br /&gt;
&lt;br /&gt;
you also need stuff to do compiles&lt;br /&gt;
* alpine sdk&lt;br /&gt;
* clang&lt;br /&gt;
* binutils&lt;br /&gt;
...&lt;br /&gt;
* elfutils(-dev)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Settings ===&lt;br /&gt;
==== settings for distcc ====&lt;br /&gt;
&lt;br /&gt;
* there&#039;s /etc/default/distcc&lt;br /&gt;
* there&#039;s /etc/conf.d/distcc &lt;br /&gt;
&lt;br /&gt;
make all your settings here&lt;br /&gt;
* command_whitelist.sh &lt;br /&gt;
&lt;br /&gt;
this is half functional, you need to set things here but you also need to maintain the symlinks that are collected under /usr/lib/distcc (for your compilers) and /usr/lib/distcc/bin (for itself)&lt;br /&gt;
&lt;br /&gt;
you MUST run the script to update the compilers!&lt;br /&gt;
Info for script and what files it will create&lt;br /&gt;
&lt;br /&gt;
/usr/sbin/update-distcc-symlinks&lt;br /&gt;
&lt;br /&gt;
tschike:/usr/bin# ls -l /usr/lib/distcc/&lt;br /&gt;
total 4&lt;br /&gt;
drwxr-xr-x 2 root root 4096 Mar  2 18:14 bin&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c89 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c99 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 cc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc-15.2.0 -&amp;gt; ../../bin/distcc&lt;br /&gt;
&lt;br /&gt;
distcc itself is in bin&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cpp -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 g++ -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 06:49 x86_64-alpine-linux-musl-gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
&lt;br /&gt;
the last symplink here is wrong, made by me and would not work...&lt;br /&gt;
BAD symlink.&lt;br /&gt;
&lt;br /&gt;
=== distcc hosts file ===&lt;br /&gt;
&lt;br /&gt;
idk about that thing it&#039;s odd&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== abuild.conf ===&lt;br /&gt;
&lt;br /&gt;
settings for aports&lt;br /&gt;
* cc=&lt;br /&gt;
* cxx=&lt;br /&gt;
* cpp=&lt;br /&gt;
* cflags=&lt;br /&gt;
* njobs&lt;br /&gt;
&lt;br /&gt;
== detail infos ==&lt;br /&gt;
&lt;br /&gt;
???&lt;br /&gt;
&lt;br /&gt;
=== hosts syntax ===&lt;br /&gt;
&lt;br /&gt;
* myhost otherhost&lt;br /&gt;
* myhost,cpp,lzo myotherhost,cpp,lzo&lt;br /&gt;
&lt;br /&gt;
==== the host ====&lt;br /&gt;
&lt;br /&gt;
hostname/ip&lt;br /&gt;
localhost&lt;br /&gt;
127.0.0.1&lt;br /&gt;
::1 - does not work&lt;br /&gt;
&lt;br /&gt;
==== protocol ====&lt;br /&gt;
&lt;br /&gt;
* no protocol given&lt;br /&gt;
* ,cpp,lzo protocol&lt;br /&gt;
&lt;br /&gt;
cpp implies lzo, it requires compression, even if you have 10gbit/s or more, it&#039;s just hardcoded&lt;br /&gt;
&lt;br /&gt;
=== threads ===&lt;br /&gt;
/number of workers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== architecture ==&lt;br /&gt;
it can handle C, C++, ObjC, maybe some other stuff&lt;br /&gt;
&lt;br /&gt;
* what happens with normal xmit&lt;br /&gt;
* what happens with pump mode&lt;br /&gt;
* at which step the include server is used and how it collects the includes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== distribution algorithm ===&lt;br /&gt;
honestly I simply don&#039;t get it&lt;br /&gt;
&lt;br /&gt;
* The order matters&lt;br /&gt;
* The number of threads matters&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== localhost ====&lt;br /&gt;
&lt;br /&gt;
* localhost precedence&lt;br /&gt;
* localhost fallback&lt;br /&gt;
&lt;br /&gt;
variable: DISTCC_FALLBACK&lt;br /&gt;
&lt;br /&gt;
0 = Fail to compile if it would need to fallback to a normal local gcc call&lt;br /&gt;
1 = If remote compile fails, just do it yourself&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Operation ==&lt;br /&gt;
&lt;br /&gt;
=== startup and shutdown ===&lt;br /&gt;
service distcc stop is not entirely reliable (it can take a minute after the stop until the processes are gone and sometimes it will never stop&lt;br /&gt;
this is very bad with openrc, the openrc script returns after a second and only relies on its service flags, not the process status.&lt;br /&gt;
manually check after stopping, wait a min, if needed, kill it all.&lt;br /&gt;
at some point the rc file needs to be rewritten, it can&#039;t stay like it is.&lt;br /&gt;
&lt;br /&gt;
if you used a pump mode session, that also needs a logout (pump --shutdown)&lt;br /&gt;
avoid running multiple startups without shutdown in one session. it&#039;s safe as far as I can tell but nothing cleans up these processes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== ccache and memcached ===&lt;br /&gt;
CCACHE is said to be conflicting with pump mode unless when you call them in the backend&lt;br /&gt;
so, where you start the compile, you don&#039;t use it&lt;br /&gt;
where the compile happens, you use it&lt;br /&gt;
they can share the cache via memcached, this is a nice trick for consistency&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== dockerized / native ===&lt;br /&gt;
&lt;br /&gt;
it remains mostly the same, a container needs to make sure it monitors the right services (distccd, nginx, include_server)&lt;br /&gt;
if you&#039;re using zeroconf, you need to somehow expose the mdns service broadcasts &amp;amp; reception&lt;br /&gt;
&lt;br /&gt;
Processs list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
Workdir list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
=== alpine-chroot ===&lt;br /&gt;
&lt;br /&gt;
when using the &#039;official&#039; script there&#039;s still some odd pieces, seemed to be the processes died on logout. but not all of them.&lt;br /&gt;
&lt;br /&gt;
==== manual launch ====&lt;br /&gt;
&lt;br /&gt;
Starting the daemon would be using&lt;br /&gt;
/usr/bin/distccd --pid-file /var/run/distccd/distccd.pid -N 15 --user distcc --port 3632 --log-level=debug --log-file=/var/log/distccd.log --allow my-sub-net/24&lt;br /&gt;
&lt;br /&gt;
==== localhost? =====&lt;br /&gt;
unclear if you need to use --allow for 127.0.0.1/32 or something to allow the remote preproccesor.&lt;br /&gt;
&lt;br /&gt;
== Kernel specific settings ==&lt;br /&gt;
&lt;br /&gt;
currently (distcc 3.4-r9 on Alpine) you need a patch to build the kernel.&lt;br /&gt;
See &lt;br /&gt;
&lt;br /&gt;
=== Include server Settings ===&lt;br /&gt;
&lt;br /&gt;
cache reset triggers&lt;br /&gt;
This ought to be set before enabling pump mode.&lt;br /&gt;
&lt;br /&gt;
export INCLUDE_SERVER_ARGS=&amp;quot;--stat_reset_triggers=include/linux/compile.h:include/asm/asm-offsets.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
link to explanation TBA&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Disabling GCC Plugins ===&lt;br /&gt;
&lt;br /&gt;
KConfig unselect HAVE_GCC_PLUGINS&lt;br /&gt;
&lt;br /&gt;
Some info is here in the troubleshooting part of the Arch Wiki&lt;br /&gt;
https://wiki.archlinux.org/title/Distcc#Troubleshooting&lt;br /&gt;
&lt;br /&gt;
=== Patches ===&lt;br /&gt;
&lt;br /&gt;
Other things (for 6.6LTS)&lt;br /&gt;
PCIe Stub patch&lt;br /&gt;
&lt;br /&gt;
=== Autoconf === &lt;br /&gt;
&lt;br /&gt;
No known setup examples&lt;br /&gt;
Add whatever it publishes in mdns&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== troubleshooting / analysis ==&lt;br /&gt;
&lt;br /&gt;
=== testing ===&lt;br /&gt;
&lt;br /&gt;
# turn off fallback&lt;br /&gt;
&lt;br /&gt;
# GCC example compiles&lt;br /&gt;
## code example C&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example C++&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example ObjC&lt;br /&gt;
## same with included header&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
no ccache here yet&lt;br /&gt;
&lt;br /&gt;
# Cmake example compiles&lt;br /&gt;
the thing with compile launcher ccache;distcc&lt;br /&gt;
&lt;br /&gt;
=== Latency ===&lt;br /&gt;
&lt;br /&gt;
Latency of pump mode startups and fallbacks needs to be investigated.&lt;br /&gt;
LZO is enforced even if you have faster network&lt;br /&gt;
DNS Requests, very old bug report from Gcode, one request per call, is it true? how to get rid of it?&lt;br /&gt;
TMPDIR is respected, make sure it&#039;s on ramdisk even on the remote nodes.&lt;br /&gt;
Compile ideally never goes to disk when it doesn&#039;t have to.&lt;br /&gt;
How efficient is the include server collection and unpacking?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== security ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== tcpwrapper style ip range filter ===&lt;br /&gt;
&lt;br /&gt;
the original security model consists of ip restrictions.&lt;br /&gt;
there seems to also be some GSSAPI user auth.&lt;br /&gt;
further, commands that can be called are restricted by name and location.&lt;br /&gt;
this appears to be a runtime whitelist lookup, meaning it&#039;s done and authorized by the same parts of the daemon as processes the compile request along with the intended compiler.&lt;br /&gt;
so the main weaknesses against malicious clients seem to be in sending things to compile, and in overriding the remote compiler to use.&lt;br /&gt;
it can be assumed that a malicious client able to exploit the compiler handshake can then run arbitrary stuff.&lt;br /&gt;
There&#039;s at least a github issue regarding this google.com/search?q=distcc+seccomp&amp;amp;rlz=1C5CHFA_enDE1121DE1121&amp;amp;oq=distcc+seccomp&amp;amp;gs_lcrp=EgZjaHJvbWUyBggAEEUYOTIHCAEQIRigATIHCAIQIRigAdIBCDM1NjRqMGo3qAIAsAIA&amp;amp;sourceid=chrome&amp;amp;ie=UTF-8 suggesting running over ssh. That does only partitally alleviate this risk with regard  to a key based verfication of a client versus a the standard ip restrictions which always include some parsing.&lt;br /&gt;
So this protects against someone directly exploiting the TCP code of distcc.&lt;br /&gt;
It does not protect against malicious clients.&lt;br /&gt;
(ssh force command can&#039;t be used or you&#039;ll not compile anything)&lt;br /&gt;
&lt;br /&gt;
The basic step for protecting access should be filtering who can access the distcc server, so use nftables etc. to restrict access to port 3262 (??) set up the internal filter the same way.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== seccomp ===&lt;br /&gt;
&lt;br /&gt;
The next thing is to confine the compiler calls to only write in their temp directory and that they can only run compilers (using nsjail, apparmor, selinux etc)&lt;br /&gt;
&lt;br /&gt;
the above issue also references the second bit of security, namely a seccomp filter which will already cover a good bit of the above&lt;br /&gt;
https://github.com/distcc/distcc/pull/235&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
One needs to investigate when compiler_whitelist.sh is exactly called. as far as I recall it doesn&#039;t close stdin/stdout.&lt;br /&gt;
&lt;br /&gt;
The other internal security bit is that they do some priviledge dropping. it runs as a dedicated user (distcc), so you can also have an audit policy, and can/could use something like iptables&#039; to ensure it can only connect to the other distcc/memcached hosts, but nothing else.&lt;br /&gt;
&lt;br /&gt;
=== selinux ===&lt;br /&gt;
&lt;br /&gt;
I think that&#039;s safe enough, the main vector is breakouts and confinement is possible.&lt;br /&gt;
there&#039;s also a selinux policy for distcc from gentoo or liguros if one is so inclined.&lt;br /&gt;
https://repology.org/project/selinux-distcc/versions&lt;br /&gt;
&lt;br /&gt;
=== general posture ===&lt;br /&gt;
&lt;br /&gt;
Some security measures like the above should definitely be used since the project has only a few part-time maintainers that cannot easily drive the project forward or do large refactors.&lt;br /&gt;
But the seccomp changes were done almost 10 years ago, so, to be fair, they still came through.&lt;/div&gt;</summary>
		<author><name>Darkfader</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32126</id>
		<title>User:Darkfader/distcc</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32126"/>
		<updated>2026-03-03T10:44:30Z</updated>

		<summary type="html">&lt;p&gt;Darkfader: /* general posture */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi,&lt;br /&gt;
&lt;br /&gt;
I&#039;m preparing this page. It can take a long time till I finish.&lt;br /&gt;
If you are also wishing to write on this topic, feel free to integrate the content.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Document overview ==&lt;br /&gt;
&lt;br /&gt;
I noticed that almost every distro has one partially complete, partially helpful document on how to use distcc on the distro.&lt;br /&gt;
Usually they also have one for ccache.&lt;br /&gt;
In either case, they&#039;re enough to get started, but not really a reliable watertight thing.&lt;br /&gt;
We definitely needed one of our own.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== goal ===&lt;br /&gt;
&lt;br /&gt;
to describe a working setup for building aports in easiest/fastests fashion&lt;br /&gt;
not planning to add versatility or features where it would make the setup more errorprone.&lt;br /&gt;
the page should describe enough of the steps to successfully compile an LTS kernel via aports and have that job be distributed over multiple nodes.&lt;br /&gt;
Logs should be set up and able to display errors, but not show any errors during the test compile.&lt;br /&gt;
&lt;br /&gt;
To include a path for analysis via testing components.&lt;br /&gt;
&lt;br /&gt;
distcc can greatly improve compile speeds for large software, it comes with a different set of features than ccache; it focusses not avoiding unneccessary compile work, but on a way to speed up the necessary one.&lt;br /&gt;
&lt;br /&gt;
=== audience ===&lt;br /&gt;
people running software builds on alpine and have multiple computers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This page will show a specific installation, specific configuration, and specific tests, resulting in a specific set of functionality that can be tested to be working.&lt;br /&gt;
&lt;br /&gt;
== installation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Packages ===&lt;br /&gt;
&lt;br /&gt;
you need, on each host&lt;br /&gt;
* distcc&lt;br /&gt;
* distccd-openrc&lt;br /&gt;
* distcc-pump&lt;br /&gt;
* distcc-pump-pyc&lt;br /&gt;
&lt;br /&gt;
the .pyc will speed up the invocations, without it &lt;br /&gt;
idk if one or both should be installed in that case. but it appears to be also automatically be precompiled in /usr/lib/python3.12/site-packages/include_server/__pycache__/ so what does the package do exactly?&lt;br /&gt;
&lt;br /&gt;
There&#039;s some references to cpython-312, so maybe it actually still uses classy python-c conversion or matbe that&#039;s just a component for reading C source code. I have zero idea.&lt;br /&gt;
&lt;br /&gt;
you also need stuff to do compiles&lt;br /&gt;
* alpine sdk&lt;br /&gt;
* clang&lt;br /&gt;
* binutils&lt;br /&gt;
...&lt;br /&gt;
* elfutils(-dev)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Settings ===&lt;br /&gt;
==== settings for distcc ====&lt;br /&gt;
&lt;br /&gt;
* there&#039;s /etc/default/distcc&lt;br /&gt;
* there&#039;s /etc/conf.d/distcc &lt;br /&gt;
&lt;br /&gt;
make all your settings here&lt;br /&gt;
* command_whitelist.sh &lt;br /&gt;
&lt;br /&gt;
this is half functional, you need to set things here but you also need to maintain the symlinks that are collected under /usr/lib/distcc (for your compilers) and /usr/lib/distcc/bin (for itself)&lt;br /&gt;
&lt;br /&gt;
you MUST run the script to update the compilers!&lt;br /&gt;
Info for script and what files it will create&lt;br /&gt;
&lt;br /&gt;
/usr/sbin/update-distcc-symlinks&lt;br /&gt;
&lt;br /&gt;
tschike:/usr/bin# ls -l /usr/lib/distcc/&lt;br /&gt;
total 4&lt;br /&gt;
drwxr-xr-x 2 root root 4096 Mar  2 18:14 bin&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c89 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c99 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 cc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc-15.2.0 -&amp;gt; ../../bin/distcc&lt;br /&gt;
&lt;br /&gt;
distcc itself is in bin&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cpp -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 g++ -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 06:49 x86_64-alpine-linux-musl-gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
&lt;br /&gt;
the last symplink here is wrong, made by me and would not work...&lt;br /&gt;
BAD symlink.&lt;br /&gt;
&lt;br /&gt;
=== distcc hosts file ===&lt;br /&gt;
&lt;br /&gt;
idk about that thing it&#039;s odd&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== abuild.conf ===&lt;br /&gt;
&lt;br /&gt;
settings for aports&lt;br /&gt;
* cc=&lt;br /&gt;
* cxx=&lt;br /&gt;
* cpp=&lt;br /&gt;
* cflags=&lt;br /&gt;
* njobs&lt;br /&gt;
&lt;br /&gt;
== detail infos ==&lt;br /&gt;
&lt;br /&gt;
???&lt;br /&gt;
&lt;br /&gt;
=== hosts syntax ===&lt;br /&gt;
&lt;br /&gt;
* myhost otherhost&lt;br /&gt;
* myhost,cpp,lzo myotherhost,cpp,lzo&lt;br /&gt;
&lt;br /&gt;
==== the host ====&lt;br /&gt;
&lt;br /&gt;
hostname/ip&lt;br /&gt;
localhost&lt;br /&gt;
127.0.0.1&lt;br /&gt;
::1 - does not work&lt;br /&gt;
&lt;br /&gt;
==== protocol ====&lt;br /&gt;
&lt;br /&gt;
* no protocol given&lt;br /&gt;
* ,cpp,lzo protocol&lt;br /&gt;
&lt;br /&gt;
cpp implies lzo, it requires compression, even if you have 10gbit/s or more, it&#039;s just hardcoded&lt;br /&gt;
&lt;br /&gt;
=== threads ===&lt;br /&gt;
/number of workers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== architecture ==&lt;br /&gt;
it can handle C, C++, ObjC, maybe some other stuff&lt;br /&gt;
&lt;br /&gt;
* what happens with normal xmit&lt;br /&gt;
* what happens with pump mode&lt;br /&gt;
* at which step the include server is used and how it collects the includes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== distribution algorithm ===&lt;br /&gt;
honestly I simply don&#039;t get it&lt;br /&gt;
&lt;br /&gt;
* The order matters&lt;br /&gt;
* The number of threads matters&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== localhost ====&lt;br /&gt;
&lt;br /&gt;
* localhost precedence&lt;br /&gt;
* localhost fallback&lt;br /&gt;
&lt;br /&gt;
variable: DISTCC_FALLBACK&lt;br /&gt;
&lt;br /&gt;
0 = Fail to compile if it would need to fallback to a normal local gcc call&lt;br /&gt;
1 = If remote compile fails, just do it yourself&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Operation ==&lt;br /&gt;
&lt;br /&gt;
=== startup and shutdown ===&lt;br /&gt;
service distcc stop is not entirely reliable (it can take a minute after the stop until the processes are gone and sometimes it will never stop&lt;br /&gt;
this is very bad with openrc, the openrc script returns after a second and only relies on its service flags, not the process status.&lt;br /&gt;
manually check after stopping, wait a min, if needed, kill it all.&lt;br /&gt;
at some point the rc file needs to be rewritten, it can&#039;t stay like it is.&lt;br /&gt;
&lt;br /&gt;
if you used a pump mode session, that also needs a logout (pump --shutdown)&lt;br /&gt;
avoid running multiple startups without shutdown in one session. it&#039;s safe as far as I can tell but nothing cleans up these processes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== ccache and memcached ===&lt;br /&gt;
CCACHE is said to be conflicting with pump mode unless when you call them in the backend&lt;br /&gt;
so, where you start the compile, you don&#039;t use it&lt;br /&gt;
where the compile happens, you use it&lt;br /&gt;
they can share the cache via memcached, this is a nice trick for consistency&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== dockerized / native ===&lt;br /&gt;
&lt;br /&gt;
it remains mostly the same, a container needs to make sure it monitors the right services (distccd, nginx, include_server)&lt;br /&gt;
if you&#039;re using zeroconf, you need to somehow expose the mdns service broadcasts &amp;amp; reception&lt;br /&gt;
&lt;br /&gt;
Processs list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
Workdir list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
=== alpine-chroot ===&lt;br /&gt;
&lt;br /&gt;
when using the &#039;official&#039; script there&#039;s still some odd pieces, seemed to be the processes died on logout. but not all of them.&lt;br /&gt;
&lt;br /&gt;
==== manual launch ====&lt;br /&gt;
&lt;br /&gt;
Starting the daemon would be using&lt;br /&gt;
/usr/bin/distccd --pid-file /var/run/distccd/distccd.pid -N 15 --user distcc --port 3632 --log-level=debug --log-file=/var/log/distccd.log --allow my-sub-net/24&lt;br /&gt;
&lt;br /&gt;
==== localhost? =====&lt;br /&gt;
unclear if you need to use --allow for 127.0.0.1/32 or something to allow the remote preproccesor.&lt;br /&gt;
&lt;br /&gt;
== Kernel specific settings ==&lt;br /&gt;
&lt;br /&gt;
currently (distcc 3.4-r9 on Alpine) you need a patch to build the kernel.&lt;br /&gt;
See &lt;br /&gt;
&lt;br /&gt;
=== Include server Settings ===&lt;br /&gt;
&lt;br /&gt;
cache reset triggers&lt;br /&gt;
This ought to be set before enabling pump mode.&lt;br /&gt;
&lt;br /&gt;
export INCLUDE_SERVER_ARGS=&amp;quot;--stat_reset_triggers=include/linux/compile.h:include/asm/asm-offsets.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
link to explanation TBA&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Disabling GCC Plugins ===&lt;br /&gt;
&lt;br /&gt;
KConfig unselect HAVE_GCC_PLUGINS&lt;br /&gt;
&lt;br /&gt;
Some info is here in the troubleshooting part of the Arch Wiki&lt;br /&gt;
https://wiki.archlinux.org/title/Distcc#Troubleshooting&lt;br /&gt;
&lt;br /&gt;
=== Patches ===&lt;br /&gt;
&lt;br /&gt;
Other things (for 6.6LTS)&lt;br /&gt;
PCIe Stub patch&lt;br /&gt;
&lt;br /&gt;
=== Autoconf === &lt;br /&gt;
&lt;br /&gt;
No known setup examples&lt;br /&gt;
Add whatever it publishes in mdns&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== troubleshooting / analysis ==&lt;br /&gt;
&lt;br /&gt;
=== testing ===&lt;br /&gt;
&lt;br /&gt;
# turn off fallback&lt;br /&gt;
&lt;br /&gt;
# GCC example compiles&lt;br /&gt;
## code example C&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example C++&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example ObjC&lt;br /&gt;
## same with included header&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
no ccache here yet&lt;br /&gt;
&lt;br /&gt;
# Cmake example compiles&lt;br /&gt;
the thing with compile launcher ccache;distcc&lt;br /&gt;
&lt;br /&gt;
=== Latency ===&lt;br /&gt;
&lt;br /&gt;
Latency of pump mode startups and fallbacks needs to be investigated.&lt;br /&gt;
LZO is enforced even if you have faster network&lt;br /&gt;
DNS Requests, very old bug report from Gcode, one request per call, is it true? how to get rid of it?&lt;br /&gt;
TMPDIR is respected, make sure it&#039;s on ramdisk even on the remote nodes.&lt;br /&gt;
Compile ideally never goes to disk when it doesn&#039;t have to.&lt;br /&gt;
How efficient is the include server collection and unpacking?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== security ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== tcpwrapper style ip range filter ===&lt;br /&gt;
&lt;br /&gt;
the original security model consists of ip restrictions.&lt;br /&gt;
there seems to also be some GSSAPI user auth.&lt;br /&gt;
further, commands that can be called are restricted by name and location.&lt;br /&gt;
this appears to be a runtime whitelist lookup, meaning it&#039;s done and authorized by the same parts of the daemon as processes the compile request along with the intended compiler.&lt;br /&gt;
so the main weaknesses against malicious clients seem to be in sending things to compile, and in overriding the remote compiler to use.&lt;br /&gt;
it can be assumed that a malicious client able to exploit the compiler handshake can then run arbitrary stuff.&lt;br /&gt;
There&#039;s at least a github issue regarding this google.com/search?q=distcc+seccomp&amp;amp;rlz=1C5CHFA_enDE1121DE1121&amp;amp;oq=distcc+seccomp&amp;amp;gs_lcrp=EgZjaHJvbWUyBggAEEUYOTIHCAEQIRigATIHCAIQIRigAdIBCDM1NjRqMGo3qAIAsAIA&amp;amp;sourceid=chrome&amp;amp;ie=UTF-8 suggesting running over ssh. That does only partitally alleviate this risk with regard  to a key based verfication of a client versus a the standard ip restrictions which always include some parsing.&lt;br /&gt;
So this protects against someone directly exploiting the TCP code of distcc.&lt;br /&gt;
It does not protect against malicious clients.&lt;br /&gt;
(ssh force command can&#039;t be used or you&#039;ll not compile anything)&lt;br /&gt;
&lt;br /&gt;
The basic step for protecting access should be filtering who can access the distcc server, so use nftables etc. to restrict access to port 3262 (??) set up the internal filter the same way.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== seccomp ===&lt;br /&gt;
&lt;br /&gt;
The next thing is to confine the compiler calls to only write in their temp directory and that they can only run compilers (using nsjail, apparmor, selinux etc)&lt;br /&gt;
&lt;br /&gt;
the above issue also references the second bit of security, namely a seccomp filter which will already cover a good bit of the above&lt;br /&gt;
https://github.com/distcc/distcc/pull/235&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
One needs to investigate when compiler_whitelist.sh is exactly called. as far as I recall it doesn&#039;t close stdin/stdout.&lt;br /&gt;
&lt;br /&gt;
The other internal security bit is that they do some priviledge dropping. it runs as a dedicated user (distcc), so you can also have an audit policy, and can/could use something like iptables&#039; to ensure it can only connect to the other distcc/memcached hosts, but nothing else.&lt;br /&gt;
&lt;br /&gt;
=== selinux ===&lt;br /&gt;
&lt;br /&gt;
I think that&#039;s safe enough, the main vector is breakouts and confinement is possible.&lt;br /&gt;
there&#039;s also a selinux policy for distcc from gentoo or liguros if one is so inclined.&lt;br /&gt;
https://repology.org/project/selinux-distcc/versions&lt;br /&gt;
&lt;br /&gt;
=== general posture ===&lt;br /&gt;
&lt;br /&gt;
Some security measures like the above should definitely be used since the project has only a few part-time maintainers that cannot drive the project forward or do large refactors.&lt;/div&gt;</summary>
		<author><name>Darkfader</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32125</id>
		<title>User:Darkfader/distcc</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32125"/>
		<updated>2026-03-03T10:44:03Z</updated>

		<summary type="html">&lt;p&gt;Darkfader: /* security */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi,&lt;br /&gt;
&lt;br /&gt;
I&#039;m preparing this page. It can take a long time till I finish.&lt;br /&gt;
If you are also wishing to write on this topic, feel free to integrate the content.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Document overview ==&lt;br /&gt;
&lt;br /&gt;
I noticed that almost every distro has one partially complete, partially helpful document on how to use distcc on the distro.&lt;br /&gt;
Usually they also have one for ccache.&lt;br /&gt;
In either case, they&#039;re enough to get started, but not really a reliable watertight thing.&lt;br /&gt;
We definitely needed one of our own.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== goal ===&lt;br /&gt;
&lt;br /&gt;
to describe a working setup for building aports in easiest/fastests fashion&lt;br /&gt;
not planning to add versatility or features where it would make the setup more errorprone.&lt;br /&gt;
the page should describe enough of the steps to successfully compile an LTS kernel via aports and have that job be distributed over multiple nodes.&lt;br /&gt;
Logs should be set up and able to display errors, but not show any errors during the test compile.&lt;br /&gt;
&lt;br /&gt;
To include a path for analysis via testing components.&lt;br /&gt;
&lt;br /&gt;
distcc can greatly improve compile speeds for large software, it comes with a different set of features than ccache; it focusses not avoiding unneccessary compile work, but on a way to speed up the necessary one.&lt;br /&gt;
&lt;br /&gt;
=== audience ===&lt;br /&gt;
people running software builds on alpine and have multiple computers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This page will show a specific installation, specific configuration, and specific tests, resulting in a specific set of functionality that can be tested to be working.&lt;br /&gt;
&lt;br /&gt;
== installation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Packages ===&lt;br /&gt;
&lt;br /&gt;
you need, on each host&lt;br /&gt;
* distcc&lt;br /&gt;
* distccd-openrc&lt;br /&gt;
* distcc-pump&lt;br /&gt;
* distcc-pump-pyc&lt;br /&gt;
&lt;br /&gt;
the .pyc will speed up the invocations, without it &lt;br /&gt;
idk if one or both should be installed in that case. but it appears to be also automatically be precompiled in /usr/lib/python3.12/site-packages/include_server/__pycache__/ so what does the package do exactly?&lt;br /&gt;
&lt;br /&gt;
There&#039;s some references to cpython-312, so maybe it actually still uses classy python-c conversion or matbe that&#039;s just a component for reading C source code. I have zero idea.&lt;br /&gt;
&lt;br /&gt;
you also need stuff to do compiles&lt;br /&gt;
* alpine sdk&lt;br /&gt;
* clang&lt;br /&gt;
* binutils&lt;br /&gt;
...&lt;br /&gt;
* elfutils(-dev)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Settings ===&lt;br /&gt;
==== settings for distcc ====&lt;br /&gt;
&lt;br /&gt;
* there&#039;s /etc/default/distcc&lt;br /&gt;
* there&#039;s /etc/conf.d/distcc &lt;br /&gt;
&lt;br /&gt;
make all your settings here&lt;br /&gt;
* command_whitelist.sh &lt;br /&gt;
&lt;br /&gt;
this is half functional, you need to set things here but you also need to maintain the symlinks that are collected under /usr/lib/distcc (for your compilers) and /usr/lib/distcc/bin (for itself)&lt;br /&gt;
&lt;br /&gt;
you MUST run the script to update the compilers!&lt;br /&gt;
Info for script and what files it will create&lt;br /&gt;
&lt;br /&gt;
/usr/sbin/update-distcc-symlinks&lt;br /&gt;
&lt;br /&gt;
tschike:/usr/bin# ls -l /usr/lib/distcc/&lt;br /&gt;
total 4&lt;br /&gt;
drwxr-xr-x 2 root root 4096 Mar  2 18:14 bin&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c89 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c99 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 cc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc-15.2.0 -&amp;gt; ../../bin/distcc&lt;br /&gt;
&lt;br /&gt;
distcc itself is in bin&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cpp -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 g++ -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 06:49 x86_64-alpine-linux-musl-gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
&lt;br /&gt;
the last symplink here is wrong, made by me and would not work...&lt;br /&gt;
BAD symlink.&lt;br /&gt;
&lt;br /&gt;
=== distcc hosts file ===&lt;br /&gt;
&lt;br /&gt;
idk about that thing it&#039;s odd&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== abuild.conf ===&lt;br /&gt;
&lt;br /&gt;
settings for aports&lt;br /&gt;
* cc=&lt;br /&gt;
* cxx=&lt;br /&gt;
* cpp=&lt;br /&gt;
* cflags=&lt;br /&gt;
* njobs&lt;br /&gt;
&lt;br /&gt;
== detail infos ==&lt;br /&gt;
&lt;br /&gt;
???&lt;br /&gt;
&lt;br /&gt;
=== hosts syntax ===&lt;br /&gt;
&lt;br /&gt;
* myhost otherhost&lt;br /&gt;
* myhost,cpp,lzo myotherhost,cpp,lzo&lt;br /&gt;
&lt;br /&gt;
==== the host ====&lt;br /&gt;
&lt;br /&gt;
hostname/ip&lt;br /&gt;
localhost&lt;br /&gt;
127.0.0.1&lt;br /&gt;
::1 - does not work&lt;br /&gt;
&lt;br /&gt;
==== protocol ====&lt;br /&gt;
&lt;br /&gt;
* no protocol given&lt;br /&gt;
* ,cpp,lzo protocol&lt;br /&gt;
&lt;br /&gt;
cpp implies lzo, it requires compression, even if you have 10gbit/s or more, it&#039;s just hardcoded&lt;br /&gt;
&lt;br /&gt;
=== threads ===&lt;br /&gt;
/number of workers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== architecture ==&lt;br /&gt;
it can handle C, C++, ObjC, maybe some other stuff&lt;br /&gt;
&lt;br /&gt;
* what happens with normal xmit&lt;br /&gt;
* what happens with pump mode&lt;br /&gt;
* at which step the include server is used and how it collects the includes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== distribution algorithm ===&lt;br /&gt;
honestly I simply don&#039;t get it&lt;br /&gt;
&lt;br /&gt;
* The order matters&lt;br /&gt;
* The number of threads matters&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== localhost ====&lt;br /&gt;
&lt;br /&gt;
* localhost precedence&lt;br /&gt;
* localhost fallback&lt;br /&gt;
&lt;br /&gt;
variable: DISTCC_FALLBACK&lt;br /&gt;
&lt;br /&gt;
0 = Fail to compile if it would need to fallback to a normal local gcc call&lt;br /&gt;
1 = If remote compile fails, just do it yourself&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Operation ==&lt;br /&gt;
&lt;br /&gt;
=== startup and shutdown ===&lt;br /&gt;
service distcc stop is not entirely reliable (it can take a minute after the stop until the processes are gone and sometimes it will never stop&lt;br /&gt;
this is very bad with openrc, the openrc script returns after a second and only relies on its service flags, not the process status.&lt;br /&gt;
manually check after stopping, wait a min, if needed, kill it all.&lt;br /&gt;
at some point the rc file needs to be rewritten, it can&#039;t stay like it is.&lt;br /&gt;
&lt;br /&gt;
if you used a pump mode session, that also needs a logout (pump --shutdown)&lt;br /&gt;
avoid running multiple startups without shutdown in one session. it&#039;s safe as far as I can tell but nothing cleans up these processes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== ccache and memcached ===&lt;br /&gt;
CCACHE is said to be conflicting with pump mode unless when you call them in the backend&lt;br /&gt;
so, where you start the compile, you don&#039;t use it&lt;br /&gt;
where the compile happens, you use it&lt;br /&gt;
they can share the cache via memcached, this is a nice trick for consistency&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== dockerized / native ===&lt;br /&gt;
&lt;br /&gt;
it remains mostly the same, a container needs to make sure it monitors the right services (distccd, nginx, include_server)&lt;br /&gt;
if you&#039;re using zeroconf, you need to somehow expose the mdns service broadcasts &amp;amp; reception&lt;br /&gt;
&lt;br /&gt;
Processs list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
Workdir list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
=== alpine-chroot ===&lt;br /&gt;
&lt;br /&gt;
when using the &#039;official&#039; script there&#039;s still some odd pieces, seemed to be the processes died on logout. but not all of them.&lt;br /&gt;
&lt;br /&gt;
==== manual launch ====&lt;br /&gt;
&lt;br /&gt;
Starting the daemon would be using&lt;br /&gt;
/usr/bin/distccd --pid-file /var/run/distccd/distccd.pid -N 15 --user distcc --port 3632 --log-level=debug --log-file=/var/log/distccd.log --allow my-sub-net/24&lt;br /&gt;
&lt;br /&gt;
==== localhost? =====&lt;br /&gt;
unclear if you need to use --allow for 127.0.0.1/32 or something to allow the remote preproccesor.&lt;br /&gt;
&lt;br /&gt;
== Kernel specific settings ==&lt;br /&gt;
&lt;br /&gt;
currently (distcc 3.4-r9 on Alpine) you need a patch to build the kernel.&lt;br /&gt;
See &lt;br /&gt;
&lt;br /&gt;
=== Include server Settings ===&lt;br /&gt;
&lt;br /&gt;
cache reset triggers&lt;br /&gt;
This ought to be set before enabling pump mode.&lt;br /&gt;
&lt;br /&gt;
export INCLUDE_SERVER_ARGS=&amp;quot;--stat_reset_triggers=include/linux/compile.h:include/asm/asm-offsets.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
link to explanation TBA&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Disabling GCC Plugins ===&lt;br /&gt;
&lt;br /&gt;
KConfig unselect HAVE_GCC_PLUGINS&lt;br /&gt;
&lt;br /&gt;
Some info is here in the troubleshooting part of the Arch Wiki&lt;br /&gt;
https://wiki.archlinux.org/title/Distcc#Troubleshooting&lt;br /&gt;
&lt;br /&gt;
=== Patches ===&lt;br /&gt;
&lt;br /&gt;
Other things (for 6.6LTS)&lt;br /&gt;
PCIe Stub patch&lt;br /&gt;
&lt;br /&gt;
=== Autoconf === &lt;br /&gt;
&lt;br /&gt;
No known setup examples&lt;br /&gt;
Add whatever it publishes in mdns&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== troubleshooting / analysis ==&lt;br /&gt;
&lt;br /&gt;
=== testing ===&lt;br /&gt;
&lt;br /&gt;
# turn off fallback&lt;br /&gt;
&lt;br /&gt;
# GCC example compiles&lt;br /&gt;
## code example C&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example C++&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example ObjC&lt;br /&gt;
## same with included header&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
no ccache here yet&lt;br /&gt;
&lt;br /&gt;
# Cmake example compiles&lt;br /&gt;
the thing with compile launcher ccache;distcc&lt;br /&gt;
&lt;br /&gt;
=== Latency ===&lt;br /&gt;
&lt;br /&gt;
Latency of pump mode startups and fallbacks needs to be investigated.&lt;br /&gt;
LZO is enforced even if you have faster network&lt;br /&gt;
DNS Requests, very old bug report from Gcode, one request per call, is it true? how to get rid of it?&lt;br /&gt;
TMPDIR is respected, make sure it&#039;s on ramdisk even on the remote nodes.&lt;br /&gt;
Compile ideally never goes to disk when it doesn&#039;t have to.&lt;br /&gt;
How efficient is the include server collection and unpacking?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== security ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== tcpwrapper style ip range filter ===&lt;br /&gt;
&lt;br /&gt;
the original security model consists of ip restrictions.&lt;br /&gt;
there seems to also be some GSSAPI user auth.&lt;br /&gt;
further, commands that can be called are restricted by name and location.&lt;br /&gt;
this appears to be a runtime whitelist lookup, meaning it&#039;s done and authorized by the same parts of the daemon as processes the compile request along with the intended compiler.&lt;br /&gt;
so the main weaknesses against malicious clients seem to be in sending things to compile, and in overriding the remote compiler to use.&lt;br /&gt;
it can be assumed that a malicious client able to exploit the compiler handshake can then run arbitrary stuff.&lt;br /&gt;
There&#039;s at least a github issue regarding this google.com/search?q=distcc+seccomp&amp;amp;rlz=1C5CHFA_enDE1121DE1121&amp;amp;oq=distcc+seccomp&amp;amp;gs_lcrp=EgZjaHJvbWUyBggAEEUYOTIHCAEQIRigATIHCAIQIRigAdIBCDM1NjRqMGo3qAIAsAIA&amp;amp;sourceid=chrome&amp;amp;ie=UTF-8 suggesting running over ssh. That does only partitally alleviate this risk with regard  to a key based verfication of a client versus a the standard ip restrictions which always include some parsing.&lt;br /&gt;
So this protects against someone directly exploiting the TCP code of distcc.&lt;br /&gt;
It does not protect against malicious clients.&lt;br /&gt;
(ssh force command can&#039;t be used or you&#039;ll not compile anything)&lt;br /&gt;
&lt;br /&gt;
The basic step for protecting access should be filtering who can access the distcc server, so use nftables etc. to restrict access to port 3262 (??) set up the internal filter the same way.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== seccomp ===&lt;br /&gt;
&lt;br /&gt;
The next thing is to confine the compiler calls to only write in their temp directory and that they can only run compilers (using nsjail, apparmor, selinux etc)&lt;br /&gt;
&lt;br /&gt;
the above issue also references the second bit of security, namely a seccomp filter which will already cover a good bit of the above&lt;br /&gt;
https://github.com/distcc/distcc/pull/235&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
One needs to investigate when compiler_whitelist.sh is exactly called. as far as I recall it doesn&#039;t close stdin/stdout.&lt;br /&gt;
&lt;br /&gt;
The other internal security bit is that they do some priviledge dropping. it runs as a dedicated user (distcc), so you can also have an audit policy, and can/could use something like iptables&#039; to ensure it can only connect to the other distcc/memcached hosts, but nothing else.&lt;br /&gt;
&lt;br /&gt;
=== selinux ===&lt;br /&gt;
&lt;br /&gt;
I think that&#039;s safe enough, the main vector is breakouts and confinement is possible.&lt;br /&gt;
there&#039;s also a selinux policy for distcc from gentoo or liguros if one is so inclined.&lt;br /&gt;
https://repology.org/project/selinux-distcc/versions&lt;br /&gt;
&lt;br /&gt;
=== general posture ===&lt;br /&gt;
&lt;br /&gt;
Some extra measures should be taken since the project has only a few part-time maintainers that cannot drive the project forward or do large refactors.&lt;/div&gt;</summary>
		<author><name>Darkfader</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32124</id>
		<title>User:Darkfader/distcc</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32124"/>
		<updated>2026-03-03T10:32:10Z</updated>

		<summary type="html">&lt;p&gt;Darkfader: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi,&lt;br /&gt;
&lt;br /&gt;
I&#039;m preparing this page. It can take a long time till I finish.&lt;br /&gt;
If you are also wishing to write on this topic, feel free to integrate the content.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Document overview ==&lt;br /&gt;
&lt;br /&gt;
I noticed that almost every distro has one partially complete, partially helpful document on how to use distcc on the distro.&lt;br /&gt;
Usually they also have one for ccache.&lt;br /&gt;
In either case, they&#039;re enough to get started, but not really a reliable watertight thing.&lt;br /&gt;
We definitely needed one of our own.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== goal ===&lt;br /&gt;
&lt;br /&gt;
to describe a working setup for building aports in easiest/fastests fashion&lt;br /&gt;
not planning to add versatility or features where it would make the setup more errorprone.&lt;br /&gt;
the page should describe enough of the steps to successfully compile an LTS kernel via aports and have that job be distributed over multiple nodes.&lt;br /&gt;
Logs should be set up and able to display errors, but not show any errors during the test compile.&lt;br /&gt;
&lt;br /&gt;
To include a path for analysis via testing components.&lt;br /&gt;
&lt;br /&gt;
distcc can greatly improve compile speeds for large software, it comes with a different set of features than ccache; it focusses not avoiding unneccessary compile work, but on a way to speed up the necessary one.&lt;br /&gt;
&lt;br /&gt;
=== audience ===&lt;br /&gt;
people running software builds on alpine and have multiple computers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This page will show a specific installation, specific configuration, and specific tests, resulting in a specific set of functionality that can be tested to be working.&lt;br /&gt;
&lt;br /&gt;
== installation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Packages ===&lt;br /&gt;
&lt;br /&gt;
you need, on each host&lt;br /&gt;
* distcc&lt;br /&gt;
* distccd-openrc&lt;br /&gt;
* distcc-pump&lt;br /&gt;
* distcc-pump-pyc&lt;br /&gt;
&lt;br /&gt;
the .pyc will speed up the invocations, without it &lt;br /&gt;
idk if one or both should be installed in that case. but it appears to be also automatically be precompiled in /usr/lib/python3.12/site-packages/include_server/__pycache__/ so what does the package do exactly?&lt;br /&gt;
&lt;br /&gt;
There&#039;s some references to cpython-312, so maybe it actually still uses classy python-c conversion or matbe that&#039;s just a component for reading C source code. I have zero idea.&lt;br /&gt;
&lt;br /&gt;
you also need stuff to do compiles&lt;br /&gt;
* alpine sdk&lt;br /&gt;
* clang&lt;br /&gt;
* binutils&lt;br /&gt;
...&lt;br /&gt;
* elfutils(-dev)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Settings ===&lt;br /&gt;
==== settings for distcc ====&lt;br /&gt;
&lt;br /&gt;
* there&#039;s /etc/default/distcc&lt;br /&gt;
* there&#039;s /etc/conf.d/distcc &lt;br /&gt;
&lt;br /&gt;
make all your settings here&lt;br /&gt;
* command_whitelist.sh &lt;br /&gt;
&lt;br /&gt;
this is half functional, you need to set things here but you also need to maintain the symlinks that are collected under /usr/lib/distcc (for your compilers) and /usr/lib/distcc/bin (for itself)&lt;br /&gt;
&lt;br /&gt;
you MUST run the script to update the compilers!&lt;br /&gt;
Info for script and what files it will create&lt;br /&gt;
&lt;br /&gt;
/usr/sbin/update-distcc-symlinks&lt;br /&gt;
&lt;br /&gt;
tschike:/usr/bin# ls -l /usr/lib/distcc/&lt;br /&gt;
total 4&lt;br /&gt;
drwxr-xr-x 2 root root 4096 Mar  2 18:14 bin&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c89 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c99 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 cc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc-15.2.0 -&amp;gt; ../../bin/distcc&lt;br /&gt;
&lt;br /&gt;
distcc itself is in bin&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cpp -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 g++ -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 06:49 x86_64-alpine-linux-musl-gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
&lt;br /&gt;
the last symplink here is wrong, made by me and would not work...&lt;br /&gt;
BAD symlink.&lt;br /&gt;
&lt;br /&gt;
=== distcc hosts file ===&lt;br /&gt;
&lt;br /&gt;
idk about that thing it&#039;s odd&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== abuild.conf ===&lt;br /&gt;
&lt;br /&gt;
settings for aports&lt;br /&gt;
* cc=&lt;br /&gt;
* cxx=&lt;br /&gt;
* cpp=&lt;br /&gt;
* cflags=&lt;br /&gt;
* njobs&lt;br /&gt;
&lt;br /&gt;
== detail infos ==&lt;br /&gt;
&lt;br /&gt;
???&lt;br /&gt;
&lt;br /&gt;
=== hosts syntax ===&lt;br /&gt;
&lt;br /&gt;
* myhost otherhost&lt;br /&gt;
* myhost,cpp,lzo myotherhost,cpp,lzo&lt;br /&gt;
&lt;br /&gt;
==== the host ====&lt;br /&gt;
&lt;br /&gt;
hostname/ip&lt;br /&gt;
localhost&lt;br /&gt;
127.0.0.1&lt;br /&gt;
::1 - does not work&lt;br /&gt;
&lt;br /&gt;
==== protocol ====&lt;br /&gt;
&lt;br /&gt;
* no protocol given&lt;br /&gt;
* ,cpp,lzo protocol&lt;br /&gt;
&lt;br /&gt;
cpp implies lzo, it requires compression, even if you have 10gbit/s or more, it&#039;s just hardcoded&lt;br /&gt;
&lt;br /&gt;
=== threads ===&lt;br /&gt;
/number of workers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== architecture ==&lt;br /&gt;
it can handle C, C++, ObjC, maybe some other stuff&lt;br /&gt;
&lt;br /&gt;
* what happens with normal xmit&lt;br /&gt;
* what happens with pump mode&lt;br /&gt;
* at which step the include server is used and how it collects the includes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== distribution algorithm ===&lt;br /&gt;
honestly I simply don&#039;t get it&lt;br /&gt;
&lt;br /&gt;
* The order matters&lt;br /&gt;
* The number of threads matters&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== localhost ====&lt;br /&gt;
&lt;br /&gt;
* localhost precedence&lt;br /&gt;
* localhost fallback&lt;br /&gt;
&lt;br /&gt;
variable: DISTCC_FALLBACK&lt;br /&gt;
&lt;br /&gt;
0 = Fail to compile if it would need to fallback to a normal local gcc call&lt;br /&gt;
1 = If remote compile fails, just do it yourself&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Operation ==&lt;br /&gt;
&lt;br /&gt;
=== startup and shutdown ===&lt;br /&gt;
service distcc stop is not entirely reliable (it can take a minute after the stop until the processes are gone and sometimes it will never stop&lt;br /&gt;
this is very bad with openrc, the openrc script returns after a second and only relies on its service flags, not the process status.&lt;br /&gt;
manually check after stopping, wait a min, if needed, kill it all.&lt;br /&gt;
at some point the rc file needs to be rewritten, it can&#039;t stay like it is.&lt;br /&gt;
&lt;br /&gt;
if you used a pump mode session, that also needs a logout (pump --shutdown)&lt;br /&gt;
avoid running multiple startups without shutdown in one session. it&#039;s safe as far as I can tell but nothing cleans up these processes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== ccache and memcached ===&lt;br /&gt;
CCACHE is said to be conflicting with pump mode unless when you call them in the backend&lt;br /&gt;
so, where you start the compile, you don&#039;t use it&lt;br /&gt;
where the compile happens, you use it&lt;br /&gt;
they can share the cache via memcached, this is a nice trick for consistency&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== dockerized / native ===&lt;br /&gt;
&lt;br /&gt;
it remains mostly the same, a container needs to make sure it monitors the right services (distccd, nginx, include_server)&lt;br /&gt;
if you&#039;re using zeroconf, you need to somehow expose the mdns service broadcasts &amp;amp; reception&lt;br /&gt;
&lt;br /&gt;
Processs list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
Workdir list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
=== alpine-chroot ===&lt;br /&gt;
&lt;br /&gt;
when using the &#039;official&#039; script there&#039;s still some odd pieces, seemed to be the processes died on logout. but not all of them.&lt;br /&gt;
&lt;br /&gt;
==== manual launch ====&lt;br /&gt;
&lt;br /&gt;
Starting the daemon would be using&lt;br /&gt;
/usr/bin/distccd --pid-file /var/run/distccd/distccd.pid -N 15 --user distcc --port 3632 --log-level=debug --log-file=/var/log/distccd.log --allow my-sub-net/24&lt;br /&gt;
&lt;br /&gt;
==== localhost? =====&lt;br /&gt;
unclear if you need to use --allow for 127.0.0.1/32 or something to allow the remote preproccesor.&lt;br /&gt;
&lt;br /&gt;
== Kernel specific settings ==&lt;br /&gt;
&lt;br /&gt;
currently (distcc 3.4-r9 on Alpine) you need a patch to build the kernel.&lt;br /&gt;
See &lt;br /&gt;
&lt;br /&gt;
=== Include server Settings ===&lt;br /&gt;
&lt;br /&gt;
cache reset triggers&lt;br /&gt;
This ought to be set before enabling pump mode.&lt;br /&gt;
&lt;br /&gt;
export INCLUDE_SERVER_ARGS=&amp;quot;--stat_reset_triggers=include/linux/compile.h:include/asm/asm-offsets.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
link to explanation TBA&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Disabling GCC Plugins ===&lt;br /&gt;
&lt;br /&gt;
KConfig unselect HAVE_GCC_PLUGINS&lt;br /&gt;
&lt;br /&gt;
Some info is here in the troubleshooting part of the Arch Wiki&lt;br /&gt;
https://wiki.archlinux.org/title/Distcc#Troubleshooting&lt;br /&gt;
&lt;br /&gt;
=== Patches ===&lt;br /&gt;
&lt;br /&gt;
Other things (for 6.6LTS)&lt;br /&gt;
PCIe Stub patch&lt;br /&gt;
&lt;br /&gt;
=== Autoconf === &lt;br /&gt;
&lt;br /&gt;
No known setup examples&lt;br /&gt;
Add whatever it publishes in mdns&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== troubleshooting / analysis ==&lt;br /&gt;
&lt;br /&gt;
=== testing ===&lt;br /&gt;
&lt;br /&gt;
# turn off fallback&lt;br /&gt;
&lt;br /&gt;
# GCC example compiles&lt;br /&gt;
## code example C&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example C++&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example ObjC&lt;br /&gt;
## same with included header&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
no ccache here yet&lt;br /&gt;
&lt;br /&gt;
# Cmake example compiles&lt;br /&gt;
the thing with compile launcher ccache;distcc&lt;br /&gt;
&lt;br /&gt;
=== Latency ===&lt;br /&gt;
&lt;br /&gt;
Latency of pump mode startups and fallbacks needs to be investigated.&lt;br /&gt;
LZO is enforced even if you have faster network&lt;br /&gt;
DNS Requests, very old bug report from Gcode, one request per call, is it true? how to get rid of it?&lt;br /&gt;
TMPDIR is respected, make sure it&#039;s on ramdisk even on the remote nodes.&lt;br /&gt;
Compile ideally never goes to disk when it doesn&#039;t have to.&lt;br /&gt;
How efficient is the include server collection and unpacking?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== security ==&lt;br /&gt;
&lt;br /&gt;
the security model consists of ip restrictions.&lt;br /&gt;
there seems to also be some GSSAPI user auth.&lt;br /&gt;
further, commands that can be called are restricted by name and location.&lt;br /&gt;
this appears to be a runtime whitelist lookup, meaning it&#039;s done and authorized by the same parts of the daemon as processes the compile request along with the intended compiler.&lt;br /&gt;
so the main weaknesses against malicious clients seem to be in sending things to compile, and in overriding the remote compiler to use.&lt;br /&gt;
it can be assumed that a malicious client able to exploit the compiler handshake can then run arbitrary stuff.&lt;br /&gt;
There&#039;s at least a github issue regarding this google.com/search?q=distcc+seccomp&amp;amp;rlz=1C5CHFA_enDE1121DE1121&amp;amp;oq=distcc+seccomp&amp;amp;gs_lcrp=EgZjaHJvbWUyBggAEEUYOTIHCAEQIRigATIHCAIQIRigAdIBCDM1NjRqMGo3qAIAsAIA&amp;amp;sourceid=chrome&amp;amp;ie=UTF-8 suggesting running over ssh. That does only partitally alleviate this risk with regard  to a key based verfication of a client versus a the standard ip restrictions which always include some parsing.&lt;br /&gt;
So this protects against someone directly exploiting the TCP code of distcc.&lt;br /&gt;
It does not protect against malicious clients.&lt;br /&gt;
(ssh force command can&#039;t be used or you&#039;ll not compile anything)&lt;br /&gt;
&lt;br /&gt;
The basic step for protecting access should be filtering who can access the distcc server, so use nftables etc. to restrict access to port 3262 (??) set up the internal filter the same way.&lt;br /&gt;
&lt;br /&gt;
The next thing is to confine the compiler calls to only write in their temp directory and that they can only run compilers (using nsjail, apparmor, selinux etc)&lt;br /&gt;
&lt;br /&gt;
One needs to investigate when compiler_whitelist.sh is exactly called. as far as I recall it doesn&#039;t close stdin/stdout.&lt;br /&gt;
&lt;br /&gt;
The other internal security bit is that they do some priviledge dropping. it runs as a dedicated user (distcc), so you can also have an audit policy, and can/could use something like iptables&#039; to ensure it can only connect to the other distcc/memcached hosts, but nothing else.&lt;br /&gt;
&lt;br /&gt;
I think that&#039;s safe enough, the main vector is breakouts and confinement is possible.&lt;br /&gt;
there&#039;s also a selinux policy for distcc from gentoo or liguros if one is so inclined.&lt;br /&gt;
https://repology.org/project/selinux-distcc/versions&lt;br /&gt;
&lt;br /&gt;
Some extra measures should be taken since the project has only a few part-time maintainers that cannot drive the project forward or do large refactors.&lt;/div&gt;</summary>
		<author><name>Darkfader</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32123</id>
		<title>User:Darkfader/distcc</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32123"/>
		<updated>2026-03-03T10:24:17Z</updated>

		<summary type="html">&lt;p&gt;Darkfader: /* Disabling GCC Plugins */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi,&lt;br /&gt;
&lt;br /&gt;
I&#039;m preparing this page. It can take a long time till I finish.&lt;br /&gt;
If you are also wishing to write on this topic, feel free to integrate the content.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Document overview ==&lt;br /&gt;
&lt;br /&gt;
I noticed that almost every distro has one partially complete, partially helpful document on how to use distcc on the distro.&lt;br /&gt;
Usually they also have one for ccache.&lt;br /&gt;
In either case, they&#039;re enough to get started, but not really a reliable watertight thing.&lt;br /&gt;
We definitely needed one of our own.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== goal ===&lt;br /&gt;
&lt;br /&gt;
to describe a working setup for building aports in easiest/fastests fashion&lt;br /&gt;
not planning to add versatility or features where it would make the setup more errorprone.&lt;br /&gt;
the page should describe enough of the steps to successfully compile an LTS kernel via aports and have that job be distributed over multiple nodes.&lt;br /&gt;
Logs should be set up and able to display errors, but not show any errors during the test compile.&lt;br /&gt;
&lt;br /&gt;
To include a path for analysis via testing components.&lt;br /&gt;
&lt;br /&gt;
distcc can greatly improve compile speeds for large software, it comes with a different set of features than ccache; it focusses not avoiding unneccessary compile work, but on a way to speed up the necessary one.&lt;br /&gt;
&lt;br /&gt;
=== audience ===&lt;br /&gt;
people running software builds on alpine and have multiple computers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This page will show a specific installation, specific configuration, and specific tests, resulting in a specific set of functionality that can be tested to be working.&lt;br /&gt;
&lt;br /&gt;
== installation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Packages ===&lt;br /&gt;
&lt;br /&gt;
you need, on each host&lt;br /&gt;
* distcc&lt;br /&gt;
* distccd-openrc&lt;br /&gt;
* distcc-pump&lt;br /&gt;
* distcc-pump-pyc&lt;br /&gt;
&lt;br /&gt;
the .pyc will speed up the invocations, without it &lt;br /&gt;
idk if one or both should be installed in that case. but it appears to be also automatically be precompiled in /usr/lib/python3.12/site-packages/include_server/__pycache__/ so what does the package do exactly?&lt;br /&gt;
&lt;br /&gt;
There&#039;s some references to cpython-312, so maybe it actually still uses classy python-c conversion or matbe that&#039;s just a component for reading C source code. I have zero idea.&lt;br /&gt;
&lt;br /&gt;
you also need stuff to do compiles&lt;br /&gt;
* alpine sdk&lt;br /&gt;
* clang&lt;br /&gt;
* binutils&lt;br /&gt;
...&lt;br /&gt;
* elfutils(-dev)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Settings ===&lt;br /&gt;
==== settings for distcc ====&lt;br /&gt;
&lt;br /&gt;
* there&#039;s /etc/default/distcc&lt;br /&gt;
* there&#039;s /etc/conf.d/distcc &lt;br /&gt;
&lt;br /&gt;
make all your settings here&lt;br /&gt;
* command_whitelist.sh &lt;br /&gt;
&lt;br /&gt;
this is half functional, you need to set things here but you also need to maintain the symlinks that are collected under /usr/lib/distcc (for your compilers) and /usr/lib/distcc/bin (for itself)&lt;br /&gt;
&lt;br /&gt;
you MUST run the script to update the compilers!&lt;br /&gt;
Info for script and what files it will create&lt;br /&gt;
&lt;br /&gt;
/usr/sbin/update-distcc-symlinks&lt;br /&gt;
&lt;br /&gt;
tschike:/usr/bin# ls -l /usr/lib/distcc/&lt;br /&gt;
total 4&lt;br /&gt;
drwxr-xr-x 2 root root 4096 Mar  2 18:14 bin&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c89 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c99 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 cc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc-15.2.0 -&amp;gt; ../../bin/distcc&lt;br /&gt;
&lt;br /&gt;
distcc itself is in bin&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cpp -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 g++ -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 06:49 x86_64-alpine-linux-musl-gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
&lt;br /&gt;
the last symplink here is wrong, made by me and would not work...&lt;br /&gt;
BAD symlink.&lt;br /&gt;
&lt;br /&gt;
=== distcc hosts file ===&lt;br /&gt;
&lt;br /&gt;
idk about that thing it&#039;s odd&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== abuild.conf ===&lt;br /&gt;
&lt;br /&gt;
settings for aports&lt;br /&gt;
* cc=&lt;br /&gt;
* cxx=&lt;br /&gt;
* cpp=&lt;br /&gt;
* cflags=&lt;br /&gt;
* njobs&lt;br /&gt;
&lt;br /&gt;
== detail infos ==&lt;br /&gt;
&lt;br /&gt;
???&lt;br /&gt;
&lt;br /&gt;
=== hosts syntax ===&lt;br /&gt;
&lt;br /&gt;
* myhost otherhost&lt;br /&gt;
* myhost,cpp,lzo myotherhost,cpp,lzo&lt;br /&gt;
&lt;br /&gt;
==== the host ====&lt;br /&gt;
&lt;br /&gt;
hostname/ip&lt;br /&gt;
localhost&lt;br /&gt;
127.0.0.1&lt;br /&gt;
::1 - does not work&lt;br /&gt;
&lt;br /&gt;
==== protocol ====&lt;br /&gt;
&lt;br /&gt;
* no protocol given&lt;br /&gt;
* ,cpp,lzo protocol&lt;br /&gt;
&lt;br /&gt;
cpp implies lzo, it requires compression, even if you have 10gbit/s or more, it&#039;s just hardcoded&lt;br /&gt;
&lt;br /&gt;
=== threads ===&lt;br /&gt;
/number of workers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== architecture ==&lt;br /&gt;
it can handle C, C++, ObjC, maybe some other stuff&lt;br /&gt;
&lt;br /&gt;
* what happens with normal xmit&lt;br /&gt;
* what happens with pump mode&lt;br /&gt;
* at which step the include server is used and how it collects the includes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== distribution algorithm ===&lt;br /&gt;
honestly I simply don&#039;t get it&lt;br /&gt;
&lt;br /&gt;
* The order matters&lt;br /&gt;
* The number of threads matters&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== localhost ====&lt;br /&gt;
&lt;br /&gt;
* localhost precedence&lt;br /&gt;
* localhost fallback&lt;br /&gt;
&lt;br /&gt;
variable: DISTCC_FALLBACK&lt;br /&gt;
&lt;br /&gt;
0 = Fail to compile if it would need to fallback to a normal local gcc call&lt;br /&gt;
1 = If remote compile fails, just do it yourself&lt;br /&gt;
&lt;br /&gt;
Latency of pump mode startups and fallbacks needs to be investigated.&lt;br /&gt;
&lt;br /&gt;
== Operation ==&lt;br /&gt;
&lt;br /&gt;
=== startup and shutdown ===&lt;br /&gt;
service distcc stop is not entirely reliable (it can take a minute after the stop until the processes are gone and sometimes it will never stop&lt;br /&gt;
this is very bad with openrc, the openrc script returns after a second and only relies on its service flags, not the process status.&lt;br /&gt;
manually check after stopping, wait a min, if needed, kill it all.&lt;br /&gt;
at some point the rc file needs to be rewritten, it can&#039;t stay like it is.&lt;br /&gt;
&lt;br /&gt;
if you used a pump mode session, that also needs a logout (pump --shutdown)&lt;br /&gt;
avoid running multiple startups without shutdown in one session. it&#039;s safe as far as I can tell but nothing cleans up these processes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== ccache and memcached ===&lt;br /&gt;
CCACHE is said to be conflicting with pump mode unless when you call them in the backend&lt;br /&gt;
so, where you start the compile, you don&#039;t use it&lt;br /&gt;
where the compile happens, you use it&lt;br /&gt;
they can share the cache via memcached, this is a nice trick for consistency&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== dockerized / native ===&lt;br /&gt;
&lt;br /&gt;
it remains mostly the same, a container needs to make sure it monitors the right services (distccd, nginx, include_server)&lt;br /&gt;
if you&#039;re using zeroconf, you need to somehow expose the mdns service broadcasts &amp;amp; reception&lt;br /&gt;
&lt;br /&gt;
Processs list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
Workdir list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
=== alpine-chroot ===&lt;br /&gt;
&lt;br /&gt;
when using the &#039;official&#039; script there&#039;s still some odd pieces, seemed to be the processes died on logout. but not all of them.&lt;br /&gt;
&lt;br /&gt;
==== manual launch ====&lt;br /&gt;
&lt;br /&gt;
Starting the daemon would be using&lt;br /&gt;
/usr/bin/distccd --pid-file /var/run/distccd/distccd.pid -N 15 --user distcc --port 3632 --log-level=debug --log-file=/var/log/distccd.log --allow my-sub-net/24&lt;br /&gt;
&lt;br /&gt;
==== localhost? =====&lt;br /&gt;
unclear if you need to use --allow for 127.0.0.1/32 or something to allow the remote preproccesor.&lt;br /&gt;
&lt;br /&gt;
== Kernel specific settings ==&lt;br /&gt;
&lt;br /&gt;
currently (distcc 3.4-r9 on Alpine) you need a patch to build the kernel.&lt;br /&gt;
See &lt;br /&gt;
&lt;br /&gt;
=== Include server Settings ===&lt;br /&gt;
&lt;br /&gt;
cache reset triggers&lt;br /&gt;
This ought to be set before enabling pump mode.&lt;br /&gt;
&lt;br /&gt;
export INCLUDE_SERVER_ARGS=&amp;quot;--stat_reset_triggers=include/linux/compile.h:include/asm/asm-offsets.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
link to explanation TBA&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Disabling GCC Plugins ===&lt;br /&gt;
&lt;br /&gt;
KConfig unselect HAVE_GCC_PLUGINS&lt;br /&gt;
&lt;br /&gt;
Some info is here in the troubleshooting part of the Arch Wiki&lt;br /&gt;
https://wiki.archlinux.org/title/Distcc#Troubleshooting&lt;br /&gt;
&lt;br /&gt;
=== Patches ===&lt;br /&gt;
&lt;br /&gt;
Other things (for 6.6LTS)&lt;br /&gt;
PCIe Stub patch&lt;br /&gt;
&lt;br /&gt;
=== Autoconf === &lt;br /&gt;
&lt;br /&gt;
No known setup examples&lt;br /&gt;
Add whatever it publishes in mdns&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== troubleshooting / analysis ==&lt;br /&gt;
&lt;br /&gt;
=== testing ===&lt;br /&gt;
&lt;br /&gt;
# turn off fallback&lt;br /&gt;
&lt;br /&gt;
# GCC example compiles&lt;br /&gt;
## code example C&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example C++&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example ObjC&lt;br /&gt;
## same with included header&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
no ccache here yet&lt;br /&gt;
&lt;br /&gt;
# Cmake example compiles&lt;br /&gt;
the thing with compile launcher ccache;distcc&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== security ==&lt;br /&gt;
&lt;br /&gt;
the security model consists of ip restrictions.&lt;br /&gt;
there seems to also be some GSSAPI user auth.&lt;br /&gt;
further, commands that can be called are restricted by name and location.&lt;br /&gt;
this appears to be a runtime whitelist lookup, meaning it&#039;s done and authorized by the same parts of the daemon as processes the compile request along with the intended compiler.&lt;br /&gt;
so the main weaknesses against malicious clients seem to be in sending things to compile, and in overriding the remote compiler to use.&lt;br /&gt;
it can be assumed that a malicious client able to exploit the compiler handshake can then run arbitrary stuff.&lt;br /&gt;
There&#039;s at least a github issue regarding this google.com/search?q=distcc+seccomp&amp;amp;rlz=1C5CHFA_enDE1121DE1121&amp;amp;oq=distcc+seccomp&amp;amp;gs_lcrp=EgZjaHJvbWUyBggAEEUYOTIHCAEQIRigATIHCAIQIRigAdIBCDM1NjRqMGo3qAIAsAIA&amp;amp;sourceid=chrome&amp;amp;ie=UTF-8 suggesting running over ssh. That does only partitally alleviate this risk with regard  to a key based verfication of a client versus a the standard ip restrictions which always include some parsing.&lt;br /&gt;
So this protects against someone directly exploiting the TCP code of distcc.&lt;br /&gt;
It does not protect against malicious clients.&lt;br /&gt;
(ssh force command can&#039;t be used or you&#039;ll not compile anything)&lt;br /&gt;
&lt;br /&gt;
The basic step for protecting access should be filtering who can access the distcc server, so use nftables etc. to restrict access to port 3262 (??) set up the internal filter the same way.&lt;br /&gt;
&lt;br /&gt;
The next thing is to confine the compiler calls to only write in their temp directory and that they can only run compilers (using nsjail, apparmor, selinux etc)&lt;br /&gt;
&lt;br /&gt;
One needs to investigate when compiler_whitelist.sh is exactly called. as far as I recall it doesn&#039;t close stdin/stdout.&lt;br /&gt;
&lt;br /&gt;
The other internal security bit is that they do some priviledge dropping. it runs as a dedicated user (distcc), so you can also have an audit policy, and can/could use something like iptables&#039; to ensure it can only connect to the other distcc/memcached hosts, but nothing else.&lt;br /&gt;
&lt;br /&gt;
I think that&#039;s safe enough, the main vector is breakouts and confinement is possible.&lt;br /&gt;
there&#039;s also a selinux policy for distcc from gentoo or liguros if one is so inclined.&lt;br /&gt;
https://repology.org/project/selinux-distcc/versions&lt;br /&gt;
&lt;br /&gt;
Some extra measures should be taken since the project has only a few part-time maintainers that cannot drive the project forward or do large refactors.&lt;/div&gt;</summary>
		<author><name>Darkfader</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32122</id>
		<title>User:Darkfader/distcc</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32122"/>
		<updated>2026-03-03T10:22:24Z</updated>

		<summary type="html">&lt;p&gt;Darkfader: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi,&lt;br /&gt;
&lt;br /&gt;
I&#039;m preparing this page. It can take a long time till I finish.&lt;br /&gt;
If you are also wishing to write on this topic, feel free to integrate the content.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Document overview ==&lt;br /&gt;
&lt;br /&gt;
I noticed that almost every distro has one partially complete, partially helpful document on how to use distcc on the distro.&lt;br /&gt;
Usually they also have one for ccache.&lt;br /&gt;
In either case, they&#039;re enough to get started, but not really a reliable watertight thing.&lt;br /&gt;
We definitely needed one of our own.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== goal ===&lt;br /&gt;
&lt;br /&gt;
to describe a working setup for building aports in easiest/fastests fashion&lt;br /&gt;
not planning to add versatility or features where it would make the setup more errorprone.&lt;br /&gt;
the page should describe enough of the steps to successfully compile an LTS kernel via aports and have that job be distributed over multiple nodes.&lt;br /&gt;
Logs should be set up and able to display errors, but not show any errors during the test compile.&lt;br /&gt;
&lt;br /&gt;
To include a path for analysis via testing components.&lt;br /&gt;
&lt;br /&gt;
distcc can greatly improve compile speeds for large software, it comes with a different set of features than ccache; it focusses not avoiding unneccessary compile work, but on a way to speed up the necessary one.&lt;br /&gt;
&lt;br /&gt;
=== audience ===&lt;br /&gt;
people running software builds on alpine and have multiple computers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This page will show a specific installation, specific configuration, and specific tests, resulting in a specific set of functionality that can be tested to be working.&lt;br /&gt;
&lt;br /&gt;
== installation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Packages ===&lt;br /&gt;
&lt;br /&gt;
you need, on each host&lt;br /&gt;
* distcc&lt;br /&gt;
* distccd-openrc&lt;br /&gt;
* distcc-pump&lt;br /&gt;
* distcc-pump-pyc&lt;br /&gt;
&lt;br /&gt;
the .pyc will speed up the invocations, without it &lt;br /&gt;
idk if one or both should be installed in that case. but it appears to be also automatically be precompiled in /usr/lib/python3.12/site-packages/include_server/__pycache__/ so what does the package do exactly?&lt;br /&gt;
&lt;br /&gt;
There&#039;s some references to cpython-312, so maybe it actually still uses classy python-c conversion or matbe that&#039;s just a component for reading C source code. I have zero idea.&lt;br /&gt;
&lt;br /&gt;
you also need stuff to do compiles&lt;br /&gt;
* alpine sdk&lt;br /&gt;
* clang&lt;br /&gt;
* binutils&lt;br /&gt;
...&lt;br /&gt;
* elfutils(-dev)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Settings ===&lt;br /&gt;
==== settings for distcc ====&lt;br /&gt;
&lt;br /&gt;
* there&#039;s /etc/default/distcc&lt;br /&gt;
* there&#039;s /etc/conf.d/distcc &lt;br /&gt;
&lt;br /&gt;
make all your settings here&lt;br /&gt;
* command_whitelist.sh &lt;br /&gt;
&lt;br /&gt;
this is half functional, you need to set things here but you also need to maintain the symlinks that are collected under /usr/lib/distcc (for your compilers) and /usr/lib/distcc/bin (for itself)&lt;br /&gt;
&lt;br /&gt;
you MUST run the script to update the compilers!&lt;br /&gt;
Info for script and what files it will create&lt;br /&gt;
&lt;br /&gt;
/usr/sbin/update-distcc-symlinks&lt;br /&gt;
&lt;br /&gt;
tschike:/usr/bin# ls -l /usr/lib/distcc/&lt;br /&gt;
total 4&lt;br /&gt;
drwxr-xr-x 2 root root 4096 Mar  2 18:14 bin&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c89 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c99 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 cc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc-15.2.0 -&amp;gt; ../../bin/distcc&lt;br /&gt;
&lt;br /&gt;
distcc itself is in bin&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cpp -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 g++ -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 06:49 x86_64-alpine-linux-musl-gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
&lt;br /&gt;
the last symplink here is wrong, made by me and would not work...&lt;br /&gt;
BAD symlink.&lt;br /&gt;
&lt;br /&gt;
=== distcc hosts file ===&lt;br /&gt;
&lt;br /&gt;
idk about that thing it&#039;s odd&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== abuild.conf ===&lt;br /&gt;
&lt;br /&gt;
settings for aports&lt;br /&gt;
* cc=&lt;br /&gt;
* cxx=&lt;br /&gt;
* cpp=&lt;br /&gt;
* cflags=&lt;br /&gt;
* njobs&lt;br /&gt;
&lt;br /&gt;
== detail infos ==&lt;br /&gt;
&lt;br /&gt;
???&lt;br /&gt;
&lt;br /&gt;
=== hosts syntax ===&lt;br /&gt;
&lt;br /&gt;
* myhost otherhost&lt;br /&gt;
* myhost,cpp,lzo myotherhost,cpp,lzo&lt;br /&gt;
&lt;br /&gt;
==== the host ====&lt;br /&gt;
&lt;br /&gt;
hostname/ip&lt;br /&gt;
localhost&lt;br /&gt;
127.0.0.1&lt;br /&gt;
::1 - does not work&lt;br /&gt;
&lt;br /&gt;
==== protocol ====&lt;br /&gt;
&lt;br /&gt;
* no protocol given&lt;br /&gt;
* ,cpp,lzo protocol&lt;br /&gt;
&lt;br /&gt;
cpp implies lzo, it requires compression, even if you have 10gbit/s or more, it&#039;s just hardcoded&lt;br /&gt;
&lt;br /&gt;
=== threads ===&lt;br /&gt;
/number of workers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== architecture ==&lt;br /&gt;
it can handle C, C++, ObjC, maybe some other stuff&lt;br /&gt;
&lt;br /&gt;
* what happens with normal xmit&lt;br /&gt;
* what happens with pump mode&lt;br /&gt;
* at which step the include server is used and how it collects the includes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== distribution algorithm ===&lt;br /&gt;
honestly I simply don&#039;t get it&lt;br /&gt;
&lt;br /&gt;
* The order matters&lt;br /&gt;
* The number of threads matters&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== localhost ====&lt;br /&gt;
&lt;br /&gt;
* localhost precedence&lt;br /&gt;
* localhost fallback&lt;br /&gt;
&lt;br /&gt;
variable: DISTCC_FALLBACK&lt;br /&gt;
&lt;br /&gt;
0 = Fail to compile if it would need to fallback to a normal local gcc call&lt;br /&gt;
1 = If remote compile fails, just do it yourself&lt;br /&gt;
&lt;br /&gt;
Latency of pump mode startups and fallbacks needs to be investigated.&lt;br /&gt;
&lt;br /&gt;
== Operation ==&lt;br /&gt;
&lt;br /&gt;
=== startup and shutdown ===&lt;br /&gt;
service distcc stop is not entirely reliable (it can take a minute after the stop until the processes are gone and sometimes it will never stop&lt;br /&gt;
this is very bad with openrc, the openrc script returns after a second and only relies on its service flags, not the process status.&lt;br /&gt;
manually check after stopping, wait a min, if needed, kill it all.&lt;br /&gt;
at some point the rc file needs to be rewritten, it can&#039;t stay like it is.&lt;br /&gt;
&lt;br /&gt;
if you used a pump mode session, that also needs a logout (pump --shutdown)&lt;br /&gt;
avoid running multiple startups without shutdown in one session. it&#039;s safe as far as I can tell but nothing cleans up these processes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== ccache and memcached ===&lt;br /&gt;
CCACHE is said to be conflicting with pump mode unless when you call them in the backend&lt;br /&gt;
so, where you start the compile, you don&#039;t use it&lt;br /&gt;
where the compile happens, you use it&lt;br /&gt;
they can share the cache via memcached, this is a nice trick for consistency&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== dockerized / native ===&lt;br /&gt;
&lt;br /&gt;
it remains mostly the same, a container needs to make sure it monitors the right services (distccd, nginx, include_server)&lt;br /&gt;
if you&#039;re using zeroconf, you need to somehow expose the mdns service broadcasts &amp;amp; reception&lt;br /&gt;
&lt;br /&gt;
Processs list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
Workdir list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
=== alpine-chroot ===&lt;br /&gt;
&lt;br /&gt;
when using the &#039;official&#039; script there&#039;s still some odd pieces, seemed to be the processes died on logout. but not all of them.&lt;br /&gt;
&lt;br /&gt;
==== manual launch ====&lt;br /&gt;
&lt;br /&gt;
Starting the daemon would be using&lt;br /&gt;
/usr/bin/distccd --pid-file /var/run/distccd/distccd.pid -N 15 --user distcc --port 3632 --log-level=debug --log-file=/var/log/distccd.log --allow my-sub-net/24&lt;br /&gt;
&lt;br /&gt;
==== localhost? =====&lt;br /&gt;
unclear if you need to use --allow for 127.0.0.1/32 or something to allow the remote preproccesor.&lt;br /&gt;
&lt;br /&gt;
== Kernel specific settings ==&lt;br /&gt;
&lt;br /&gt;
currently (distcc 3.4-r9 on Alpine) you need a patch to build the kernel.&lt;br /&gt;
See &lt;br /&gt;
&lt;br /&gt;
=== Include server Settings ===&lt;br /&gt;
&lt;br /&gt;
cache reset triggers&lt;br /&gt;
This ought to be set before enabling pump mode.&lt;br /&gt;
&lt;br /&gt;
export INCLUDE_SERVER_ARGS=&amp;quot;--stat_reset_triggers=include/linux/compile.h:include/asm/asm-offsets.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
link to explanation TBA&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Disabling GCC Plugins ===&lt;br /&gt;
&lt;br /&gt;
KConfig unselect&lt;br /&gt;
&lt;br /&gt;
=== Patches ===&lt;br /&gt;
&lt;br /&gt;
Other things (for 6.6LTS)&lt;br /&gt;
PCIe Stub patch&lt;br /&gt;
&lt;br /&gt;
=== Autoconf === &lt;br /&gt;
&lt;br /&gt;
No known setup examples&lt;br /&gt;
Add whatever it publishes in mdns&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== troubleshooting / analysis ==&lt;br /&gt;
&lt;br /&gt;
=== testing ===&lt;br /&gt;
&lt;br /&gt;
# turn off fallback&lt;br /&gt;
&lt;br /&gt;
# GCC example compiles&lt;br /&gt;
## code example C&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example C++&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example ObjC&lt;br /&gt;
## same with included header&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
no ccache here yet&lt;br /&gt;
&lt;br /&gt;
# Cmake example compiles&lt;br /&gt;
the thing with compile launcher ccache;distcc&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== security ==&lt;br /&gt;
&lt;br /&gt;
the security model consists of ip restrictions.&lt;br /&gt;
there seems to also be some GSSAPI user auth.&lt;br /&gt;
further, commands that can be called are restricted by name and location.&lt;br /&gt;
this appears to be a runtime whitelist lookup, meaning it&#039;s done and authorized by the same parts of the daemon as processes the compile request along with the intended compiler.&lt;br /&gt;
so the main weaknesses against malicious clients seem to be in sending things to compile, and in overriding the remote compiler to use.&lt;br /&gt;
it can be assumed that a malicious client able to exploit the compiler handshake can then run arbitrary stuff.&lt;br /&gt;
There&#039;s at least a github issue regarding this google.com/search?q=distcc+seccomp&amp;amp;rlz=1C5CHFA_enDE1121DE1121&amp;amp;oq=distcc+seccomp&amp;amp;gs_lcrp=EgZjaHJvbWUyBggAEEUYOTIHCAEQIRigATIHCAIQIRigAdIBCDM1NjRqMGo3qAIAsAIA&amp;amp;sourceid=chrome&amp;amp;ie=UTF-8 suggesting running over ssh. That does only partitally alleviate this risk with regard  to a key based verfication of a client versus a the standard ip restrictions which always include some parsing.&lt;br /&gt;
So this protects against someone directly exploiting the TCP code of distcc.&lt;br /&gt;
It does not protect against malicious clients.&lt;br /&gt;
(ssh force command can&#039;t be used or you&#039;ll not compile anything)&lt;br /&gt;
&lt;br /&gt;
The basic step for protecting access should be filtering who can access the distcc server, so use nftables etc. to restrict access to port 3262 (??) set up the internal filter the same way.&lt;br /&gt;
&lt;br /&gt;
The next thing is to confine the compiler calls to only write in their temp directory and that they can only run compilers (using nsjail, apparmor, selinux etc)&lt;br /&gt;
&lt;br /&gt;
One needs to investigate when compiler_whitelist.sh is exactly called. as far as I recall it doesn&#039;t close stdin/stdout.&lt;br /&gt;
&lt;br /&gt;
The other internal security bit is that they do some priviledge dropping. it runs as a dedicated user (distcc), so you can also have an audit policy, and can/could use something like iptables&#039; to ensure it can only connect to the other distcc/memcached hosts, but nothing else.&lt;br /&gt;
&lt;br /&gt;
I think that&#039;s safe enough, the main vector is breakouts and confinement is possible.&lt;br /&gt;
there&#039;s also a selinux policy for distcc from gentoo or liguros if one is so inclined.&lt;br /&gt;
https://repology.org/project/selinux-distcc/versions&lt;br /&gt;
&lt;br /&gt;
Some extra measures should be taken since the project has only a few part-time maintainers that cannot drive the project forward or do large refactors.&lt;/div&gt;</summary>
		<author><name>Darkfader</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32121</id>
		<title>User:Darkfader/distcc</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32121"/>
		<updated>2026-03-03T10:19:46Z</updated>

		<summary type="html">&lt;p&gt;Darkfader: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi,&lt;br /&gt;
&lt;br /&gt;
I&#039;m preparing this page. It can take a long time till I finish.&lt;br /&gt;
If you are also wishing to write on this topic, feel free to integrate the content.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Document overview ==&lt;br /&gt;
&lt;br /&gt;
I noticed that almost every distro has one partially complete, partially helpful document on how to use distcc on the distro.&lt;br /&gt;
Usually they also have one for ccache.&lt;br /&gt;
In either case, they&#039;re enough to get started, but not really a reliable watertight thing.&lt;br /&gt;
We definitely needed one of our own.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== goal ===&lt;br /&gt;
&lt;br /&gt;
to describe a working setup for building aports in easiest/fastests fashion&lt;br /&gt;
not planning to add versatility or features where it would make the setup more errorprone.&lt;br /&gt;
the page should describe enough of the steps to successfully compile an LTS kernel via aports and have that job be distributed over multiple nodes.&lt;br /&gt;
Logs should be set up and able to display errors, but not show any errors during the test compile.&lt;br /&gt;
&lt;br /&gt;
To include a path for analysis via testing components.&lt;br /&gt;
&lt;br /&gt;
=== audience ===&lt;br /&gt;
people running software builds on alpine and have multiple computers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This page will show a specific installation, specific configuration, and specific tests, resulting in a specific set of functionality that can be tested to be working.&lt;br /&gt;
&lt;br /&gt;
== installation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Packages ===&lt;br /&gt;
&lt;br /&gt;
you need, on each host&lt;br /&gt;
* distcc&lt;br /&gt;
* distccd-openrc&lt;br /&gt;
* distcc-pump&lt;br /&gt;
* distcc-pump-pyc&lt;br /&gt;
&lt;br /&gt;
the .pyc will speed up the invocations, without it &lt;br /&gt;
idk if one or both should be installed in that case. but it appears to be also automatically be precompiled in /usr/lib/python3.12/site-packages/include_server/__pycache__/ so what does the package do exactly?&lt;br /&gt;
&lt;br /&gt;
There&#039;s some references to cpython-312, so maybe it actually still uses classy python-c conversion or matbe that&#039;s just a component for reading C source code. I have zero idea.&lt;br /&gt;
&lt;br /&gt;
you also need stuff to do compiles&lt;br /&gt;
* alpine sdk&lt;br /&gt;
* clang&lt;br /&gt;
* binutils&lt;br /&gt;
...&lt;br /&gt;
* elfutils(-dev)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Settings ===&lt;br /&gt;
==== settings for distcc ====&lt;br /&gt;
&lt;br /&gt;
* there&#039;s /etc/default/distcc&lt;br /&gt;
* there&#039;s /etc/conf.d/distcc &lt;br /&gt;
&lt;br /&gt;
make all your settings here&lt;br /&gt;
* command_whitelist.sh &lt;br /&gt;
&lt;br /&gt;
this is half functional, you need to set things here but you also need to maintain the symlinks that are collected under /usr/lib/distcc (for your compilers) and /usr/lib/distcc/bin (for itself)&lt;br /&gt;
&lt;br /&gt;
you MUST run the script to update the compilers!&lt;br /&gt;
Info for script and what files it will create&lt;br /&gt;
&lt;br /&gt;
/usr/sbin/update-distcc-symlinks&lt;br /&gt;
&lt;br /&gt;
tschike:/usr/bin# ls -l /usr/lib/distcc/&lt;br /&gt;
total 4&lt;br /&gt;
drwxr-xr-x 2 root root 4096 Mar  2 18:14 bin&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c89 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c99 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 cc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc-15.2.0 -&amp;gt; ../../bin/distcc&lt;br /&gt;
&lt;br /&gt;
distcc itself is in bin&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cpp -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 g++ -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 06:49 x86_64-alpine-linux-musl-gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
&lt;br /&gt;
the last symplink here is wrong, made by me and would not work...&lt;br /&gt;
BAD symlink.&lt;br /&gt;
&lt;br /&gt;
=== distcc hosts file ===&lt;br /&gt;
&lt;br /&gt;
idk about that thing it&#039;s odd&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== abuild.conf ===&lt;br /&gt;
&lt;br /&gt;
settings for aports&lt;br /&gt;
* cc=&lt;br /&gt;
* cxx=&lt;br /&gt;
* cpp=&lt;br /&gt;
* cflags=&lt;br /&gt;
* njobs&lt;br /&gt;
&lt;br /&gt;
== detail infos ==&lt;br /&gt;
&lt;br /&gt;
???&lt;br /&gt;
&lt;br /&gt;
=== hosts syntax ===&lt;br /&gt;
&lt;br /&gt;
* myhost otherhost&lt;br /&gt;
* myhost,cpp,lzo myotherhost,cpp,lzo&lt;br /&gt;
&lt;br /&gt;
==== the host ====&lt;br /&gt;
&lt;br /&gt;
hostname/ip&lt;br /&gt;
localhost&lt;br /&gt;
127.0.0.1&lt;br /&gt;
::1 - does not work&lt;br /&gt;
&lt;br /&gt;
==== protocol ====&lt;br /&gt;
&lt;br /&gt;
* no protocol given&lt;br /&gt;
* ,cpp,lzo protocol&lt;br /&gt;
&lt;br /&gt;
cpp implies lzo, it requires compression, even if you have 10gbit/s or more, it&#039;s just hardcoded&lt;br /&gt;
&lt;br /&gt;
=== threads ===&lt;br /&gt;
/number of workers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== architecture ==&lt;br /&gt;
it can handle C, C++, ObjC, maybe some other stuff&lt;br /&gt;
&lt;br /&gt;
* what happens with normal xmit&lt;br /&gt;
* what happens with pump mode&lt;br /&gt;
* at which step the include server is used and how it collects the includes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== distribution algorithm ===&lt;br /&gt;
honestly I simply don&#039;t get it&lt;br /&gt;
&lt;br /&gt;
* The order matters&lt;br /&gt;
* The number of threads matters&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== localhost ====&lt;br /&gt;
&lt;br /&gt;
* localhost precedence&lt;br /&gt;
* localhost fallback&lt;br /&gt;
&lt;br /&gt;
variable: DISTCC_FALLBACK&lt;br /&gt;
&lt;br /&gt;
0 = Fail to compile if it would need to fallback to a normal local gcc call&lt;br /&gt;
1 = If remote compile fails, just do it yourself&lt;br /&gt;
&lt;br /&gt;
Latency of pump mode startups and fallbacks needs to be investigated.&lt;br /&gt;
&lt;br /&gt;
== Operation ==&lt;br /&gt;
&lt;br /&gt;
=== startup and shutdown ===&lt;br /&gt;
service distcc stop is not entirely reliable (it can take a minute after the stop until the processes are gone and sometimes it will never stop&lt;br /&gt;
this is very bad with openrc, the openrc script returns after a second and only relies on its service flags, not the process status.&lt;br /&gt;
manually check after stopping, wait a min, if needed, kill it all.&lt;br /&gt;
at some point the rc file needs to be rewritten, it can&#039;t stay like it is.&lt;br /&gt;
&lt;br /&gt;
if you used a pump mode session, that also needs a logout (pump --shutdown)&lt;br /&gt;
avoid running multiple startups without shutdown in one session. it&#039;s safe as far as I can tell but nothing cleans up these processes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== ccache and memcached ===&lt;br /&gt;
CCACHE is said to be conflicting with pump mode unless when you call them in the backend&lt;br /&gt;
so, where you start the compile, you don&#039;t use it&lt;br /&gt;
where the compile happens, you use it&lt;br /&gt;
they can share the cache via memcached, this is a nice trick for consistency&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== dockerized / native ===&lt;br /&gt;
&lt;br /&gt;
it remains mostly the same, a container needs to make sure it monitors the right services (distccd, nginx, include_server)&lt;br /&gt;
if you&#039;re using zeroconf, you need to somehow expose the mdns service broadcasts &amp;amp; reception&lt;br /&gt;
&lt;br /&gt;
Processs list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
Workdir list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
=== alpine-chroot ===&lt;br /&gt;
&lt;br /&gt;
when using the &#039;official&#039; script there&#039;s still some odd pieces, seemed to be the processes died on logout. but not all of them.&lt;br /&gt;
&lt;br /&gt;
==== manual launch ====&lt;br /&gt;
&lt;br /&gt;
Starting the daemon would be using&lt;br /&gt;
/usr/bin/distccd --pid-file /var/run/distccd/distccd.pid -N 15 --user distcc --port 3632 --log-level=debug --log-file=/var/log/distccd.log --allow my-sub-net/24&lt;br /&gt;
&lt;br /&gt;
==== localhost? =====&lt;br /&gt;
unclear if you need to use --allow for 127.0.0.1/32 or something to allow the remote preproccesor.&lt;br /&gt;
&lt;br /&gt;
== Kernel specific settings ==&lt;br /&gt;
&lt;br /&gt;
currently (distcc 3.4-r9 on Alpine) you need a patch to build the kernel.&lt;br /&gt;
See &lt;br /&gt;
&lt;br /&gt;
=== Include server Settings ===&lt;br /&gt;
&lt;br /&gt;
cache reset triggers&lt;br /&gt;
This ought to be set before enabling pump mode.&lt;br /&gt;
&lt;br /&gt;
export INCLUDE_SERVER_ARGS=&amp;quot;--stat_reset_triggers=include/linux/compile.h:include/asm/asm-offsets.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
link to explanation TBA&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Disabling GCC Plugins ===&lt;br /&gt;
&lt;br /&gt;
KConfig unselect&lt;br /&gt;
&lt;br /&gt;
=== Patches ===&lt;br /&gt;
&lt;br /&gt;
Other things (for 6.6LTS)&lt;br /&gt;
PCIe Stub patch&lt;br /&gt;
&lt;br /&gt;
=== Autoconf === &lt;br /&gt;
&lt;br /&gt;
No known setup examples&lt;br /&gt;
Add whatever it publishes in mdns&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== troubleshooting / analysis ==&lt;br /&gt;
&lt;br /&gt;
=== testing ===&lt;br /&gt;
&lt;br /&gt;
# turn off fallback&lt;br /&gt;
&lt;br /&gt;
# GCC example compiles&lt;br /&gt;
## code example C&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example C++&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example ObjC&lt;br /&gt;
## same with included header&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
no ccache here yet&lt;br /&gt;
&lt;br /&gt;
# Cmake example compiles&lt;br /&gt;
the thing with compile launcher ccache;distcc&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== security ==&lt;br /&gt;
&lt;br /&gt;
the security model consists of ip restrictions.&lt;br /&gt;
there seems to also be some GSSAPI user auth.&lt;br /&gt;
further, commands that can be called are restricted by name and location.&lt;br /&gt;
this appears to be a runtime whitelist lookup, meaning it&#039;s done and authorized by the same parts of the daemon as processes the compile request along with the intended compiler.&lt;br /&gt;
so the main weaknesses against malicious clients seem to be in sending things to compile, and in overriding the remote compiler to use.&lt;br /&gt;
it can be assumed that a malicious client able to exploit the compiler handshake can then run arbitrary stuff.&lt;br /&gt;
There&#039;s at least a github issue regarding this google.com/search?q=distcc+seccomp&amp;amp;rlz=1C5CHFA_enDE1121DE1121&amp;amp;oq=distcc+seccomp&amp;amp;gs_lcrp=EgZjaHJvbWUyBggAEEUYOTIHCAEQIRigATIHCAIQIRigAdIBCDM1NjRqMGo3qAIAsAIA&amp;amp;sourceid=chrome&amp;amp;ie=UTF-8 suggesting running over ssh. That does only partitally alleviate this risk with regard  to a key based verfication of a client versus a the standard ip restrictions which always include some parsing.&lt;br /&gt;
So this protects against someone directly exploiting the TCP code of distcc.&lt;br /&gt;
It does not protect against malicious clients.&lt;br /&gt;
(ssh force command can&#039;t be used or you&#039;ll not compile anything)&lt;br /&gt;
&lt;br /&gt;
The basic step for protecting access should be filtering who can access the distcc server, so use nftables etc. to restrict access to port 3262 (??) set up the internal filter the same way.&lt;br /&gt;
&lt;br /&gt;
The next thing is to confine the compiler calls to only write in their temp directory and that they can only run compilers (using nsjail, apparmor, selinux etc)&lt;br /&gt;
&lt;br /&gt;
One needs to investigate when compiler_whitelist.sh is exactly called. as far as I recall it doesn&#039;t close stdin/stdout.&lt;br /&gt;
&lt;br /&gt;
The other internal security bit is that they do some priviledge dropping. it runs as a dedicated user (distcc), so you can also have an audit policy, and can/could use something like iptables&#039; to ensure it can only connect to the other distcc/memcached hosts, but nothing else.&lt;br /&gt;
&lt;br /&gt;
I think that&#039;s safe enough, the main vector is breakouts and confinement is possible.&lt;br /&gt;
there&#039;s also a selinux policy for distcc from gentoo or liguros if one is so inclined.&lt;br /&gt;
https://repology.org/project/selinux-distcc/versions&lt;br /&gt;
&lt;br /&gt;
Some extra measures should be taken since the project has only a few part-time maintainers that cannot drive the project forward or do large refactors.&lt;/div&gt;</summary>
		<author><name>Darkfader</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32120</id>
		<title>User:Darkfader/distcc</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=User:Darkfader/distcc&amp;diff=32120"/>
		<updated>2026-03-03T10:15:58Z</updated>

		<summary type="html">&lt;p&gt;Darkfader: /* architecture */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi,&lt;br /&gt;
&lt;br /&gt;
I&#039;m preparing this page. It can take a long time till I finish.&lt;br /&gt;
If you are also wishing to write on this topic, feel free to integrate the content.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Document overview ==&lt;br /&gt;
&lt;br /&gt;
I noticed that almost every distro has one partially complete, partially helpful document on how to use distcc on the distro.&lt;br /&gt;
Usually they also have one for ccache.&lt;br /&gt;
In either case, they&#039;re enough to get started, but not really a reliable watertight thing.&lt;br /&gt;
We definitely needed one of our own.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== goal ===&lt;br /&gt;
&lt;br /&gt;
to describe a working setup for building aports in easiest/fastests fashion&lt;br /&gt;
not planning to add versatility or features where it would make the setup more errorprone.&lt;br /&gt;
the page should describe enough of the steps to successfully compile an LTS kernel via aports and have that job be distributed over multiple nodes.&lt;br /&gt;
Logs should be set up and able to display errors, but not show any errors during the test compile.&lt;br /&gt;
&lt;br /&gt;
To include a path for analysis via testing components.&lt;br /&gt;
&lt;br /&gt;
=== audience ===&lt;br /&gt;
people running software builds on alpine and have multiple computers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This page will show a specific installation, specific configuration, and specific tests, resulting in a specific set of functionality that can be tested to be working.&lt;br /&gt;
&lt;br /&gt;
== installation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Packages ===&lt;br /&gt;
&lt;br /&gt;
you need, on each host&lt;br /&gt;
* distcc&lt;br /&gt;
* distccd-openrc&lt;br /&gt;
* distcc-pump&lt;br /&gt;
* distcc-pump-pyc&lt;br /&gt;
&lt;br /&gt;
the .pyc will speed up the invocations, without it &lt;br /&gt;
idk if one or both should be installed in that case. but it appears to be also automatically be precompiled in /usr/lib/python3.12/site-packages/include_server/__pycache__/ so what does the package do exactly?&lt;br /&gt;
&lt;br /&gt;
There&#039;s some references to cpython-312, so maybe it actually still uses classy python-c conversion or matbe that&#039;s just a component for reading C source code. I have zero idea.&lt;br /&gt;
&lt;br /&gt;
you also need stuff to do compiles&lt;br /&gt;
* alpine sdk&lt;br /&gt;
* clang&lt;br /&gt;
* binutils&lt;br /&gt;
...&lt;br /&gt;
* elfutils(-dev)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Settings ===&lt;br /&gt;
==== settings for distcc ====&lt;br /&gt;
&lt;br /&gt;
* there&#039;s /etc/default/distcc&lt;br /&gt;
* there&#039;s /etc/conf.d/distcc &lt;br /&gt;
&lt;br /&gt;
make all your settings here&lt;br /&gt;
* command_whitelist.sh &lt;br /&gt;
&lt;br /&gt;
this is half functional, you need to set things here but you also need to maintain the symlinks that are collected under /usr/lib/distcc (for your compilers) and /usr/lib/distcc/bin (for itself)&lt;br /&gt;
&lt;br /&gt;
you MUST run the script to update the compilers!&lt;br /&gt;
Info for script and what files it will create&lt;br /&gt;
&lt;br /&gt;
/usr/sbin/update-distcc-symlinks&lt;br /&gt;
&lt;br /&gt;
tschike:/usr/bin# ls -l /usr/lib/distcc/&lt;br /&gt;
total 4&lt;br /&gt;
drwxr-xr-x 2 root root 4096 Mar  2 18:14 bin&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c89 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 c99 -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 cc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-g++ -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc -&amp;gt; ../../bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root   16 Mar  2 07:02 x86_64-alpine-linux-musl-gcc-15.2.0 -&amp;gt; ../../bin/distcc&lt;br /&gt;
&lt;br /&gt;
distcc itself is in bin&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 cpp -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 g++ -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 18:14 gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
lrwxrwxrwx 1 root root 15 Mar  2 06:49 x86_64-alpine-linux-musl-gcc -&amp;gt; /usr/bin/distcc&lt;br /&gt;
&lt;br /&gt;
the last symplink here is wrong, made by me and would not work...&lt;br /&gt;
BAD symlink.&lt;br /&gt;
&lt;br /&gt;
=== distcc hosts file ===&lt;br /&gt;
&lt;br /&gt;
idk about that thing it&#039;s odd&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== abuild.conf ===&lt;br /&gt;
&lt;br /&gt;
settings for aports&lt;br /&gt;
* cc=&lt;br /&gt;
* cxx=&lt;br /&gt;
* cpp=&lt;br /&gt;
* cflags=&lt;br /&gt;
* njobs&lt;br /&gt;
&lt;br /&gt;
== detail infos ==&lt;br /&gt;
&lt;br /&gt;
???&lt;br /&gt;
&lt;br /&gt;
=== hosts syntax ===&lt;br /&gt;
&lt;br /&gt;
* myhost otherhost&lt;br /&gt;
* myhost,cpp,lzo myotherhost,cpp,lzo&lt;br /&gt;
&lt;br /&gt;
==== the host ====&lt;br /&gt;
&lt;br /&gt;
hostname/ip&lt;br /&gt;
localhost&lt;br /&gt;
127.0.0.1&lt;br /&gt;
::1 - does not work&lt;br /&gt;
&lt;br /&gt;
==== protocol ====&lt;br /&gt;
&lt;br /&gt;
* no protocol given&lt;br /&gt;
* ,cpp,lzo protocol&lt;br /&gt;
&lt;br /&gt;
cpp implies lzo, it requires compression, even if you have 10gbit/s or more, it&#039;s just hardcoded&lt;br /&gt;
&lt;br /&gt;
=== threads ===&lt;br /&gt;
/number of workers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== architecture ==&lt;br /&gt;
it can handle C, C++, ObjC, maybe some other stuff&lt;br /&gt;
&lt;br /&gt;
* what happens with normal xmit&lt;br /&gt;
* what happens with pump mode&lt;br /&gt;
* at which step the include server is used and how it collects the includes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== distribution algorithm ===&lt;br /&gt;
honestly I simply don&#039;t get it&lt;br /&gt;
&lt;br /&gt;
* The order matters&lt;br /&gt;
* The number of threads matters&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== localhost ====&lt;br /&gt;
&lt;br /&gt;
* localhost precedence&lt;br /&gt;
* localhost fallback&lt;br /&gt;
&lt;br /&gt;
variable: DISTCC_FALLBACK&lt;br /&gt;
&lt;br /&gt;
0 = Fail to compile if it would need to fallback to a normal local gcc call&lt;br /&gt;
1 = If remote compile fails, just do it yourself&lt;br /&gt;
&lt;br /&gt;
Latency of pump mode startups and fallbacks needs to be investigated.&lt;br /&gt;
&lt;br /&gt;
== Operation ==&lt;br /&gt;
&lt;br /&gt;
=== startup and shutdown ===&lt;br /&gt;
service distcc stop is not entirely reliable (it can take a minute after the stop until the processes are gone and sometimes it will never stop&lt;br /&gt;
this is very bad with openrc, the openrc script returns after a second and only relies on its service flags, not the process status.&lt;br /&gt;
manually check after stopping, wait a min, if needed, kill it all.&lt;br /&gt;
at some point the rc file needs to be rewritten, it can&#039;t stay like it is.&lt;br /&gt;
&lt;br /&gt;
if you used a pump mode session, that also needs a logout (pump --shutdown)&lt;br /&gt;
avoid running multiple startups without shutdown in one session. it&#039;s safe as far as I can tell but nothing cleans up these processes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== ccache and memcached ===&lt;br /&gt;
CCACHE is said to be conflicting with pump mode unless when you call them in the backend&lt;br /&gt;
so, where you start the compile, you don&#039;t use it&lt;br /&gt;
where the compile happens, you use it&lt;br /&gt;
they can share the cache via memcached, this is a nice trick for consistency&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== dockerized / native ===&lt;br /&gt;
&lt;br /&gt;
it remains mostly the same, a container needs to make sure it monitors the right services (distccd, nginx, include_server)&lt;br /&gt;
if you&#039;re using zeroconf, you need to somehow expose the mdns service broadcasts &amp;amp; reception&lt;br /&gt;
&lt;br /&gt;
Processs list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
Workdir list:&lt;br /&gt;
&lt;br /&gt;
* TBA&lt;br /&gt;
&lt;br /&gt;
== Kernel specific settings ==&lt;br /&gt;
&lt;br /&gt;
currently (distcc 3.4-r9 on Alpine) you need a patch to build the kernel.&lt;br /&gt;
See &lt;br /&gt;
&lt;br /&gt;
=== Include server Settings ===&lt;br /&gt;
&lt;br /&gt;
cache reset triggers&lt;br /&gt;
This ought to be set before enabling pump mode.&lt;br /&gt;
&lt;br /&gt;
export INCLUDE_SERVER_ARGS=&amp;quot;--stat_reset_triggers=include/linux/compile.h:include/asm/asm-offsets.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
link to explanation TBA&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Disabling GCC Plugins ===&lt;br /&gt;
&lt;br /&gt;
KConfig unselect&lt;br /&gt;
&lt;br /&gt;
=== Patches ===&lt;br /&gt;
&lt;br /&gt;
Other things (for 6.6LTS)&lt;br /&gt;
PCIe Stub patch&lt;br /&gt;
&lt;br /&gt;
=== Autoconf === &lt;br /&gt;
&lt;br /&gt;
No known setup examples&lt;br /&gt;
Add whatever it publishes in mdns&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== troubleshooting / analysis ==&lt;br /&gt;
&lt;br /&gt;
=== testing ===&lt;br /&gt;
&lt;br /&gt;
# turn off fallback&lt;br /&gt;
&lt;br /&gt;
# GCC example compiles&lt;br /&gt;
## code example C&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example C++&lt;br /&gt;
## same with included header&lt;br /&gt;
## code example ObjC&lt;br /&gt;
## same with included header&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
no ccache here yet&lt;br /&gt;
&lt;br /&gt;
# Cmake example compiles&lt;br /&gt;
the thing with compile launcher ccache;distcc&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== security ==&lt;br /&gt;
&lt;br /&gt;
the security model consists of ip restrictions.&lt;br /&gt;
there seems to also be some GSSAPI user auth.&lt;br /&gt;
further, commands that can be called are restricted by name and location.&lt;br /&gt;
this appears to be a runtime whitelist lookup, meaning it&#039;s done and authorized by the same parts of the daemon as processes the compile request along with the intended compiler.&lt;br /&gt;
so the main weaknesses against malicious clients seem to be in sending things to compile, and in overriding the remote compiler to use.&lt;br /&gt;
it can be assumed that a malicious client able to exploit the compiler handshake can then run arbitrary stuff.&lt;br /&gt;
There&#039;s at least a github issue regarding this google.com/search?q=distcc+seccomp&amp;amp;rlz=1C5CHFA_enDE1121DE1121&amp;amp;oq=distcc+seccomp&amp;amp;gs_lcrp=EgZjaHJvbWUyBggAEEUYOTIHCAEQIRigATIHCAIQIRigAdIBCDM1NjRqMGo3qAIAsAIA&amp;amp;sourceid=chrome&amp;amp;ie=UTF-8 suggesting running over ssh. That does only partitally alleviate this risk with regard  to a key based verfication of a client versus a the standard ip restrictions which always include some parsing.&lt;br /&gt;
So this protects against someone directly exploiting the TCP code of distcc.&lt;br /&gt;
It does not protect against malicious clients.&lt;br /&gt;
(ssh force command can&#039;t be used or you&#039;ll not compile anything)&lt;br /&gt;
&lt;br /&gt;
The basic step for protecting access should be filtering who can access the distcc server, so use nftables etc. to restrict access to port 3262 (??) set up the internal filter the same way.&lt;br /&gt;
&lt;br /&gt;
The next thing is to confine the compiler calls to only write in their temp directory and that they can only run compilers (using nsjail, apparmor, selinux etc)&lt;br /&gt;
&lt;br /&gt;
One needs to investigate when compiler_whitelist.sh is exactly called. as far as I recall it doesn&#039;t close stdin/stdout.&lt;br /&gt;
&lt;br /&gt;
The other internal security bit is that they do some priviledge dropping. it runs as a dedicated user (distcc), so you can also have an audit policy, and can/could use something like iptables&#039; to ensure it can only connect to the other distcc/memcached hosts, but nothing else.&lt;br /&gt;
&lt;br /&gt;
I think that&#039;s safe enough, the main vector is breakouts and confinement is possible.&lt;br /&gt;
there&#039;s also a selinux policy for distcc from gentoo or liguros if one is so inclined.&lt;br /&gt;
https://repology.org/project/selinux-distcc/versions&lt;br /&gt;
&lt;br /&gt;
Some extra measures should be taken since the project has only a few part-time maintainers that cannot drive the project forward or do large refactors.&lt;/div&gt;</summary>
		<author><name>Darkfader</name></author>
	</entry>
</feed>