Linux servers.

DISA STIG Compliance For Linux

The STIG Requirements

The Security Technical Implementation Guide (or STIG) documents describe cybersecurity requirements for a wide range of computer operating systems, routers, and other computing systems. They are written by DISA, the Defense Information System Agency, part of the U.S. Department of Defense. STIG details are based on concepts in NIST Special Publication 800-53, which specifies security controls for all U.S. federal information systems other than national security systems.

The STIGs are far specific than "how to secure a server" or even "how to secure a Linux server". Specific STIGs exist for various Linux distribution and version combinations. For example, Red Hat Enterprise Linux (RHEL) 7 and RHEL 8, and Oracle Linux 7 and Oracle Linux 8, and Canonical Ubuntu Linux 16.04 and 18.04. Other UNIX-family and Microsoft Windows operating systems are addressed in version-specific documents.

There is no
STIG for Debian

DISA will only create a STIG for an operating system from a trusted provider. For example, Red Hat (and now IBM) for RHEL, Oracle for Oracle Linux, and Canonical for Ubuntu Linux. There is no STIG for Debian, nor will there be one, because there is no company controlling Debian releases and maintaining quality and patch control.

DISA STIG
Archive

There are STIGs for network equipment including A10 Application Delivery Controllers, Cisco IOS, various F5 BIG-IP devices, various Juniper devices, Palo Alto Networks devices, and others.

STIGs also exist for individual software products, such as the Google Chrome browser, the Apache web server (with specific STIGs for both UNIX-family and Windows versions), the BIND DNS server, Microsoft Office, various VMware products, and others.

There is even a STIG for keyboard-video-mouse switches!

DOD used to provide the "Gold Disks" with testing scripts. Now a number of contractors are paid to create and maintain scanning software. These products do vulnerability scanning as well as test compliance to the Federal Desktop Core Configuration (or FDCC) and to the STIGs. I have a list of these products on another page.

The following is my personal and entirely non-authoritative take on the RHEL 6 and RHEL 7 manual STIG documents. This comes from a project for a client. A major defense contractor had done poorly on a recent audit. A follow-up audit was approaching in a few months, and they were trying to figure out how to get their internal people up to speed.

The manual STIG document for RHEL 7

You can download a manual STIG document from the DISA site. It comes as a zip file with some meta-level "how to use this" PDF files, and a subdirectory with the document itself. Read the XML file with a browser. The *.xml file is the document, while *.xsl is a style sheet. There will also be a JPEG banner as seen here.

$ tree -F RHEL-7-STIG-v01r01/
RHEL-7-STIG-v01r01/
|-- U_Readme_SRG_and_STIG.pdf
|-- U_Red_Hat_Enterprise_Linux_7_V1R1_Manual_STIG/
|   |-- DoD-DISA-logos-as-JPEG.jpg
|   |-- STIG_unclass.xsl
|   `-- U_Red_Hat_Enterprise_Linux_7_STIG_V1R1_Manual-xccdf.xml
`-- U_Red_Hat_Enterprise_Linux_7_V1R1_Overview.pdf 

I found that Firefox handles the document well, while Chrome may not.

It starts with a large "UNCLASSIFIED" banner. You are left wondering whether the real STIG might contain something more or different. I don't think so, but there's no way of telling.

Linux STIG Rules

A STIG contains a series of rules. Each rule involves a very specific test. Password maintenance leads to a large number of rules. One for length, four rules for each of the character classes that a password must contain, and rules for password change scheduling.

A rule's title usually serves as a one-sentence summary. That is followed by a discussion which may or may not expand significantly on the importance of the rule or details of what it involves.

The "Check Content" section tells how to test for compliance. Most of them direct you to run a command and see if certain output does or does not occur. A relatively small number tell you to inspect some configuration file, looking for specific content.

The "Fix Text" section then tells you how to fix the problem if your system failed this rule. It may tell you exactly what to do, but frequently you must make some judgement to fill in some specific detail. Some are rather open-ended, like the requirements for separate file systems for /tmp, /home, /var, /var/log, and /var/log/audit:
Ensure it has its own partition or logical volume at installation time, or migrate it using LVM.

Here is the first rule in the RHEL 7 STIG:

Group ID (Vulid): V-71849
Group Title: SRG-OS-000257-GPOS-00098
Rule ID: SV-86473r2_rule
Severity: CAT I
Rule Version (STIG-ID): RHEL-07-010010
Rule Title: The file permissions, ownership, and group membership of system files and commands must match the vendor values.

Vulnerability Discussion: Discretionary access control is weakened if a user or group has access permissions to system files and directories greater than the default.

Satisfies: SRG-OS-000257-GPOS-00098, SRG-OS-000278-GPOS-00108

Check Content:
Verify the file permissions, ownership, and group membership of system files and commands match the vendor values.

Check the file permissions, ownership, and group membership of system files and commands with the following command:

# rpm -Va | grep '^.M'

If there is any output from the command indicating that the ownership or group of a system file or command, or a system file, has permissions less restrictive than the default, this is a finding.

Fix Text: Run the following command to determine which package owns the file:

# rpm -qf <filename>

Reset the permissions of files within a package with the following command:

#rpm --setperms <packagename>

Reset the user and group ownership of files within a package with the following command:

#rpm --setugids <packagename>

CCI: CCI-001494

CCI: CCI-001496

The lack of formatting can make the commands ambiguous. For example, the RHEL 6 STIG tells you to check whether /tmp has its own file system with this command:

$ mount | grep "on /tmp"

Proportional fonts can leave you wondering about the white space within strings.

This becomes more dangerous when you are told to run a command and verify that some output does not appear. Is your system OK, or did that output not appear because you didn't do the appropriate test?

Notice in the above example rule that the first two commands have a space between the prompt character "#" and the command, while the second two do not. That does not give me confidence that the rest of the line is carefully formatted!

Running The Tests

For the most part, you can simply copy and paste the command text into a command-line environment.

The prompt character, "$" versus "#", should indicate whether you need root privileges. However, a few rules indicate running a command as an unprivileged user when that won't work.

Understanding The Tests

This is where the problems begin.

DISA now enforces the Risk Management Framework. Any talk about RMF usually focuses on strict separation of duties.

You cannot simply rely on a system administrator's statement that their server is secure because they say it is. RMF requires that one person builds and maintains the server, and then a different person tests it for compliance.

As is often the case, this is a great idea in theory, but practical situations quickly become, well, impractical.

The reality is that because Auditors are not allowed to touch anything that they audit, they frequently to not understand what they are looking at. Very few are knowledgeable system administrators who moved into auditing. Most of them have little to no background in the systems they are supposed to audit.

This was the point of my project. What does an auditor need to know in order to understand enough of what they're seeing to make reasonable decisions about compliance, and to direct system administrators to make all needed changes?

And, of course, what is the bare minimum with which they can just barely scrape by, in order to minimize the training time and cost?

What's In The Linux STIG?

I grouped the 261 rules in the RHEL 6 STIG into what seemed to me to be the meaningful categories. The client was mostly running RHEL 6. I later went through the 234 rules of the RHEL 7 STIG. My counts were:

Boot loader and SELinux
Enforce ownership and access to grub.conf, require a password to modify booting, and ensure that SELinux is enabled and enforcing a targeted policy. SELinux is required for the audit daemon to work.
RHEL 6: 9 rules (3.4%)
RHEL 7: 7 rules (3.0%)

File system
Partition the file systems, mount cautiously, make backups, and encrypt if needed.
RHEL 6: 19 rules (7.3%)
RHEL 7: 10 rules (4.3%)

Packages and patching
Install RPM PGP keys and set up a repository, install certain packages (including some McAfee software) and don't install certain others, and verify integrity of all package content and metadata.
RHEL 6: 25 rules (9.6%)
RHEL 7: 17 rules (7.3%)

Booting and service control
Restrict booting to single-user mode, start certain services and don't start certain others, schedule AIDE checks via cron, configure running services carefully, disable core dumps, and forward root's mail.
RHEL 6: 50 rules (19.2%)
RHEL 7: 24 rules (10.3%)

Files
Verify owner and group and permissions on critical files and directories, and forbid .rhosts or .netrc files. (and, in RHEL 7, .shosts or shosts.equiv)
RHEL 6: 22 rules (8.4%)
RHEL 7: 19 rules (8.1%)

Authentication
Prohibit direct root login, lock system accounts other than root, enforce several password maintenance details, cautiously configure SSH, enable screen locking, configure user shell defaults, and display warning banners.
RHEL 6: 59 rules (22.6%)
RHEL 7: 73 rules (31.2%)

Kernel
Disable forbidden kernel modules (Bluetooth, USB storage) in /etc/modprobe.conf, and tune the kernel IP stack with sysctl.
RHEL 6: 24 rules (9.2%)
RHEL 7: 12 rules (5.1%)

Logging
Configure Rsyslog and the audit daemon, and protect and rotate log files.
RHEL 6: 53 rules (20.3%)
RHEL 7: 72 rules (30.8%)

But What Does An Auditor Really Need To Know?

And just the bare minimum, of course, because everyone wants to do this as quickly and cheaply as possible...

Very Basic User Fundamentals

An auditor must be able to find their way around the file system, starting with the distinction between files and directories (and, eventually, symbolic links). This must include the concept of a file system tree structure.

Many Windows users today, including some people that corporations want to turn into Linux security auditors, don't realize that there is anything other than their graphical desktop and whatever folders it contains. They no longer realize that their desktop is somewhere like c:\users\myname\Desktop, three levels deep in a much larger tree of files. An auditor must examine files in these directories, checking for the presence of files, their owner and permissions, and their contents:

/etc   (and several subdirectories 1 and 2 levels down)
/tmp
/var/log
/var/log/audit
/usr/lib
/usr/lib64
/usr/bin
/usr/sbin
/home 

They must know commands to figure out where they are, what files and directories are there, and how to get to somewhere else. That means running these commands and understanding their output:

pwd
ls
ls -F
ls -a
ls -aF
ls -l
ls directory
ls -d directory
cd relative/path
cd /absolute/path
cd 

With the first set of commands they need to learn the basics of a command-line interface: the command itself as the first token, then options and parameters (and the distinction between those).

They also must distinguish between good command output and error messages. That will only come with the familiarity that comes from time at the keyboard. Any plan to rapidly show people a few user commands, then look at a few system administration commands and configuration files, and then consider them to be useful Linux security auditors within a few days is absurd.

Now use ls to learn file name wild cards:

ls *
ls a*
ls *a*
ls [abc]*
ls *.?
ls ???[a-z] 

Next, manipulate files and directories:

cp file1 file2
cp file1 file2 directory
cp foo.* directory
mv file1 file2
mv file1 file2 directory
mv foo.* directory
rm file1
rm -r directory
mkdir directory
rmdir directory 

Understand ownership and permissions:

id
ls -l 

For that long listing, understand:

Next, how to use more (or less) and cat to view file contents, including how to search within more and less. Plus a few more checks on files and their contents:

cat file
more file
less file
head file
head -5 file
tail file
tail -5 file
tail -f /var/log/messages
sort file
wc *
file * 

Search for patterns within files, including basic regular expressions:

grep pattern file
grep pattern *.conf
grep -w pattern file
grep -v pattern file
grep -i pattern file
grep '^pattern' file
grep 'pattern$' file
grep 'pattern[0-9]' file
grep 'pat.ern' file
grep 'pat.*ern' file
grep 'pattern[0-9][0-9]*$' file
egrep -w '0|root' /etc/passwd 

Select columns and fields from files and output streams:

cut -d: -f 1,3 /etc/passwd
awk -F: '{print $1, $3}' /etc/passwd 

Construct multi-command pipelines:

awk -F: '{print $1, $3}' /etc/passwd | grep 0 | sort 

Redirect I/O:

ls -l > my-list
sort < my-list
find / -name mine 2> /dev/null 

Use command substitution (yes, the following is in the RHEL 7 STIG):

ls -ld $( egrep ':[0-9]{4}' /etc/passwd | cut -d: -f6 ) 

Finally, search the file system:

find * -name whatever
find / -perm -abcd
find / -mtime -1 

With the above background, including plenty of time on the keyboard to become familiar with the environment, they would have a beginner-level ability as a user.

Commands and Files for the STIG Rule Categories

All of these following in addition to the above user fundamentals. To perform and understand the STIG tests, they must understand what the following commands do. They must also have at least an idea of the purpose of the referenced file and their contents.

A few of the fixes can be done with the following commands and changes to the referenced configuration files, but far more background is needed to safely carry out most of the needed changes.

Boot loader and SELinux

COMMANDS:
ls --context
restorecon
semanage              (only referenced in RHEL 7 STIG)

FILES:
/etc/selinux/config
/boot/grub/grub.conf  (RHEL 6 only)
/boot/grub2/grub.cfg  (RHEL 7 only, *much* larger!) 

File system

COMMANDS:
df
mount
mount | grep pattern

FILES:
/var/log        (generally, what is there)
/var/log/audit  (generally, what is there)
/etc/fstab
/etc/exports
/etc/samba.smb.conf 

Packages and patching

COMMANDS:
rpm    (used with several different options for tests and fixes)

FILES:
/etc/yum.conf
/etc/yum.repos.d/* 

Booting and service control

COMMANDS:
newaliases
service    (RHEL 6 only)
chkconfig  (RHEL 6 only)
systemctl  (RHEL 7 only)

FILES:
/etc/sysconfig/init            (RHEL 6 only)
/etc/sysconfig/ip*tables
/etc/subsystem.conf            (generally, for various subsystems)
/etc/subsystem.d/*             (generally, for various subsystems)
/etc/cron.*/
/etc/security/limits.conf
/etc/sysconfig/*
/etc/xinetd.d/*
/etc/aliases*
/etc/sysconfig/network-scripts/ifcfg-* 

Files

COMMANDS:
find -name whatever
find -perm -abcd
chmod   (both octal for absolute settings with
         4 digits to include SETUID/SETGID/Sticky,
	 and symbolic for relative changes) 

Authentication

COMMANDS:
pwck
grpck
gconftool-2          (for GNOME desktop checks and fixes)

FILES:
/etc/passwd
/etc/shadow
/etc/group
/etc/gshadow         (for very historical reasons)
/etc/pam.d/*         (also cracklib.so options for RHEL 6,
                      and pwquality.so options for RHEL 7)
/lib64/security/*.so
/etc/securetty
/etc/login.defs
/etc/libuser.conf
/etc/security/limits.conf
/etc/issue
/etc/ssh/ssh*_config
/etc/sudoers
/etc/sudoers.d/* 

Kernel

COMMANDS:
sysctl

FILES
/etc/sysctl.conf
/etc/sysctl.d/*.conf
/proc/sys/net/ipv4/*
/proc/sys/net/ipv6/*
/etc/modprobe.conf
/etc/modprobe.d/*.conf 

Logging

COMMANDS:
lsof        (are log files really in use?)
tail -f
service     (RHEL 6 only)
chkconfig   (RHEL 6 only)
systemctl   (RHEL 7 only)
df -h       (how much space left in /var/log/audit?)

FILES:
/etc/rsyslog.conf
/etc/rsyslog.d/*.conf
/etc/audit/auditd.conf
/etc/audit/audit.rules
/etc/audit/rules.d/*
/var/log/audit/audit.log
/etc/logrotate.conf
/etc/logrotate.d/*
/etc/cron.* 

Appendix: STIG Rule IDs

Here are the rule IDs as I assigned them for the RHEL 6 STIG. These are just the core numeric component of the rule ID. For example, "50482" for the rule named "SV-50482r2_rule".

Boot loader and SELinux

RHEL 6 (9 rules):
50238 50380 50382 50384 50386 65547 65573 65579 65589

RHEL 7 (7 rules):
86585 86587 86595 86613 86615 86663 86691

File system

RHEL 6 (19 rules):
50237 50255 50256 50260 50263 50267 50273 50287 50289 50453 50455 50456 50457 50458 50460 50462 50463 50478 71919

RHEL 7 (10 rules):
86609 86665 86667 86669 86683 86685 86687 86689 86935 87813

Packages and patching

RHEL 6 (25 rules):
50247 50252 50253 50254 50276 50281 50283 50288 50290 50385 50388 50391 50392 50404 50407 50428 50438 50464 50465 50466 50467 50468 50472 50477 50488

RHEL 7 (17 rules):
86473 86479 86591 86593 86601 86603 86605 86611 86621 86623 86701 86837 86857 86923 86925 86931 87041

Booting and service control

RHEL 6 (50 rules):
50244 50246 50278 50313 50314 50350 50352 50354 50356 50361 50383 50387 50389 50390 50395 50399 50400 50403 50405 50410 50416 50419 50421 50422 50423 50441 50442 50445 50447 50449 50451 50454 50461 50461 50469 50470 50471 50473 50474 50475 50476 50480 50487 50492 50496 50497 50499 50501 50502 50503

RHEL 7 (24 rules):
86597 86599 86617 86681 86693 86695 86697 86699 86839 86843 86845 86851 86853 86855 86859 86893 86895 86897 86905 86921 86929 86937 86939 86941

Files

RHEL 6 (22 rules):
50243 50248 50249 50250 50251 50257 50258 50259 50261 50265 50266 50269 50272 50292 50303 50304 50305 50420 50444 50498 50500 65601

RHEL 7 (19 rules):
86631 86633 86639 86641 86643 86645 86647 86649 86651 86653 86655 86657 86659 86661 86671 86677 86679 86901 86903

Authentication

RHEL 6 (59 rules):
50239 50274 50275 50277 50279 50280 50282 50285 50293 50295 50297 50298 50300 50301 50302 50370 50371 50372 50373 50374 50375 50377 50378 50393 50394 50396 50408 50409 50411 50412 50413 50414 50415 50416 50417 50418 50430 50431 50439 50440 50443 50446 50448 50450 50452 50459 50482 50484 50485 50486 50489 50490 50491 50493 50494 50495 55880 66089 73331

RHEL 7 (73 rules):
86483 86485 86487 86515 86517 86519 86521 86523 86525 86619 86625 86627 86629 86635 86637 86673 86841 86847 86849 86861 86863 86865 86867 86869 86871 86873 86875 86877 86879 86881 86883 86885 86887 86889 86891 86899 86927 87051 87057 87059 87527 87529 87531 87533 87535 87537 87539 87541 87543 87545 87547 87549 87551 87553 87555 87557 87559 87561 87563 87565 87567 87569 87571 87573 87575 87577 87579 87581 87583 87589 87807 87809 87811

Kernel

RHEL 6 (24 rules):
50291 50312 50315 50316 50317 50318 50324 50325 50327 50329 50330 50333 50334 50336 50338 50340 50343 50345 50349 50397 50398 50401 50402 50483

RHEL 7 (12 rules):
86607 86907 86909 86911 86913 86915 86917 86919 86933 86943 87827 87829

Logging

RHEL 6 (53 rules):
50245 50264 50268 50270 50271 50294 50296 50299 50319 50320 50321 50322 50323 50326 50328 50331 50332 50335 50337 50339 50341 50342 50344 50346 50348 50351 50353 50355 50357 50358 50359 50360 50362 50364 50366 50367 50368 50369 50376 50379 50381 50424 50425 50429 50432 50433 50434 50435 50436 50437 58479 58481 68627

RHEL 7 (72 rules):
86675 86703 86705 86707 86709 86711 86713 86715 86717 86719 86721 86723 86725 86727 86729 86731 86733 86735 86737 86739 86741 86743 86745 86747 86749 86751 86753 86755 86757 86759 86761 86763 86765 86767 86771 86773 86775 86777 86779 86781 86783 86785 86787 86789 86791 86793 86795 86797 86799 86801 86803 86805 86807 86809 86811 86813 86815 86817 86819 86821 86823 86825 86827 86829 86831 86833 86835 87815 87817 87819 87823 87825