Run web-ui in a docker container?


#21

Thank you for your research regarding the machine-id!

/var/lib/dbus/machine-id will be identical for everyone running your image since it’s “baked in”. So if two different users happen to use the same hostname (e.g. duplicacy), Duplicacy would detect a license violation, no? Having a static machine-id also seems, to me at least, to be contrary to the semantics of what the value is supposed to represent.

I’ve updated my image to generate a temporary machine-id when the container launches, but also allow a few different ways for users to supply their own static values (i.e. bind-mount or environment variable).


#22

Ooooops. You are right. I did not think that through. I assumed that the image will be rebuilt every time from the source, which is not the case.

I think the solution would be to install dbus in init script, as opposed to backed into the image; as the machine-id seems to be generated by dbus-uuidgen in the dbuses post-install script.

Proof of concept:

aleximac:~ alex$ docker run -it alpine /bin/sh
/ # apk add dbus
...
(3/3) Installing dbus (1.10.24-r1)
Executing dbus-1.10.24-r1.pre-install
Executing dbus-1.10.24-r1.post-install
Executing busybox-1.28.4-r2.trigger
OK: 5 MiB in 16 packages
/ # cat /var/lib/dbus/machine-id
50ad3d4b81530f1ee29a3f7c5c50ea85
/ # exit
aleximac:~ alex$ docker run -it alpine /bin/sh
/ # apk add dbus
...
(3/3) Installing dbus (1.10.24-r1)
Executing dbus-1.10.24-r1.pre-install
Executing dbus-1.10.24-r1.post-install
Executing busybox-1.28.4-r2.trigger
OK: 5 MiB in 16 packages
/ # cat /var/lib/dbus/machine-id
076c0a40baf41f59667dc0595c50ea98
/ #

Thank you for catching that!

I’ll fix that and check in the fix in the evening.

Edit. Actually, I think it would be even better to just leave dbus backed in the image, but run the dbus-uuidgen script in the init script unless the saved machine-id already exists in the config folder, in which case just copy it.

Edit. This is what I ended up doing; this takes care of new machine-id generation, verification and correction.

# Preparing persistent unique machine ID
if ! dbus-uuidgen --ensure=/config/machine-id; then 
	echo machine-id contains invalid data. Regenerating.
	dbus-uuidgen > /config/machine-id
fi

# Copying machine-id to container
cp /config/machine-id /var/lib/dbus/machine-id
chmod o+r,g+r /var/lib/dbus/machine-id

#23

Any reason why don’t you use dbus_uuidgen which is intended to generate machine-id, and instead simulate its behavior (which may change)? Also I’m not sure urandom is diverse enough, i’d add some sort of crypto hash on top. Or just use dbus tools.

Also, i’d validate user-supplied values (dbus-uuidgen can do that for you) - duplicacy likely expects compliant string.


#24

Mostly because I don’t want to install dbus into the image just to create a 32 character string, especially since it can be done with a one-liner.

dbus-uuidgen internally reads from /dev/urandom, too.

Not to get off-topic, but I don’t know of a better source of random data. And I don’t think that hashing a random value will produce a more random value; If anything, hashing could have the opposite effect.


#25

I’d argue that anything could be written in one line; but it is less readable than using dedicated tool. In addition, duplicacy uses dbus, so it does make sense to use the same environment instead of simulating it; space is cheap.
Also, dbus may be useful later, to communicate with keychain for example to work with encryption keys, etc.

They sort of make an attempt to add variability by concatenating current time to it, but honestly, I did expect more.

Since you are reading random data almost very first thing after boot, the entropy pool may not be deep enough yet (see /proc/sys/kernel/random/entropy_avail). /dev/urandom will not block and return poor quality random data; and since this is used to derive license keys we really want to minimize collisions so I would at least wait for sufficient entropy to accumulate. Simply using /dev/random should do the trick, as it will block until enough entropy is available.

The amount of entropy won’t change, but correlation between bits will (when using crypto hash, not just CRC). In fairness, I can’t imagine that somebody will try to exploit that to get free duplicacy license :slight_smile: but addressing this does not cost anything and may reduce probability of collisions.


#26

I hear ya and respect your idea, but in this case I just have a different opinion. ¯\_(ツ)_/¯

I disagree here. Remember that a container shares the same kernel with the host, so reading from /dev/{u}random in the container will, behind the scenes, ask the same kernel for random bytes. You can verify this yourself:

cat /proc/sys/kernel/random/entropy_avail && docker run --rm alpine cat /proc/sys/kernel/random/entropy_avail

You’ll see that the available entropy is essentially the same, even in the freshly-started container.

You could make the argument that a physical system or virtual machine will have low entropy on boot, but even then many distros will keep a seed file (/lib/systemd/systemd-random-seed or /var/lib/systemd/random-seed) to help with entropy after booting.

The consensus among the experts, as I interpret it at least, is that urandom is recommended for the vast majority of all cryptographic uses. There are a few rare instances where /dev/random is better like embedded systems after boot, or information-theoretic security.

Again I have to disagree. A hash of any kind (crypto or otherwise) simply maps a set of bits to another set of a fixed number bits; it won’t improve the randomness of the final value. Even if you salt the input or use a randomness extraction function on it, you’re relying on additional random data that needs to come from somewhere.

But I agree with you that we’re dealing with a software license and not protecting someone’s bank account or medical history, so we might be going overboard :slight_smile: But it’s a good discussion, and I look forward to continuing to work together to develop images for Duplicacy.