In this chapter we will cover the following topics:
Using Tripwire for file integrity checking
Using immutable files to prevent modifications
Closing vulnerable network ports and services
Using network security kernel tunables to protect your system
Using TCP wrappers to allow and deny remote connections
Enforcing the use of strong passwords and restricting the use of previous passwords
Restricting direct login and su access
Securing SSH login
The number of security threats related to operating systems and databases are increasing every day, and this trend is expected to continue. Therefore, effective countermeasures to reduce or eliminate these threats must be found and applied. The database administrators and system administrators should strive to maintain a secure and stable environment for the systems they support. The need for securing and ensuring that the database servers are operational is crucial, especially in cases in which we are working with mission critical systems that require uninterrupted access to data stored in Oracle Databases.
In this chapter, we will focus on some operating system security measures to be taken to have a reliable, stable, and secure system. Obviously operating system security is a vast domain and to cover this subject in a few pages is not possible. However, we can briefly describe several key items that can provide a starting point to address some of the concerns we will highlight in our recipes.
Briefly, the possible operating security threats are:
Denial of service
Exploits and vulnerabilities
Backdoors, viruses, and worms
Operating system bugs
Recommendations and guidelines:
Develop a patching policy.
Perform security assessments regularly.
Try to use hard-to-guess passwords.
Disable direct root login and create a special login user. It would be also easier to perform auditing.
Limit the number of users.
Limit the number of users who can issue the
su
command to become the root or oracle owner user.Limit the number of services started, use only the necessary ones.
Limit the number of open ports.
Refrain from using symbolic links whenever possible.
Do not give more permissions to users than is necessary.
Secure
ssh
.Use firewalls.
In these series of recipes for the server environment, we will use the operating system Red Hat Enterprise Linux Server release 6.0 (Santiago) 64-bit version. For the client environment we will use the Fedora 11 update 11 64-bit version. The server hostname will be nodeorcl1
and the client hostname will be nodeorcl5
. All machines used are virtual machines, created with Oracle Virtual Box 4.1.12.
As a preliminary task before we start, prepare the server environment in terms of kernel parameters, directories, users, groups, and software installation as instructed in Oracle® Database Installation Guide 11g Release 2 (11.2) for Linux (http://docs.oracle.com/cd/E11882_01/install.112/e24321/toc.htm). Download and install Oracle Enterprise Edition 11.2.0.3, create a database called HACKDB
, configured with
Enterprise Manager and
Sample Schemas, and define a listener called LISTENER
with a default port of 1521.
Due to the limited page constraints, we will omit the description of each command and their main differences on other Linux distributions or Unix variants. The most important thing to understand is the main concept behind every security measure.
Appropriate file and filesystem permissions are essential in order to ensure the integrity of the files that physically
comprise the database and the Oracle software. We must make sure that we do not grant permissions to other users to write or read data belonging to physical database and configuration files, such as listener.ora
or sqlnet.ora
outside of the oracle owner user. When Automatic Storage Management
(ASM) is used as a storage medium, we also need to ensure that we have the appropriate permissions defined at the exposed raw disks level. Even if these files are not normally seen with OS commands, disks can be compromised by using the dd
command. Another problem may be related to the script or program execution, as power users and attackers may have group-level permissions that would allow them to unexpectedly or intentionally endanger the integrity of the database files.
The alteration of files and directories considered critical in terms of content and permissions could be the first sign of attack or system penetration. In this category we can also add suspect files with SUID and GUID enabled (most rootkits have files with SUID and GUID permissions), world writeable, readable and executable files, and unowned files. One option is to use custom scripts for change detection. In my opinion this is error prone and requires serious development effort. A better option is to use specialized intrusion detection tools that have built-in integrity checking algorithms and real-time alerting capabilities (SNMP traps, e-mail, and sms).
Tripwire is an intrusion detection system (IDS), which is able to take time-based snapshots and compare them in order to check different types of modifications performed on monitored files and directories.
In the following recipe we will use the open source variant of the Tripwire intrusion detection system and demonstrate some of its key capabilities.
All steps will be performed as root user on nodeorcl1
.
As a prerequisite, download the latest version source code of the Tripwire extract and copy it to a directory that will be used for compiling and linking the source code.
Enter in the directory where you have extracted the Tripwire source code, configure and build Tripwire binaries and libraries as follows:
[root@nodeorcl1 tripwire-2.4.2.2-src]# ./configure …………………………………………………… [root@nodeorcl1 tripwire-2.4.2.2-src]# ./make install ……………………………………………………… g++ -O -pipe -Wall -Wno-non-virtual-dtor -L../../lib -o tripwire generatedb.o ………………………………………………………… /usr/bin/install -c -m 644 './twconfig.4' '/usr/local/share/man/man4/twconfig.4' /usr/bin/install -c -m 644 './twpolicy.4' '/usr/local/share/man/man4/twpolicy.4'
During make install phase we will be asked to accept the license agreement and a series of passphrases for generating the site and local key:
…………………………………………………………… LICENSE AGREEMENT for Tripwire(R) 2.4 Open Source Please read the following license agreement. You must accept the agreement to continue installing Tripwire. Press ENTER to view the License Agreement. ……………………………………………………………………………………………………………………… Please type "accept" to indicate your acceptance of this license agreement. [do not accept] accept ………………………………………………………………………………………………………………………………… Continue with installation? [y/n] y (When selecting a passphrase, keep in mind that good passphrases typically have upper and lower case letters, digits and punctuation marks, and are at least 8 characters in length.) Enter the site keyfile passphrase: Verify the site keyfile passphrase: Generating key (this may take several minutes)...Key generation complete. …………………………………………………………………………………………… Enter the local keyfile passphrase: Verify the local keyfile passphrase: Generating key (this may take several minutes)...Key generation complete. ---------------------------------------------- ……………………………………………… [root@nodeorcl1 tripwire-2.4.2.2-src]#
After the installation is complete, initialize Tripwire. At this step, the policy and configuration files will be encrypted and applied. Based on policies and configuration, an initial baseline check will be performed and a database containing the characteristics of monitored files will be built:
[root@nodeorcl1 etc]# tripwire --init Please enter your local passphrase: Parsing policy file: /usr/local/etc/tw.pol Generating the database... *** Processing Unix File System *** ………………………………………… Wrote database file: /usr/local/lib/tripwire/nodeorcl1.twd The database was successfully generated. [root@nodeorcl1 etc]#
After Tripwire will finalize the initialization, we will be able to add our own policies. On Red Hat, by default, the initial policy file,
twpol.txt
, and configuration file,twcfg.txt
, will be located in the/local/usr/etc/tripwire/
directory. For security reasons these files must be deleted. To generate a text-based policy file from the existent policy configuration execute the following command:[root@nodeorcl1 etc]#twadmin --print-polfile > //usr/local/etc//twpolicy.txt [root@nodeorcl1 etc]#
Open and edit the /
local/usr/etc/tripwire/twpolicy.txt
file. In the global section afterHOSTNAME=/nodeorcl1
add theORACLE_HOME
variable as follows:HOSTNAME=nodeorcl1; ORACLE_HOME="/u01/app/oracle/product/11.2.0/dbhome_1";
Add two new rules related to the Oracle software binaries and libraries (all files from
$ORACLE_HOME/bin
and$ORACLE_HOME/lib
) and network configuration files (all files from$ORACLE_HOME/network/admin
). The files from these directories are mostly static; all modifications performed here are usually performed by database administrators (patching, enabling, or disabling an option, such as OVA, OLS, and network settings). In this case theReadOnly
mask summary is appropriate. Add a rule for the directory that contains the Oracle Database files (/u02/HACKDB
). These files change frequently, and the$Dynamic
summary mask should be appropriate here. Add the following three sections at the end of thetwpolicy.txt
file:################################ # Oracle Libraries and Binaries # ################################ ( rulename = "Oracle Binaries and Libraries", severity = 99, ) { $(ORACLE_HOME)/bin -> $(ReadOnly); $(ORACLE_HOME)/lib -> $(ReadOnly); } ##################################### # Oracle Network Configuration Files # ##################################### ( rulename = " Oracle Network Configuration files", severity = 90, ) { $(ORACLE_HOME)/network/admin -> $(ReadOnly); } ########################################## # Oracle Datafiles ########################################## ( rulename="Oracle Datafiles", severity=99, ) { /u02/HACKDB -> $(Dynamic); }
Perform some modifications in
listener.ora
andsqlnet.ora
. Also, we have decided to not use external procedures and external job execution in the future. Therefore as a primary security measure we will move (normally in a production environment you should delete them) these files from$ORACLE_HOME/bin directory
to/extprocjob
directory:[oracle@nodeorcl1 bin]# mv /u01/app/oracle/product/11.2.0/dbhome_1/bin/extproc /extprocjob [oracle@nodeorcl1 bin]# mv /u01/app/oracle/product/11.2.0/dbhome_1/bin/extjob /extprocjob
Next, as root update the Tripwire database using the new updated policy file as follows:
[root@nodeorcl1 etc]# tripwire -m p --secure-mode low /usr/local/etc/twpolicy.txt Parsing policy file: /usr/local/etc/twpol.txt Please enter your local passphrase: Please enter your site passphrase: …………………………………………………………………………… Wrote policy file: /usr/local/etc/tw.pol Wrote database file: /usr/local/lib/tripwire/nodeorcl1.twd [root@nodeorcl1 etc]#
Again, to simulate an intrusion, perform some modifications on
listener.ora
andsqlnet.ora
, change permissions on/u02/HACKDB/users01.dbf
to world readeable, and moveextjob
andextproc
back to$ORACLE_HOME/bin
. Create a file namedha_script
in/home/oracle
with the SUID and GUID bit set and a file with world writeable permissions calledha_wwfile
:[root@nodeorcl1 ~]$ chmod o+r /u02/HACKDB/users01.dbf [root@nodeorcl1 oracle]# touch ha_script [root@nodeorcl1 oracle]# chmod u+s,g+s,u+x ha_script [root@nodeorcl1 oracle]# touch ha_wwfile [root@nodeorcl1 oracle]# chmod o+w ha_wwfile
Next as root, perform an interactive type check to find out the modifications performed on monitored directories and files. The expected values are recorded in the
Expected
column. All modifications are recorded in theObserved
column as follows:[root@nodeorcl1 etc]# tripwire –check --interactive Parsing policy file: /usr/local/etc/tw.pol *** Processing Unix File System *** Performing integrity check... …………………………………………………… ### Continuing... …………………………………………………………………………………………………………………………………………… Remove the "x" from the adjacent box to prevent updating the database with the new values for this object. Added: [x] "/home/oracle/ha_script" [x] "/home/oracle/ha_wwfile" /……………………………………………………………………………………………………………………………………………. Remove the "x" from the adjacent box to prevent updating the database with the new values for this object. Added: [x] "/u01/app/oracle/product/11.2.0/dbhome_1/bin/extproc" [x] "/u01/app/oracle/product/11.2.0/dbhome_1/bin/extjob" Modified: [x] "/u01/app/oracle/product/11.2.0/dbhome_1/bin" ------------------------------------------------------------------------------- Rule Name: Oracle Network Configuration files (/u01/app/oracle/product/11.2.0/dbhome_1/network/admin) Severity Level: 90 ------------------------------------------------------------------------------- Remove the "x" from the adjacent box to prevent updating the database with the new values for this object. Modified: [x] "/u01/app/oracle/product/11.2.0/dbhome_1/network/admin" [x] "/u01/app/oracle/product/11.2.0/dbhome_1/network/admin/listener.ora" [x] "/u01/app/oracle/product/11.2.0/dbhome_1/network/admin/sqlnet.ora" ------------------------------------------------------------------------------- Rule Name: Oracle Datafiles (/u02/HACKDB) Severity Level: 99 ------------------------------------------------------------------------------- Remove the "x" from the adjacent box to prevent updating the database with the new values for this object. Modified: [x] "/u02/HACKDB/users01.dbf" ………………………………………………………………………………………………………………………………… Modified object name: /u02/HACKDB/users01.dbf Property: Expected Observed ------------- ----------- ----------- Object Type Regular File Regular File Device Number 64768 64768 Inode Number 393224 393224 * Mode -rw-r----- -rw-r--r-- Num Links 1 1 UID oracle (501) oracle (501) GID oinstall (502) oinstall (502) …………………………………………………………………………………………………………………………………………………………………………
Also you will find information, visible in the
Observed
column, about the two files added in/home/oracle
:Added Objects: 2 ---------------------------------------- Added object name: /home/oracle/ha_script Property: Expected Observed ------------- ----------- ----------- * Object Type --- Regular File * Device Number --- 64771 * Inode Number --- 262354 * Mode --- -rwsr-lr-- * Num Links --- 1 * UID --- oracle (501) * GID --- oinstall (502) * Size --- 0 * Modify Time --- Sun 23 Sep 2012 10:03:54 PM EEST * Blocks --- 0 * CRC32 --- D///// * MD5 --- DUHYzZjwCyBOmACZjs+EJ+ Added object name: /home/oracle/ha_wwfile Property: Expected Observed ------------- ----------- ----------- * Object Type --- Regular File * Device Number --- 64771 * Inode Number --- 262355 * Mode --- -rw-r--rw- * Num Links --- 1 * UID --- oracle (501) * GID --- oinstall (502) * Size --- 0 * Modify Time --- Sun 23 Sep 2012 10:04:24 PM EEST * Blocks --- 0 * CRC32 --- D///// * MD5 --- DUHYzZjwCyBOmACZjs+EJ+
Note
Downloading the example code
You can download the example code files for all Packt books you have purchased from your account at http://www.PacktPub.com. If you purchased this book elsewhere, you can visit http://www.PacktPub.com/support and register to have the files e-mailed directly to you.
The most appropriate moment to install and perform an initial check for creating a baseline is right after operating system installation. Starting with a clean baseline we will be able to monitor and catch any suspect change performed on files over time. The monitoring performed by Tripwire is based on a policy and compliance model. There are a multitude of parameters or property masks that can be applied on monitored files, based on permission change, checksum, object owner, modification timestamp, and more. A property mask tells Tripwire what change about a file is being monitored. A summary property mask is a collection of property masks. The description of property masks and summary masks can be found in the policy file header.
Print Tripwire configuration file:
[root@nodeorcl1 lib]# twadmin --print-cfgfile ROOT =/usr/local/sbin POLFILE =/usr/local/etc/tw.pol DBFILE =/usr/local/lib/tripwire/$(HOSTNAME).twd REPORTFILE =/usr/local/lib/tripwire/report/$(HOSTNAME)-$(DATE).twr SITEKEYFILE =/usr/local/etc/site.key LOCALKEYFILE =/usr/local/etc/nodeorcl1-local.key EDITOR =/bin/vi LATEPROMPTING =false LOOSEDIRECTORYCHECKING =false MAILNOVIOLATIONS =true EMAILREPORTLEVEL =3 REPORTLEVEL =3 MAILMETHOD =SENDMAIL SYSLOGREPORTING =false MAILPROGRAM =/usr/sbin/sendmail -oi -t
To create or recreate the local and site keys, execute the following:
/ [root@nodeorcl1 lib]# tripwire-setup-keyfiles
To print information about a database entry related to a file or object:
[root@nodeorcl1 lib]# twprint --print-dbfile $ORACLE_HOME/network/admin/listener.ora
To print a generated report:
twprint --print-report –twrfile usr/local/lib/tripwire/report/report_name.txt
To add an e-mail address within a rule for change alert:
########################################## # Oracle Datafiles ########################################## ( rulename="Oracle Datafiles", severity=99, emailto = <your email address> ) { /u02/HACKDB -> $(Dynamic); }
It is a very powerful method to set files as not modifiable even by the root user. Usually configuration files, binaries, and libraries, which are static in nature, are good candidates to set as immutable.
Before you change the file attribute to immutable, be absolutely sure that these files are static and may not cause outages.
For example, to prevent any modification to the Oracle listener configuration file
listener.ora
, modify it as immutable by executing the following command:[root@nodeorcl1 kit]# chattr -V +i /u01/app/oracle/product/11.2.0/dbhome_1/network/admin/listener.ora Flags of /u01/app/oracle/product/11.2.0/dbhome_1/network/admin/listener.ora set as ----i--------
Now the file cannot be modified even by the root user:
[root@nodeorcl1 kit]# echo "" >> /u01/app/oracle/product/11.2.0/dbhome_1/network/admin/listener.ora bash: /u01/app/oracle/product/11.2.0/dbhome_1/network/admin/listener.ora: Permission denied
At this step, we will set a library as immutable. For example, to protect against disabling the Oracle Database Vault option, turn
$ORACLE_HOME/rdbms/lib/libknlopt.a
immutable:chattr -V +i /u01/app/oracle/product/11.2.0/dbhome_1/rdbms/lib/libknlopt.a chattr 1.39 (29-May-2006) Flags of /u01/app/oracle/product/11.2.0/dbhome_1/rdbms/lib/libknlopt.a set as ----i--------
If we try to disable the Oracle Database Vault option, we will receive an
Operation not permitted
message:[oracle@nodeorcl1 lib]$ make -f $ORACLE_HOME/rdbms/lib/ins_rdbms.mk dv_off /usr/bin/ar d /u01/app/oracle/product/11.2.0/dbhome_1/rdbms/lib/libknlopt.a kzvidv.o /usr/bin/ar: unable to rename '/u01/app/oracle/product/11.2.0/dbhome_1/rdbms/lib/libknlopt.a' reason: Operation not permitted make: *** [dv_off] Error 1 [oracle@nodeorcl1 lib]$
To check if a file is immutable we can use the
lattr
command:[root@nodeorcl1 kit]# lsattr /u01/app/oracle/product/11.2.0/dbhome_1/network/admin/listener.ora ----i-------- /u01/app/oracle/product/11.2.0/dbhome_1/network/admin/listener.ora [root@nodeorcl1 kit]#
To disable the immutable flag from
listener.ora
, execute the following command:[root@nodeorcl1 kit]# chattr -V -i /u01/app/oracle/product/11.2.0/dbhome_1/network/admin/listener.ora chattr 1.39 (29-May-2006) Flags of /u01/app/oracle/product/11.2.0/dbhome_1/network/admin/listener.ora set as -------------
The
lsattr
command can be used to check if the immutable flag is on or off:[root@nodeorcl1 kit]# lsattr /u01/app/oracle/product/11.2.0/dbhome_1/network/admin/listener.ora ------------- /u01/app/oracle/product/11.2.0/dbhome_1/network/admin/listener.ora [root@nodeorcl1 kit]#
The immutable flag can be set with the chattr
command using the +i
switch. To disable the immutable flag use –i
. The –V
switch translates to verbose mode. More about the chattr
command can be found in the man
pages.
In this section we will see how we can use lcap
to prevent the root user from changing the immutable attribute. The kernel capabilities modified with lcap
will stay disabled until the system is rebooted.
The lcap
utility can disable some specific kernel capabilities.
Download and install
lcap
:[root@nodeorcl1 kit]# rpm -Uhv lcap-0.0.6-6.2.el5.rf.x86_64.rpm warning: lcap-0.0.6-6.2.el5.rf.x86_64.rpm: Header V3 DSA signature: NOKEY, key ID 6b8d79e6 Preparing... ########################################### [100%] 1:lcap ########################################### [100%] [root@nodeorcl1 kit]#
Disable the possibility to disable or enable immutability for files:
[root@nodeorcl1 kit]# lcap CAP_LINUX_IMMUTABLE [root@nodeorcl1 kit]# chattr -V -i /u01/app/oracle/product/11.2.0/dbhome_1/rdbms/lib/libknlopt.a chattr 1.39 (29-May-2006) Flags of /u01/app/oracle/product/11.2.0/dbhome_1/rdbms/lib/libknlopt.a set as ------------- chattr: Operation not permitted while setting flags on /u01/app/oracle/product/11.2.0/dbhome_1/rdbms/lib/libknlopt.a
In general, a standard operating system setup will install more services than necessary to run a typical Oracle environment. An additional service means a service that we do not really need to run on an Oracle database server. Keep in mind that if there are fewer services that listen, the more it reduces system vulnerabilities and also we will reduce the attacking surface. Most exploits are built upon the vulnerabilities of these services to penetrate the system. In addition, we may reduce the resource consumption that is induced by these additional services.
In this recipe, we will present some commands to find listening ports and active services, including those controlled by the inetd
daemon, followed by an example on how to disable a service.
To find out the listening sockets, issue the following command:
[root@nodeorcl1 ~]# lsof -i -n COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME portmap 1887 rpc 3u IPv4 4472 UDP *:sunrpc portmap 1887 rpc 4u IPv4 4473 TCP *:sunrpc (LISTEN) rpc.statd 1922 root 3u IPv4 4591 UDP *:pkix-3-ca-ra …………………………………………………………………………………………………………………… sshd 2239 root 3u IPv6 6274 TCP *:ssh (LISTEN) sendmail 2280 root 4u IPv4 6426 TCP 127.0.0.1:smtp (LISTEN) [root@nodeorcl1 ~]#
For more concise information about listening ports we can use
nmap
:[root@nodeorcl1 ~]# nmap -sTU nodeorcl1 Starting Nmap 4.11 ( http://www.insecure.org/nmap/ ) at 2012-01-11 23:31 EET mass_dns: warning: Unable to determine any DNS servers. Reverse DNS is disabled. Try using --system-dns or specify valid servers with --dns_servers Interesting ports on nodeorcl1 (127.0.0.1): Not shown: 3158 closed ports PORT STATE SERVICE 22/tcp open ssh 25/tcp open smtp 111/tcp open rpcbind …………………………………………………………………………… 826/udp open|filtered unknown 829/udp open|filtered unknown [root@nodeorcl1 ~]#
To list the active services and their corresponding runlevels, issue the following command:
[root@nodeorcl1 ~]# chkconfig --list | grep on acpid 0:off 1:off 2:on 3:on 4:on 5:on 6:off anacron 0:off 1:off 2:on 3:on 4:on 5:on 6:off ………………………………………………………………………………………………… xinetd 0:off 1:off 2:off 3:on 4:on 5:on 6:off yum-updatesd 0:off 1:off 2:on 3:on 4:on 5:on 6:off [root@nodeorcl1 ~]#
To stop and disable a service, for example
iptables6
, issue the following command:[root@nodeorcl1 ~]# chkconfig ip6tables stop [root@nodeorcl1 ~]# chkconfig ip6tables off
List the current state for the
ip6tables
service (now it has the statusoff
for every runlevel):[root@nodeorcl1 ~]# chkconfig --list | grep ip6tables ip6tables 0:off 1:off 2:off 3:off 4:off 5:off 6:off
To list the
xinetd
controlled services issue the following command:[root@nodeorcl1 ~]# chkconfig --list | awk '/xinetd based services/,/""/' xinetd based services: chargen-dgram: off chargen-stream: off cvs: off ……………………………………………………………………………………………
Related configuration files for every service controlled by
xinetd
are located at/etc/xinetd.d/
. Configuration files have the same name as the service controlled.For example, the content of cvs configuration file,
CVS service
is disabled. To disable axinetd
service modify thedisable
parameter toyes
:[root@nodeorcl1 xinetd.d]# more cvs # default: off # description: The CVS service can record the history of your source \ # files. CVS stores all the versions of a file in a single \ # file in a clever way that only stores the differences \ # between versions. service cvspserver { disable = yes port = 2401 socket_type = stream protocol = tcp wait = no user = root passenv = PATH server = /usr/bin/cvs env = HOME=/var/cvs server_args = -f --allow-root=/var/cvs pserver # bind = 127.0.0.1 }
Almost every service can be configured to start or stop at a particular runlevel. It's good to remember that not every service listens on a port, so it is not representing necessarily the danger of being attacked from outside. Some services can introduce other avoidable problems, such as unnecessary resource consumption or functional bugs.
To avoid time-consuming tasks, such as finding and closing unnecessary services, it is recommended to start with a minimal installation. This conservative approach can help to ensure that optional services are installed and turned on only when they have been determined to be absolutely necessary to enable required functionality.
If you are not using an advanced firewall to protect your system, it is possible to protect it against TCP and UDP protocol-level attacks by setting a list of kernel parameters, or tunables. Most operating systems allow this type of setting for protection against flood attacks, spoof, and ICMP-type attacks.
In this recipe we will enable network protection using kernel tunables. All steps will be performed as root on nodeorcl1
.
All tunables must be added to /etc/sysctl.conf
to be persistent across system reboots.
To enable them immediately execute the following command:
[root@nodeorcl1 xinetd.d]# sysctl –p
All security kernel tunables require restarting the network service to take effect:
[root@nodeorcl1 xinetd.d]# service network restart
The following is the list and description of tunables:
Enable TCP SYN cookie protection: A SYN attack or SYN flood is a form of denial of service attack in which an attacker sends a succession of SYN requests. The main scope of this type of attack is to consume all the resources from a machine and to make it irresponsive to subsequent network traffic by filling up the SYN queue . SYN cookies allow a server to avoid dropping connections when the SYN queue fills up. One well known tool with SYN flood capabilities available on Linux is
hping
, but there are several other free tools that can generate this kind of attack. These days almost all major Linux distributions have this tunable set to1
. To enable TCP SYN cookie protection or SYN flood protection, add the following network tunable to/etc/sysctl.conf
:net.ipv4.tcp_syncookies = 1
More details about TCP SYN cookie attacks can be found at the following link: http://etherealmind.com/tcp-syn-cookies-ddos-defence/
Disable IP source routing: Source routing is a technique whereby an attacker can specify a route through the network from source to destination. This will force the destination host to use the same route as the source packets. To disable IP source routing add the following tunable to
/etc/sysctl.conf
:net.ipv4.conf.all.accept_source_route = 0
Disable ICMP redirect acceptance: ICMP protocol is used by routers to redirect a source host to an alternative better path to other networks. An intruder could potentially redirect the traffic by altering the host's routing table and changing the traffic route. To disable ICMP and redirect acceptance, add the following tunable to
/etc/sysctl.conf
:net.ipv4.conf.all.accept_redirects = 0
Enable IP spoofing protection: IP spoofing is a technique where an intruder conceals his identity by sending out packets that claim to be from another host. The manipulation of packets is made by forging the IP header's address making them appear as though they are sent from a different address. To enable IP spoofing protection add the following tunable:
net.ipv4.conf .all.rp_filter = 1
Ignore ping requests: If you want or need Linux to ignore ping requests, to enable ignoring of ICMP requests, add the following tunable:
net.ipv4.icmp_ echo_ignore_all = 1
To enable logging for spoofed packets, source routed packets, and redirect packets, add the following tunable to
/etc/sysctl.conf
:net.ipv4.conf.all.log_martians = 1
Enable bad error message protection: Bad error messages are usually used in DoS type attacks and are indented to fill up the the filesystems on the disk with useless log messages. To enable bad message protection add the following tunable to
/etc/sysctl.conf
:net.ipv4.icmp_ignore_bogus_error_responses = 1
The protection is activated at kernel level and it is very effective. There are slight differences between Linux distributions but you should find the same parameters that address network protection at kernel level.
Usually these modifications should be tested first. Placing your server behind a properly configured firewall is typically the preferred way to enable these types of protections. However, a database administrator tasked with protecting sensitive data may want to consider kernel-level tunables as a technique that may provide an additional level of protection, or that adds a defensive layer in case of a firewall configuration issue.
By using TCP wrappers you can control the accepting or denying of incoming connections from
specified servers and networks. You may use this capability to protect your network in conjunction with a firewall. In the following recipe, we will allow connections opened through ssh
only from the nodeorcl5
host and deny from all others by using TCP wrappers.
TCP wrappers at host level are
controlled by two files located in the /etc
directory called hosts.allow
and hosts.deny
.
First we will start to deny all incoming connections from all hosts using all services by adding the following line into
/etc/hosts.deny
:# hosts.deny This file describes the names of the hosts which are # *not* allowed to use the local INET services, as decided # by the '/usr/sbin/tcpd' server. # # The portmap line is redundant, but it is left to remind you that # the new secure portmap uses hosts.deny and hosts.allow. In particular # you should know that NFS uses portmap! ALL:ALL ................................................................
In this moment if we try to establish a connection from
nodeorcl5
it will be denied:[oraclient@nodeorcl5 ~]$ ssh -l oracle nodeorcl1 ssh_exchange_identification: Connection closed by remote host [oraclient@nodeorcl5 .ssh]$ ssh -l oracle nodeorcl1 oracle@nodeorcl1's password: Last login: Sun Aug 12 19:47:21 2012 from nodeorcl5 [oracle@nodeorcl1 ~]$
To allow incoming connections only with
ssh
include the following in/etc/hosts.allow
:# # # hosts.allow This file describes the names of the hosts which are # allowed to use the local INET services, as decided # by the '/usr/sbin/tcpd' server. # sshd: nodeorcl5 ……………………………………………………………………………………
All changes to hosts.deny
and hosts.allow
takes immediately in effect; hosts.allow
has precedence over the hosts.deny
file.
The format for rules is composed by a service or daemon, and host name or IP address. In our examples, we denied all services from all hosts and allowed only ssh
connections from nodeorcl5
.
It is essential to establish an effective security policy for Oracle software owner
users. In this recipe we will talk about managing complex password rules that can primarily prevent brute force attacks. Restriction of using previous passwords and too similar passwords is an additional security measure which can be implemented to prevent undesired access into the system.
Password rule checking and restriction of the use of previous passwords is performed by Pluggable Authentication Module, or simply known as PAM, discussed in this recipe. In these days PAM is available and used on all major Linux and Unix distributions. The differences in implementation on these platforms are minimal.
As the user
root
open/etc/pam.d/system-auth
for editing. Modify the line that begins withpassword requisite pam_cracklib.so
, with the following line:password requisite pam_cracklib.so try_first_pass retry=3 minlen=12 lcredit=-2 ucredit=-2 dcredit=-1 ocredit=-1
Save and close the file. At this step you can try to set some weak passwords, such as dictionary-based or very short passwords to verify that the defined rules are enforced.
If the password enforcement rules are working, login as the
oracle
user and change the password to a strong password, such asof24UT()next(1)=2
:[oracle@nodeorcl1 ~]$ passwd Changing password for user oracle. Changing password for oracle (current) UNIX password: New UNIX password: Retype new UNIX password: passwd: all authentication tokens updated successfully.
At this step we will set up the restriction for using previous passwords. First create
/etc/security/opasswd
file and set its permission to600
. This file will retain the used password history for comparisons:[root@nodeorcl1 security]# touch /etc/security/opasswd ; chmod 600 /etc/security/opasswd
Open the
/etc/pam.d/system-auth
file and modify the line added in step 4 by appending thedifok
parameter andremember
parameter at the end of the line beginning withpassword sufficient pam_unix.so
as follows:password requisite pam_cracklib.so try_first_pass retry=3 minlen=12 lcredit=-2 ucredit=-2 dcredit=-1 ocredit=-1 difok=6 password sufficient pam_unix.so md5 shadow nullok try_first_pass use_authtok remember=10
Login as
oracle
and change the password. Try to set the password as the same password used before. The PAM module will detect that the password is unchanged as we can see from the following listing:[oracle@nodeorcl1 ~]$ passwd Changing password for user oracle. Changing password for oracle (current) UNIX password: New UNIX password: Password unchanged New UNIX password
Next, type a password with only two characters, difference. We will get a message that will tell us that the password is too similar to the old one:
[oracle@nodeorcl1 ~]$ passwd Changing password for user oracle. Changing password for oracle (current) UNIX password: New UNIX password: BAD PASSWORD: is too similar to the old one Finally use a strong password (Ty%u60i)R_"Wa?) with more than three different characters as follows: [oracle@nodeorcl1 ~]$ passwd Changing password for user oracle. Changing password for oracle (current) UNIX password: New UNIX password: Retype new UNIX password: passwd: all authentication tokens updated successfully. [oracle@nodeorcl1 ~]$
Note
It is highly recommended to perform security assessments regularly on your system. To check your real password's strength you should try to use a password cracker.
For a list and description of some of the best available password crackers consult http://nrupentheking.blogspot.com/2011/02/best-password-crackers-in-hackers.html.
Some recommendations for generating strong passwords:
-
Strong passwords should contain lowercase, uppercase, special characters (such as@,&,},?, and !), high ASCII code characters (such as
and ♫), or unicode characters (such as ﭏ, and ﭚ).
Divide your password in to more than 2 or 3 groups and use special characters, high ASCII codes, or Unicode characters as delimiters for groups (for example: u6Yi5@My1k!P;m8U where @,!, and ; are delimiters).
Use more than 8 characters; 15-20 is a good number to prevent brute-force attacks. A brute force cracker program will need exponentially more time to break a password directly proportional with the password length.
Do not use more that 40 percent numbers in your password.
Avoid dictionary words.
The Linux PAM module pam_cracklib.so
checks the password against dictionary words and other constraints using minlen
, lcredi
, ucredi
, dcredit
, and ocredit
parameters, which are defined as follows:
To restrict the use of a previous password, the system must save the used passwords to use them for comparison. The file used for storing previous passwords is called opasswd
. In case it does not exist, it must be created in the /etc/security
directory. The restrict enforcement is performed in stacking mode by combining the remember
parameter of the pam_unix.so
module with the
difok
parameter of the pam_cracklib.so
module. The remember
parameter will configure the number of previous passwords that cannot be reused, and difok
is used to specify the number of characters that must be different between the old and the new password.
PAM configuration files on Red Hat Linux and variants are located in /etc/pam.d
directory. The service shares the same name as the application designed to authenticate; for example the PAM configuration file for the su
command is contained in a file with the same name (/etc/pam.d/su
).
Next, we will take a look at the PAM configuration file format. To understand this we will use the line corresponding to the password module modified in this recipe:
password requisite pam_cracklib.so try_first_pass retry=3 minlen=12 lcredit=-2 ucredit=-2 dcredit=-1 ocredit=-1
The first directive is the module type. A brief summary of module types and how PAM enforces the rules is as follows:
The second directive from the PAM configuration files is represented by control flags. These flags tell what to do with the result returned by a module. All PAM modules return a success or failure result when called.
The third directive is the pluggable module. The next parameters represent the arguments passed to the pluggable module.
You can bypass PAM rules for password enforcement as root; hence the passwords to comply with the enforcement rules must be changed by each user.
Download and build John the Ripper from source code as follows:
[root@nodeorcl1 run]# make clean linux-x86-64
Unshadow
/etc/password
and/etc/shadow
into a separate file,/tmp/passwd.db
:[root@nodeorcl1 run]# ./unshadow /etc/passwd /etc/shadow > /tmp/passwd.db
Add the file as an argument and perform a simple password cracking session:
[root@nodeorcl1 run]# ./john /tmp/passwd.db
The weak passwords are found instantaneously:
Loaded 3 password hashes with 3 different salts (FreeBSD MD5 [32/64 X2]) testuser (testuser) root1234 (root) guesses: 3 time: 0:00:00:00 100% (1) c/s: 2150 trying: Root999 - root1234 Use the "--show" option to display all of the cracked passwords reliably [root@nodeorcl1 run]#
On critical systems it is usually considered a bad practice to allow direct remote logins to system users, such as root or other application owners, and shared users, such as oracle
. As a method for better control and from the user audit point of view, it is recommended to create different login users that will be allowed to connect and perform switches (su
) to users considered critical. No other users should be exposed to the external world to allow direct, remote, or local connections.
In this recipe, we will create a group log and a user named loguser1
, and we will disable direct logins for all others.
Create a designated group for users allowed to log in:
[root@nodeorcl1 ~]# groupadd logingrp
Create an user and assign it to
logingrp
group as follows:[root@nodeorcl1 ~]# useradd -g logingrp loginuser1
To disable direct login for all users add the following line to
/etc/pam.d/system-auth
:account required pam_access.so
Uncomment and modify the following line from
/etc/security/access.conf
::ALL EXCEPT logingrp :ALL
All logins excepting users from the
logingrp
group will be denied. If we try to connect fromnodeorcl5
the connection will be closed:[loguser1@nodeorcl5 ~]$ ssh -l oracle nodeorcl1 oracle@nodeorcl1's password: Connection closed by 10.241.132.218 [loguser1@nodeorcl5 ~]$
The connection succeeds as
loginuser1
:[loguser1@nodeorcl5 ~]$ ssh -l loginuser1 nodeorcl1 loguser1@nodeorcl1's password: [loguser1@nodeorcl1 ~]$
To disable the
su
capabilities for all users exemptingloginuser1
, open/etc/pam.d/su
and uncomment the following line as instructed in the file:# Uncomment the following line to require a user to be in the "wheel" group. auth required pam_wheel.so use_uid
At this moment all users that don't belong to the
wheel
group are not allowed to switch to an other user. Addloginuser1
to thewheel
group as follows. In this way the only user that may executesu
command will beloginuser1
:[root@nodeorcl1 etc]# usermod -G wheel loginuser1
If you try to execute an
su
command with theoracle
user, you will getincorrect password
message, and the switch cannot be performed:[oracle@nodeorcl1 ~]$ su - Password: su: incorrect password [oracle@nodeorcl1 ~]$
But as user
loguser1
it succeeds:[loguser1@nodeorcl1 ~]$ su - Password: [root@nodeorcl1 ~]#
These days ssh
login can be considered the de facto method for connecting to remote servers. It is reliable and secure but if it is configured improperly, it can be more of a liability than an asset. In this recipe will change a couple of parameters to secure ssh
and we will set up passwordless connections using public keys.
All the steps from this recipe will be performed on nodeorcl1
as the root user. The remote logins will be performed from nodeorcl5
.
All parameters that will be modified are located in the /etc/sshd_config
configuration file.
Change the default port 22. Most port scanners will identify automatically port 22 with the
ssh
service. Therefore it will be a good idea to change the defaultssh
port:Port 13120
Disable root logins:
PermitRootLogin no
ssh
will check for proper permissions in the user's home. Use strict mode:StrictModes yes
Suppress all host-based authentications. Usually these methods should be avoided as primary authentication:
HostbasedAuthentication no
This parameter is very effective against DoS type attacks. Limit the maximum number of unauthenticated connections and connection attempts:
MaxStartups 10:50:10
Allow just users that belong to a defined group to log in:
AllowGroups logingrp
To make the changes effective, restart the
sshd
service:[root@nodeorcl1 ~]# service sshd restart Stopping sshd: [ OK ] Starting sshd: [ OK ]
After restart, the
sshd
daemon will listen on port 13120:[root@nodeorcl1 ~]# lsof -i -n | grep sshd sshd 14089 root 3u IPv6 55380 TCP *:13120 (LISTEN) [root@nodeorcl1 ~]#
Try to connect from
nodeorcl5
tonodeorcl1
as root. Direct root log ins will be denied:[loguser1@nodeorcl5 ~]$ ssh -l root -p 13120 nodeorcl1 root@nodeorcl1's password: Permission denied, please try again. Permission denied (publickey,gssapi-with-mic).
After any change of configuration parameters, a daemon restart is needed. You can perform the restart in different ways, such as restarting the service or by sending a HUP
(kill -1
) signal to the sshd
daemon process.
Using key authentication instead of using passwords is probably one of the securest methods of authentication. This will suppress definitively any brute force attempt using passwords.
Open the
/etc/ssh/sshd_config
file and disable password authentication by modifying the following parameter:PasswordAuthentication no
Enable key authentication:
RSAAuthentication yes PubkeyAuthentication yes
On the client machine
nodeorcl5
as the userloginuser1
, create a passphase protected public/private key:[loginuser1@nodeorcl5 ~]$ ssh-keygen Generating public/private rsa key pair. Enter file in which to save the key (/home/loginuser1/.ssh/id_rsa): Created directory '/home/loginuser1/.ssh'. Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/loginuser1/.ssh/id_rsa. Your public key has been saved in /home/loginuser1/.ssh/id_rsa.pub. The key fingerprint is: 1b:a2:9f:d5:e8:77:08:1c:b5:6a:6a:29:3e:53:46:a5 loginuser1@nodeorcl5 The key's randomart image is: +--[ RSA 2048]----+ | | | . . | | o . . | | E . . | | ...So | | .o.== | | .o ++... | | +.++ o . | | ..=o .. . | +-----------------+
Now deploy the key on
nodeorcl1
as follows:[loginuser1@nodeorcl5 ~]$ ssh-copy-id '–p 13120 -i .ssh/id_rsa.pub loguser1@nodeorcl1' The authenticity of host 'nodeorcl1 (10.241.132.218)' can't be established. RSA key fingerprint is 34:39:af:94:9a:2e:4b:f8:37:9c:af:27:67:1c:74:2b. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added 'nodeorcl1,10.241.132.218' (RSA) to the list of known hosts. loguser1@nodeorcl1's password: Now try logging into the machine, with "ssh 'loguser1@nodeorcl1'", and check in: .ssh/authorized_keys To make sure we haven't added extra keys that you weren't expecting.
Log in to
nodeorcl1
; you must type the passphrase entered during key creation:loguser1@nodeorcl2:~> ssh loguser1@nodeorcl1 Enter passphrase for key '/home/loguser1/.ssh/id_rsa': [loguser1@nodeorcl1 ~]$
Restart the
sshd
service as follows:[root@nodeorcl1 ~]# service sshd restart Stopping sshd: [ OK ] Starting sshd: [ OK ]