Saturday, May 1, 2010

Crontab file syntax

Crontab is a file which contains the schedule of cron entries to be run and at specified times.
*     *     *   *    *        command to be executed
-     -     -   -    -
|     |     |   |    |
|     |     |   |    +----- day of week (0 - 6) (Sunday=0)
|     |     |   +------- month (1 - 12)
|     |     +--------- day of month (1 - 31)
|     +----------- hour (0 - 23)
+------------- min (0 - 59)
# 00:30 on 1st of Jan, June & Dec
30    0   1        1,6,12  *
# 8.00 PM every weekday (Mon-Fri) only in Oct 
0     20  *        10      1-5  
# Midnight on 1st ,10th & 15th of month
0     0   1,10,15  *       *
# 12.05,12.10 every Monday & on 10th of every month 
5,10  0   10       *       1  
# Every 2 hours, at 2am, 4am, 6am, and so on
0     */2 *        *       *
You can simply drop your cron schedule file into /etc/cron.d/. Read more about cron here.

Friday, April 30, 2010

Simple apt daily update script

Here is a simple apt update script (file /usr/local/sbin/apt-update):

# Download only; package files are only retrieved, not unpacked or
# installed.
apt-get -dqq update
apt-get -dyqq upgrade
Make this file executable:
chmod +x /usr/local/sbin/apt-update
Run it by cron per schedule (file /usr/local/etc/cron.d/apt-update):
# Regular cron jobs for apt-update

# Run on Sun, Tue, Thu at 2:05 AM
# m h dom mon dow user  command
05 2 * * 0,2,4 root test -x /usr/local/sbin/apt-update && apt-update > $LOG
Let cron know about our scheduled apt-update:
ln -s /usr/local/etc/cron.d/apt-update /etc/cron.d/cron-apt-update

Color Bash Prompt

User root doesn't have colored bash prompt by default, you can enable color prompt by adding the following to /etc/profile.d/
if [ "$BASH" ]; then
    # set a fancy prompt (non-color, unless we know 
    # we "want" color)
    case "$TERM" in
        linux | xterm-color) color_prompt=yes;;

    if [ "$color_prompt" = yes ]; then
        export PS1='\[\033[01;31m\]\h\[\033[00m\]:\
        \[\033[01;34m\]\w\[\033[00m\]\$ '
        export PS1='\h:\w\$ '
    unset color_prompt

alias ls='ls --color=auto'
alias grep='grep --color=auto'
Read more about powerful bash prompts here.

Thursday, April 29, 2010

Suppress kernel talkativness

Kernel log levels (defined in linux/kernel.h):
#define KERN_EMERG    "<0>"  /* system is unusable               */
#define KERN_ALERT    "<1>"  /* action must be taken immediately */
#define KERN_CRIT     "<2>"  /* critical conditions              */
#define KERN_ERR      "<3>"  /* error conditions                 */
#define KERN_WARNING  "<4>"  /* warning conditions               */
#define KERN_NOTICE   "<5>"  /* normal but significant condition */
#define KERN_INFO     "<6>"  /* informational                    */
#define KERN_DEBUG    "<7>"  /* debug-level messages             */
Check the current log level:
deby:~# cat /proc/sys/kernel/printk
7 4 1 7


Ensure you have the following in /etc/sysctl.conf:
# The four values in printk denote: 
# console_loglevel, default_message_loglevel,
# minimum_console_loglevel, default_console_loglevel
# Uncomment the following to stop low-level messages on console
kernel.printk = 4 4 1 6
These changes become effective after reboot. But you might need changes take place immediately:
echo "4 4 1 6" > /proc/sys/kernel/printk


You can pass quiet parameter during kernel boot in /boot/grub/menu.list in order to suppress logs during boot:
kernel /boot/vmlinuz-2.6.26-2-686 root=/dev/sda1 ro quiet panic=0
Please note that after kernel upgrade the above changes to grub will be lost, so take this into account or add another section to your grub loader as shown below.
# Put static boot stanzas before and/or after AUTOMAGIC KERNEL LIST
title    Debian GNU/Linux, kernel 2.6.26-2-686 (quiet)
root     (hd0,0)
kernel   /boot/vmlinuz-2.6.26-2-686 root=/dev/sda1 ro quiet panic=0
initrd   /boot/initrd.img-2.6.26-2-686

## lines between the AUTOMAGIC KERNELS LIST markers will be modified
## by the debian update-grub script except for the default options 
## below

Wednesday, April 28, 2010

Error: Driver 'pcspkr' is already registered, aborting...

If you are experiencing the following complain during the boot (see /var/log/kern.log):
Dec 14 17:08:40 deby kernel: [    5.973561] Error: 
Driver 'pcspkr' is already registered, aborting...
Issue the following command and reboot:
echo 'blacklist snd-pcsp' >> \

Tuesday, April 27, 2010

Timing disk read performance with hdparm

You can benchmark you hard disk performance with hdparm. You need install it first:
apt-get install hdparm
You can perform timings of cache/device reads for benchmark and comparison purposes. For meaningful results, this operation should be repeated 2-3 times on an otherwise inactive system (no other active processes) with at least a couple of megabytes of free memory.
deby:~# hdparm -Tt /dev/sda

 Timing cached reads:   858 MB in  2.00 seconds = 428.78 MB/sec
 Timing buffered disk reads:   60 MB in  3.03 seconds =  19.78 MB/sec
This measurement is essentially an indication of the throughput of the processor, cache, and memory of the system under test, as well as how fast the drive can sustain sequential data reads under Linux, without any filesystem overhead. Read more about this tool here.

Secure network with kernel features

You can configure /etc/sysctl.conf to enable certain kernel options that will help your network be more secure:
# Ignore ICMP broadcasts
net.ipv4.icmp_echo_ignore_broadcasts = 1
# Ignore bogus ICMP errors
net.ipv4.icmp_ignore_bogus_error_responses = 1
# Do not accept ICMP redirects (prevent MITM attacks)
net.ipv4.conf.all.accept_redirects = 0
# Do not send ICMP redirects (we are not a router)
net.ipv4.conf.all.send_redirects = 0
# Do not accept IP source route packets (we are not
# a router)
net.ipv4.conf.all.accept_source_route = 0

Monday, April 26, 2010

Control remote access with pam_access

You need enabled pam_access module first. Uncomment the following line in /etc/pam.d/login and /etc/pam.d/sshd files:
account  required

Secure Administrative Logins

Modify /etc/security/access.conf to disallow remote logins to administrative accounts, disallow local logins to non-administrative account. The order of entries is important:
# Disallow non-root logins on tty1
- : ALL EXCEPT root : tty1
# Allow root login on tty1
+ : root : tty1
# Disallow console logins
# ...
# User "root" should be denied to get access from all 
# other sources
- : root : ALL

Secure Network Logins

Setup a group to control users who can access the system remotely (via ssh).
groupadd -r sshusers
Modify /etc/security/access.conf in order to allow only sshusers group network access.
# Allow group 'sshusers' get access from everythere
+ : (sshusers) : ALL
# All other users should be denied to get access from 
# all sources.
- : ALL : ALL
Add users to group sshusers:
usermod -a -G sshusers user1
The changes take place immediately, you do not have to reboot.

Locking out users with pam_tally

Module pam_tally deny access if too many access attempts fail. Add this line to /etc/pam.d/common-auth to lock the account after 3 failed logins. The accounts will be automatically unlocked after 20 minutes.
# Lock the account after 3 failed logins. The accounts 
# will be automatically unlocked after 20 minutes.
account required deny=3 unlock_time=1200
You can unlock user manually with:
pam_tally --user user1 --reset=0
Read more about this here.

Limit resource usage with pam_limits

To enable PAM limits you need to ensure this line in /etc/pam.d/login and /etc/pam.d/ssh:
session  required /lib/security/
Configuration in /etc/security/limits.conf.

Disable core dumps

Core files can be created when a program crashes. They have been used in security exploits, overwriting system files, or by containing sensitive information (such as passwords).
*               hard    core            0

Maximum data size

Prevent an attacker from trying to fill up the partitions your log files are stored on (10Mb):
@notroot        hard    data            10240

Number of times a user can login

@users          hard    maxlogins       2

Maximum CPU time

This is very useful for preventing run-away processes from eating up all the cpu time (in minutes).
@users          hard    cpu             15

Maximum number of processes

To prevent fork bombs:
*               hard    nproc           75

Maximum memory per process

Here we limiting to 10Mb:
*               hard    rss             10240

Check users in group

The output below shows who is in group users:
deby:~# grep ^users: /etc/group
You can add user to this group:
usermod -a -G users user1
The best way to go with limits is to make them as low as possible, monitor it and increase limits as needed if any.

Get rid of tempfile vulnerabilities with pam_tmpdir

The libpam-tmpdir is a good package to install.
apt-get install libpam-tmpdir
Next you have to do is add the following to /etc/pam.d/common-session:
# Sets $TMPDIR and $TMP for PAM sessions and sets the 
# permissions quite tight. This helps system security 
# by having an extra layer of security, making such 
# symlink attacks and other /tmp based attacks harder 
# or impossible.
session    optional

Enforce password strength-checking policy with pam_cracklib

You can enforce password strength-checking policy by installing libpam-cracklib module.
apt-get install libpam-cracklib
Edit /etc/pam.d/common-password as the following:
# The line below must be commented out
# password required nullok obscure md5

password required retry=3 minlen=8 difok=4
password required use_authtok nullok md5
The cracklib PAM module provides password strength-checking, prompts for a new password with a minimum length of 8 characters, a difference of at least 4 characters from the old password, and allows 3 retries.

Protect su with pam_wheel

You need to add a new group "wheel" to your system.
addgroup --system wheel
Add users that should be able to su to this group.
usermod -a -G wheel user1
Then add the following line to /etc/pam.d/su:
auth requisite group=wheel
Other users will not be able to become root, they will get a denied message if they try to become root.
test1@deby:~$ su -
su: Permission denied
If you want wheel members to be able to su without a password add the following.
auth sufficient group=wheel trust use_uid

Mount EXT3 partitions securely

The ext3 file system has several options you can apply to /etc/fstab. The option nosuid ignores the setuid and setgid bits, noexec forbids execution of any program on that mount point, nodev ignores device files. Having this in mind, here you go:
# /home was on /dev/sda9 during installation
UUID=... /home  ext3 defaults,noatime,nodiratime,nodev,nosuid  0 2
# /tmp was on /dev/sda8 during installation
UUID=... /tmp   ext3    defaults,noatime,nodiratime,nodev,nosuid,noexec  0 2
# /usr was on /dev/sda5 during installation
UUID=... /usr   ext3    defaults,noatime,nodiratime,nodev,ro  0 2
# /var was on /dev/sda6 during installation
UUID=... /var   ext3    defaults,noatime,nodiratime,nodev,noexec,nosuid  0 2
/dev/hda  /cdrom udf,iso9660 user,noauto,ro,nodev,nosuid,noexec 0 0
While you have /usr read-only you need remount it read-write while making the system upgrade.
mount -o remount, rw /usr && mount -o remount, exec /var
apt-get upgrade
Here is a way to remount partions back:
mount -o remount, ro /usr && mount -o remount, noexec /var
Since entering the above command takes some time you soon come up with a script, here they are just in case, file /usr/local/sbin/fs-write:

/bin/mount -o remount,rw /usr || echo 'Failed to remount /usr rw'
/bin/mount -o remount,exec /var || echo 'Failed to remount /var exec'
/bin/mount -o remount,exec /tmp || echo 'Failed to remount /tmp exec'
and /usr/local/sbin/fs-readonly:

/bin/mount -o remount,ro /usr || echo 'Failed to remount /usr ro'
/bin/mount -o remount,noexec /var \
|| echo 'Failed to remount /var noexec'
/bin/mount -o remount,noexec /tmp \
|| echo 'Failed to remount /tmp noexec'
See also this.

Optimize EX3 filesystem performance

Suppose your /etc/fstab looks like this:
/dev/sda1 /     ext3    errors=remount-ro        0 1
/dev/sda9 /home ext3    defaults                 0 2

Turning off atime

If atime is on, every time a file is accessed, whether for read or write, a small change is written to the file detailing the last access time. To disable atime on ext3 partitions:
/dev/sda1 /     ext3  errors=remount-ro,noatime,nodiratime 0 1
/dev/sda9 /home ext3  defaults,noatime,nodiratime 0 2

Disable extended user attributes

Most likely you do not need extended user attributes, so disable them.
/dev/sda9 /home ext3  defaults,noatime,nodiratime,nouser_xattr 0 2

Use journal data writeback

By default journal data ordered option is used. According to this report, you can double read performance. You can simply turn on writeback for any filesystem (but root) by adding data=writeback.
/dev/sda1 /     ext3    errors=remount-ro        0 1
/dev/sda9 /home ext3    defaults,noatime,nodiratime,nouser_xattr,data=writeback 0 2

Journal data writeback for root filesystem

If you try to do this with root (/) filesystem you will get an error message during the boot and the root filesystem remains read-only. Remount it read-write:
mount -n -o remount, rw /
You need setup default filesystem option for root:
deby:~# tune2fs -o journal_data_writeback /dev/sda1
deby:~# tune2fs -l /dev/sda1 | grep 'Default mount option'
Default mount options:    journal_data_writeback
Now you can reboot your system so your changes take effect.

Deactivate barriers

Write barriers enforce proper on-disk ordering of journal commits, making volatile disk write caches safe to use, at some performance penalty. Deactivating barriers make sense if you have battery-backed storage only.
/dev/sda9 /home ext3  defaults,noatime,nodiratime,nouser_xattr,data=writeback,barrier=0 0 2

Avoid buffer heads association

Do not attach buffer_heads to file pagecache. This works together with data writeback option.
/dev/sda9 /home ext3  defaults,noatime,nodiratime,data=writeback,barrier=0,nobh 0 2

Extend commit interval

This options let sync all data and metadata every N seconds. The default value is 5 seconds.
/dev/sda9 /home ext3  defaults,noatime,nodiratime,nouser_xattr,data=writeback,barrier=0,nobh,commit=30 0 2
Have a look at more mount options here. Reboot your computer so all fine tunning take place.

Disable reboot continuously on kernel panic

In order to disable reboot continuously on kernel panic add panic=0 to the kernel boot options in /boot/grub/menu.list:
kernel /boot/vmlinuz-2.6.26-2-686 root=/dev/sda1 ro quiet panic=0

Pretty your GRUB loader

It is pretty easy to change default boot timeout and colors.


Edit the following settings in /boot/grub/grub.cfg:
# Set a timeout, in seconds, before automatically booting 
# the default entry (normally the first entry defined).
timeout  2

# Pretty colours
color  light-blue/black light-cyan/black


Disable graphical terminal /etc/default/grub:
# Uncomment to disable graphical terminal (grub-pc only)
Edit the settings in /etc/grub.d/05_debian_theme:

     # Set the traditional Debian blue theme.
     #echo "${1}set menu_color_normal=cyan/blue"
     #echo "${1}set menu_color_highlight=white/blue"
     echo "${1}set menu_color_normal=light-gray/black"
     echo "${1}set menu_color_highlight=white/black"
Once finished issue the command to regenerate grub config files:

Password-protect the GRUB boot loader

GRUB provide access to a boot loader command prompt. This special command prompt is used to issue commands to override the kernel's boot process for a variety of reasons. From this command prompt a user could issue commands to change the boot process and gain root access. To prevent this you need to password-protect the boot loader's command prompt.

Generate an encrypted password

deby:~# grub-md5-crypt
Retype password:
You will need to replace/ add the following to /boot/grub/menu.lst:
password -md5 $1$97T9Y/$0y1o5CCyci7TPM5SX.2rG0
This way you have locked down interactive editing in GRUB (in this case you would have to press ‘p’ key and enter the correct password to access advanced options).

Lock down specific menu entries

If you want to lock down specific menu entries so that anyone without the knowledge of the correct password cannot boot into that you should add the word lock on a separate line just after the title specification for each entry in the menu.
title     Debian GNU/Linux, kernel 2.6.26-2-686 (single-user mode)
root      (hd0,0)
kernel    /boot/vmlinuz-2.6.26-2-686 root=/dev/sda1 ro single
initrd    /boot/initrd.img-2.6.26-2-686

Secure menu file

By default /boot/grub/menu.lst can be read by everyone:
deby:~# ls -l /boot/grub/menu.lst
-rw-r--r-- 1 root root 3967 2010-04-25 22:57 /boot/grub/menu.lst
Let fix that:
deby:~# chmod o-o /boot/grub/menu.lst
user1@deby:~$ cat /boot/grub/menu.lst
cat: /boot/grub/menu.lst: Permission denied
Read more how to harden GNU/Linux against local intrusions here.

Sunday, April 25, 2010

How to disable a service in Debian

To disable a service ar runlevel 2 (that is default in Debian), rename its script in /etc/rc2.d directory so that the new name begins with a 'K' and a two-digit number, where the number is the difference between the two-digit number following the 'S' in its current name, and 100. To re-enable the service, rename the script back to its original name beginning with 'S'.
mv /etc/rcS.d/S05bootlogd /etc/rcS.d/K95bootlogd
mv /etc/rcS.d/S43portmap /etc/rcS.d/K57portmap
mv /etc/rcS.d/S44nfs-common /etc/rcS.d/K56nfs-common
mv /etc/rcS.d/S70x11-common /etc/rcS.d/K30x11-common

mv /etc/rc2.d/S12acpid /etc/rc2.d/K88acpid
mv /etc/rc2.d/S20nfs-common /etc/rc2.d/K80nfs-common
mv /etc/rc2.d/S20openbsd-inetd /etc/rc2.d/K80openbsd-inetd
mv /etc/rc2.d/S23ntp /etc/rc2.d/K77ntp
mv /etc/rc2.d/S89atd /etc/rc2.d/K11atd
mv /etc/rc2.d/S99stop-bootlogd /etc/rc2.d/K01stop-bootlogd
The other way is to use rcconf or update-rc.d tool
rcconf --off my-service-name
update-rc.d my-service-name disable
Read more about different services here.

Block netbios traffic using iptables

If you already have basic firewall, just add the following:
# ----------- BEGIN OF CUSTOM RULES -----------
# Ignore netbios-ns, netbios-dgm, netbios-ssn, 
# microsoft-ds, bootps, bootpc, epman
-A INPUT -p tcp -m multiport --dports netbios-ns,netbios-dgm,netbios-ssn,microsoft-ds,bootps,bootpc,epman -j DROP
-A INPUT -p udp -m multiport --dports netbios-ns,netbios-dgm,netbios-ssn,microsoft-ds,bootps,bootpc,epman -j DROP

# ------------ END OF CUSTOM RULES ------------
Note: The list of system known ports (as well as known to iptables) is based on file /etc/services. Now you can activate these rules as described here.

Allow ping using iptables

If you already have basic firewall, just add the following:
# ----------- BEGIN OF CUSTOM RULES -----------
# Allow ping
-A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT

# ------------ END OF CUSTOM RULES ------------
Now you can activate these rules as described here.

Allow HTTP/HTTPS traffic with iptables

If you already have basic firewall, just add the following:
# ----------- BEGIN OF CUSTOM RULES -----------
# Allows HTTP and HTTPS connections from anywhere
-A INPUT -p tcp --dport 80 -j ACCEPT
-A INPUT -p tcp --dport 443 -j ACCEPT

# ------------ END OF CUSTOM RULES ------------
Now you can activate these rules as described here.

Port knocking using iptables

The following let you in basic firewall through sequential port knocking to open SSH access for 5 seconds:
# ----------- BEGIN OF CUSTOM RULES -----------
# Note: Knock ports 100,200,300,400 to open SSH port for 5 seconds.
-A INTO-PHASE2 -m recent --name PHASE1 --remove
-A INTO-PHASE2 -m recent --name PHASE2 --set
-A INTO-PHASE2 -j LOG --log-prefix "INTO PHASE2: "
-A INTO-PHASE3 -m recent --name PHASE2 --remove
-A INTO-PHASE3 -m recent --name PHASE3 --set
-A INTO-PHASE3 -j LOG --log-prefix "INTO PHASE3: "
-A INTO-PHASE4 -m recent --name PHASE3 --remove
-A INTO-PHASE4 -m recent --name PHASE4 --set
-A INTO-PHASE4 -j LOG --log-prefix "INTO PHASE4: "

-A INPUT -m recent --name PHASE1 --update

-A INPUT -p tcp --dport 100 -i eth0 -m recent --set --name PHASE1
-A INPUT -p tcp --dport 200 -m recent --rcheck --name PHASE1 -j INTO-PHASE2
-A INPUT -p tcp --dport 300 -m recent --rcheck --name PHASE2 -j INTO-PHASE3
-A INPUT -p tcp --dport 400 -m recent --rcheck --name PHASE3 -j INTO-PHASE4

-A INPUT -p tcp --dport 22 -i eth0 -m recent --rcheck --seconds 5 --name PHASE4 -j ACCEPT

# ------------ END OF CUSTOM RULES ------------
If you are knocking from windows client you can use nmap tool. Download command-line zipfile Add to knockin.cmd:
@echo off
echo Knock in... %1
nmap -PN --host_timeout 1501 --max-retries 0 -p %2 %1 1>&0 2>&0
nmap -PN --host_timeout 1501 --max-retries 0 -p %3 %1 1>&0 2>&0
nmap -PN --host_timeout 1501 --max-retries 0 -p %4 %1 1>&0 2>&0
nmap -PN --host_timeout 1501 --max-retries 0 -p %5 %1 1>&0 2>&0
Run as the following (suppose you are knocking to
C:\Program Files\nmap-5.00>knockin.cmd 100 200 300 400
Right after you issued above command the SSH port remains open for 5 seconds. Use your favorite SSH client to login. Just in case have a look here.

Basic iptables firewall

Here are basic firewall features:
  • allows lo0 traffic
  • accepts established connections
  • allows all outgoing traffic
  • log everything denied.
Place the following into ~/iptables.rules

# Defaults are to DROP anything sent to firewall or internal
# network, permit anything going out.

# Flush all specific rules

# Allows all loopback (lo0) traffic and drop all traffic to 127/8 
# that doesn't use lo0
-A INPUT -i lo -j ACCEPT
-A INPUT -i ! lo -d -j REJECT

# Accepts all established inbound connections

# Allows all outbound traffic
# You could modify this to only allow certain traffic

# ----------- BEGIN OF CUSTOM RULES -----------
# Add your custom rules here, e.g. port knocking, ignore netbios, etc.

# ------------ END OF CUSTOM RULES ------------

# log iptables denied calls (access via 'dmesg' command)
-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7

# Reject all other inbound - default deny unless explicitly 
# allowed policy:

Now you can activate these rules as described here.

Activate iptables rules after reboot

List iptables rules:
iptables -L
Activate rules from file:
iptables-restore < iptables.rules
Save rules:
iptables-save > /etc/iptables.up.rules
These rules need to be restored when the network connection is going up.
touch /etc/network/if-pre-up.d/iptables
chmod +x /etc/network/if-pre-up.d/iptables
Add the following to /etc/network/if-pre-up.d/iptables:
/sbin/iptables-restore < /etc/iptables.up.rules