major.io

Words of wisdom from a Linux engineer focused on information security

major.io

Words of wisdom from a systems engineer

  • Who am I?
  • icanhazip FAQ
  • Résumé
  • Keybase
  • RSS
Creative Commons License

What I learned while securing Ubuntu

October 14, 2015 By Major Hayden 13 Comments

The blog posts have slowed down a bit lately because I’ve been heads down on a security project at work. I’m working with people in the OpenStack community to create a new Ansible role called openstack-ansible-security. The role aims to improve host security by using hardening standards to improve the configuration of various parts of the operating system.

This means applying security hardening to Ubuntu 14.04 systems since that’s the only host operating system supported by openstack-ansible at the moment. I have plenty of experience with securing Red Hat-based systems like Red Hat Enteprise Linux, CentOS and Fedora; but Ubuntu is new territory entirely. The rest of this post is full of lessons learned along the way.

Searching for hardening standards

Finding a complete hardening standard for Ubuntu 14.04 is challenging. The Center for Internet Security offers Ubuntu security benchmarks with two big caveats:

  • There are very few controls to apply (relative to what’s available for RHEL)
  • The terms of use are highly restrictive (no derivative works allowed)

With that idea off the table, I examined the other options that meet Requirement 2.2 of PCI-DSS 3.1 [PDF]. Anther choice was ISO 27002, but it’s not terribly specific or easy to automate with scripts. The same goes for NIST 800-53.

After plenty of searching, the decision was made to go forth with the Security Technical Implementation Guide (STIG) from the Defense Information Systems Agency (DISA) (part of the US Department of Defense). The STIGs aren’t licensed and they’re in the public domain. The only downside is that the closest STIG for use with Ubuntu 14.04 is the RHEL 6 STIG.

Using the RHEL 6 STIG meant that plenty of things will need to be translated for the different tools, configuration files, and package names that come with Ubuntu. It was frustrating to search all over for a hardening standard that applies well to Ubuntu and comes with decent auditing tools, but this was the best we could find.

Automatically starting daemons

The standard Ubuntu and Debian practice of automatically starting daemons has perplexed me before and it still continues to do so. Starting a daemon before I’ve had a chance to configure it makes little sense. The main argument is that the daemons come up with a highly secure configuration, so starting it automatically shouldn’t be a big deal. I’d prefer to install a package, have a look at the configuration, alter the configuration, and then start the daemon. Also, it had better not start after a reboot unless I explicitly ask it to do so.

There are plenty of examples where automatically starting a daemon with its default configuration is a bad idea. Take the postfix package as an example. If you install the package in non-interactive mode (as Ansible does by default), postfix will come online wth the following configuration option set:

XHTML
1
inet_interfaces = all

Since Ubuntu doesn’t come with a firewall enabled by default, your postfix server is listening on all interfaces for mail immediately. The mynetworks configuration should prevent relaying, but any potential vulnerabilities in your postfix daemon are exposed to the network without your consent. I would prefer to configure postfix first before I ever allow it to run on my server.

Verifying packages

Say what you will about RPM packages and the rpm command, but the verification portions of the rpm command are quite helpful. Here’s an example of verifying the aide RPM in Fedora:

XHTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# rpm -Vv aide
.........  c /etc/aide.conf
.........  c /etc/logrotate.d/aide
.........    /usr/sbin/aide
.........    /usr/share/doc/aide
.........  d /usr/share/doc/aide/AUTHORS
.........  d /usr/share/doc/aide/COPYING
.........  d /usr/share/doc/aide/ChangeLog
.........  d /usr/share/doc/aide/NEWS
.........  d /usr/share/doc/aide/README
.........  d /usr/share/doc/aide/README.quickstart
.........    /usr/share/doc/aide/contrib
.........  d /usr/share/doc/aide/contrib/aide-attributes.sh
.........  d /usr/share/doc/aide/contrib/bzip2.sh
.........  d /usr/share/doc/aide/contrib/gpg2_check.sh
.........  d /usr/share/doc/aide/contrib/gpg2_update.sh
.........  d /usr/share/doc/aide/contrib/gpg_check.sh
.........  d /usr/share/doc/aide/contrib/gpg_update.sh
.........  d /usr/share/doc/aide/contrib/sshaide.sh
.........  d /usr/share/doc/aide/manual.html
.........  d /usr/share/man/man1/aide.1.gz
.........  d /usr/share/man/man5/aide.conf.5.gz
.........    /var/lib/aide
.........    /var/log/aide

If the verification finds that nothing in the package has changed, it won’t print anything. I’ve added the -v here to ensure that everything is printed to the console. In the output, you can see that everything is checked. That includes configuration files, log directories, libraries, and documentation. If I change the content of the aide.conf by adding a comment, I see that change:

XHTML
1
2
3
# echo "# Comment" >> /etc/aide.conf
# rpm -V aide
S.5....T.  c /etc/aide.conf

The 5 denotes that the MD5 checksum on the file has changed since the package was installed. What happens if I change the owner, group, and mode of the aide.conf?

XHTML
1
2
3
# chown major:major /etc/aide.conf
# rpm -V aide
S.5..UGT.  c /etc/aide.conf

Now I have a UG there that denotes a user/group ownership change. Similar messages appear for changes to the permissions on files or directories. The restorecon command even lets you figure out when SELinux contexts have changed. If you set a file to have the wrong ownership or permission, one rpm command gets you back to normal:

XHTML
1
# rpm --setperms --setugids aide

On the Ubuntu side, you can use the debsums package to help with some verification:

XHTML
1
2
3
4
5
6
7
8
9
10
# debsums aide
/usr/bin/aide                                                                 OK
/usr/share/doc/aide/NEWS.Debian.gz                                            OK
/usr/share/doc/aide/changelog.Debian.gz                                       OK
...
# debums aide-common
/usr/bin/aide-attributes                                                      OK
/usr/bin/aide.wrapper                                                         OK
/usr/sbin/aideinit                                                            OK
...

But wait — where are the configuration files? Where are the log and library directories? If you type these commands on an Ubuntu system, you’ll see that the configuration files and directories aren’t checked. In addition, there’s not a method for querying whether a particular file in a package has changed ownership or has had its mode changed. There’s also no option to restore the right permissions and ownership after an errant chown -R or chmod -R.

Managing AIDE

The AIDE package is critical for secure deployments since it helps administrators monitor for file integrity on a regular basis. However, Ubuntu ships with some interesting configuration files and wrappers for AIDE.

One of the unique configuration files is this one:

XHTML
1
2
# cat /etc/aide/aide.conf.d/99_aide_root
/ Full

This causes AIDE to wander all over the system, indexing all types of files. It’s best to limit AIDE to a small number of directories whenever possible so that the AIDE runs complete quickly and the database file remains relatively small. Plenty of disk I/O can be used during AIDE runs, so it’s best to limit the scope.

Also, trying to initialize the database provides an unhelpful error:

XHTML
1
2
# aide --init
Couldn't open file /var/lib/aide/please-dont-call-aide-without-parameters/aide.db.new for writing

That path doesn’t exist, and I’m confused because I did pass a parameter to aide. Long story short, you must use the aideinit command to initialize the aide database. That’s actually a bash script which then calls on aide.wrapper (another bash script) to actually run the aide binary for you. Better yet, aideinit is in /usr/sbin while aide.wrapper is in /usr/bin. This leads to plenty of confusion.

Linux Security Modules

It’s possible to run SELinux on Ubuntu, but the policies aren’t as well maintained as they are on other distributions. AppArmor is the recommended LSM on Ubuntu, but it doesn’t provide the granularity of SELinux. For example, SELinux confines almost every single process on a minimal Fedora system, but AppArmor confines almost nothing on a minimal Ubuntu-based system. AppArmor policies aren’t terribly restrictive and it’s possible to work around them due to their reliance on path names.

Fortunately, both LSM’s provide decent coverage with virtual machines and containers (using libvirt’s sVirt capability).

Summary

The upside is that there is plenty of room for security improvements, especially around usability, in Ubuntu. Ubuntu-centric hardening standards are difficult to find and challenging to apply. Every distribution has its quirks and differences, but it seems like securing Ubuntu comes with more unusual hoops to jump through relative to Red Hat-based distributions, OpenSUSE, and even Arch.

I plan to open some bugs for some of these smaller issues in the coming days. However, some of the larger philosophical issues (like automatically starting daemons) will be tougher to tackle.

Share this post:

  • Twitter
  • Google
  • LinkedIn
  • Reddit
  • Email
  • Print

Tagged With: ansible, apparmor, debian, fedora, openstack, security, selinux, ubuntu

Comments

  1. Ewen McNeill says

    October 14, 2015 at 6:44 pm

    On the AIDE on Debian/Ubuntu front, that particular set of defaults frustrates me too — they’ve basically chosen to (a) configure stupid defaults into the aide binary, and then (b) provide aide.wrapper which runs aide with appropriate command line flags to “work sensibly”. Effectively this means that you always need to run “aide.wrapper” rather than the “aide” command directly, for basically all aide interactions.

    It’s been like this for years (IIRC around 10 years; ISTR reporting it at the time to the maintainer, but I can’t quickly find the bug report/email now). There’s “sort of” a rationalisation for it (the Debian config is an auto-generated concatenation of bits), but it could have been handled so much better — including just making “aide” be the wrapper script, and calling the underlying binary something users wouldn’t try to run standalone…

    Ewen

    Reply
  2. Bhaskar Chowdhury says

    October 14, 2015 at 10:07 pm

    Right time Major!. I am building an infra for a small firm and unfortunately it is on Ubuntu. So, you can imagine how much hard time am having. Moreover my negligence and dislike about Ubuntu over long time, make it more problematic. Trying to finding out best possible method to get around it. Thanks a bunch for the heads up man!.

    Reply
  3. Martin says

    October 15, 2015 at 3:51 am

    > The standard Ubuntu and Debian practice of automatically starting daemons has perplexed me before and it still continues to do so.

    I agree! It drives me batty when I’m trying to write configuration management code (e.g. Chef cookbooks) and I have to account for some distros starting the daemon, like Ubuntu, when others don’t.

    Reply
  4. Javier Javi says

    October 15, 2015 at 6:06 am

    Hey, that was an excellent job. I don’t know why they close their eyes so much to obvious points in the security. But I completely agree the lack of default secure settings is a little bit more than stupid.

    Reply
  5. Rex says

    June 10, 2016 at 12:05 pm

    If you these commands on an Ubuntu system ?

    Typo?

    Reply
  6. Vincent Bernat says

    June 10, 2016 at 12:14 pm

    You can decide if a daemon should start on install by adding /usr/sbin/policy-rc.d file. It is described in /usr/share/doc/sysv-rc/README.policy-rc.d. Notably, just putting “exit 101” should give you something similar to what you expect on Redhat.

    You can get the original MD5 sums of the configuration files with dpkg –status. You could also just install tripwire that would cover all files.

    Reply
    • Igor Khomyakov says

      June 13, 2016 at 5:10 am

      Please be aware that it could break something in your system. for example log rotation scripts and cron jobs are relying on that policy so you script should be smarter that just alway return 101. You probably should allow ‘reload’ and ‘rotate’ actions

      Grep your /etc folder for invoke-rc.d before make any changes.

      Reply
  7. Enn Nickolas says

    June 10, 2016 at 4:47 pm

    Since dpkg v1.17.2 you can run ‘dpkg -V’ to verify integrity of packages, including config files.

    Reply
  8. stephen says

    June 11, 2016 at 4:23 pm

    Let’s hope that more packages adopt the practice of using /etc/default/ to control enabling/disabling the service.

    Reply
  9. stephen says

    June 11, 2016 at 4:25 pm

    I hope that more packages adopt the practice of using /etc/default/ to control enabling/disabling the service.

    Reply
  10. guate says

    March 30, 2017 at 1:36 pm

    Hello major.io. Thanks for the great post.
    Can you provide an update as to how far you have been able to progress in applying security hardening to Ubuntu 14.04 systems?
    Thanks

    Reply
    • Justin says

      April 12, 2017 at 10:30 am

      I’m interested in your progress as well. I have some experience locking down RedHat/CentOS using DISA STIGs but Ubuntu is a whole new animal.

      Reply
  11. John Sicklick says

    September 21, 2017 at 3:47 pm

    DISA STIGs for Ubuntu 14.04 were released on 9/18/17.

    Reply

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

loading Cancel
Post was not sent - check your email addresses!
Email check failed, please try again
Sorry, your blog cannot share posts by email.