site  contact  subhomenews

Improved X server security in Easy Containers

July 06, 2018 — BarryK

I am gradually ramping up the security for Easy Containers. Most recently, attention has been given to the X server that is used in a container, and the ways in which it can be accessed. Here is a snapshot of the latest Easy Container Management (see Filesystem menu):


Now, there is a choice of Xorg or Xephyr X servers. The latter is a nested server, which outputs to its own window within the main Xorg desktop. Using Xephyr in a container is considered to be more secure.

There are four ways in which an application can "connect" to the X server: tcp port, abstract socket, pipe or Unix Domain Socket. Both Xorg and Xephyr are started with "-nolisten tcp", thus disabling that option.

To see where the servers are launched and the commandline, for Xorg, see /usr/bin/xwin, for Xephyr see /root/Startup/xephyr (in the upcoming EasyOS 0.9.5)

The other three have arguments for an against. For EasyOS 0.9.5, I decided to launch Xorg with "-nolisten tcp -nolisten local", thus in the case of Xorg there only remains the Pipe and Unix Domain socket options.

Anyway, the "?" help button that you can see in the above snapshot, has useful summaries of each option.

To see the choices applied to a container, there is a configuration file. EasyOS 0.9.5 has a new container named "petget0", and the configuration file is here:


Printing the X choices:

#Connect to X by abstract socket, pipe, or unix domain socket (abstract|pipe|unix)...
#Use Xorg or Xephyr server (xorg|xephyr)...

As I posted recently, I wanted to rethink some of the basics. That will be ongoing, however, I am now looking at implementing containers in a different, simpler, way. Simple, so that the above Easy Containers Management GUI app will never even be needed to run. So the user will not have to get involved in the details of creating a container and making those technical security choices.

Will explain more soon...

Tags: easy

coreutils cp utility broken compiled with musl

July 02, 2018 — BarryK

In the latest build of EasyOS I am getting file copy errors when using 'cp'. This build is using a statically compiled coreutils single-binary (with applets symlinked to it, just like busybox), that was compiled in OE.

Here is an example:

# coreutils --coreutils-prog=cp -a -f /mnt/sdb1/projects/woof/woof-project/builds/quirky-out_amd64_amd64_oe_pyro_easy/sandbox3/rootfs-complete/var varX
coreutils: failed to preserve ownership for varX/local/pupdial/isp: Not supported

"isp" is a symlink to a folder, target with permissions '777'. That is what causes the error message, though the copy does succeed.

Alright, trying busybox cp:

# rm -rf varX
# busybox cp -a -f /mnt/sdb1/projects/woof/woof-project/builds/quirky-out_amd64_amd64_oe_pyro_easy/sandbox3/rootfs-complete/var varX

...good, no error message.

OK, compiling coreutils with uClibc. I used a very old uClibc, refer to, and bumped coreutils to 8.30. Have a static single binary, test it:

# rm -rf varX
# coreutils --coreutils-prog=cp -a -f /mnt/sdb1/projects/woof/woof-project/builds/quirky-out_amd64_amd64_oe_pyro_easy/sandbox3/rootfs-complete/var varX


Grumble, grumble, this reinforces my dislike of musl. I did a search on the Internet, this bug has been reported over several years.

Tags: easy, oe

Xorg .Xauthority is extra protection

July 02, 2018 — BarryK

I don't know of any pups that have bothered with this, however, ~/.Xauthority is an extra level of security, that I have now implemented in EasyOS.

I am playing with running X apps in containers with the Xephyr nested X server. In /usr/bin/xwin, I now launch Xorg with "-nolisten tcp -nolisten local", which prevents any app to connect to the Xorg server via a TCP port or what is called an "abstract socket".

That leaves /root/.X11-unix/X0 a Unix Domain Socket. This is how apps will communicate with Xorg.

Inside a container, it is still possible to connect with Xorg :0, even though apps inside the container cannot "see" /root/.X--unix/X0 in the host. This can be done with 'socat'. Do this in the host:

# socat -ly -d -d TCP-LISTEN:6000,fork,bind=localhost UNIX-CONNECT:/tmp/.X11-unix/X0 &

Then in the container:

# export DISPLAY=localhost:0

However, Xorg itself is considered to have many security weaknesses, and one step-up to improve security is to use Xephyr, which is a nested kdrive X server. I am running this on DISPLAY :1, launched in the host,

Putting that aside, while reading up on X xecurity, it seemed to me that it will be a good thing to implement /root/.Xauthority. A "cookie" can be placed in this file, and any other computer that wants to connect to our local Xorg must have a matching cookie in its own ~/.Xauthority file.

So, /etc/rc.d/rc.sysinit now has this, just after the hostname is autogenerated:

 xPW="$(< /dev/urandom tr -dc 'a-f0-9' | head -c32)"
echo -n '' > /root/.Xauthority
xauth -f /root/.Xauthority add ${PUPHOSTNAME}/unix:0 . ${xPW}

The hostname may also be changed in QuickSetup, /usr/sbin/quicksetup, which calls /usr/sbin/hostname-set. So, the same code is now in hostname-set, just after writing to /etc/hosts.

I think that I have got it right, not verified yet! If I haven't, if the cookie has the wrong hostname, then the desktop will become non-functional.

There is something called "FamilyWild", which basically enters a wildcard in place of the hostname. That means the cookie will work for all local displays, regardless of what the hostname is. Unfortunately, I want to distinguish between :0 and :1, whereas the docs state that FamilyWild applies to "all displays".

Here is some further info:


A special connection family (FamilyWild, value 65535) causes an entry to match every display, allowing the entry to be used for all connections.

For the record, I found this on the Internet, a way to convert a cookie to FamilyWild:

# touch test1
# xauth nlist :0 | sed -e '/^..../ffff/' | xauth -f test1 nmerge -
# xauth -f test1 list

Tags: easy

EasyOS and Quirky development hiatus

June 29, 2018 — BarryK

I have decided to put the development of EasyOS and Quirky on-hold for awhile, as I want to reconsider some of the basic architecture.

Various thoughts have been brewing in the back of my mind for awhile, and it has come to a head as I have been implementing EasyPak, my concept for "universal packages".

Universal packaging systems include Flatpak and Snaps, and the more I looked into these, the more troubled I became. The idea, basically, is that a universal package will run on "any Linux distro", however, I started to realise that there are caveats to this. Some assumptions have to be made about the underlying OS, such as existence of pulseaudio, systemd, dbus, and so on. In other words, the "universal app" will actually only run on certain distros.

Then there is the size. A universal package is just about an entire distribution. Yep, just about every underlying package has to be included in the universal package. Hence, when I installed the Krita flatpak, the Qt-based paint program, from Flathub, the download was 566MB.

I began to question the value of the whole philosophy of universal packages.

I am also troubled by the philosophy underlying containers. Yeah, yeah, universal packages, containers, flavour of the month, flavour of the year, whatever.

There are some aspects of Android that I like. Android runs each app as a separate user. This is actually a very simple isolation mechanism, that uses Unix groups/users architecture that has been there right from the start of Unix and Linux.

I have never liked Java, yet the JVM does provide abstraction from the hardware (HAL), which has one important principle, that packages can be shipped as Java code and will run on all Android phones and tablets. Well, the Java API provided with Android does change. You can download an app, size say 10 - 50MB, and it will run on all phones that have the minimum specified Android version. Yes, these are universal packages, a fraction of the size of those coming from Flatpak and Snap.

Anyway, there are a few lines of thought that I want to follow, will try and post here when there is an interesting development. 

Tags: easy, quirky

Packages recompiled in oe-qky-src

June 23, 2018 — BarryK

Finalised, for now, the backporting of packages from the Sumo release of OpenEmbedded, in my fork 'oe-qky-src', see commits (June 23, 2018):

Did a build overnight, and have now imported the binary packages, all 724 of them, into woofQ, for future builds of EasyOS and Quirky. The packages will be available in the "oe-pyro" repository in the PPM (Package Manager), and so are uploaded.

Here they are:

Now, I am keen to get back to EasyPak, an exciting new idea for "universal packages"...

Tags: oe, easy, quirky

How to give super-powers to zeus

June 20, 2018 — BarryK

This is very interesting! I have a user named 'zeus', your normal underprivileged user. How can I give zeus admin-privileges, without actually becoming root -- because, that is what 'sudo' does, can bump up to 'root' to perform admin operations.

I want to perform some admin operations, while still being zeus. Never mind why I want to do this, I just do.

The 'capsh' utility, in the 'libcap' package, can do it. I wrote about "Linux capabilities" recently:

...however, I am not interested in the cap_sys_mount patch anymore.

Puppy Linux and derivatives such as Easy and Quirky, run as 'root', with the ability to run Internet applications as user 'spot', and in Easy in containers with unprivileged-root -- the latter is achieved by using 'capsh' to drop privileges when chroot into a container.

Anyway, running as root, it would seem that capsh could be used to switch to a normal user, yet keep any privileges that we want to keep. In Easy, there is a user named 'zeus', that I created especially for this experiment.

I thought that capsh would work (using "--secbits"), however, it didn't. I am using libcap version 2.25, which the original author stopped work on some years ago. I discovered that some further work has been done on libcap, to add that missing/broken feature:

...thanks Andrew!

I modified the source slightly, copied from the kernel source /usr/src/linux-4.14.44/include/uapi/linux/capability.h, prctl.h, and securebits.h, to libcap-2.25/libcap/include/uapi/linux/, and changed the "DYNAMIC..." line in Make.Rules to this:

DYNAMIC := $(shell echo yes) as to get dynamically liked executables.

Then just ran the usual:

# make
# new2dir make install

Running "capsh --print" prints out all of the capabilities. Now, if I want to change to user zeus and keep all of those capabilities:

# capsh --keep=1 --user='zeus' --inh='cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_linux_immutable,cap_net_bind_service,cap_net_broadcast,cap_net_admin,cap_net_raw,cap_ipc_lock,cap_ipc_owner,cap_sys_module,cap_sys_rawio,cap_sys_chroot,cap_sys_ptrace,cap_sys_pacct,cap_sys_admin,cap_sys_boot,cap_sys_nice,cap_sys_resource,cap_sys_time,cap_sys_tty_config,cap_mknod,cap_lease,cap_audit_write,cap_audit_control,cap_setfcap,cap_mac_override,cap_mac_admin,cap_syslog,cap_wake_alarm,cap_block_suspend,cap_audit_read' --addamb='cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_linux_immutable,cap_net_bind_service,cap_net_broadcast,cap_net_admin,cap_net_raw,cap_ipc_lock,cap_ipc_owner,cap_sys_module,cap_sys_rawio,cap_sys_chroot,cap_sys_ptrace,cap_sys_pacct,cap_sys_admin,cap_sys_boot,cap_sys_nice,cap_sys_resource,cap_sys_time,cap_sys_tty_config,cap_mknod,cap_lease,cap_audit_write,cap_audit_control,cap_setfcap,cap_mac_override,cap_mac_admin,cap_syslog,cap_wake_alarm,cap_block_suspend,cap_audit_read' --
# whoami
# rm -f NewFile1

'NewFile1' was owned by root, and a user would not be able to delete it, which I checked was the case when I just did a normal "su zeus". Yippee, zeus has super-powers!

Note, the order is important:

capsh --keep=1 --user='zeus' --inh='...' --addamb='...' -- 

The "--" causes bash to run, so you have a new shell, and get back to root by typing "exit".

Tags: easy, linux, quirky

Devuan will be repo for EasyPak

June 18, 2018 — BarryK

I posted yesterday about the genesis of EasyPak, my take on "universal packages":

I decided to use the Devuan "ascii" repository for building the universal packages. I have created script /usr/local/EasyPak/create_db and a repository spec file /usr/local/EasyPak/DISTRO_COMPAT_REPOS-devuan.

It works, creates the Puppy-format package files in /usr/local/EasyPak, for "main", "contrib" and "non-free". Script create_db can be rerun at any time in a running EasyOS to update these db files.

EasyOS "Pyro" series is built from packages compiled in my fork of OpenEmbedded. That is, a distro compiled entirely from source. However, the "universal packages" will be constructed from Devuan DEBs. This does not matter, as that is the whole idea of universal packages, that they will run on any Linux distro. Implementing this will be "proof of the pudding".

The next step... taking a break, will think about that later.

Tags: easy

Applying the KISS principle to universal packages

June 17, 2018 — BarryK

The main contenders for "universal packages", that is, apps that will run on any Linux distribution, are AppImages, Flatpaks and Snaps.

I have been studying them. AppImages seem a bit too limited, though a simple concept. Flatpaks and Snaps are very complicated, and after much reading, I think that there is a much easier way to achieve similar goals.

Thinking about a very simple mechanism for universal packages, it would seem that I need a proper CLI package manager, instead of PPM (PETget Package Manager, or Puppy Package Manager). Then I remember, there is such as project, named Pkg.

Pkg is a mammoth effort by Puppy Forum member sc0ttman. The project is described here:

There is older discussion here:

The project is online, at gitlab:

I downloaded:

# git clone git:// --depth 1

My idea for a universal package system, is to use what is already there, the DEB and RPM repositories, and their superb versioning and updating handling. The idea is simple: choose a package from a Debian/Ubuntu/Devuan/whatever repo, in a container in Easy, download it and all deps -- the secret is to download most deps, overwriting many packages that are already in the underlying q.sfs. A few details to fill in, but that's it, essentially.

The important point here, is that containers in Easy are complete, containing the entire Easy filesystem. This is because every container has q.sfs as a read-only layer in it. Other distros do not have this, they construct cut-down containers.

Each container in Easy has its own complete package manager. Which is where sc0ttman's Pkg may have a roll to play. I need to be able to do many operations from scripts.

So, although Easy now supports Flatpaks, from the commandline anyway, I might not use it.

Of course, my idea needs a name, so I reckon EasyPaks is appropriate! That's it, I officially name my universal packaging system EasyPak. With due acknowledgement of these guys!:

Tags: easy