Password Protecting Grub in RHEL 6

19552780-illustration-of-cartoon-wormGrub, is the standard boot loader used by each and every Linux type operating system that I can think of. RHEL 6 uses what I guess we are now calling grub 1.o, since grub 2.0 has been released and in use by Fedora for the last few releases. You will also find that grub 2.0 has replaced grub 1.0 in RHEL 7. At some point I plan to explore grub 2 at lenght, but today is not that day (unless something strange happens before I go to bed tonight — you never know).

 

Anyway – I digress. Below is an excerpt from the current grub.conf that is in use by my EC2 RHEL 6.5 instance. I've made it really tiny to save space.

# grub.conf generated by anaconda
#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE:  You do not have a /boot partition.  This means that
#          all kernel and initrd paths are relative to /, eg.
#          root (hd0)
#          kernel /boot/vmlinuz-version console=ttyS0 ro root=/dev/vda1
#          initrd /boot/initrd-[generic-]version.img
#boot=/dev/vda
default=0
timeout=1

splashimage=(hd0)/boot/grub/splash.xpm.gz

hiddenmenu
title Red Hat Enterprise Linux Server (2.6.32-431.17.1.el6.x86_64)
        root (hd0)
        kernel /boot/vmlinuz-2.6.32-431.17.1.el6.x86_64 console=ttyS0 ro root=UUID=05e7b919-2577-40a7-91fb-1ccdede87fc4 rd_NO_LUKS  KEYBOARDTYPE=pc KEYTABLE=us LANG=en_US.UTF-8 xen_blkfront.sda_is_xvda=1 console=ttyS0,115200n8 console=tty0 rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=auto rd_NO_LVM rd_NO_DM rhgb quiet
        initrd /boot/initramfs-2.6.32-431.17.1.el6.x86_64.img

To configure a password to use for grub you need to use the grub-crypt command. as you can see in the example below, grub-crypt prompts you for your password, although you can also pass the password to grub-crypt in the inital command. Grub-crypt spits out your hashed and salted password.

[root@ip-172-31-22-45 ~]# grub-crypt
Password:
Retype password:
$6$V0qkcD4b/CouCY/L$.7vrHd.X6MZWzzDxvXdQn3avPwv2rUX80XKuS.Hvh1YqR11ZyINZszvJ/e0qH6VcsFMAVWAPWXtugHHYTzYj90

Now stick this password in your grub.conf using the format below.

password –encrypted $6$V0qkcD4b/CouCY/L$.7vrHd.X6MZWzzDxvXdQn3avPwv2rUX80XKuS.Hvh1YqR11ZyINZszvJ/e0qH6VcsFMAVWAPWXtugHHYTzYj90

You have a couple of options when inserting the password into the grub.conf. You can either stick this entry near the top of the file, which protects each and every boot image that you might be configured to use, or you can stick the entry directly into a particular stanza to protect a specific boot image. For example, if you are building your servers with the option to pxe-boot from grub, or wipe the disk from grub, you might want to protect these options with a password.

Also note that adding a password to grub does not keep an unauthorized user from being able to boot or reboot a server, rather what it does is protect the grub menu from being edited manually durring a reboot. This keeps nefarious users from being able to break the boot sequence and boot into single-user mode where they can compromise your system.

 

Related articles

RHEL6 – Restore Grub on MBR
Grub
RHEL6 – Mount: Could Not Find Any Free Loop Device
Advertisements

Introduction to AIDE – Advanced Intrusion Detection Environment

Wally_Gator_PhotoEver heard of AIDE, neither had I. Apparently its a simple intrusion detection application that can be used to monitor file changes.  It can be confired to monitor permission, ownership, timestamp, or content changes.

Lets install it. Its in the stock Redhat repos, so its a piece of cake to install via yum.

 

[root@localhost ~]# yum -y install aide

Once installed, you can tweak the config file (/etc/aide.conf) to your liking. The stock config is pretty robust, so I am going to trim it down a bit and just monitor /etc for permission changes, and /bin for what are defined as normal changes. Normal looks at file hashes to see if the files have been modified.

/bin    NORMAL
/etc    PERMS
 

Now lets start aide

[root@localhost ~]# aide –init

AIDE, version 0.15.1

### AIDE database at /var/lib/aide/aide.db.new.gz initialized.

 

Now this part is silly, we need to rename the database created above to the name that aide is configured to use.

[root@localhost ~]# cp /var/lib/aide/aide.db.new.gz /var/lib/aide/aide.db.gz

 

Now lets check for changes.

[root@localhost ~]# aide –check

AIDE, version 0.15.1

### All files match AIDE database. Looks okay!

Hey no changes. Now lets monkey with something and see if aide catches it. In this example we are creating a new file in /etc. As seen below aide catches the new file and reports on it.

 

[root@localhost ~]# touch /etc/aide.test.change
[root@localhost ~]# aide –check
AIDE 0.15.1 found differences between database and filesystem!!
Start timestamp: 2014-07-15 19:51:14

Summary:
  Total number of files:        5054
  Added files:                  1
  Removed files:                0
  Changed files:                0

—————————————————
Added files:
—————————————————

added: /etc/aide.test.change

 

So now lets re-initialize the database, which is pretty much a snapshot.

[root@localhost ~]# aide –init

AIDE, version 0.15.1

### AIDE database at /var/lib/aide/aide.db.new.gz initialized.

 

Don't forget to overwrite the old database.

[root@localhost ~]# cp /var/lib/aide/aide.db.new.gz /var/lib/aide/aide.db.gz
cp: overwrite ‘/var/lib/aide/aide.db.gz’? yes

Now lets change the permissions on our test file and see if aide catches the change.  I'll spare you the suspense and let you know that aide did its job. See below.

 

[root@localhost ~]# chmod 777 /etc/aide.test.change
[root@localhost ~]# aide –check                    
AIDE 0.15.1 found differences between database and filesystem!!
Start timestamp: 2014-07-15 19:54:09

Summary:
  Total number of files:        5054
  Added files:                  0
  Removed files:                0
  Changed files:                2

—————————————————
Changed files:
—————————————————

changed: /etc/aide.test.change
changed: /root/.mozilla/firefox/8u03e3hs.default/sessionstore.js

—————————————————
Detailed information about changes:
—————————————————

File: /etc/aide.test.change
 Perm     : -rw-r–r–                       , -rwxrwxrwx
 ACL      : old = A:
—-
user::rw-
group::r–
other::r–
—-
                  D: <NONE>
            new = A:
—-
user::rwx
group::rwx
other::rwx
—-
                  D: <NONE>

Now aide on its own is just a simple tool, but run via cron with a bit of tuning and a bit more logic behind it and I can see it being a very useful tool. Looking forward to playing with it more.

Related articles

How To Install Aide on a DigitalOcean VPS
RHEL6 – How to Setup an Anonymous Download Only FTP Server

Yum: Under the Covers with GPG Keys

Skeleton_key_1_keychain_sculpture_photo_cut_outs-r558fef9b275d4609b522ac07970a6af6_x7sa6_8byvr_324Hey look at this spooky key. Don't be frightened little one. Nothing scary is going to happen to you here. This is a safe place. As a matter of fact, if you stick around you might just learn a thing or two. A thing or two about GPG!

First off do any of us really know what GPG stands for? Well yes we do! It stands for GNU Privacy Guard. RPM Package creators use GPG to apply a digital signature to their packages. If a package was tampered with, then its GPG signature will no longer match what was placed in the original package.

First off to check what keys you have installed on your Linux server you can run the following rpm command as show in the example below.

[root@ip-172-31-22-45 ~]# rpm -qa gpg-pubkey
gpg-pubkey-0608b895-4bd22942
gpg-pubkey-fd431d51-4ae0493b
gpg-pubkey-2fa658e0-45700c69

 

Neet I have three keys installed. But lets say want to install another one. Well I can do so with the command below. In this example I have navigated to /etc/pki/rpm-gpg and am going to install the redhat beta key on my server.

[root@ip-172-31-22-45 rpm-gpg]# rpm –import RPM-GPG-KEY-redhat-beta

Hey that was fun. Now lets get our hands a bit dirtier.

Want to get more information on a specific key. Then this command is your huckleberry. Here you can see that this is the pubkey for the EPEL repo.

[root@ip-172-31-22-45 rpm-gpg]# rpm -qi gpg-pubkey-0608b895-4bd22942
Name        : gpg-pubkey                   Relocations: (not relocatable)
Version     : 0608b895                          Vendor: (none)
Release     : 4bd22942                      Build Date: Sat 14 Jun 2014 09:13:58 AM EDT
Install Date: Sat 14 Jun 2014 09:13:58 AM EDT      Build Host: localhost
Group       : Public Keys                   Source RPM: (none)
Size        : 0                                License: pubkey
Signature   : (none)
Summary     : gpg(EPEL (6) <epel@fedoraproject.org>)
Description :

 

To verify signature of a downloaded package, use the rpm command as shown below. In this example I have highlighted the key that was used to sign this package.

# rpm -vK nautilus-dropbox-1.6.0-1.fedora.i386.rpm
nautilus-dropbox-1.6.0-1.fedora.i386.rpm:
    Header V3 RSA/SHA1 Signature, key ID 5044912e: OK
    Header SHA1 digest: OK (a4d51906633f92913db075ba33946f50999c245e)
    V3 RSA/SHA1 Signature, key ID 5044912e: OK
    MD5 digest: OK (1b8ff7abc18f68bf274e24fc57fd3a87)

 

Using the bolded information in the example above, I can then use this information to track down the exact key that was used to sign the package.

[root@localhost Downloads]# rpm -qa | grep 5044912e
gpg-pubkey-5044912e-4b7489b1

 

Is this awesome, well not really, but you never know when you might need to use this information. Like on a test. Wink Wink.

Related articles

Using Yum Update to Apply Security Patches Only
How to Enable EPEL Repository on CentOs for Yum
Signing rpm packages with GPG

RPM Package Inspection for Fun and Profit

6a00d8341c562c53ef01538f8abd65970b-800wi"Whats in the box" — David Mills

Lets face it, one of your users needs to have a package installed on a system, you tend to do it for them. That is, as long as the package looks safe. Sure, your not going to install an rpm that is clearly dangerous, but as long as the package name looks reasonable and you trust the user, you might actually just go ahead an install it for them without thinking much about it. Hell, I know that I have done the exact same thing from time to time. And I have done it with an unsigned package.

"Sure you need this Oracle thing installed on this database server?"

 "You got it directly from Oracle right?"

But honestly, this is a very bad practice as you have no idea what the RPM is installing, and what its pre and post scripts might be doing to your system. Using the command below, you can inspect a packages post and pre install scripts to see if they are doing anything funny. In this instance I am taking a look at the dropbox package for my little Eeepc.

[root@localhost ~]# rpm -qp –scripts /root/Downloads/nautilus-dropbox-1.6.0-1.fedora.i386.rpm

If you have already installed a package and want to see what its pre and post install scripts did. You can run the command above using the installed package name. Note that you will drop the "P" from the command. See my sendmail example below.

[root@localhost ~]#rpm -q –scripts sendmail-8.14.8-2.fc20.i686

 

In addition to checking the pre and post scripts, you also want to check to see if the rpm has any triggers. What are triggers you ask? Well they are extensions to the normal install scripts, and they may often call for the installation of another package or the execution of a command. Just look at all the triggers that fire when you install sendmail.

[root@localhost ~]# rpm -q –triggers sendmail-8.14.8-2.fc20.i686
triggerun scriptlet (using /bin/sh) — sendmail < 8.14.5-3
/usr/bin/systemd-sysv-convert –save sendmail >/dev/null 2>&1 ||:
/bin/systemctl enable sendmail.service >/dev/null 2>&1
/bin/systemctl enable sm-client.service >/dev/null 2>&1
/sbin/chkconfig –del sendmail >/dev/null 2>&1 || :
/bin/systemctl try-restart sendmail.service >/dev/null 2>&1 || :
/bin/systemctl try-restart sm-client.service >/dev/null 2>&1 || :
# workaround for systemd rhbz#738022
/bin/systemctl is-active sendmail.service >/dev/null 2>&1 && \
        ! /bin/systemctl is-active sm-client.service >/dev/null 2>&1 && \
        /bin/systemctl start sm-client.service >/dev/null 2>&1 || :

Obviously you also want to check to see what files are actually part of a package. This can be accomplished with the query and list arguments seen below. Add the "P" argument if the rpm is not already installed. In this case I have already installed sendmail, so I exclude the "P" from the command.

 

[root@localhost ~]# rpm -ql sendmail-8.14.8-2.fc20.i686
/etc/NetworkManager/dispatcher.d/10-sendmail
/etc/mail
/etc/mail/Makefile
/etc/mail/access
/etc/mail/access.db
/etc/mail/aliasesdb-stamp
/etc/mail/domaintable
/etc/mail/domaintable.db
/etc/mail/helpfile
/etc/mail/local-host-names
..truncated…

 

So whats the moral of the story here. Well its really not that hard to take a minute and look under the covers and make sure that the packages that you are installing are not harming your systems. Is definetly worth 5 minutes of your time. Might just save your behind.

 

Related articles

RHEL6 – Simple Postfix Configuration
RHEL6 – Common Postfix Server Roles
Configure sendmail as a client for SMTPs
Sendmail Server

Quick and Dirty Yum Security Plugin Overview

Maneki-neko-mountain-tummy-13745890The YUM security plugin is a package that allows you to search specifically for security patches applicable to a Redhat/Centos server.  This functionality comes in very handy when having to cross reference CVEs to Redhat Security Advisories (RHSAs). If you work closely with anyone in an information security role, you already know how vital functionality is.

Before you can begin you need to make sure that you have the plugin installed.  Use the command below to install it.

# yum -y install yum-plugin-security

 

Then you can use the plugin to get a overview of the security updates availible for your system.

# yum updateinfo
    
Updates Information Summary: available
3 Security notice(s)
         1 Important Security notice(s)
         2 Moderate Security notice(s)
12 Bugfix notice(s)
1 Enhancement notice(s)

 

You can get a specific list of updates, sorted by security advisories, bug fixes, and enhancement advisories.

# yum updateinfo list

 

To get more specific information on a RHSA and the CVEs that it applies to, you can search by RHSA as seen below.

# yum updateinfo RHSA-2014:0771

 

Need to see what patches are required to address a certain CVE, then this next command is for you. Trust me this one is useful as it gives you a list of all required packages that address that CVE.

# yum updateinfo list –cve=CVE-2013-6378
Loaded plugins: amazon-id, rhui-lb, security
RHSA-2014:0771 Important/Sec. kernel-2.6.32-431.20.3.el6.x86_64
RHSA-2014:0771 Important/Sec. kernel-firmware-2.6.32-431.20.3.el6.noarch
RHSA-2014:0771 Important/Sec. kernel-headers-2.6.32-431.20.3.el6.x86_64
RHSA-2014:0771 Important/Sec. perf-2.6.32-431.20.3.el6.x86_64

 

Want to see a list of all fixes by severity. Then you can use the command below. Note that I am using important as my severity as there are no critical updates that are applicable to my test system at this time.

yum updateinfo list –sec-severity=Important
RHSA-2014:0771 Important/Sec. kernel-2.6.32-431.20.3.el6.x86_64
RHSA-2014:0771 Important/Sec. kernel-firmware-2.6.32-431.20.3.el6.noarch
RHSA-2014:0771 Important/Sec. kernel-headers-2.6.32-431.20.3.el6.x86_64
RHSA-2014:0771 Important/Sec. perf-2.6.32-431.20.3.el6.x86_64

 

You can also search for security fixes by package name as shown below.

# yum updateinfo list kernel
RHSA-2014:0771 Important/Sec. kernel-2.6.32-431.20.3.el6.x86_64

 

You can also use YUM to apply only security related updates. See below. This is useful if you are in a pinch and need to quickly apply all security updates to make your Infosec Team happy.

# yum –security update

Related articles

Using Yum Update to Apply Security Patches Only
SCAP CVE Audit
YFD plugin updated

RHEL6 – SELinux Modes and Contexts

Anime,art,cartoon,chibi,darth,vader,darthvader-26d94e794e11142d417a277b8fbdc0eb_hSELinux, or Security-Enhanced Linux as its known by the guy who invented it, is a Linux feature that provides an additional level of security by setting rules for which processes can access which files, directories, ports, etc.

Display and Modify SELinux Modes:

You can use /etc/sysconfig/selinux to change the default SELinux mode at boot, and the setenforce command can be used to change the default level on the fly. Getenforce can be used to determine the current SELinux mode. 

# getenforce
Enforcing

Display SELinux Contexts:

Under SELinux, every file, process, directory, or port is assigned a special security label called a context.

To view the contexts assigned to a file or directory use the '-Z' option. Coupled with and 'ls" or a 'ps" this is a formidable command.

To view a list of all possible assigned contexts use semanage.

# semanage fcontext -l

Modify SELinux Contexts:

For example, lets create two test files in /tmp called testfile1 and testfile2, and then lets check their contexts.

# ls -lZ test*
-rw-r–r–. root root unconfined_u:object_r:user_tmp_t:s0 testfile1
-rw-r–r–. root root unconfined_u:object_r:user_tmp_t:s0 testfile2

Now compare this to the default context assigned to apache content

# ls -ldZ /var/www/html
drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 /var/www/html

So lets say that I want to move testfile1 to /var/www/html and make it accessable via a webbrowser; in order to do this I must assign the correct context to the file using the restorecon command.

# restorecon -Rv /var/www/html

The command above restores or even better, allows the testfiles to inherit the contexts assigned to the parent directory, which in this case is /var/www/html/

Add SELinux Contexts:

Now lets say that you need to add a directory and apply a context directly to that directory, instead of allowing a context to be inheritted. For example, lets say that I need to setup an apache virtual server under /virtual_server2, so lets first create the directory and a simple index.html

# mkdir /virtual_server2
# vi /virtual_server2/index.html
# ls -Zd /virtual_server2
drwxr-xr-x. root root unconfined_u:object_r:default_t:s0 /virtual_server2

# ls -Zd /virtual_server2/index.html
-rw-r–r–. root root unconfined_u:object_r:default_t:s0 /virtual_server2/index.html

Now we need to set and apply the correct http content context to /virtual_server2 and its contents (say that 5 times fast)

# semanage fcontext -a -f "" -t httpd_sys_content_t '/virtual_server2(/.*)?'

# restorecon -RFvvv /virtual_server2/

restorecon reset /virtual_server2 context unconfined_u:object_r:default_t:s0->system_u:object_r:httpd_sys_content_t:s0
restorecon reset /virtual_server2/index.html context unconfined_u:object_r:default_t:s0->system_u:object_r:httpd_sys_content_t:s0

Now that our context is correct apache should have no issue serving up our new content (once configured on the apache side)

# ls -Zd /virtual_server2/
drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 /virtual_server2/