Planet HantsLUG

Syndicate content
Planet HantsLUG -
Updated: 1 hour 48 min ago

Steve Kemp: Linux security modules, round two.

Sat, 24/06/2017 - 22:00

So recently I wrote a Linux Security Module (LSM) which would deny execution of commands, unless an extended attribute existed upon the filesystem belonging to the executables.

The whitelist-LSM worked well, but it soon became apparent that it was a little pointless. Most security changes are pointless unless you define what you're defending against - your "threat model".

In my case it was written largely as a learning experience, but also because I figured it seemed like it could be useful. However it wasn't actually as useful because you soon realize that you have to whitelist too much:

  • The redis-server binary must be executable, to the redis-user, otherwise it won't run.
  • /usr/bin/git must be executable to the git user.

In short there comes a point where user alice must run executable blah. If alice can run it, then so can mallory. At which point you realize the exercise is not so useful.

Taking a step back I realized that what I wanted to to prevent was the execution of unknown/unexpected, and malicious binaries How do you identify known-good binaries? Well hashes & checksums are good. So for my second attempt I figured I'd not look for a mere "flag" on a binary, instead look for a valid hash.

Now my second LSM is invoked for every binary that is executed by a user:

  • When a binary is executed the sha1 hash is calculated of the files contents.
  • If that matches the value stored in an extended attribute the execution is permitted.
    • If the extended-attribute is missing, or the checksum doesn't match, then the execution is denied.

In practice this is the same behaviour as the previous LSM - a binary is either executable, because there is a good hash, or it is not, because it is missing or bogus. If somebody deploys a binary rootkit this will definitely stop it from executing, but of course there is a huge hole - scripting-languages:

  • If /usr/bin/perl is whitelisted then /usr/bin/perl /tmp/ will succeed.
  • If /usr/bin/python is whitelisted then the same applies.

Despite that the project was worthwhile, I can clearly describe what it is designed to achieve ("Deny the execution of unknown binaries", and "Deny binaries that have been modified"), and I learned how to hash a file from kernel-space - which was surprisingly simple.

(Yes I know about IMA and EVM - this was a simple project for learning purposes. Public-key signatures will be something I'll look at next/soon/later. :)

Perhaps the only other thing to explore is the complexity in allowing/denying actions based on the user - in a human-readable fashion, not via UIDs. So www-data can execute some programs, alice can run a different set of binaries, and git can only run /usr/bin/git.

Of course down that path lies apparmour, selinux, and madness..

Categories: LUG Community Blogs

Debian Bits: Hewlett Packard Enterprise Platinum Sponsor of DebConf17

Fri, 23/06/2017 - 15:15

We are very pleased to announce that Hewlett Packard Enterprise (HPE) has committed support to DebConf17 as a Platinum sponsor.

"Hewlett Packard Enterprise is excited to support Debian's annual developer conference again this year", said Steve Geary, Senior Director R&D at Hewlett Packard Enterprise. "As Platinum sponsors and member of the Debian community, HPE is committed to supporting Debconf. The conference, community and open distribution are foundational to the development of The Machine research program and will our bring our Memory Driven Computing agenda to life."

HPE is one of the largest computer companies in the world, providing a wide range of products and services, such as servers, storage, networking, consulting and support, software, and financial services.

HPE is also a development partner of Debian, and provides hardware for port development, Debian mirrors, and other Debian services (hardware donations are listed in the Debian machines page).

With this additional commitment as Platinum Sponsor, HPE contributes to make possible our annual conference, and directly supports the progress of Debian and Free Software helping to strengthen the community that continues to collaborate on Debian projects throughout the rest of the year.

Thank you very much Hewlett Packard Enterprise, for your support of DebConf17!

Become a sponsor too!

DebConf17 is still accepting sponsors. Interested companies and organizations may contact the DebConf team through, and visit the DebConf17 website at

Categories: LUG Community Blogs

Debian Bits: Debian 9.0 Stretch has been released!

Sun, 18/06/2017 - 07:25

Let yourself be embraced by the purple rubber toy octopus! We're happy to announce the release of Debian 9.0, codenamed Stretch.

Want to install it? Choose your favourite installation media among Blu-ray Discs, DVDs, CDs and USB sticks. Then read the installation manual.

Already a happy Debian user and you only want to upgrade? You can easily upgrade from your current Debian 8 Jessie installation, please read the release notes.

Do you want to celebrate the release? Share the banner from this blog in your blog or your website!

Categories: LUG Community Blogs

Debian Bits: Upcoming Debian 9.0 Stretch!

Fri, 16/06/2017 - 23:30

The Debian Release Team in coordination with several other teams are preparing the last bits needed for releasing Debian 9 Stretch. Please, be patient! Lots of steps are involved and some of them take some time, such as building the images, propagating the release through the mirror network, and rebuilding the Debian website so that "stable" points to Debian 9.

Follow the live coverage of the release on or the @debian profile in your favorite social network! We'll spread the word about what's new in this version of Debian 9, how the release process is progressing during the weekend and facts about Debian and the wide community of volunteer contributors that make it possible.

Categories: LUG Community Blogs

Steve Kemp: Porting pfctl to Linux

Wed, 14/06/2017 - 22:00

If you have a bunch of machines running OpenBSD for firewalling purposes, which is pretty standard, you might start to use source-control to maintain the rulesets. You might go further, and use some kind of integration testing to deploy changes from your revision control system into production.

Of course before you deploy any pf.conf file you need to test that the file contents are valid/correct. If your integration system doesn't run on OpenBSD though you have a couple of choices:

  • Run a test-job that SSH's to the live systems, and tests syntax.
    • Via pfctl -n -f /path/to/rules/pf.conf.
  • Write a tool on your Linux hosts to parse and validate the rules.

I looked at this last year and got pretty far, but then got distracted. So the other day I picked it up again. It turns out that if you're patient it's not hard to use bison to generate some C code, then glue it together such that you can validate your firewall rules on a Linux system.

deagol ~/pf.ctl $ ./pfctl ./pf.conf ./pf.conf:298: macro 'undefined_variable' not defined ./pf.conf:298: syntax error

Unfortunately I had to remove quite a lot of code to get the tool to compile, which means that while some failures like that above are caught others are missed. The example above reads:

vlans="{vlan1,vlan2}" .. pass out on $vlans proto udp from $undefined_variable

Unfortunately the following line does not raise an error:

pass out on vlan12 inet proto tcp from <unknown> to $http_server port {80,443}

That comes about because looking up the value of the table named unknown just silently fails. In slowly removing more and more code to make it compile I lost the ability to keep track of table definitions - both their names and their values - Thus the fetching of a table by name has become a NOP, and a bogus name will result in no error.

Now it is possible, with more care, that you could use a hashtable library, or similar, to simulate these things. But I kinda stalled, again.

(Similar things happen with fetching a proto by name, I just hardcoded inet, gre, icmp, icmp6, etc. Things that I'd actually use.)

Might be a fun project for somebody with some time anyway! Download the OpenBSD source, e.g. from a github mirror - yeah, yeah, but still. CVS? No thanks! - Then poke around beneath sbin/pfctl/. The main file you'll want to grab is parse.y, although you'll need to setup a bunch of headers too, and write yourself a Makefile. Here's a hint:

deagol ~/pf.ctl $ tree . ├── inc │   ├── net │   │   └── pfvar.h │   ├── queue.h │   └── sys │   ├── _null.h │   ├── refcnt.h │   └── tree.h ├── Makefile ├── parse.y ├── pf.conf ├── pfctl.h ├── pfctl_parser.h └── 3 directories, 11 files
Categories: LUG Community Blogs

Steve Kemp: So I accidentally wrote a linux security module

Thu, 01/06/2017 - 22:00

Tonight I read this weeks LWN quotes-page a little later than usual because I was busy at work for most of the day. Anyway as always LWNs content was awesome, and this particular list lead to an interesting discussion about a new Linux-Security-Module (LSM).

That read weirdly, what I was trying to say was that every Thursday morning I like to read LWN at work. Tonight is the first chance I had to get round to it.

One of the later replies in the thread was particularly interesting as it said:

Suggestion: Create an security module that looks for the attribute security.WHITELISTED on things being executed/mmapped and denys it if the attribute isn't present. Create a program (whitelistd) that reads /etc/whitelist.conf and scans the system to ensure that only things on the list have the attribute.

So I figured that was a simple idea, and it didn't seem too hard even for myself as a non-kernel non-developer. There are several linux security modules included in the kernel-releases, beneath the top-level security/ directory, so I assumed I could copy & paste code around them to get something working.

During the course of all this work, which took about 90 minutes from start to Finnish (that pun never gets old), this online documentation was enormously useful:

Brief attr primer

If you're not familiar with the attr tool it's pretty simple. You can assign values to arbitrary labels on files. The only annoying thing is you have to use extra-flags to commands like rsync, tar, cp, etc, to preserve the damn things.

Set three attributes on the file named moi:

$ touch moi $ attr -s forename -V "Steve" moi $ attr -s surname -V "Kemp" moi $ attr -s name -V "Steve Kemp" moi

Now list the attributes present:

$ attr -l moi Attribute "name" has a 10 byte value for moi Attribute "forename" has a 5 byte value for moi Attribute "surname" has a 4 byte value for moi

And retrieve one?

$ attr -q -g name moi Steve Kemp LSM Skeleton

My initial starting point was to create "steve_lsm.c", with the following contents:

#include <linux/lsm_hooks.h> /* * Log things for the moment. */ static int steve_bprm_check_security(struct linux_binprm *bprm) { printk(KERN_INFO "STEVE LSM check of %s\n", bprm->filename); return 0; } /* * Only check exec(). */ static struct security_hook_list steve_hooks[] = { LSM_HOOK_INIT(bprm_check_security, steve_bprm_check_security), }; /* * Somebody set us up the bomb. */ static void __init steve_init(void) { security_add_hooks(steve_hooks, ARRAY_SIZE(steve_hooks), "steve"); printk(KERN_INFO "STEVE LSM initialized\n"); }

With that in place I had to modify the various KBuild files beneath security/ to make sure this could be selected as an LSM, and add in a Makefile to the new directory security/steve/.

With the boiler-plate done though, and the host machine rebooted into my new kernel it was simple to test things out.

Obviously the first step, post-boot, is to make sure that the module is active, which can be done in two ways, looking at the output of dmesg, and explicitly listing the modules available:

~# dmesg | grep STEVE | head -n2 STEVE LSM initialized STEVE LSM check of /init $ echo $(cat /sys/kernel/security/lsm) capability,steve Making the LSM functional

The next step was to make the module do more than mere logging. In short this is what we want:

  • If a binary is invoked by root - allow it.
    • Although note that this might leave a hole, if the user can enter a new namespace where their UID is 0..
  • If a binary is invoked by a non-root user look for an extended attribute on the target-file named security.WHITELISTED.
    • If this is present we allow the execution.
    • If this is missing we deny the execution.

NOTE we don't care what the content of the extended attribute is, we just care whether it exists or not.

Reading the extended attribute is pretty simple, using the __vfs_getxattr function. All in all our module becomes this:

#include <linux/xattr.h> #include <linux/binfmts.h> #include <linux/lsm_hooks.h> #include <linux/sysctl.h> #include <linux/ptrace.h> #include <linux/prctl.h> #include <linux/ratelimit.h> #include <linux/workqueue.h> #include <linux/string_helpers.h> #include <linux/task_work.h> #include <linux/sched.h> #include <linux/spinlock.h> #include <linux/lsm_hooks.h> /* * Perform a check of a program execution/map. * * Return 0 if it should be allowed, -EPERM on block. */ static int steve_bprm_check_security(struct linux_binprm *bprm) { // The current task & the UID it is running as. const struct task_struct *task = current; kuid_t uid = task->cred->uid; // The target we're checking struct dentry *dentry = bprm->file->f_path.dentry; struct inode *inode = d_backing_inode(dentry); // The size of the label-value (if any). int size = 0; // Root can access everything. if ( uid.val == 0 ) return 0; size = __vfs_getxattr(dentry, inode, "user.whitelisted", NULL, 0); if ( size >= 0 ) { printk(KERN_INFO "STEVE LSM check of %s resulted in %d bytes from 'user.whitelisted' - permitting access for UID %d\n", bprm->filename, size, uid.val ); return 0; } printk(KERN_INFO "STEVE LSM check of %s denying access for UID %d [ERRO:%d] \n", bprm->filename, uid.val, size ); return -EPERM; } /* * The hooks we wish to be installed. */ static struct security_hook_list steve_hooks[] = { LSM_HOOK_INIT(bprm_check_security, steve_bprm_check_security), }; /* * Initialize our module. */ void __init steve_add_hooks(void) { /* register ourselves with the security framework */ security_add_hooks(steve_hooks, ARRAY_SIZE(steve_hooks), "steve"); printk(KERN_INFO "STEVE LSM initialized\n"); }

Once again we reboot with this new kernel, and we test that the LSM is active. After the basic testing, as before, we can now test real functionality. By default no binaries will have the attribute we look for present - so we'd expect ALL commands to fail, unless executed by root. Let us test that:

~# su - nobody -s /bin/sh No directory, logging in with HOME=/ Cannot execute /bin/sh: Operation not permitted

That looks like it worked. Let us allow users to run /bin/sh:

~# attr -s whitelisted -V 1 /bin/sh

Unfortunately that fails, because symlinks are weird, but repeating the test with /bin/dash works as expected:

~# su - nobody -s /bin/dash No directory, logging in with HOME=/ Cannot execute /bin/dash: Operation not permitted ~# attr -s whitelisted -V 1 /bin/dash ~# attr -s whitelisted -V 1 /usr/bin/id ~# su - nobody -s /bin/dash No directory, logging in with HOME=/ $ id uid=65534(nobody) gid=65534(nogroup) groups=65534(nogroup) $ uptime -su: 2: uptime: Operation not permitted

And our logging shows the useful results as we'd expect:

STEVE LSM check of /usr/bin/id resulted in 1 bytes from 'user.WHITELISTED' - permitting access for UID 65534 STEVE LSM check of /usr/bin/uptime denying access for UID 65534 [ERRO:-95] Surprises

If you were paying careful attention you'll see that we changed what we did part-way through this guide.

  • The initial suggestion said to look for security.WHITELISTED.
  • But in the kernel module I look for user.whitelisted.
    • And when setting the attribute I only set whitelisted.

Not sure what is going on there, but it was very confusing. It appears to be the case that when you set an attribute a secret user. prefix is added to the name.

Could be worth some research by somebody with more time on their hands than I have.

Anyway I don't expect this is a terribly useful module, but it was my first, and I think it should be pretty stable. Feedback on my code certainly welcome!

Categories: LUG Community Blogs

Steve Kemp: Security is hard ..

Mon, 29/05/2017 - 22:00

I continued to be impressed with local vendors, found on 3dhubs. I've had several more things printed out, including an "internet button", and some card-holders for Settlers of Catan.

The most recent print I had made was a collection of display cases, for holding an OLED display, as well as an ESP8266 device.

Unfortunately at the same time as I was falling in love with the service I discovered a glaring XSS attack against the site itself.

Anybody who viewed my profile page could have arbitrary javascript executed, which in some cases would actually disclose their private details - such as:

  • Their forename & surname.
  • Their email-address.
  • Their telephone number.
  • Their GeoIP details.

Discovering this took minutes, writing it up took an hour, and a month later it is still unfixed.

I've deleted my account.

Categories: LUG Community Blogs

Steve Kemp: Getting ready for Stretch

Wed, 24/05/2017 - 22:00

I run about 17 servers. Of those about six are very personal and the rest are a small cluster which are used for a single website. (Partly because the code is old and in some ways a bit badly designed, partly because "clustering!", "high availability!", "learning!", "fun!" - seriously I had a lot of fun putting together a fault-tolerant deployment with haproxy, ucarp, etc, etc. If I were paying for it the site would be both retired and static!)

I've started the process of upgrading to stretch by picking a bunch of hosts that do things I could live without for a few days - in case there were big problems, or I needed to restore from backups.

So far I've upgraded:

  • master.steve
    • This is a puppet-master, so while it is important killing it wouldn't be too bad - after all my nodes are currently setup properly, right?
    • Upgrading this host changed the puppet-server from 3.x to 4.x.
    • That meant I had to upgrade all my client-systems, because puppet 3.x won't talk to a 4.x master.
    • Happily jessie-backports contains a recent puppet-client.
    • It also meant I had to rework a lot of my recipes, in small ways.
  • builder.steve
    • This is a host I use to build packages upon, via pbuilder.
    • I have chroots setup for wheezy, jessie, and stretch, each in i386 and amd64 flavours.
  • git.steve
    • This is a host which stores my git-repositories, via gitbucket.
    • While it is an important host in terms of functionality, the software it needs is very basic: nginx proxies to a java application which runs on localhost:XXXX, with some caching magic happening to deal with abusive clients.
    • I do keep considering using gitlab, because I like its runners, etc. But that is pretty resource intensive.
    • On the other hand If I did switch I could drop my builder.steve host, which might mean I'd come out ahead in terms of used resources.
  • leave.steve
    • Torrent-box.
    • Upgrading was painless, I only run rtorrent, and a simple object storage system of my own devising.

All upgrades were painless, with only one real surprise - the attic-backup software was removed from Debian.

Although I do intend to retry using Larss' excellent obnum in the near future pragmatically I wanted to stick with what I'm familiar with. Borg backup is a fork of attic I've been aware of for a long time, but I never quite had a reason to try it out. Setting it up pretty much just meant editing my backup-script:


Once I did that, and created some new destinations all was good: ~ $ borg init /backups/ ~ $ borg init /backups/ ~ $ ..

Upgrading other hosts, for example my website(s), and my email-box, will be more complex and fiddly. On that basis they will definitely wait for the formal stretch release.

But having a couple of hosts running the frozen distribution is good for testing, and to let me see what is new.

Categories: LUG Community Blogs

Steve Kemp: Some minor updates ..

Sun, 14/05/2017 - 22:00

The past few weeks have been randomly busy, nothing huge has happened, but several minor diversions.


I made a new release of my console-based mail-client, with integrated Lua scripting, this is available for download over at

I've also given a talk (!!) on using a literate/markdown configuration for GNU Emacs. In brief I created two files:


This contains both my configuration of GNU Emacs as well as documentation for the same. Neat.


This parse the previous file, specifically looking for "code blocks" which are then extracted and evaluated.

This system is easy to maintain, and I'm quite happy with it :)


Somebody nice took the time to report a couple of bugs against my simple bytecode-intepretting virtual-machine project - all found via fuzzing.

I've done some fun fuzzing of my own in the past, so this was nice to see. I've now resolved those bugs, and updated the file to include instructions on fuzzing it. (Which I started doing myself, after receiving the first of the reports )

Finally I have more personal news too: I had a pair of CT-scans carried out recently, and apparently here in sunny Finland (that's me being ironic, it was snowing in the first week of May) when you undergo a CT-scan you can pay to obtain your data on CD-ROM.

I'm 100% definitely going to get a copy of my brain-scan data. I'll be able to view a 3d-rendered model of my own brain on my desktop. (Once upon a time I worked for a company that produced software, sold to doctors/surgeons, for creating 3d-rendered volumes from individual slices. I confirmed with the radiologist that handled my tests that they do indeed use the standard DICOM format. Small world.)

Categories: LUG Community Blogs

Debian Bits: New Debian Developers and Maintainers (March and April 2017)

Sun, 14/05/2017 - 13:39

The following contributors got their Debian Developer accounts in the last two months:

  • Guilhem Moulin (guilhem)
  • Lisa Baron (jeffity)
  • Punit Agrawal (punit)

The following contributors were added as Debian Maintainers in the last two months:

  • Sebastien Jodogne
  • Félix Lechner
  • Uli Scholler
  • Aurélien Couderc
  • Ondřej Kobližek
  • Patricio Paez


Categories: LUG Community Blogs

Debian Bits: Bursary applications for DebConf17 are closing in 48 hours!

Mon, 08/05/2017 - 21:30

This is a final reminder: if you intend to apply for a DebConf17 bursary and have not yet done so, please proceed as soon as possible.

Bursary applications for DebConf17 will be accepted until May 10th at 23:59 UTC. Applications submitted after this deadline will not be considered.

You can apply for a bursary when you register for the conference.

Remember that giving a talk is considered towards your bursary; if you have a submission to make, submit it even if it is only sketched-out. You will be able to detail it later.

Please make sure to double-check your accommodation choices (dates and venue). Details about accommodation arrangements can be found on the wiki.

Note: For DebCamp we only have on-site accommodation available. The option chosen in the registration system will only be for the DebConf period (August 5 to 12).

See you in Montréal!

Categories: LUG Community Blogs