Monthly Archives: August 2021

VoidLinux in FreeBSD Jail; with init

Two important things happened this week for me.

First, Faraz asked me if I can rename my Jail manager to something other than Jailio because he got that domain for his Jailer manager already. So I named it

Second, I was able to run a complete Linux system using Jailer. While the repo for Jailer is not released yet (we are auditing for possible security issues), I would like to share how I was able to run VoidLinux in a Jail.

Since Jailer is not announced yet, I will give the examples using jail.conf, as most people either are or should be familiar with its concepts.

I went with VoidLinux because I am able to run the init process without its need to be running as PID1.

Let’s start, shall we?

First, ZFS dataset for our jail!

zfs create zroot/jails/voidlinux

Next we need to fetch the base system of VoidLinux. Luckily they do provide it on their website.

fetch https://alpha.de.repo.voidlinux.org/live/current/void-x86_64-ROOTFS-20210218.tar.xz

Now we can extract this into our dataset

tar xf void-x86_64-ROOTFS-20210218.tar.xz -C /usr/local/jails/voidlinux/

You might get an error that ./usr/bin/iputils-ping: Cannot restore extended attributes: security.capability, which is fine, I think?

If you are on FreeBSD 12.2-RELEASE or later, now you need to enable the Linuxulator.

service linux enable; service linux start

Now you can at least chroot into the system.

chroot /usr/local/jails/voidlinux/ /bin/bash

If everything is fine until now, perfect.

Now we need to add a root user into the system.

root@host:~ # cd /usr/local/jails/voidlinux/etc/
root@host:/usr/local/jails/voidlinux/etc # echo "root::0:0::0:0:Charlie &:/root:/bin/bash" > master.passwd
root@host:/usr/local/jails/voidlinux/etc # pwd_mkdb -d ./ -p master.passwd
pwd_mkdb: warning, unknown root shell

Execute the rest of the commands in Void.

root@host:~ # chroot /usr/local/jails/voidlinux/ /bin/bash
bash-5.1# cd /etc/
bash-5.1# pwconv 
bash-5.1# grpconv 
bash-5.1# passwd 
New password: 
Retype new password: 
passwd: password updated successfully
bash-5.1# exit

If all went fine, then the system is ready to be run as a Jail!

First we need to make an fstab for the system.

Create a file at /usr/local/jails/voidlinux/etc/fstab.pre and insert the following inside

devfs       /usr/local/jails/voidlinux/dev      devfs           rw                      0   0
tmpfs       /usr/local/jails/voidlinux/dev/shm  tmpfs           rw,size=1g,mode=1777    0   0
fdescfs     /usr/local/jails/voidlinux/dev/fd   fdescfs         rw,linrdlnk             0   0
linprocfs   /usr/local/jails/voidlinux/proc     linprocfs       rw                      0   0
linsysfs    /usr/local/jails/voidlinux/sys      linsysfs        rw                      0   0
/tmp        /usr/local/jails/voidlinux/tmp      nullfs          rw                      0   0

Next, let’s create a loopback interface for networking. Oh yes, VNET is not supported yet, but I’m working on a patch 🙂

ifconfig lo1 create
ifconfig lo1 inet 10.10.0.1/24 up # sorry, 10.0.0.0/24 was unavailable :P

Okay, time to create our Jail conf!

exec.clean;
allow.raw_sockets;
mount.devfs;

voidlinux {
    $id     = "1";
    $ipaddr = "10.10.0.42";
    $mask   = "255.255.255.0";
    $domain = "srv0.bsd.am";
    devfs_ruleset  = 4;
    allow.mount;
    allow.mount.devfs;
    mount.fstab = "${path}/etc/fstab.pre";

    exec.start     = "/bin/sh /etc/runit/2 &";
    exec.stop      = "/bin/sh /etc/runit/3";


    ip4.addr      = "${ipaddr}";
    interface     = "lo1";
    host.hostname = "${name}.${domain}";
    path = "/usr/local/jails/voidlinux";
    exec.consolelog = "/var/log/jail-${name}.log";
    persist;
    allow.socket_af;
}

Let’s check?

# jls
   JID  IP Address      Hostname                      Path
     1  192.168.0.42    voidlinux.srv0.bsd.am         /usr/local/jails/voidlinux

And the process tree?

# ps auxd -J voidlinux
USER   PID %CPU %MEM  VSZ  RSS TT  STAT STARTED    TIME COMMAND
root 35182  0.0  0.1 2320 1428  -  SsJ  21:09   0:00.12 runsvdir -P /run/runit/runsvdir/current log: ot set SO_PASSCRED: Protocol not available\ncould not set SO_PASSCRED: Protocol
root 35190  0.0  0.1 2168 1376  -  SsJ  21:09   0:00.02 - runsv agetty-tty6
root 35397  0.0  0.1 2412 1704  -  SsJ  21:10   0:00.00 `-- agetty tty6 38400 linux
root 35191  0.0  0.1 2168 1376  -  SsJ  21:09   0:00.02 - runsv agetty-tty1
root 35396  0.0  0.1 2412 1704  -  SsJ  21:10   0:00.00 `-- agetty --noclear tty1 38400 linux
root 35192  0.0  0.1 2168 1376  -  SsJ  21:09   0:00.02 - runsv agetty-tty5
root 35398  0.0  0.1 2412 1704  -  SsJ  21:10   0:00.01 `-- agetty tty5 38400 linux
root 35193  0.0  0.1 2168 1376  -  SsJ  21:09   0:00.02 - runsv agetty-tty2
root 35393  0.0  0.1 2412 1704  -  SsJ  21:10   0:00.00 `-- agetty tty2 38400 linux
root 35194  0.0  0.1 2168 1396  -  RsJ  21:09   0:00.12 - runsv udevd
root 35195  0.0  0.1 2168 1376  -  SsJ  21:09   0:00.02 - runsv agetty-tty3
root 35394  0.0  0.1 2412 1704  -  SsJ  21:10   0:00.00 `-- agetty tty3 38400 linux
root 35196  0.0  0.1 2168 1376  -  SsJ  21:09   0:00.02 - runsv agetty-tty4
root 35390  0.0  0.1 2412 1704  -  SsJ  21:10   0:00.00 `-- agetty tty4 38400 linux

You may jexec now 🙂

# jexec voidlinux /bin/bash
bash-5.1# uname -a
Linux voidlinux.srv0.bsd.am 3.2.0 FreeBSD 12.2-RELEASE-p6 GENERIC x86_64 GNU/Linux

Let’s check networking?

bash-5.1# ping -c 1 10.10.0.1
ping: WARNING: setsockopt(ICMP_FILTER): Protocol not available
PING 10.10.0.1 (10.10.0.1) 56(84) bytes of data.
64 bytes from 10.10.0.1: icmp_seq=1 ttl=64 time=0.069 ms

--- 10.10.0.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.069/0.069/0.069/0.000 ms

There you go! Well, things that are related to netlink might not work, but other than that it’s okay.

I did have some problems while installing packages, something about too many levels of symbolic links. Here’s the exact output when I was trying to install the curl package

[*] Unpacking packages
libev-4.33_1: unpacking ...
ERROR: libev-4.33_1: [unpack] failed to extract file `./usr/lib/libev.so.4': Too many levels of symbolic links
ERROR: libev-4.33_1: [unpack] failed to extract files: Too many levels of symbolic links
ERROR: libev-4.33_1: [unpack] failed to unpack files from archive: Too many levels of symbolic links
Transaction failed! see above for errors.

Now, I did not find the time to fix this yet, but if you have any idea, please let me know or comment below 🙂

So, what do we have here? A Linux Jail, running VoidLinux, with init, so you can also run services, and basic networking for it.

That’s all folks…

Reply via email.

Linux is dead, long-live Docker monoculture

Full Discloser: While reading this blog post, please put yourself in my shoes. You’ve been looking around for a simple monitoring solution, you found some. None of the some are working because you use an Operating System that is used by Apple, WhatsApp, Netflix and many more, but developers think that everyone, everywhere, runs either macOS or Linux. And they all use Docker.

A while back Rubenerd wrote that he’s not sure that UNIX won and how Linux created a monoculture of assuming everything is supposed to run on Linux.

For me, this was not much of a problem, I can run Linux binaries on FreeBSD, I even watch Netflix using Linuxulator.

But now things are on another level, WAY another level.

I have a simple monitoring setup using cron, Grafana, InfluxDB and ping. It basically pings my servers and sends me a telegram message if they are down.

I set that up years ago, but now I have more public facing infrastructure that other people use as well, such as an Armenian Lobsters instance, Jabber.am, a WriteFreely instance and more.

As a self-respecting Ops, I wanted to make a simple dashboard for my users to see the uptime status of these services as well. First, they won’t bug me asking if something is not working; they will SEE, that, SSL/TLS certificate is expired, or the network is an issue, or that the server is down.

<rant>

So I started hunting on the internet for some software that do just that.

The first one that came to my mind was Gatus. I’ve used Gatus before for one of my clients, I like it a lot. It’s simple, it does what it’s supposed to do.

As a sane person, I fetched the code from GitHub using fetch, extracted the tarball and ran make. Nothing happens. Let’s see the Makefile, shall we?

Docker executed in Make

Oh boy, if only, only, I had Docker, all my problems would be solved. First of all, let’s talk about the fact that this Makefile is used as a… script. There’s no dependencies in the targets!

Okay, let’s read that Dockerfile. Executing the scripts inside it should help out, aye?

# Build the go application into a binary
FROM golang:alpine as builder
RUN apk --update add ca-certificates
WORKDIR /app
COPY . ./
RUN CGO_ENABLED=0 GOOS=linux go build -mod vendor -a -installsuffix cgo -o gatus .

# Run Tests inside docker image if you don't have a configured go environment
#RUN apk update && apk add --virtual build-dependencies build-base gcc
#RUN go test ./... -mod vendor

# Run the binary on an empty container
FROM scratch
COPY --from=builder /app/gatus .
COPY --from=builder /app/config.yaml ./config/config.yaml
COPY --from=builder /app/web/static ./web/static
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
ENV PORT=8080
EXPOSE ${PORT}

There are multiple things wrong in me this.

First, please stop putting your binaries in /app, please, pretty-please? We have /usr/local/bin/ for that.

Second, I thought that running go build without GOOS=linux would solve all of my problems. I was wrong, very wrong.

root@mon:~/gatus/gatus-2.8.1 # env CGO_ENABLED=0 go build -mod vendor -a -installsuffix cgo -o gatus .
package github.com/TwinProduction/gatus
        imports github.com/TwinProduction/gatus/config
        imports github.com/TwinProduction/gatus/storage
        imports github.com/TwinProduction/gatus/storage/store
        imports github.com/TwinProduction/gatus/storage/store/sqlite
        imports modernc.org/sqlite
        imports modernc.org/libc
        imports modernc.org/libc/errno: build constraints exclude all Go files in /root/gatus/gatus-2.8.1/vendor/modernc.org/libc/errno

Okay, check this out, the package is called modernc.org/sqlite and it says:

Package sqlite is a CGo-free port of SQLite.

SQLite is an in-process implementation of a self-contained, serverless, zero-configuration, transactional SQL database engine.

Of course it is. Looks like I have to port all of this to FreeBSD. Which, don’t get me wrong, I’m okay with doing that, but I thought that we have POSIX for a reason. notsomuch.

Okay, I’m an open-source guy, I’ll spend some time this weekend to port this to FreeBSD. Let’s look for another solution!

Here’s another one, it’s called statping, also written in Go, the readme is so promising.

No Requirements

Statping is built in Go Language so all you need is the precompile binary based on your operating system. You won’t need to install anything extra once you have the Statping binary installed. You can even run Statping on a Raspberry Pi.

Sounds good! Let’s try it out.

Again, I fetch the tarball, I extract and I bake make.

apt executed in Make

Of course it requires apt! Because not only we all run Linux, be we all run a specific distribution of Linux with a specific package manager.

While tweeting with anger, Daniel pointed out that I should tell them kindly and it’ll work out. I’m sure it will. Let’s hope I can make it work first. I don’t like just opening issues. I’d rather send a patch directly.

</rant>

Overall, now I understand why most *BSD folks use, what’s the word here? ah, yes, old-school software on their systems, like Nagios and the rest.

The developers of the New World Order will assume, always, you are running Linux, as Ubuntu, and you always have Docker.

Hopefully this weekend I will be able to port these software to FreeBSD, otherwise I will just use the Linux layer.

Like Rubenerd said, I am thankful that the mainstream-ness of Linux helped other Unix systems as well, but monocultures are destroying what people have spent years to improve.

Hopefully, next week, I will write a blog post on how to fix these issues and how I got all of those up and running.

That’s all folks…

Reply via email.

Comments are back

When I started blogging 8 years ago I used WordPress. One of its features was comments. However, when I started my English blog (the one that you are reading right now) I chose Hugo and then migrated my Armenian blog to Hugo as well.

This had two amazing features. First, no more managing PHP and MySQL, since Hugo is a static sigh site generator, second, no more dealing with comments.

During the last years more and more people have been contacting me over email/Twitter/Telegram to give me feedback about a post that they read. This is mostly about my Armenian blog. I don’t get much feedback from the English blog, unless someone posts it on HackerNews (then I get A TON).

I started missing comments, a centralized place to read all the feedback and an easy way for the reader to post them.

In Hugo’s documentation I see there’s a section about comments but it recommends Disqus. I don’t like 3rd party services. Lucky someone on Twitter recommended an alternative, Isso!

Isso was very easy to deploy. I created a FreeBSD Jail, did a pip install isso and then setup a reverse proxy. Add some JS scripts here and there in the template, and it’s all done!

I’m not sure if I’ll be able to fight spam. I still need to setup an SMTP server so it emails the commenters if someone replied to their comments, but that’s a project for the weekend.

That’s all folks…

Reply via email.

The long awaited vacation

It’s finally here and I cannot believe it. I’ve been waiting for this for a long-long time.

We started illuria Security on… wait let me check.

$ whois illuriasecurity.com | grep -i creation
   Creation Date: 2018-05-15T16:51:31Z
Creation Date: 2018-05-15T16:51:31.00Z

Ah yes, more than 3 years now. I never had a vacation since we started the company.

Every time I told myself “Okay, you will have relax time during the weekend” I ended up coding, if not for the company software then at least for something related to it. A patch in rc.d here, a shell script there.

But now, I’ve grown (I think), I finally know the value of the self. If I’m not good, then the company is not good, if I’m tired, then the company will be tired.

So, for once, all of the co-founders decided to take a proper vacation. We are all still online, because that’s what the world expects from us these days, but at least I’m not coding in Elixir or writing Shell.

Here are some thing that I wanted to do for a LONG time.

  • Fix my ZNC server and migrate my own channels to Libera.Chat.
  • Clean up my hard drives and setup ZFS backup pools and TimeMachine.
  • There are backups of my home server but I’ve NEVER tried to restore them. Time to open the Schrödinger’s cat’s box and see the results.
  • Fix my email servers that I run for communities. God knows how many TLS certificates are there to update.
  • Think about the redundancy of this weblog, but that’s a story for another day.

9 days of vacation after 3 years doesn’t seem much, but I promised myself that I will NOT do this again. Hopefully I will have a proper 7 day vacation after 5-6 months like a normal human being.

It’s very COVID-y on Earth, but at this part of Earth, Armenia, COVID-19 pretty much does not exists. No one wears masks, very few are vaccinated, night-life is all on and internal tourism is on fire. So we ended up going to Switzerland Dilijan, away from all the noise, always raining, never complaining about traffic and almost every corner has a coffeehouse that serves latte.

Take care of yourself folks, it’s okay to write that code a day later, send that email 12 hours late, but the time you spend not taking care of yourself will be spent 10x more later. It’s like legacy code.

This will also give you time to think about… life.

That’s all folks…

Reply via email.

Music.app is a good radio app

As I mention in my other post, macOS also has Music.app, which as I said I will to try it out as well.

Turns out it’s really good! I’ve been listening to DeepHouseRadio all day. When the connection drops while I go to the kitchen to make some coffee, it buffers it properly. Although once it skipped and started playing the “next song” which was some media file.

While doing my testing, I realized that the Music.app has Radio included in it! It fetches the list of radio stations from TuneIn, which I loved using their app on my BlackBerry 9780 back in the day.

Good job Apple, not updating your QuickTime Player, but at least making sure that one of your out-of-the-box apps handles a thing properly.

That’s all folks…

Reply via email.