Monday, 19 April 2021

Kubernetes (k3s) and certificates

 Oh, Kubernetes, how I love thee.

I've been learning and running a small cluster at home on a mix of several Raspberry Pi and a laptop. It's been a great learning experience and although it was all for internal use, I finally decided I'd try to install some certificates.

Ouch! That took a lot longer to figure out than I wanted!

Turns out that if you read up on Kubernetes and cert-manager the recommended practice is to use the nginx-ingress-controller. But when I was trying that it didn't seem to work. 

It turns out that if I had searched for k3s, then I wouldn't have had to do that deployment and I could run it all with Traefik - which is installed by default in k3s. 

So thanks but here is the right way to run cert-manager and Traefik and deploy certificates (like from LetsEncrypt.)

Wednesday, 10 March 2021

Home Assistant and Zoneminder troubleshooting

 I've been using Home Assistant for a while, but never really spending a lot of time on it. 

However, as of recently, I've started playing with it a bit more and one of the things that I wanted to do was incorporate my Zoneminder cameras onto the platform.

This is rather easy with a few lines in the configuration.yaml according to the documentation at the Home Assistant page.

zoneminder:

  - host: ZM_HOST

    username: ZM_USER

    password: ZM_PASSWORD

You can add path and path_zms variables if you want.

However, I was having some problems. I kept on getting a json decoder error. 

simplejson.errors.jsondecodeerror: expecting value: line 2 column 1 (char 1)

I initially only had the host, username and password but decided to add the paths. That didn't help. I googled for answers and nothing came up that would suit this.

I couldn't figure out what was going on for a while until I did a tcpdump on the pod and noticed I was getting redirected for certain lines and 404 in others. I then looked at the server longs and that's when I realised, I was hitting the wrong site. 

What I mean is, I run multiple applications on this one host and I was going to the host by IP. I was therefore was getting a different site than intended. At first, I disabled the site to test until it finally clicked. I'm going to the host by IP in my Home Assistant configuration. 

I switched the host value from IP to FQDN and voila! Everything started working.

Monday, 5 October 2020

DHCP and DNS - HA at home AKA bind-hole

What is more annoying to people at home, that having their internet services go down? How about the internet service is still working, but other services like DHCP and DNS aren't working and therefore blaming the internet service.

As it turns out, my wifi router at home isn't great at running both of those services. Not only that but because they're on the router, I can't do things like block malware and ads like you can with a pi-hole. If you don't know about the pi-hole, I really think you should give take a look at it. Using a Raspberry Pi, you can run DNS and even DHCP on it and it'll filter all of those ads for you. So, I did that.

Service DID improve quite a bit. People were happy! But, whenever I had to do work on the Pi, like update it, reboot it, etc, then the service would once again go down.

That was when I decided to look at creating a more robust service. Enter 2 Raspberry Pi and ISC's implementation of DHCP. And while I was at it, thought I'd look to see if I could get the same malware and ad blocking as you can with ISC's BIND. The short answer to that was, yes, yes you can.

DHCP


Install DHCP with apt.

sudo apt install isc-dhcpd

DHCP as HA is a piece of cake. Just following the documentation at https://kb.isc.org/docs/aa-00502

You can copy the configs and set the options that are right for your environment. I've put a copy (but slightly modified) version of what I am using. The main thing is to change the key and your IP ranges. Also, if you don't have a domain, you should buy one, they're relatively cheap. You could use the pseudo-tld ".home" so setting up "ns1.yourname.home" would work instead of "ns1.example.org" shown below.

Primary dhcp server


# option definitions common to all supported networks...
option domain-name "bulteel.home";
option domain-name-servers ns1.bulteel.home, ns2.bulteel.home;

default-lease-time 3600;
max-lease-time 7200;

# The ddns-updates-style parameter controls whether or not the server will
# attempt to do a DNS update when a lease is confirmed. We default to the
# behavior of the version 2 packages ('none', since DHCP v2 didn't
# have support for DDNS.)
ddns-update-style none;

# If this DHCP server is the official DHCP server for the local
# network, the authoritative directive should be uncommented.
authoritative;

# Use this to send dhcp log messages to a different log file (you also
# have to hack syslog.conf to complete the redirection).
log-facility local7;

failover peer "failover-partner" {
     primary;
     address dhcp-primary.bulteel.home;
     port 519;
     peer address dhcp-secondary.bulteel.home;
     peer port 520;
     max-response-delay 60;
     max-unacked-updates 10;
     mclt 3600;
     split 128;
     load balance max seconds 3;
}

subnet 192.168.1.0 netmask 255.255.255.0 {
  option routers 192.168.1.1, router.bulteel.home;
  pool {
    failover peer "failover-partner";
    range 192.168.1.50 192.168.1.250;
  }

}
# insert this (with your own key text substituted) into dhcpd.conf on primary and secondary.

omapi-port 7911;
omapi-key omapi_key;

key omapi_key {
     algorithm hmac-md5;
     secret generate-this-with-dnssec-keygen-see-isc-docs==;
}

Secondary dhcp server


# option definitions common to all supported networks...
option domain-name "bulteel.home";
option domain-name-servers ns1.bulteel.home, ns2.example.bulteel.home;

default-lease-time 3600;
max-lease-time 7200;

# The ddns-updates-style parameter controls whether or not the server will
# attempt to do a DNS update when a lease is confirmed. We default to the
# behavior of the version 2 packages ('none', since DHCP v2 didn't
# have support for DDNS.)
ddns-update-style none;

# If this DHCP server is the official DHCP server for the local
# network, the authoritative directive should be uncommented.
authoritative;

# Use this to send dhcp log messages to a different log file (you also
# have to hack syslog.conf to complete the redirection).
log-facility local7;

# This is a very basic subnet declaration.

#subnet 10.254.239.0 netmask 255.255.255.224 {
#  range 10.254.239.10 10.254.239.20;
#  option routers rtr-239-0-1.example.org, rtr-239-0-2.example.org;
#}

failover peer "failover-partner" {
     secondary;
     address dhcp-secondary.bulteel.home;
     port 520;
     peer address dhcp-primary.bulteel.home;
     peer port 519;
     max-response-delay 60;
     max-unacked-updates 10;
     load balance max seconds 3;
}

subnet 192.168.1.0 netmask 255.255.255.0 {
  option routers 192.168.1.1, router.bulteel.home;
  option domain-name-servers 192.168.1.7, 192.168.1.9;
  pool {
    failover peer "failover-partner";
    range 192.168.1.50 192.168.1.250;
  }

}

# insert this (with your own key text substituted) into dhcpd.conf on primary and secondary.

omapi-port 7911;
omapi-key omapi_key;

key omapi_key {
     algorithm hmac-md5;
     secret generate-this-with-dnssec-keygen-see-isc-docs-copy-from-primary==;
}

Just restart both dhcp servers and make sure they're set to boot up. (systemctl enable isc-dhcp-server ; systemctl restart isc-dhcp-server)

DNS


Now there are two things you need to do for DNS. You need to setup RPZ(s) and then a master/slave setup. Neither of these is hard to do.

First, let's do the master/slave setup.

Install the software on both Pi.

sudo apt install bind9 dns-utils

Configure the master. Configure the slave. Job done. Do you have your own domain and you want to have internal DNS resolution of a host? You can even setup DHCP to dynamically update DNS. 

Bind on Debian separates things into named.conf.local and named.conf.options files.

In the named.conf.local of the master

zone "rpz.example.com" {
        type master;
also-notify { 192.168.1.5; };
        file "/var/lib/bind/db.rpz.example.com";
};


zone "bulteel.home" {
type master;
also-notify { 192.168.1.5; };
file "/var/lib/bind/bulteel.home.hosts";
allow-transfer { 192.168.0.9; };
allow-update { key "rndc-key"; };
};

zone "1.168.192.in-addr.arpa" {
type master;
also-notify { 192.168.1.5; };
file "/var/lib/bind/db.1.168.192.in-addr.arpa";
allow-transfer { 192.168.1.5; };
allow-update { key "rndc-key"; };
};


In the named.conf.local of the slave:

zone "rpz.example.com" {
        type slave;
        file "/var/lib/bind/db.rpz.example.com";
        masters { 192.168.1.4; };
};

zone "bulteel.home" {
type slave;
file "/var/lib/bind/bulteel.home.hosts";
        masters { 192.168.1.4; };
};

zone "1.168.192.in-addr.arpa" {
        type slave;
        file "/var/lib/bind/db.1.168.192.in-addr.arpa";
        masters { 192.168.1.4; };
        };

Once that's done, you add domains to the RPZ file using the py-hole-bind script located

https://github.com/glenpp/py-hole/blob/master/py-hole-bind9RPZ

So, you might be asking about how to get stats and a nice dashboard? Well, that'll be for another blog post. 


Tuesday, 31 December 2019

Happy New Year!

2019. The year of crazy! I thought there would be some sanity in the world, but boy was I wrong.

I hope that THIS new year will be great. That 2020 will bring you success.

That 2020 brings sanity! Ohhh, the insanity.

I hope you get to spend it with your family and friends. That the year treats you well.

I don't know what my 2020 will look like. Joy? 2019 sure had its share of emotions.

Well, I wish you all a Happy 2020.

Happy New Year!

Thursday, 19 September 2019

Netscaler VPN client on Linux seems to have issues with libraries.

I have to use the Netscaler VPN client on Linux to do some work. However, I noticed that after upgrading to a newer version of Linux (via wipe/reinstall) the client now doesn't seem to work.

The error appears when you run the client on the CLI, otherwise you get nothing. It says:

./NSGClient: error while loading shared libraries: libssl.so.1.0.0: cannot open shared object file: No such file or directory

Great! Let's install libssl. Oh, it's installed. Let's check what libraries it needs/are missing.

ldd NSGClient 
./NSGClient: /lib/x86_64-linux-gnu/libcurl.so.4: version `CURL_OPENSSL_3' not found (required by ./NSGClient)
linux-vdso.so.1 (0x00007ffef68d9000)
libX11.so.6 => /lib/x86_64-linux-gnu/libX11.so.6 (0x00007f4a1b1b3000)
libssl.so.1.0.0 => not found
libcrypto.so.1.0.0 => not found
libcurl.so.4 => /lib/x86_64-linux-gnu/libcurl.so.4 (0x00007f4a1b125000)
        ... <cut more output - all libraries present>
libcrypt.so.1 => /lib/x86_64-linux-gnu/libcrypt.so.1 (0x00007f4a17286000)
libgpg-error.so.0 => /lib/x86_64-linux-gnu/libgpg-error.so.0 (0x00007f4a17263000)

Two things to note from that output.

1. libcurl.so.4 complains about CURL_OPENSSL_3 not found.
2. Two libraries are not found.

So I tried a couple of things all of which complained that the OpenSSL version of the library was needed. A search on my system came up with the steam directory containing the libraries I required!

Well, that's convenient.

I did the following in the /opt/Citrix/NSGClient/bin/ directory.

ln -s /home/user/.steam/ubuntu12_32/steam-runtime/amd64/lib/x86_64-linux-gnu/libssl.so.1.0.0
ln -s /home/user/.steam/ubuntu12_32/steam-runtime/amd64/lib/x86_64-linux-gnu/libcrypto.so.1.0.0
ln -s /home/user/.steam/ubuntu12_32/steam-runtime/amd64/usr/lib/x86_64-linux-gnu/libcurl.so.4
ln -s /home/user/.steam/ubuntu12_32/steam-runtime/amd64/usr/lib/x86_64-linux-gnu/librtmp.so.0

Job done. NSG VPN Client now works.

So, if you are in need of the right libraries for your VPN client, install Steam!

Tuesday, 23 July 2019

Server: WebProxy/1.0 Pre-Alpha errors? Are you tethering?


Today, I had to tether to my phone and run a few web requests top build a Raspberry Pi. However, the requests were failing. It would "sit there" and it didn't seem to work. I couldn't see anything wrong on the server, but I decided I would try a simple "curl -v" to see what would happen and to avoid TLS issues, I tried HTTP.

I was greeted with:

 < HTTP/1.1 503 Service Unavailable
 < Server: WebProxy/1.0 Pre-Alpha
 < Date: Tue, 23 Jul 2019 10:04:43 GMT
 < Content-Length: 0< Connection: keep-alive

What the heck? I knew my mobile provider had some proxies. I googled and noticed a few people complain about the same thing and then it occurred to me. I'm tethered, could this be my device? Would rebooting fix the issue?

So, since one of the troubleshooting tasks I'd suggest would be "Did you turn it off and back on" I decided to give it a whirl.

Guess what! That fixed the issue.

Monday, 20 May 2019

Kodi, inputstream.adaptive and Netflix not working...

In a previous post, I mentioned how I finally solved an issue with the Netflix add-on for Kodi and how items didn't play properly but sound worked fine. It was due to the Raspberry Pi not being powerful enough since it has to do software decoding.

However, I did an update from 9.0.1 version of Libreelec to 9.0.2 and for some reason, Netflix wouldn't even play the video.

Looking through the logs I could see that the /usr/lib/kodi/addons/inputstream.adaptive/ directory couldn't be found which lead to a lot of Googling and no answers. I tried uninstalling, re-installing inputstream.adaptive and tweaking with its settings, even changing LD_LIBRARY_PATH to point to a different location... all in vain.

How did I solve it? I uninstalled the Netflix addon, and reinstalled it.

I removed all settings prior to the removal, but you might not need to do that. I just didn't want to have to deal with it not working and thought it might be a good idea.

So, there you go. Neflix not working on Libreelec (doesn't matter which version) on a Raspberry Pi. Uninstall the addon and add it back in! Why? Not sure... but at least it's working now.

Monday, 1 April 2019

Kodi, inputstream.adaptive and Netflix

One of the things I love about the latest version of Kodi is being able to use the Netflix add-on and being able to view everything in one place.

I had a problem that took me a bit to troubleshoot. Whenever I watch Netflix, I noticed that videos would start to play slower than the audio. In other words, the video would look like it was in slow motion while the audio played at normal speed.

After doing updates, downgrades, etc I finally found that people were discussing this issue but weren't able to reproduce, however, while looking at the issue myself, I noticed the videos that I was watching from Netflix were in 1080p quality. I went into the properties for inputstream.adaptive and changed the settings to the secured streams from MAX to 720p.

It worked! My Netflix streams are smooth like butter.

Monday, 31 December 2018

Happy New Year!

2018 has come and gone! It went by so quickly!

I hope that the new year will be great, and bring you success.

That 2019 brings some sanity back to the world!!!

Beyond that, that you can spend it with your family and friends. That all your goals for the year are a success.

I wish you all a Happy 2019.

Happy New Year!

Friday, 22 June 2018

Pidgin Part 3 - Or how I learned to ha... dislike Lync

The company is migrating to MS Teams in the near future. This is actually great and seems to work with Linux quite well, even if there isn't an official client for Linux. If Microsoft were to actually make a full Teams client for Linux, that would be the first official application I'd be running on my Linux laptop.

That said, we haven't actually fully moved to Teams, and are actually still using Lync (while moving to Skype-for-Business i.e. Lync 2016) in the nearer future. I'm still on the old Lync server and now, for some reason, my Pidgin-Sipe client has stopped working.

I cannot seem to connect to the server and I haven't found out why yet.

Currently, when running Pidgin with the --debug flag I get the following.

(14:03:26) sipe: sipe_http_request_response_unauthorized: init context target 'HTTP/server.domain.com' token '<NULL>'
(14:03:26) sipe: sipe_http_request_response_unauthorized: authentication failed, throwing away context

Obviously, I'm not giving out the server name.

It's a different error than having an incorrect password, so I'm not sure what the problem is. (Yet.)

If anyone happens on this blog and has more input or an idea, please add it in the comments.

Tuesday, 30 January 2018

Getting Pidgin and Microsoft Lync to work nicely (Part 2)

I last wrote about trying to get Pidgin working on a Windows environment by using the pidgin-sipe plugin and a few other things. (See the first post.)

Since then, I've changed work/company and decided I would go with TelRed's Wync Sky and even pay for the year's subscription. However, even with the license I still had a lot of issues. Also, since the group that I work with worked on Skype instead of Lync, I was using Skype for Linux and didn't bother trying to sort out my issues.

However, people need me to be available via Lync now. I decided to give Pidgin another go.

So, following what I knew from the first post, I edited the UserAgent and put in the rest of my information.

Well, it wouldn't work. The error I got was something related to the service not providing a token. I couldn't find any Pidgin logs, so I started it on the command line with the -d flag (for debugging.) and I noticed that it wouldn't accept the SSL certificate and would disconnect me.

Reading about this issue, it led me to enable the NSS Preferences plugin and then trying to figure out what Cypher the site I was trying to connect to was using. The logs didn't give much information with regards to that, so I tried Google Chrome. I couldn't find the information in Chrome by viewing the SSL Certificate itself, but going to into Developer Tools, and then the security at the bottom it showed that the site was using some old Cyphers and protocols. I enabled those in the NSS Preferences plugin and then my error changed!

Now, it was still failing, but it gave me a "Read" error. I googled for that and eventually came to an OLD Debian bug (649456) which showed that the workaround was to use NSS_SSL_CBC_RANDOM_IV=0 and then start pidgin. So, I did that and voila!

I'm available on Lync now. I now noticed I can even do some other things that I couldn't before, but I haven't had the chance to try them.

Last thing: we are migrating to O365 soon, so I will probably have to write another part to this saga when that's completed. I believe there's going to be two steps to that since we're doing email first and moving the Lync instances to Skype 4 Business second.

Keep your eyes out for the next instalment.

Sunday, 31 December 2017

Happy New Year!

2017 - another year added to our belt.

I hope that the new year will be bring you joy.

That 2018 will be a successful year.

That you can spend it with your family and friends because you'll never know how much you'll miss them until you cannot spend time with them.

I wish you all a Happy 2018.

Happy New Year!

Wednesday, 8 March 2017

Backups? Who needs stinking backups!

It's not often that I get to write about a success followed by a failure... followed by a success.

I run Linux on my corporate machine (Ubuntu in one flavour or another) and I had not upgraded in a while. This meant that my version of Ubuntu was End of Life and I need to completely re-image my laptop to get onto something more current.

Therefore, I did what anyone would do... backup my data.

I then attempted a restore to make sure that the data was still valid and "restorable" and proceeded to re-image my machine.

I hate to name and shame, but I used Deja-dup which is the default Ubuntu backup software to create my backups and check that everything was working.

However, after re-imaging my machine and installing the latest version of Ubuntu, I tried to restore my backup and lo-and-behold, Deja-dup tells me "There is no backup...."

WHAT?!

Are you might assume, I went ahead and tried to find what I could do - I saw that all the backup files (duplicity-full.xxxx.tardiff.gz) were in the backup location so I didn't think anything about it...

I tried re-launching the application and when I did it tried to make a backup. I didn't want a backup, so I stopped it. Then started the app again and tried to restore with the same error message.

I decided I would try something else, so I go to the directory where my backup was located and.... it was empty! Actually, there was a duplicity-checksum file that had been created by the previous backup attempt.)

WHAT?!

I couldn't believe my eyes. I wanted to die! I had not only documents but also code I had written. I had over a year's worth of work, notes, and items that I had saved... ALL GONE!

ALL! GONE!

So, I started looking for what I could do to recover something that was recently deleted. I found ext4magic and extundelete...

I installed both, made my partition read-only (which was an encrypted drive.)

sudo mount -o remount,ro /dev/mapper/luks-<uid-of-drive>

I then proceeded to read the documentation on both and decided that extundelete was worth a shot...

I created a temporary directory to try to restore into and ran the application (and crossed my fingers) ...

sudo extundelete /dev/mapper/luks-<uid-of-drive> -o RESTORE/ --restore-all

I waited. And finally...

42GB recovered!

I then copied them over to another drive (for safe keeping) and tried to restore from those files... Still, Deja-dup said, "No backup found!" $!*&"!

I went and looked for what I could do to recover if I didn't have Deja-dup and I found that I could simply gunzip and untar the files. That it would create a "snapshot" directory and a "multivol-snapshot" directory. Everything in the "snapshot" directory was the file in the original state... while the other one contained parts which had to be put together.

Well, I did it... and I've recovered almost all the stuff I had.

Now to switch to something that I have used before and that works quite well... Back-in-time.


Saturday, 31 December 2016

Happy New Year!

2016. It came rather quickly and seem to have gone rather quickly too.

What has happened this year? I learnt I needed to update my IF rules earlier in the year so that at least I post something relevant! I had one of my dogs hit by a car at the very beginning of the year.

But with those things, I get stronger. I get smarter and wiser. I get a little bit more confident.

2017 will be another successful year. :-( He's ok now.

I wish you all a Happy 2017. May all your goals come true... that means work hard!

Happy New Year!

Monday, 4 January 2016

Remotely printing on a printer behind a firewall...

Printing...


Today I needed to print something at home. My wife was there and she needed the document but didn't have a way of printing it herself.

So, how do you go about doing this? Well, there's probably a few ways, like creating a print queue using a shared drive and having a print server at home that checks that queue. Then you can upload the file to dropbox, gdrive or where ever you've shared the directory and get that printed.

But what if you haven't set that up yet? Well, depending on the printer and if you have a server/desktop with ssh running, you could tunnel it.

sudo ssh user@ext.er.nal.ip -L 161:pri.nt.er.ip:161 -L 162:pri.nt.er.ip:162 -L 9100:pri.nt.er.ip:9100 

Obviously substitute your external IP with the IP to get to your ssh box and the printer IP with the one for the printer you're trying to use.

This command by the way is for printing to an HP printer and worked fine for me!

-P

Thursday, 31 December 2015

Happy New Year!

And 2014 is over, just like that.
What has happened this year? Too much to really. A grandchild, a wife with a Masters, new friends, old friends...
I wish you all a Happy 2015. May all your wishes come true.
Happy New Year!

So as you can probably tell, I've automated my response to when a New Year even happens. I did it with IFTTT (If This Then That) which is great. However... I didn't update the message for this year so I so elegantly posted the same message I posted last year!

This happened on Facebook and here as you can see.

So, Rule #1 when starting a new year. Update the message you're planning on posting! You don't need to have it completed, but at least the gist. So that if you haven't done anything and 20xx comes along, at least you have the right message!

Happy New Year - May 2016 be a great year for you.

-P

Wednesday, 31 December 2014

Happy New Year!

And 2014 is over, just like that.


What has happened this year? Too much to really. A grandchild, a wife with a Masters, new friends, old friends...


I wish you all a Happy 2015. May all your wishes come true.


Happy New Year!

Wednesday, 1 January 2014

Predictions for 2014

The New Year is here and lots of people are posting their New Year resolutions. This year I thought I'd try something different. Here are my New Year Predictions.
1. In the area of social media, we will find that all those companies that are gathering our tweets, Facebook posts, G+ shares, etc will finally start providing services that make use of this data. Thanks to Big Data Analytics and Predictive Analytics these companies will provide better discounts, more relevant and interesting advertising AND they will do it in such a way we won't even realize the complexities behind it all.
2. Space exploration will have some privately funded companies looking for new ideas by using crowdsourcing techniques and mass marketing.
3. Looking at DNA for techniques to prolong life has been going on for a while, but I think the next big breakthrough will happen this year. Now beating diseases like cancer is going to become even more important. Please donate to those doing research in these diseases.
4. Advances in cheap disposable computing device like the Pi and Arduino will make more DIY projects more appealing. Watch the big companies start to sweat at having these cheap device take over in the home. Thanks to this, educators will start to focus on technology again, making it more appealing to kids.
5. Google makes Glass more affordable than people currently expect it will be and finally opens it to everyone. In the $150-200 range. (OK that's just wishful thinking.)
Well, that is all I am going to put down for now. Now let 2014 begin!

Tuesday, 31 December 2013

Happy New Year!

It's a brand new year. People will start thinking about the things that they have accomplished and the things they wish they had accomplished.


I know that this past year was a great year. I managed to do so many things and a lot of them wouldn't have happened if it weren't for my wonderful wife.


Happy New Year!

Wednesday, 2 October 2013

Debugging a core? What tools do you use?

Whenever you have an application crash or become unstable and the worse part is that logs don't give you anything useful, what do you do? What tools could you use.

Well, one thing is strace. Running and tracing a process while it's doing its thing is one way. Crashing the process or generating a core with "gencore", gcore (aka gdb core) or something similar is another.

But what do you do when you want to capture the core and its dependencies on another machine to debug? 

On AIX IBM has snapcore. If you don't know this utility, read about it! It's a great tool but there is no equivalent in Linux. 

What can you do?

Well it turns out that gdb can provide a few things that make this easier. For example, gdb can list the libraries that are loaded in memory on the core. This is helpful so that you can gather those to bring in house.

So once you are in gdb you can do a "info sharedlib" and get this list.

Once you do that, you can collect the libraries that you need and use them to debug the core locally by loading them at the same time as you load the core and binary. You need to set some information when you are doing this.

I'll write another post with my way of doing this... and possibly a "snapcore" equivalent for Linux.

-P