Contents
xinetd Services - DisablingrootIn this portion of the guide, instead of taking a must, recommended or may approach to the setup of a secured host, we will address security topics in a more “general” fashion. This is where you will get a rule-of-thumb or best-practice even a basic recommendation. The procedures and examples here should give you the ability to apply security enhancement techniques to a wider variety of server-based services and programs.
Even if some of these topics might have been covered in “explicit” terms earlier with no leniency towards implementation variation (in accordance with the EAL target evaluation) you may find the examples that follow to contain more detail or explanation. Some of the general topics will include:
Physical Security – Protection of the server from environmental threats (people, places, things).
Security Policies and Procedures – Server lifecycle management, disk/media reclamation, backup and archive security.
Systems Monitoring – Procedures around event notification/management.
Systems Automation – Mechanisms and/or procedures for automatic security measures. Heuristics, account control, security reporting and remediation, automated shutdown, etc.
Systems Management – Methods to obtaining packages, verification and signing keys, patching procedures and recommendations.
Securing Network – Addition programs, ports and service wrappers – iptables, tcpwrappers, services.
Remote Access – extra SSH information and key federation. CA integration.
Common Services – mail, nfs and automount.
Securing the Kernel and Init Process – parameters, inittab, runlevels and boot scripts.
Access Control – user/groups/permissions.
Password Security and Warnings – Proper setup of passwords, banners
and xinetd.
Miscellaneous Security – Assorted security settings and miscellaneous stuff.
Resources – Web links, documentation and example references, HOWTOs and general information, product links.
The sections will again be organized by a topical hierarchy for continuity-sake. Refer to the main table of contents for easy reference.
![]() | Typography |
|---|---|
The following examples will show the | |
Physical security should be one of the utmost concerns if not the one of the primary ones. Linux production servers should be in locked datacenters where only people with passed security checks have access. Depending on the environment and circumstances, you also may want to consider boot loader passwords. Some questions to consider: Who has direct physical access to the host? Of those that do, should they? Can the host be protected from tampering? Should it be? Etc.
The amount of physical security needed on a particular system depends on the situation, and can also vary widely by available funds.
Most data center server racks include a “locking” feature. Usually this will be a hasp/cylinder lock on the front of the rack that allows you to turn an included key to a locked or unlocked position – granting or denying entry. Cage locks can help prevent someone from tampering or stealing devices/media from the servers, or opening up the cases and directly manipulating/sabotaging the hardware. Preventing system reboots or the booting from alternate devices is also important (e.g. floppys, CD/DVDs/USB drives/etc.).
Some servers also have case locks. These locks can do different things according to the designs of the system vendor and construction. Many systems are designed to self-disable if attempts are made to open the system without unlocking. Others have device covers that will not let you plug in or unplug new keyboards or mice. While locks are sometimes a useful feature, they are usually lower quality and easily defeated by attackers with ill intent.
The BIOS (Basic Input/Output System) is the lowest level of software/firmware that dictates system configuration and low-level hardware. GRUB, LILO and other Linux boot loaders access the BIOS to determine how to boot the host. Other hardware types (POWER/System z) that run Linux also have low-level software/firmware. Typically the BIOS can be configured to help prevent attackers from being able to reboot the host and manipulate the system.
Most BIOS varieties allow the setting of a boot password. While this does not provide a high level of security (a BIOS can be reset, removed or modified – assuming case access), but it can be another deterrent.
Many BIOS capabilities have other various security settings – checking with the system vendor, the system documentation or examine the BIOS during a system boot.
![]() | Booting when a BIOS Password is Set |
|---|---|
If a system host has been set up with a boot password, the host will not boot up unattended (e.g. a system reboot, power failure, etc.). This is the trade-off/risk. | |
Linux boot loaders, like GRUB (used by default in SUSE Linux Enterprise Server) and LILO (optional), can also have a boot passwords set. LILO has the password and restricted settings. The password setting requires a password at boot time, and the restricted setting requires a boot-time password only if you specify different boot options (such as single ) at the LILO prompt.
GRUB also provides a “password” feature, so that only administrators can start the interactive operations (i.e. editing menu entries and entering the command-line interface). If a password is specified, GRUB will disallow any interactive control until you press the key P or E and enter a correct password.
You can refer to the GRUB and LILO man pages for examples.
It is very important to keep in mind that when setting these passwords they will obviously need to be remembered! Also, enabling these passwords might merely slow an intrusion, not necessarily prevent it. Again, someone could boot from a floppy, and mount your root partition. If you are using BIOS-level security as well as a boot loader, it is a good practice to disable the ability to boot from floppy or other devices in your computer's BIOS, and then also password-protecting the BIOS itself.
Also keep in mind that the boot loader config files will need to be
protected by changing their mode to 600 (read/write
for root only), or others will be able to read your passwords or
hashes!
Verifying Security Action ItemsIt is highly recommended to have scripts in place which can verify that security actions or procedures have been run. Even the best systems administrators can make errors or forget something. If you have a small or large Linux installation or environment, you should consider the use of the seccheck scripts.
Seccheck is the SUSE Security Checker. It is a set of several
shellscripts designed to check the local security of the system on a
regular basis. There are three main scripts that are executed at
different time intervals. They are security-daily,
security-weekly and
security-monthly. At installation these scripts all
have schedule entries that get placed in cron that determine when they
run. Although cron scheduling is the default behavior, this can be
controlled via configuration settings (see next section). The daily
script runs at midnight, and if changes are detected since the last run
(the night before), an email noting the differences will be sent. The
weekly script runs every Monday at 1:00am, and only if changes to the
last run (the week before) are found, a mail with the differences will
be sent. The monthly script runs every on every 1st of the month and
sends the full last daily and weekly report via email.
Please note that you can change the receiver of the seccheck mails
from root to anyone else if you add an entry like this one to
/etc/sysconfig/seccheck:
SECCHK_USER="firewall" # exchange firewall is an admin user's account name
Please also note that the START_SECCHK variable from
/etc/sysconfig/seccheck controls whether the
security check will be run from cron. (It's ignored, if you call
security-control manually.)
The following daily checks are done:
|
|
length/number/contents of fields, accounts with same uid accounts with uid/gid of 0 or 1 beside root and bin |
|
|
length/number/contents of fields, accounts with no password |
|
|
length/number/contents of fields |
|
user root checks |
secure umask and |
|
|
checks if important system users are put there |
|
|
checks for mail aliases which execute programs |
|
|
checks if users' |
|
homedirectory |
checks if homedirectories are writable or owned by someone else |
|
dot-files check |
checks many dot-files in the homedirectories if they are writable or owned by someone else |
|
mailbox check |
checks if user mailboxes are owned by user and unreadable |
|
NFS export check |
exports should not be exported globaly |
|
NFS import check |
NFS mounts should have the |
|
promisc check |
checks if network cards are in promiscious mode |
|
list modules |
just lists loaded modules |
|
list sockets |
just lists open ports |
|
Weekly Checks are as follows: | |
|
password check |
runs john to crack the password file, user will get an email notice to change his password asap |
|
rpm md5 check |
checks for changed files via rpm's md5 checksum feature |
|
suid/sgid check |
lists all suid and sgid files |
|
exec group write |
lists all executables which are group/world writeable |
|
writable check |
lists all files which are world writable (incl. Above) |
|
device check |
lists all devices |
![]() | |
For the weekly seccheck password check to work the “john the ripper” package needs to be installed yet could be considered a security risk in itself. It's important to understand the operation of john. Normally it will be used only to send notice of weak passwords to users as an email as part of the weekly seccheck cron job. Since “john” would need to be installed separately, it is recommended to weigh the benefits and risks before doing so. | |
Additional monthly checks are also run, however the key difference is mainly that the monthly file is not a “diff” like the daily/weekly ones but the full reports in one file.
Security policies usually contain some procedures for the treatment of storage media that is going to be retired or disposed of. Disk and media “wipe” procedures are frequently prescribed as is complete destruction of the media. You can find several free tools on the internet. A search of “dod disk wipe utility” - will yield several variants. To retire servers with sensitive data, it is important to ensure that data cannot be recovered from the hard disks. To ensure that all traces of data are removed, a wipe utility can be used. Some of these tools can even be operated from a floppy disk (bootable) and remove data according to the U.S. Department of Defense (DoD) standards. Note that many government agencies specify their own standards for data security. Some standards are stronger than others, yet may require more time to implement. “DiskSanitizer” is just one of many that you can find. This utility is shareware and available to download at http://freshmeat.net/projects/disksanitizer.
If your system gets compromised, your backups become invaluable. But also in cases like bugs, accidents etc. backups can be used to compare you current system against your backed-up system. For production systems it is very important to take some Backups offsite for cases like disasters (e.g. offsite storage of tapes/recordable media, or offsite initiated).
For legal reasons, some firms and organizations must be careful about backing up too much information and holding it too long. If your environment has a policy regarding the destruction of old paper files, you might have to extend this policy to Linux backup tapes as well.
Servers should have separate partitions for at least
/, /boot,
/usr, /var,
/tmp, and /home. You don't
want that e.g. logging and temporary space under
/var and /tmp fill up the
root partition. Third party applications should be on separate
filesystems as well, e.g. under /opt.
Review Part I, “ and Common Criteria”. To repeat: It is important
to understand the need to separate the partitions that could impact a
running system (for example, log files filling up
/var/log are a good reason to separate
/var from the / partition).
Another thing to keep in mind is that you will likely need to leverage
LVM or another volume manager or at the very least the
“extended” partition type to allow for the primary
partition limitations (4 partitions).
Another capability in SUSE Linux Enterprise Server is encrypting a partition or even a single folder or file as a container. Please refer to Chapter 11, Encrypting Partitions and Files (↑Security Guide) for details.
We won't cover iptables in explicit detail in this guide. Most companies use hardware based firewalls to protect their servers in a production network, which is strongly recommended for secure environments. However, SUSE Linux Enterprise Server includes the SUSE-Firewall which is a wrapper for iptables and is enabled by default as a simple and layered protection.
If you are also interested in Linux stateful firewalls using iptables, there are several HOWTOs on the internet. See the Appendix for resources. For lots of iptables tutorials and examples, see http://www.linuxguruz.com/iptables/. An overview is also available at Section “Packet Filtering with iptables” (Chapter 15, Masquerading and Firewalls, ↑Security Guide).
The following list shows tunable kernel parameters you can use to
secure your Linux server against attacks. Some of them are defaults
already within the SLE distributions. To check the current status of
any of these settings, you can query the kernel
(/proc/sys/... contents). For example, the Source
Routing setting is located in the
/proc/sys/net/ipv4/conf/all/accept_source_route
file. Simply cat the contents of a file to see how the current running
kernel is setup.
For each tunable kernel parameter shown, the change to the entry that
needs to be affected can be modified or added to the
/etc/sysctl.conf configuration file to make the
change persistent after a reboots.
You can get a list of current kernel settings by using the command:
sysctl -a
It is even a very good idea to store the output of the kernel settings (for comparison or reference) by redirecting the output of the sysctl command to a file, e.g.
sysctl -A > /root/sysctl.settings.store
Because SUSE Linux Enterprise Server includes, by default, security-focused kernel
tuning parameters, you will find the existing
/etc/sysctl.conf file to be sparsely populated.
You may choose to use the above mentioned “catalog” method
of storing the complete gamut of kernel settings and then
pick-and-choose those parameters you want to be reset at reboot. You
can place these in the /etc/sysctl.conf file or
they can be inserted immediately (into the running kernel) by running
the command sysctl -p or they will
be picked up upon a reboot.
Many third party applications like Oracle, SAP, DB2, Websphere, etc. recommend changing kernel parameters to ensure high performance for I/O or CPU processing. Having a full list of current settings can be helpful for reference.
A “SYN Attack” is a denial of service attack that
consumes all the resources on a machine. Any server that is connected
to a network is potentially subject to this attack. To enable TCP SYN
Cookie Protection, edit the /etc/sysctl.conf file
and ensure the following line and value exists:
net.ipv4.tcp_syncookies = 1
Source Routing is used to specify a path or route through the network from source to destination. This feature can be used by network people for diagnosing problems. However, if an intruder was able to send a source routed packet into the network, then he could intercept the replies and your server might not know that it's not communicating with a trusted server.
net.ipv4.conf.all.accept_source_route = 0
ICMP redirects are used by routers to tell the server that there is a
better path to other networks than the one chosen by the server.
However, an intruder could potentially use ICMP redirect packets to
alter the hosts's routing table by causing traffic to use a path you
didn't intend. To disable ICMP Redirect Acceptance, edit the
/etc/sysctl.conf file and add the following line:
net.ipv4.conf.all.accept_redirects = 0
IP spoofing is a technique where an intruder sends out packets which claim to be from another host by manipulating the source address. IP spoofing is very often used for denial of service attacks. For more information on IP Spoofing, I recommend the article IP Spoofing: Understanding the basics.
net.ipv4.conf.all.rp_filter = 1
If you want or need Linux to ignore ping requests,
edit the /etc/sysctl.conf file and add the
following line:
net.ipv4.icmp_echo_ignore_all = 1
This cannot be done in many environments, as even some monitoring systems use a rudimentary ICMP (ping) to determine the health of the device on the network (or at least its ability to respond).
If you want or need Linux to ignore broadcast requests...
net.ipv4.icmp_echo_ignore_broadcasts = 1
To alert you about bad error messages in the network...
net.ipv4.icmp_ignore_bogus_error_responses = 1
To turn on logging for Spoofed Packets, Source Routed Packets, and
Redirect Packets, edit the /etc/sysctl.conf file
and add the following line:
net.ipv4.conf.all.log_martians = 1
![]() | |
ue to the way SUSE Linux Enterprise Server is setup (with syslog) for network event tracking, keep in mind that this may cause a large amount of messages to be logged. | |
Starting with the 2.6.x kernel releases Linux now uses address-space randomization technique to mitigate buffer overflows. For more information, see
Included with SUSE Linux Enterprise Server, AppArmor is an application security tool designed to provide an easy-to-use security framework for your applications. AppArmor proactively protects the operating system and applications from external or internal threats, even zero-day attacks, by enforcing good behavior and preventing even unknown application flaws from being exploited. AppArmor security policies, called "profiles", completely define what system resources individual applications can access, and with what privileges. A number of default profiles are included with AppArmor, and using a combination of advanced static analysis and learning-based tools, AppArmor profiles for even very complex applications can be deployed successfully in a matter of hours.
AppArmor consists of:
a kernel module, shipped with the SUSE Linux kernel, which enforces the security profiles.
a collection of RPMs, also shipped with SUSE Linux, that provide:
a set of AppArmor profiles for numerous programs that ship with SUSE Linux Enterprise Server
tools to create and manage new and existing AppArmor profiles
a YaST user interface to manage reports and notification of security events
documentation about the AppArmor tools
It is best to reboot a system after completing installation, so that AppArmor can confine all system daemons.
The AppArmor quick-start and administrative guides are available online here:
http://www.novell.com/documentation/apparmor/
For additional details and step-by-step instructions on the usage and configuration of AppArmor you can also refer to Part “Confining Privileges with AppArmor” (↑Security Guide).
SELinux is an advanced technology for securing Linux systems. Included with “basic enablement” in SUSE Linux Enterprise Server 11, and included with some other distributions by default. Hardening Linux using SELinux technology, on its own, warrants its own security HOWTO and is out of scope for this guide. The SELinux: NSA's Open Source Security Enhanced Linux is very good in regards to SELinux setup and usage. As part of the “basic enablement”, SELinux will not be officially supported, but packages have now been added to SUSE Linux Enterprise Server 11 to enable its usage with minimal effort. While AppArmor is much easier to use and has a similar feature set, knowing both will most certainly be beneficial.
The programs/protocols of FTP, telnet, and rlogin (rsh) are normally vulnerable to eavesdropping, which is one of the main reasons why secure alternatives such as ssh, scp or sftp should be used instead. It is highly recommended not to run the insecure services. Due to the high risk, this guide does not cover these services (other than vsftp). It would also be a good idea (and part of our guidance, see next section) not to have FTP and Telnet server RPMs installed on the system. Note that the EAL 4+ evaluation had vsftp installed. The “vs” stands for “very secure” - which is a differentiator here when compared to normal ftp.
A very important step in securing a Linux system is to determine the primary function(s) or role(s) of the Linux server. Strive for a deterministic and specific view of what is installed and running on the system. Otherwise it can be difficult to understand what needs to be secured and hence securing these Linux systems proactively might prove ineffective. Therefore, it is very critical to look at the default list of software packages and potentially remove any unneeded package(s) or packages that don't comply with your defined security policies.
Doing this will result in a smaller number of packages that may require updates and will certainly simplify maintenance efforts if/when security alerts and/or patches are released. Refer to the note below regarding Novell's efforts around JeOS (Just Enough OS). An example could be, Apache or Samba installed on your system - if you don't use them, remove them. Also, it is generally recommended and a best practice not to have development packages, desktop software packages (e.g. X Server) etc. installed on production servers.
![]() | |
Many 3rd Party vendors like Oracle and IBM have a requirement for both the desktop environment and the development libraries to run some of their installers. Many organizations will create a silent installation (response file) in a dev lab, so this isn't an impact to production security. | |
Also, other packages like FTP and Telnet daemons should not be installed as well unless there is a justified business reason for it (again, ssh, scp or sftp should be used as replacements).
One of the first action items should be to create a Linux image that only contains RPMs needed by the system and applications, and those needed for maintenance and/or troubleshooting purposes. A good approach is to start with a minimum list of RPMs and then add packages as needed. It may be time-consuming but worth the efforts.
![]() | Just Enough Operating System (JeOS) |
|---|---|
To this end, shortly after the release of SUSE Linux Enterprise Server 10 SP2, Novell/SUSE developed a program called the SUSE Appliance Program. Included with this program is component called “JeOS” (pronounced “juice”) which stands for “Just Enough Operating System”. JeOS has a very small footprint and can be built to fit the very specific needs of a system developer. Main uses of JeOS will be for hardware/software appliance or virtual machine development. Key benefits of JeOS are efficiency, higher performance, increased security and simplified management. | |
To generate a list of all installed RPMs - use the following command:
rpm -qa
To retrieve details about a particular RPM (from the RPM itself), run:
rpm -qi package_nameTo check for and report potential conflicts and dependencies when deleting an RPM, run:
rpm -e --test package_nameThis can be very useful, as running the removal command without a “test” can often yield a mass of complaints and require manual recursive dependency hunting.
For information on performing AutoYaST installations and how to build an image, see the AutoYaST documentation at http://www.suse.de/~ug/ for more information. Uwe Gansert keeps the AutoYaST documentation up to date and lists enhancements and differences between shipping versions of AutoYaST on his page.
Building an infrastructure for the purpose of patch management is another very important part of a proactive and secure production Linux environment.
It is recommended to have a written security policy and procedure to handle Linux security updates and issues. For example, a security policy should detail the time frame for assessment, testing, and roll out of patches. Network related security vulnerabilities should get the highest priority and should be addressed immediately within a short time frame. The assessment phase should occur within a testing lab, and initial roll out should occur on development systems first
A separate security log should detail what Linux security notices have been received, when patches have been researched and assessed, when patches have been applied etc.
At this time SUSE releases their patches in three categories, security, recommended and optional. There are a few options that can be used to keep systems patched, up to date and secure. Each individual system can register and then retrieve updates via the Novell Update website using the included YaST tool – YaST Online Update. Novell has also created the Subscription Management Tool (SMT) an efficient way to maintain a local repository of available/released patches/updates/fixes that systems can then pull from (reducing internet traffic). Novell also offers ZENworks Linux Management (ZLM), part of Novell's systems management family of products, specifically for the maintenance, patching, reporting and centralized management of Linux systems, not just SUSE, but other distributions as well.
On a per-server basis, installation of important updates and improvements is possible using the YaST Online Update tool. Current updates for the SUSE Linux Enterprise family are available from the product specific update catalogs containing patches. Installation of updates and improvements is accomplished using YaST and selecting in the Group. All new patches (except the optional ones) that are currently available for your system will already be marked for installation. Clicking will then automatically install these patches.
After installation is complete, click the button. The system will be patched, current and up-to-date.
YaST also offers the possibility to set up an automatic update. Select +. Configure a Daily or a Weekly update. Some patches, such as kernel updates, require user interaction, which would cause the automatic update procedure to stop. Check for the update procedure to proceed automatically.
In this case, run a manual Online Update from time to install patches that require interaction.
When is checked, the patches
are downloaded at the specified time but not installed. They must be
installed manually. The patches are downloaded to the rug cache
directory, /var/cache/zmd/web, by default. Use
the command rug get-prefs cache-directory to get
the current rug cache directory
ZENworks Linux Management lets you install, remove, and roll back software on your Linux devices. This is done through the use of bundles, which are collections of one or more software (RPM) packages. ZENworks automatically resolves dependencies for any software packages it is installing.
When you assign a bundle to a device, it is automatically installed on the device. If you want to give the device's user the choice of whether or not to install a software package, you can use catalogs. A catalog is simply a group of bundles that appears in the ZENworks Linux Management Software Updater client on the device; the user must initiate installation of any of the bundles in the catalog.
ZENworks Linux Management provides a number of policies to help you manage the SUSE Linux Enterprise Desktop, Evolution™ e-mail client, Epiphany Web browser, and several other software applications. Policies enable you to provide consistent operating system and application configuration settings for your devices. You can lock the configuration settings so that users cannot change them.
ZENworks Linux Management includes a service called Preboot Services that enables you to perform tasks on devices before their operating systems boot up. Using Preboot Services, you can automatically or manually do the following to a Linux device when it boots up:
Run scripted installations on the device, such as AutoYaST and kickstart.
Run ZENworks imaging scripts on the device.
Make an image of the device's hard drives and other storage devices.
Restore an image to the device.
Apply an existing image to multiple devices.
Update the device's BIOS.
To accomplish these tasks automatically, there simply needs to be a PXE (Preboot Execution Environment) enabled on device targets, and to have prebootable tasks configured and assigned to the devices . Then, the devices can automatically implement these tasks when they boot. Or, to manually implement the tasks, devices can be configured to require user intervention during bootup.
ZENworks Linux Management provides the ability to use ZENworks Control Center (ZCC) to remotely manage devices by using a graphical Web interface.
ZENworks Linux Management can gather extensive software and hardware inventory for all managed devices, and it also enables you to create and export custom reports.
By combining ZENworks Linux Management capabilities with the Dell OpenManage toolkit capabilities, it is possible to manage Dell PowerEdge servers right out of the box through the entire server life cycle.
The Subscription Management Toolfor SUSE Linux Enterprise goes one step further than the Online Update process by establishing a proxy system with repository and registration targets. This helps customers centrally manage software updates within the firewall on a per-system basis, while maintaining their corporate security policies and regulatory compliance.
The downloadable SMT (http://download.novell.com/index.jsp?product_id=&search=Search&families=&date_range=&keywords=subscription+management+tool&sort_by=&results_per_page=&x=20&y=10) SMT is integrated with Novell Customer Center (http://www.novell.com/customercenter/) and provides a repository and registration target that is synchronized with it. This can be very helpful in tracking entitlements in large deployments. The SMT maintains all the capabilities of Novell Customer Center, while allowing a more secure centralized deployment. It is included with every SUSE Linux Enterprise subscription and is therefore fully supported.
The SMT provides an alternative to the default configuration, which requires opening the firewall to outbound connections for each device to receive updates. That requirement often violates corporate security policies and can be seen as a threat to regulatory compliance by some organizations. Through its integration with Novell Customer Center, the SMT ensures that each device can receive its appropriate updates without the need to open the firewall, and without any redundant bandwidth requirements.
The SMT also enables customers to locally track their SUSE Linux Enterprise devices (i.e., servers, desktops, or Point of Service terminals) throughout their enterprise. Now they can easily determine how many entitlements are in need of renewal at the end of a billing cycle without having to physically walk through the data center to manually update spreadsheets.
The SMT informs the SUSE Linux Enterprise devices of any available software updates. Each device then obtains the required software updates from the SMT. The introduction of the SMT improves the interaction among SUSE Linux Enterprise devices within the network and simplifies how they receive their system updates. The SMT enables an infrastructure for several hundred SUSE Linux Enterprise devices per instance of each installation (depending on the specific utilization profile). This offers more accurate and efficient server tracking.
In a nutshell, the Subscription Management Tool for SUSE Linux Enterprise provides customers with:
Assurance of firewall and regulatory compliance
Reduced bandwidth usage during software updates
Full support under active subscription from Novell
Maintenance of existing customer interface with Novell Customer Center
Accurate server entitlement tracking and effective measurement of subscription usage
Automated process to easily tally entitlement totals (no more spreadsheets!)
Simple installation process that automatically synchronizes server entitlement with Novell Customer Center
Securing a server requires that you know what it is serving; what services are running. Default server installations may have services running that aren't self apparent and open network ports that they are using. So, one of the most important tasks is to detect and close network ports that are not needed. To get a list of listening network ports (TCP and UDP sockets), you can use the netstat service run the following command:
netstat -tulp
Be aware that netstat output can be wider than a default terminal screen. If the screen is too narrow, the options described above will likely cause the output to wrap and be less legible.
Below is an example of output from the above command:
Proto Recv-Q Send-Q Local Foreign State PID/Program
Address Address name
tcp 0 0 *:auth *.* LISTEN 2328/xinetd
tcp 0 0 local[...].:smtp *.* LISTEN 2360/sendmail:acce
tcp 0 0 *:ssh *.* LISTEN 2317/sshdFrom the output above you can see that three tcp-based services are running and listening: xinetd, sendmail, and sshd. Sendmail should not be configured to listen for incoming network connections unless the server running it is a designated as a mail or relay server. Running a port scan from another server will be able to confirm that, but make sure to obtain proper permissions to scan/probe a machine on a production network.
![]() | |
Some organizations consider port scans without permission a security offense. | |
Using the nmap tool, just such a probe/scan can be run:
jupiter:~ # nmap -sTU remote_host
Starting nmap 3.70 ( http://www.insecure.org/nmap/ ) at 2004-12-10 22:51 CST
Interesting ports on venus (192.168.2.101):
(The 3131 ports scanned but not shown below are in state: closed)
PORT STATE SERVICE
22/tcp open ssh
113/tcp open auth
Nmap run completed -- 1 IP address (1 host up) scanned in 221.669 seconds
Note that running the nmap command can take quite a
while (in this example almost 4 minutes) depending on the options used.
If you remove the UDP port scan (leave out the -U
option), then nmap will finish the port scan nearly
immediately. Running it on a local machine will also make it complete
quickly. The results of nmap can vary widely and
might not show all listening network sockets depending on the status of
the SuSEFirewall2 (or other) and if it has been setup to block any
ports.
From the sample run above, you see that the
xinetd daemon is
listening on port auth (port 113) for IDENT (for
more information on this service, see
Section 3.17, “xinetd Services - Disabling”).
You can also see that sendmail is not listening for remote incoming
network connections.
Another method (safer) to list all of the TCP and UDP sockets to which programs are listening (on a host) is to use the lsof command – which lists open files :
jupiter:~ # lsof -i -n | egrep 'COMMAND|LISTEN|UDP' COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME sshd 2317 root 3u IPv6 6579 0t0 TCP *:ssh (LISTEN) xinetd 2328 root 5u IPv4 6698 0t0 TCP *:auth (LISTEN) sendmail 2360 root 3u IPv4 6729 0t0 TCP 127.0.0.1:smtp (LISTEN)
One of the most important tasks is the removal of any network services from a systems startup (init) process that are not needed. On SUSE systems you can list all services which are started at boot time using the following command:
chkconfig -l |grep on
This command will list any service that has been enabled to start at
any of the 7 init levels. 0 through 6 and also S (single user). Notice
there may be quite a few services enabled on a given host, but many
runlevel services (Stand-Alone Services) might not be for network
related services. There are some services that are only run during the
boot process. Make sure NOT to disable any runlevel services that are
needed by the system to run smoothly. For example, many of these type
of services will begin with a prefix of boot.
Some examples of Runlevel System Services which you may or may not want to enable (check YaST module for a complete list):
Table 3.1. init Services and their Descriptions - Examples
|
Service Name |
Description of Service |
|---|---|
|
syslog |
important for syslog services |
|
netfs |
needed only if there are NFS shares that should be mounted at boot time |
|
network |
important for starting network interfaces (e.g. eth0, eth1, bonding,...) |
|
random |
used for the system entropy pool |
|
atd |
needed if the at(1) service is used instead of cron |
|
apmd |
Advanced Power Management (APM) daemon is used for laptops and some desktops |
|
isdn |
needed if ISDN is being used |
|
iptables |
needed if Netfilter (iptables) Firewall is being used |
|
ip6tables |
needed if ip6tables Firewall is being used |
|
pcmcia |
not needed on servers - needed for laptops |
|
irqbalance |
|
|
sendmail |
needed if Sendmail is used - Procmail should be used which is more secure |
|
autofs |
needed if automounter is used - production applications should not be dependent on automounter |
|
sshd |
important for logins via SSH |
|
portmap |
needed if e.g. NFS is being used |
|
nfslock |
needed if NFS shares are mounted |
|
nfs |
|
|
mdmonitor |
needed only if software RAID is being used |
|
crond |
important for running cron jobs |
|
xinetd |
needed if xinetd services are being used, see /etc/xinetd.d/ for list of services |
|
cups |
needed if CUPS is used for the printing system |
|
rhnsd |
needed if server should connect to RHN to check for software updates etc. |
|
sysstat |
needed to reset system statistics logs |
|
audit |
needed only if Linux Audit Subsystem (LAuS) should run for collecting system call audit records |
|
psacct |
needed only if kernel process accounting information is needed |
|
smartd |
important for monitoring disk problems if hard disks support SMART technology |
|
netdump |
|
The init (start/stop) scripts of all the runlevel services are found in
the /etc/init.d directory. For example, if you
don't know what the atd service does, go to
/etc/init.d and open the file
atd. And in the script look for lines that start
programs. In the atd script the
startproc $ATD_BIN $ATD_ARGS line starts the
“process” atd. Now
having the name of the program that is started by this service, you can
check the online pages of atd
by running man atd. This will help you to find out
more about a system service.
To permanently disable e.g. the runlevel service nfs, run:
chkconfig nfs off
To immediately disable the runlevel service nfs, execute:
/etc/init.d/nfs stop
or just: rcnfs stop
xinetd Services - Disabling¶
The xinetd daemon is a
replacement for inetd, the internet services daemon. It monitors the
ports for all network services configured in
/etc/xinetd.d, and starts the services in response
to incoming connections. To check if
xinetd is enabled and
running, execute:
jupiter:~ # chkconfig --list xinetd xinetd 0:off 1:off 2:off 3:on 4:on 5:on 6:off
To check the current status of the
xinetd service, execute:
jupiter:~ # /etc/init.d/xinetd status Checking for service xinetd: xinetd (pid 2619) is running..
or just: rcxinetd status
If xinetd is active, it is very
important to see which services are active and being controlled by
xinetd. The following command
will list all services configured in /etc/xinetd.d
and whether xinetd monitors the
ports for these services:
jupiter:~ # chkconfig --list | awk '/xinetd based services/,/""/'
xinetd based services:
chargen: off
chargen-udp: off
cups-lpd: off
cvs: off
daytime: off
daytime-udp: off
discard: off
discard-udp: off
echo: off
echo-udp: off
netstat: off
rsync: off
sane-port: off
servers: off
services: off
svnserve: off
swat: off
systat: off
tftp: on
time: off
time-udp: off
vnc: off
To get a list of only active services for which xinetd monitors the
ports, you could run (where the -v option of grep does
an inverse-match) :
jupiter:~ # chkconfig --list | awk '/xinetd based services/,/""/' | grep -v off
xinetd based services:
tftp: on
In the above example you can see that the
telnet-server package
is not installed on the system. If the Telnet Server package
telnet-server would be
installed, it would show up on the list whether it's active or not.
Here is an example how to disable a service. Assuming the
tftp service is active,
run the following commands to disable it and to see how the telnet
service entries are being updated:
jupiter:~ # chkconfig -l tftp
xinetd based services:
tftp: on
jupiter:~ # cat /etc/xinetd.d/tftp | grep disable
disable = no
jupiter:~ # chkconfig tftp off
jupiter:~ # chkconfig --list tftp
xinetd based services:
tftp: off
jupiter:~ # cat /etc/xinetd.d/tftp | grep disable
disable = yesFor the tftp service it would be better to remove the package from the system since removal is always safer than just disabling (when possible):
rpm -e tftp
xinetd services¶
It is important to investigate all active
xinetd services and to disable
them (or remove their packages) if they are not needed. To find out
what a service does, here is a viable approach. Using the
tftp service as an
example and assuming its function is unknown and it is listed as an
active service. Execute the following commands:
jupiter:~ # grep " server" /etc/xinetd.d/tftp server = /usr/sbin/in.tftpd server_args = -s /tftpboot
To read the manual:
jupiter:~ # man in.tftpd
TFTPD(8) System Manager's Manual TFTPD(8)
NAME
tftpd - IPv4 Trivial File Transfer Protocol server
SYNOPSIS
in.tftpd [options...] directory...
DESCRIPTION
tftpd is a server for the Trivial File Transfer Protocol.
The TFTP protocol is extensively used to support remote boot-
ing of diskless devices. The server is normally started by
inetd, but can also run standalone.
[...]To determine what package supplies the in.tftpd binary:
jupiter:~ # rpm -qf /usr/sbin/in.tftpd tftp-0.48-101.16
To get a description of tftp and its usage, etc:
jupiter:~ # rpm -qi tftp-0.48-101.16| awk '/Description/,/""/' Description : The Trivial File Transfer Protocol (TFTP) is normally used only for booting diskless workstations and for getting or saving network component configuration files.
To get a list of what files are installed via the tftp package (RPM), execute the rpm command with the following options:
jupiter:~ # rpm -ql tftp-0.48-101.16 /etc/xinetd.d/tftp /usr/bin/tftp /usr/sbin/in.tftpd /usr/share/doc/packages/tftp /usr/share/doc/packages/tftp/README /usr/share/doc/packages/tftp/README.security /usr/share/doc/packages/tftp/sample.rules /usr/share/man/man1/tftp.1.gz /usr/share/man/man8/in.tftpd.8.gz /usr/share/man/man8/tftpd.8.gz
This example described what could be done to find out information
about services (specifically ones started by
xinetd) even if an
online manual didn't exist for the binary
in.ftpd. This example yielded a man page – but
you may not always find one. The RPM commands in the example are very
commonly used for a variety of reasons. It is also possible to use the
YaST software management interface to retrieve all of the resultant
information – however having a knowledge of RPM command syntax can
save quite a bit of time. Again to disable the tftp service, execute
the following command:
chkconfig tftp off
The xinetd daemon is quite
flexible and has many features. Here are just a few functionalities of
xinetd:
Access control for TCP, UDP, and RPC services.
Access limitations based on time.
Provides mechanisms to prevent DoS attacks.
For more specific information on Xinetd, review the documentation and usage examples at the xinetd website: http://www.xinetd.org/ and also for some xinetd usage tutorials: http://www.macsecurity.org/resources/xinetd/tutorial.shtml
The inittab file located in /etc/inittab contains
a running “tab” (table) or list of which processes are to
be started at bootup during normal system operation. Some 3rd party
vendors will install an entry there to ensure the initialization and
startup of dependent services. E.g. Oracle places cluster services
startup entries here to ensure they start at boot time. It is important
to review this file and verify all entries (in the
/etc/inittab) are appropriate in your environment.
It is highly recommended to trap the Ctrl+Alt+Del key sequence in order to
prevent accidental reboots. The following command uses the sed string
processor to find the ca::ctrlaltdel string and add
a # symbol to the front of it. This will comment-out
the whole line – thereby disabling the entry:
sed -i 's/\(ca::ctrlaltdel:\)/#\1/g' /etc/inittab
It is generally recommended to make the default runlevel of a
production system set to “3” - which means, multi-user
with networking but without
graphics. In other words – the X subsystem should not be running. It
uses server compute cycles and is generally not needed. In this case,
it should be removed – if not used. Setting the default runlevel is
normally done via YaST at time of installation – or by using the
tool in YaST. This tool
will set the inittab for you, or you can make the modification manually
(ensuring id:3:initdefault is in the inittab):
jupiter:~ # grep ':initdefault' /etc/inittab id:3:initdefault:
To have changes in /etc/inittab become effective
immediately, you can “tell” init to re-examine the
inititab like this:
telinit q
Reviewing the System Services tool in YaST is a great way to determine what will be started on a system. The tool has a normal and mode. Switch to to see some of the boot services. These can be important for things like multipath, etc.
Normally a firewall is used to protect a server from other servers and
networks – or to protect an environment from the server itself.
However, you can also protect a server or more accurately, an
individual service using a TCP wrapper (which is a function of
xinetd – already
discussed above).
The xinetd super server that
comes with SUSE Linux Enterprise Server provides a built-in TCP wrapper functionality.
This can be utilized to specifically define network services to accept
or deny incoming connections from specified hosts and networks. The TCP
wrappers implements access control through the use of two files,
/etc/hosts.allow and
/etc/hosts.deny. Note that the
hosts.allow file takes precedence over the
hosts.deny file. And you may want to change the
permissions on the two configuration files since they are both world
readable. An important difference between the security provided by a
TCP wrapper vs. the use of netfilter (iptables) – is that netfilter
works at the network layer (layer 2) and can provide security before
the traffic goes up the stack to the application layers. The trade-off
however is that a TCP wrapper allows for the use of a
“banner” - or a welcome message (per service) and some
other things. It is best to know what an organization requires – so
the best recommendation can be made.
Generally, a best-practice strategy is to block all incoming requests
by default, and allow only specific hosts or networks to connect.
Commonly called - “deny-all, permit-few” this is the
strategy that is proposed here. First, edit the
/etc/hosts.deny file and add the following line:
ALL: ALL
Then, in order to accept incoming SSH connections from specific hosts
(e.g. nodes sles-ha1,
sles-ha2 and
sles-ha3, modify the
/etc/hosts.allow file and add the following line:
sshd: sles-ha1 sles-ha2 sles-ha3
To accept incoming SSH connections from all servers from a specific
network, add the name of the subnet to
/etc/hosts.allow. Adjust the entry like this:
sshd: sles-ha1 sles-ha2 sles-ha3 .network.example.com
Remember, each service can be defined separately. In order to accept
incoming portmap connections from the host at IP address
192.168.0.1 and from the subnet
192.168.5, the following modification can be made to
/etc/hosts.allow:
portmap: 192.168.0.1 192.168.5.
To accept connections from all servers on the subnet named
.network.example.com but not from host
badhost.network.example.com, add the following line to the
/etc/hosts.allow file:
ALL: .network.example.com EXCEPT badhost.network.example.com
Here are other examples that show some features of TCP wrapper: If you
just want to restrict ssh connections without configuring or using
/etc/hosts.deny, you can add the following entries
to /etc/hosts.allow:
sshd: rac1cluster rac2cluster rac3cluster sshd: ALL: DENY
The version of TCP wrapper that comes with SUSE Linux Enterprise Server also supports
the extended options documented in the hosts_options
man page. Here is an example how an additional program can be spawned
in e.g. the /etc/hosts.allow file:
sshd: ALL : spawn echo "Login from %c to %s" | mail -s "Login Info for %s" log@loghost
For information on the % expansions, see man hosts_access.
The TCP wrapper is quite flexible. And
xinetd provides its own set of
host-based and time-based access control functions. You can even tell
xinetd to limit the rate of
incoming connections. Various documentations about the
xinetd super daemon on
the Internet and should be considered recommended reading. Just
remember the trade-offs between a TCP wrapper and the SuSEFirewall2
(netfilter/iptables).
Many network services like telnet, rlogin, and rsh are vulnerable to
eavesdropping which is one of several reasons why SSH should be used
instead. The SUSE Linux Enterprise Server default configuration for SSH meets the
security requirements for many environments. However, there are a few
parameters in /etc/ssh/sshd_config that you may
want to change.
The section on Restricting System Access from Servers and Networks shows how direct logins can be disabled for shared and system accounts including root. But it's prudent to disable direct root logins at the SSH level as well.
PermitRootLogin no
Also ensure to have privilege separation enabled where the daemon is split into two parts. With privilege separation a small part of the code runs as root and the rest of the code runs in a chroot jail environment.
UsePrivilegeSeparation yes
Since SSH protocol version 1 is not as secure you may want to limit the protocol to version 2 only:
Protocol 2
You may also want to prevent SSH from setting up TCP port and X11 forwarding if you don't need it:
AllowTcpForwarding no X11Forwarding no
Ensure the StrictModes directive is enabled which checks file
permissions and ownerships of some important files in the user's home
directory like ~/.ssh,
~/.ssh/authorized_keys etc. If any checks fail,
the user won't be able to login.
StrictModes yes
Ensure that all host-based authentications are disabled. These methods should be avoided as primary authentication.
IgnoreRhosts yes HostbasedAuthentication no RhostsRSAAuthentication no
Disable sftp if it's not needed (by commenting it out with the
#):
#Subsystem sftp /usr/lib/misc/sftp-server
After changing any directives make sure to restart the
sshd daemon:
/etc/init.d/sshd restart
Postfix is a replacement for Sendmail and has several security advantages over Sendmail. Postfix is the default mail system in SUSE Linux Enterprise Server and consists of several small programs that each performs their own small task – most of these programs run in a chroot jail. This is another reason why Postfix is recommended over Sendmail.
Linux servers that are not dedicated mail or relay servers should not
accept external emails. However, it is important for production servers
to send local emails to a relay server – some security setups (e.g.
the seccheck scripts) can be configured to send emails to someone other
than root, even off the local system.
Verify the following parameters in
/etc/postfix/main.cf are set to ensure that
Postfix accepts only local emails for delivery (look towards the bottom
of the file as the top portion is mostly commented-out example entries
and explanations):
mydestination = $myhostname, localhost.$mydomain, localhost inet_interfaces = localhost
The mydestination parameter lists all domains to
receive emails for. The inet_interfaces parameter
specifies the network to listen on. After reconfiguring Postfix, a
restart of the mail system is necessary:
rcpostfix restart
Verify that Postfix is still listening for network requests (incoming) by running one of these commands from another host:
nmap -sT -p 25 remote_host
telnet <remote_host> 25![]() | |
Running these commands on the local host will provide inaccurate results since Postfix is supposed to accept connections from the local node – use an external host for correct results. | |
NFS (Network File System) allows servers to share files over a network. But like all network services using NFS involves risks.
Here are some basic rules:
NFS should not be enabled if not needed.
If NFS is truly needed, use a TCP wrapper to restrict. remote access
Ensure to export only to those hosts that really need access.
Use a fully qualified domain name to diminish any spoofing attempts.
Export only as read-only whenever possible.
Use NFS only over TCP.
If you don't have shared directories to export, then ensure that the NFS service is not enabled nor running on the system:
Check the nfs service status:
jupiter:~ # /etc/init.d/nfsserver status Checking for kernel based NFS server: idmapd running mountd unused statd unused nfsd unused
Check the current runlevels:
jupiter:~ # chkconfig -l nfsserver nfsserver 0:off 1:off 2:off 3:off 4:off 5:off 6:off
If NFS must be used, it can be activated using the following commands on SUSE Linux Enterprise Server or more simply and securely with the YaST plugin (ncurses). Access it directly from command line with yast nfs-server or yast nfs-client – or manually:
chkconfig nfs on rcnfs start
Portmapper information:
jupiter:~ # rpcinfo -p server
program vers proto port
100000 2 tcp 111 portmapper
100000 2 udp 111 portmapper
100003 2 udp 2049 nfs
100003 3 udp 2049 nfs
100003 2 tcp 2049 nfs
100003 3 tcp 2049 nfs
100005 1 udp 623 mountd
100005 1 tcp 626 mountd
100005 2 udp 623 mountd
100005 2 tcp 626 mountd
100005 3 udp 623 mountd
100005 3 tcp 626 mountdIf you run it from an "untrusted" server or network, you should get the following output:
jupiter:~ # rpcinfo -p server
No remote programs registered.
To allow a client access to a filesystem or directory, the
/etc/exports serves as the access control list.
To give the network "network.example.com" read-only access to
/pub, the entries in
/etc/exports would look like as follows:
/pub *.network.example.com(ro,sync)
It is very important not to give write access to
NFS clients if not absolutely needed! Entries in
/etc/exports are exported read-only
(ro option) by default. To allow servers
sles-ha1,
sles-ha2 and
sles-ha3 read-write
access to the /data/MYSQL directory, the entries
in /etc/exports would look like as follows:
/data/MYSQL sles-ha1.example.com(rw,sync) sles-ha2.example.com(rw,sync) sles-ha3.example.com(rw,sync)
Note that the options must not be separated from
the host names or networks with whitespace(s). Also, fully qualified
domain names should always be used to diminish
spoofing attempts. All entries in /etc/exports
are exported with the root_squash option (“root
squashing”) by default. This means that a root user on a client
machine does not have root privileges (root access) to root-owned
files on exported NFS filesystems/directories. It is not recommended
to turn “root squashing” off using the
no_root_squash option! After you've made all your
entries in /etc/exports, you can export all
filesystems/directories using the following command:
exportfs -a
To unexport all shared filesystems/directories, run:
exportfs -ua
To see all shared filesystems/directories, run:
jupiter:~ # showmount -e localhost Export list for localhost: /pub *.network.example.com/data/MYSQL sles-ha1.example.com,sles-ha2.example.com,sles-ha3.example.com
If you need NFS, it is recommended to use NFS only over TCP since NFS
over UDP is not secure. All 2.4 and later kernels support NFS over TCP
on the client side. Server support for TCP appears in later 2.4
kernels and beyond.In order to mount a shared directory using NFS over
TCP, it is necessary to use the proto=tcp mount
option:
mount -o proto=tcp server_name:/pub /usr/local/pub
Verify that the target directory, in this case
/usr/local/pub, exists on the client:
jupiter:~ # mount [...] server_name:/pub on
/usr/local/pub type nfs (rw,proto=tcp,addr=192.168.1.110)
To have the shared directory mounted on the client at boot time, use
the /etc/fstab file. For the above example, the
/etc/fstab entry could look like this:
server_name:/pub /usr/local/pub nfs rsize=8192,wsize=8192,timeo=14,intr,tcp 0 0
This example is needed in some cases in order to enable files to be copied over the network using ssh without providing an interactive login prompt. This allows trusted hosts to be set up – an example of federation.
SSH can allow a forced command using the “command” option.
Using this option it is possible to disable scp (secure copy) and
enforce every passed ssh command to be ignored. On the server side
where you want to retrieve the file from, add the following entry to
the beginning of the SSH key in the
~/.ssh/authorized_keys2 file (the
~ represents a particular users
“home” directory – root's home directory is
/root – other users typically reside in
/home/):
username
command="/bin/cat ~/<file_name>" ssh-dss XXXYYYzzZ1122AAbbCC...{etc}
To copy now the file from the remote server, run the following command:
ssh user@server
local_file
Since /bin/cat is run on the server side, its output has to be redirected to the local file.
Another approach is to replace the /bin/cat
(referenced above) with your own script that checks the passed SSH
commands by reading the environment variable
$SSH_ORIGINAL_COMMAND. For example:
#!/bin/ksh
if [[ $SSH_ORIGINAL_COMMAND = "File1" ||
$SSH_ORIGINAL_COMMAND = "File2" ]]
then
/bin/cat $SSH_ORIGINAL_COMMAND
else
echo "Invalid file name!"
exit 1
fi
So you replace the /bin/cat portion with the script
name in ~/.ssh/authorized_keys2, and run the
following command to copy Foo1:
sshuser@serverFoo1 >local_file
To copy Foo 2, run:
sshuser@serverFoo2 >local_file
With the modifications above, every other variety of passed parameters will return errors.
The following sections deal with some of the ways in which the default permissions and file settings can be modified to enhance the security of a host. It is important to note that the use of the default SUSE Linux Enterprise Server utilities like seccheck - can be run to lock down and improve the general file security and user environment. However, it is beneficial to understand how to modify these things.
SUSE Linux Enterprise Server hosts include 3 defaults settings for file permissions:
permissions.easy,
permissions.secure, and
permissions.paranoid, all located in the
/etc directory. The purpose of these files is to
define special permissions, such as world-writable directories or, for
files, the setuser ID bit (programs with the setuser ID bit set do not
run with the permissions of the user that has launched it, but with the
permissions of the file owner, in most cases root).
Administrators can use the file
/etc/permissions.local to add their own settings.
The easiest way to implement one of the default permission rule-sets
above is to use the module in YaST.
Each of the following topics will be modified by a selected rule-set, but the information is important to understand on its own.
The umask (user file-creation mode mask) command is
a shell built-in command which determines the default file permissions
for newly created files. This can be overwritten by system calls but
many programs and utilities make use of umask. By
default, SUSE sets umask to 022.
You can modify this by changing the value in
/etc/profile.
The id command will print out the current user identity information. Example from a non-root prompt:
jupiter:~ > id uid=1000(ne0) gid=100(users) groups=16(dialout),33(video),100(users)
And to determine the active umask – use the umask command:
jupiter:~ > umask 0022
Now for comparison sake – the same commands from the root user:
jupiter:~ # id uid=0(root) gid=0(root) groups=0(root) jupiter:~ # umask 0022
When the SUID (set user ID) or SGID (set group ID) bits are set on an executable, it executes with the UID or GID of the owner of the executable rather than that of the person executing it. This means that, for example, all executables that have the SUID bit set and are owned by root are executed with the UID of root. A good example is the passwd command that allows ordinary users to update the password field in the /etc/shadow file which is owned by root.
But SUID/SGID bits can be misused when the SUID/SGID executable has a security hole. Therefore, you might want to search the entire system for SUID/SGID executables and document it. For example, ensure that code developers don't set SUID/SGID bits on their programs if it's not an absolute requirement. Very often you can use workarounds like removing just the executable bit for world/others. However, a better approach is to change the design of the software if possible.
To search the entire system for SUID or SGID files, you can run the following command:
find / -path /proc -prune -o -type f -perm +6000 -ls
The -prune option in this example is used to skip the
/proc filesystem.
World-writable files are a security risk since it allows anyone to modify them. Additionally, world-writable directories allow anyone to add or delete files. To locate world-writable files and directories, you can use the following command:
find / -path /proc -prune -o -perm -2 ! -type l -ls
The ! -type l parameter skips all symbolic links since
symbolic links are always world-writable. However, this is not a
problem as long as the target of the link is not world-writable, which
is checked by the above find command.
World-Writable directories with sticky bit such as the
/tmp directory do not allow anyone except the
owner of a file to delete or modify it in this directory. The sticky
bit makes files stick to the user who created it and it prevents other
users from deleting and renaming the files. Therefore, depending on the
purpose of the directory world-writable directories with sticky are
usually not an issue. An example is the /tmp
directory:
jupiter:~ > ls -ld /tmp drwxrwxrwt 18 root root 16384 Dec 23 22:20 /tmp
The t mode, which denotes the sticky bit, allows
files to be deleted and renamed only if the user is the owner of this
file or the owner of the directory.
Files not owned by any user or group might not necessarily be a security problem in itself. However, unowned files could pose a security problem in the future. For example, if a new user is created and the new users happens to get the same UID as the unowned files have, then this new user will automatically become the owner of these files.
To locate files not owned by any user or group, use the following command:
find / -path /proc -prune -o -nouser -o -nogroup
It is important that all system and vendor accounts that are not used
for logins are locked.To get a list of unlocked accounts on your
system, you can check for accounts that do not
have an encrypted password string starting with !
or * in the /etc/shadow file.
If you lock an account using passwd
-l, it will put a !! in
front of the encrypted password, effectively disabling the password.
If you lock an account using usermod
-L, it will put a ! in
front of the encrypted password. Many system and shared accounts are
usually locked by default by having a * or
!! in the password field which renders the
encrypted password into an invalid string. Hence, to get a list of all
unlocked (encryptable) accounts, run (egrep is used
to allow use of regular-expressions):
egrep -v '.*:\*|:\!' /etc/shadow | awk -F: '{print $1}'
Also make sure all accounts have a x in the
password field in /etc/passwd. The following
command lists all accounts that do not have a x in
the password field:
grep -v ':x:' /etc/passwd
A x in the password fields means that the password
has been shadowed, i.e. the encrypted password has to be looked up in
the /etc/shadow file. If the password field in
/etc/passwd is empty, then the system will not
lookup the shadow file and it will not prompt the user for a password
at the login prompt.
All system or vendor accounts that are not being used by users, applications, by the system or by daemons should be removed from the system. You can use the following command to find out if there are any files owned by a specific account:
find / -path /proc -prune -o -user account -ls
The -prune option in this example is used to skip the
/proc filesystem. If you are sure that an account can be deleted, you
can remove the account using the following command:
userdel -r account
Without the -r option userdel will not delete the
user's home directory and mail spool
(/var/spool/mail/).
Note that many system accounts have no home directory.
user
root¶
SUSE includes the following entry in the
/etc/inittab file to ensure that a root password
is required for Single User Mode logons:
~~:S:respawn:/sbin/sulogin
![]() | |
This works well and will even restart the sulogin if terminated, but it can be easily circumvented! | |
The GRUB prompt can accept parameters allowing the execution of an
alternate program – like the bash shell (e.g.
init=/bin/bash). This will place you at a root shell
prompt without a password. This further enhances the need to password
protect the GRUB boot loader.
Password expirations are a general best practice—but might need to be excluded for some system and shared accounts (e.g. Oracle, etc). Expiring password on those accounts could lead to system outages if the application account expires.
Typically a corporate policy should be developed that dictates rules/procedures regarding password changes for system and shared accounts. However, normal user account passwords should expire automatically. The following example shows how password expiration can be setup for individual user accounts.
The following files and parameters in the table can be used when a new
account is created with the useradd command.
Settings such as these are stored for each user account in the
/etc/shadow file. If using the YaST tool
() to add users, the
settings are available on a per-user basis. Here are the various
settings—some of which can also be system-wide (e.g. modification
of /etc/login.defs and
/etc/default/useradd):
|
|
|
Maximum number of days a password is valid. |
|
|
|
Minimum number of days before a user can change the password since the last change. |
|
|
|
Number of days when the password change reminder starts. |
|
|
|
Number of days after password expiration that account is disabled. |
|
|
|
Account expiration date in the format YYYY-MM-DD. |
![]() | |
Users created prior to these modifications will not be affected. | |
Ensure that the above parameters are changed in the
/etc/login.defs and
/etc/default/useradd files. Review of the
/etc/shadow file will show how these settings get
stored after adding a user.
To create a new user account, execute the following command:
useradd -c "Test User" -guserstest
The -g option specifies the primary group for this
account:
jupiter:~ # id test
uid=509(test) gid=100(users) groups=100(users)
The settings in /etc/login.defs and
/etc/default/useradd are recorded for the test
user in the /etc/shadow file as follows:
jupiter:~ # grep test /etc/shadow
test:!!:12742:7:60:7:14::Password aging can be modified at any time by use of the chage command. To disable password aging for system and shared accounts, you can run the following chage command:
chage -M 99999 system_account_nameTo get password expiration information:
chage -l system_account_nameFor example:
jupiter:~ # chage -l test
Minimum: 7
Maximum: 60
Warning: 7
Inactive: 14
Last Change: Jan 11, 2011
Password Expires: Mar 12, 2011
Password Inactive: Mar 26, 2011
Account Expires: NeverOn an audited system it is important to restrict people from using simple passwords that can be cracked too easily. However, if the passwords being enforced are too strong, people will write them down. Strong passwords that are written down are not much safer than weak passwords. Some will argue that strong passwords protect you against dictionary attacks and those type of attacks can be defeated by locking accounts after a few failed attempts. However, this is not always an option. If set up like this, locking system accounts could bring down your applications and systems which would be nothing short of a denial of service attack – another issue.
At any rate, it is important to practice effective password management safety. Most companies require that passwords have at the very least a number, another alpha character, and one upper case letter. Policies vary – but maintaining a balance between password strength/complexity and management is sometimes difficult.
Linux-PAM (Pluggable Authentication Modules for Linux) is a suite of shared libraries that enable the local system administrator to choose how applications authenticate users.
It is strongly recommended to familiarize oneself with the capabilities of PAM – and how this architecture can be leveraged to provide the “best” authentication setup for an environment. This configuration can be done once – and implemented across all systems (a standard) or can be enhanced for individual hosts (enhanced security – by host / service / application). The key is to realize how flexible the architecture is and how incredibly flexible it is.
To learn more about the PAM architecture – you can find PAM
documentation on a SUSE Linux Enterprise Server system in the
/usr/share/doc/packages/pam directory (in a
variety of formats).
The following discussions are examples of how to modify the default pam stacks—specifically around password policies—e.g. password strength, password re-use and account locking. While these are only a few of the possibilities, they serve as a good start and demonstrate PAM's flexibility.
SUSE Linux Enterprise Server can leverage the
pam_cracklib library
to test for weak passwords – and to suggest using a stronger one if
it determines obvious weakness. The following parameters represent an
example or policy that could be part of a corporate password policy or
something required due to audit constraints.
The pam libraries follow a defined “flow”—and in most cases, the best way to design the perfect stack is to consider all of the requirements and policies—and draw out a flow chart.
Table 3.2. Sample rules/constraints for password enforcement
|
|
|
Minimum length of password is 8 |
|
|
|
Minimum number of lower case letters is 1 |
|
|
|
Minimum number of upper case letters is 1 |
|
|
|
Minimum number of digits is 1 |
|
|
|
Minimum number of other characters is 1 |
To setup these password restrictions, use the pam-config tool and specify the parameters you want to configure. For example, the minimum length parameter could be modified like this:
pam-config --cracklib-minlen=8
The other parameters are : --cracklib-lcredit=-1,
--cracklib-ucredit=-1,
--cracklib-dcredit=-1, etc.
Now verify that the new password restrictions work for new passwords. Simply login to a non-root account and change the password using the passwd command. Note that the above requirements are not enforced if you run the passwd command under root.
The pam_unix2 module parameter remember can
be used to configure the number of previous passwords that cannot be
reused. And the pam_cracklib module parameter
difok can be used to specify the number of
characters that must be different between the old and the new
password.
The following example describes how to implement password restrictions on a system so that a password cannot be reused for at least 6 months and that at least 3 characters must be different between the old and new password.
Recall that in the section
Section 3.31, “Enabling Password Aging” we set
PASS_MIN_DAYS to 7, which
specifies the minimum number of days allowed between password changes.
Therefore, if pam_unix2 is configured to
remember 26 passwords, then the previously used
passwords cannot be reused for at least 6 months (26*7 days).
Here is an example of an enhanced pam stack. It is possible to edit
the /etc/pam.d/common-auth file to add/change
modules used and how they react. Consider the following
pam_cracklib and
pam_unix2 arguments—keeping in mind how
the pam rules are processed:
auth required pam_env.so
auth sufficient pam_unix2.so likeauth nullok
auth required pam_deny.so
account required pam_unix2.so
account sufficient pam_succeed_if.so uid < 100 quiet
account required pam_permit.so
password requisite pam_cracklib.so retry=3 minlen=8 lcredit=-1
ucredit=-1 dcredit=-1 ocredit=-1 difok=3
password sufficient pam_unix2.so nullok use_authtok md5 shadow
remember=26
password required pam_deny.so
session required pam_limits.so
session required pam_unix2.so![]() | /etc/security/opasswd |
|---|---|
If the /etc/security/opasswd doesn't exist, create the file. jupiter:~ # ls -l /etc/security/opasswd -rw------- 1 root root 0 Dec 8 06:54 /etc/security/opasswd | |
It is not generally recommend that a host automatically locks system and shared accounts after too many failed login or su attempts. This could lead to outages if the application's account gets locked due to too many login failures like in this example for an oracle shared account:
jupiter:~ # su oracle -c id su: incorrect password
This could be an easy target for a denial of service attack. The
following example shows how to lock only individual user accounts
after too many failed su or login attempts. Add the following two
lines to the /etc/pam.d/common-auth:
auth required pam_tally.so onerr=fail no_magic_root
[...]
account required pam_tally.so per_user deny=5 no_magic_root reset
The first added line counts failed login and failed su attempts for
each user. The default location for attempted accesses is recorded in
/var/log/faillog.
The second added line specifies to lock accounts automatically after
5 failed login or su attempts
(deny=5). The counter will be reset to 0 (reset) on
successful entry if
deny= was not exceeded.
But you don't want system or shared accounts to be locked after too
many login failures (denial of service attack).
n
It is also possible to add the
lock_time= parameter,
and then optionally the
nunlock_time= parameter.
For example, setting the nlock_time=60 would deny
access for 60 seconds after a failed attempt. The
unlock_time= option
would then allow access after n seconds after an account has been
locked. If this option is used the user will be locked out for the
specified amount of time after he exceeded his maximum allowed
attempts. Otherwise the account is locked until the lock is removed by
a manual intervention of the system administrator. See the
npam_tally man page for more information.
To exempt system and shared accounts from the
deny= parameter, the
per_user parameter was added to the module. The per_user parameter
instructs the module not to use the
ndeny= limit for
accounts where the maximum number of login failures is set explicitly.
For example:
n
jupiter:~ # faillog -u oracle -m -1
Username Failures Maximum Latest
oracle 0 -1 Fri Dec 10 23:57:55 -0600 2005 on unknown
The faillog command with the option -m -1 has the
effect of not placing a limit on the number of failed
logins—effectively disabling the option. To instruct the module
to activate the deny=
limit for this account again, run:
n
faillog -u oracle -m 0
By default, the maximum number of login failures for each account is
set to zero (0) which instructs pam_tally to leverage the
deny= parameter. To see
failed login attempts, run:
n
faillog
To unlock a locked account (after too many login failures), utilize
the -r option:
faillog -u user -r
Make sure to test these changes (and any changes
– for that matter) thoroughly on your system using ssh and su, and
make sure the root id does not get locked! To lock/unlock
accounts manually, you can run one of the following commands:
passwd -luserusermod -Luser
passwd -uuserusermod -Uuser
Linux allows you to set limits on the amount of system resources that users and groups can consume. This is also very handy if bugs in programs cause them to use up too much resources (e.g. memory leaks), slow down the machine, or even render the system unusable. Incorrect settings can allow programs to use too many resources which may make the server unresponsive to new connections or even local logins (e.g. if a program uses up all available file handles on the host). This can also be a security concern if someone is allowed to consume all system resources and therefore cause a denial of service attack – either unplanned or worse, planned. Setting resource limits for users and groups may be an effective way to protect systems, depending on the environment.
The following example demonstrates the practical usage of setting or
restricting system resource consumption for an Oracle user account.
For a list of system resource settings, see
/etc/security/limits.conf or man
limits.conf.
Most shells like Bash provide control over various resources (e.g. the maximum allowable number of open file descriptors or the maximum number of processes) that are available on a per/user basis. To examine all current limits in the shell execute:
ulimit -a
For more information on ulimit for the Bash shell, examine the bash man pages.
![]() | Setting Limits for SSH Sessions |
|---|---|
Setting "hard" and "soft" limits might not behave as expected when using an SSH session. To see valid behavior it may be necessary to login as root and then su to the id with limits (e.g. oracle in these examples). Resource limits should also work assuming the application has been started automatically during the boot process. It may be necessary to set UsePrivilegeSeparation in /etc/ssh/sshd_config to "no" and restart the SSH daemon (rcsshd restart) if it seems that the changes to resource limits are not working (via SSH). However this is not generally recommended – as it weakens a systems security. | |
In this example, a change to the number of file handles or open files
that the Oracle user can use is made by editing
/etc/security/limits.conf as root making
the following changes:
oracle soft nofile 4096 oracle hard nofile 63536
The “soft” limit in the first line defines the number of
file handles (open files) that the
oracle user will have
after login. If the user sees error messages about running out of file
handles, then the user can increase the number of file handles like in
this example up to the “hard” limit (in this example
63536) by executing:
ulimit -n 63536
You can set the “soft” and “hard” limits higher if necessary.
![]() | |
It is important to be judicious with the usage of ulimits –
allowing a "hard" limit for “nofile” for a user that
equals the kernel limit ( | |
You also need to ensure that pam_limits is
configured in /etc/pam.d/common-auth, or in an
individual service (like SSH, su, login, telnet, etc.) config:
/etc/pam.d/sshd (for SSH) |
/etc/pam.d/su (for su) |
/etc/pam.d/login (local logins and telnet) |
If you don't want to enable it for all logins, there is a specific PAM
module that will read the
/etc/security/limits.conf file. Entries in pam
configuration directives will have entries like:
session required /lib/security/pam_limits.so session required /lib/security/pam_unix.so
It is important to note that changes are not immediate and require a new login session:
jupiter:~ # su – oracle jupiter:~ > ulimit -n 4096
Note that these examples are specific to the Bash shell -
ulimit options are different for other shells. The
default limit for the oracle account is now 4096
and that the oracle user can increase the number of file handles up to
63536 (based on the settings enacted):
jupiter:~ # su – oracle jupiter:~ > ulimit -n 4096 jupiter:~ > ulimit -n 63536 jupiter:~ > ulimit -n 63536
Making this permanent requires the addition of the setting,
ulimit -n 63536, (again, for Bash) to the users
profile (~/.bashrc or
~/.profile file) which is the user startup file
for the Bash shell on SUSE Linux (to verify your shell run: echo
$SHELL). To do this you could simply type (or
copy/paste – if you are reading this on the system) the following
commands for the oracle user's Bash shell:
jupiter:~ # su - oracle jupiter:~ > cat >> ~oracle/.bash_profile << EOF ulimit -n 63536 EOF
In many cases (and after per corporate policy) it is necessary to place a banner on login screens on all servers for legal or audit policy reasons (and to potentially deter intruders) among other things.
If you want to print a legal banner after a user logs in using ssh,
local console etc., you can leverage the /etc/motd
(motd = message of the day) file. The file exists on SUSE – however
it is empty. Simply add content to the file that is applicable/required
by the organization.
![]() | Banner Length |
|---|---|
Try to keep the content to a single page (or less) – as it will scroll the screen if it doesn't fit. | |
For SSH you can edit the “Banner” parameter in the
/etc/ssh/sshd_config file which will then
appropriately display the banner text before the login prompt. For
local console logins you can edit the /etc/issue
file which will display the banner before the login prompt.For GDM you
could make the following changes to require a user to acknowledge the
legal banner by selecting 'Yes' or 'No'. Edit the
/etc/gdm/PreSession/Default file and add the
following lines at the beginning of the script:
if ! gdialog --yesno '\nThis system is classified...\n' 10 10; then
sleep 10
exit 1;
fi
Obviously the This system is classified...
test should be replaced with the valid text – and it is important to
note that this dialog will not prevent a login to progress. The
existence of a “Cancel” button is merely incidental.
Before you place a host into production or even on a network, consider the use of an system integrity checker – like seccheck (already discussed in Section 3.4, “Verifying Security Action with seccheck”)—so in the event of unauthorized changes, notifications can happen. Also consider the use of an intrusion detection environment, like AIDE – the Advanced Intrusion Detection Environment.
AIDE is a GPL licensed and open source intrusion detection system. It could be considered a system “fingerprinting” mechanism. AIDE works by creating a database containing information about the files on your system. The database is created from rules laid out in the configuration file aide.conf. When AIDE is run, this database is referenced to check for changes (or created for the first time). Assuming a comparison check is being run, any changes not permitted by the configuration file are reported.
By leveraging AIDE—storing a copy of the host's database in a secure location—and comparing it (on a scheduled basis or as part of a forensic effort), system integrity/insurance can be a matter of heuristics and procedure. If an intruder compromises your system you the comparison effort will enable an administrator or security officer to know what has changed on the host. The initial database should be created as a final step – before a system gets deployed into production.
It is outside the scope of this article to cover Linux Monitoring and detailed Intrusion Detection systems (IDS) or solutions – however there is a plethora of information of configuring AIDE or other solutions and many informative articles on the web. Also include with the SUSE Linux Enterprise Server distribution is a powerful open source network-intrusion prevention and detection system called Snort.
Here is a list of commands you can use to get data about user logins:
who. Shows a listing of currently logged-in users.
w. Shows who is logged on and what they are doing.
last. Shows a list of last logged-in users, including login time, logout time, login IP address, etc.
lastb.
Same as last, except that by default it shows a
log of the file /var/log/btmp, which contains
all the bad login attempts.
lastlog.
This command reports data maintained in
/var/log/lastlog, which is a record of the last
time a user logged in.
ac.
Prints out the connect time in hours on a per-user basis or daily
basis etc. This command reads /var/log/wtmp.
dump-utmp.
Converts raw data from /var/run/utmp or
/var/log/wtmp into ASCII-parsable format.
Also check the /var/log/messages file.
Finally, the following couple items might not be (specifically) security related, but misconfiguration can cause many problems – and should be reviewed:
Resolver (/etc/hosts,
/etc/resolv.conf,
/etc/nsswitch.conf).
NTP configuration (/etc/ntp.conf).