Flirting & love
Now available for free: Free Report Online Profits

Linux

Check Linux books from Amazon

index:

Linux boot sequence

This is what happens when you turn on a Linux-based PC:
  • the BIOS performs a POST (Power On Self Test), then checks installed hw, and then passes the control to the first level boot loader, which is a little program written into the first sector of the boot device. The boot device usually is the hard disk and the first sector is called MBR (Master Boot Record). MBR contains both the first level boot loader (which is passed the control to by the BIOS) *and* the partitioning information of the hard disk
  • the MBR first level boot loader calls, in turn, a second level boot loader which is another little program that is used to load into memory the true Operating System. In case more than one OS is installed, the second level boot loader also lets you choose the OS that you want to start. If you don't hit any key in the keyboard the second level boot loader waits a few seconds and then boots the first OS in the list. Usually the list contains only Linux
  • Linux offers two second level boot loaders: lilo and grub. The latter is much more easy to configure because you just need to configure its configuration file (/boot/grub/grub.conf)
  • The second level boot loader does the following:
    • loads the kernel into memory (it stands at /boot/vmlinuz-2.4.x-xx)
    • loads initrd into memory (it is a RAM disk used by the kernel to load any non-compiled driver that is necessary to startup the system; at the end of the job the memory is freed)
  • the kernel is passed the control to by the second level boot loader. The kernel is the core of the OS, and once it is loaded into the memory and has been given the control, Linux is fully operative into the PC
  • the kernel passes the control to /sbin/init, that is in charge for configuring the user environment, and it does the following:
    • calls /etc/rc.d/rc.sysinit, to initialize any dependance that needs to be initialized at system startup
    • calls /etc/inittab, which is a script that defines the runlevels, and also indicates the initial runlevel to start with
    • sets the source library into /etc/rc.d/init.d/functions
    • calls /etc/rc.d/rc.local, which is a script that is executed on entering any runlevel; use this script to add any eventual daemon you want to add at any runlevel

disable vi syntax highlight

  • enabling/disabling syntax highlightning when the editor is opened: syntax on/off
  • prevent coloured syntax highlightning in Perl scripts: find the file perl.vim and rename it (this works fine)

add a job to crontab

  • crontab -e
    
    mm hh * * * /home/.../script.sh
    

ipchains

  • /etc/sysconfig/ipchains:
     
    :input ACCEPT
    :forward DENY
    :output ACCEPT
    -A input   -s 195.110.128.1/32 53 -d 0/0        -p udp     -j ACCEPT
    -A input   -s 62.149.128.4/32  53 -d 0/0        -p udp     -j ACCEPT
    -A input   -s 62.149.132.4/32  53 -d 0/0        -p udp     -j ACCEPT
    -A input   -s 0/0                 -d 0/0   3128 -p tcp     -j ACCEPT -y
    -A input   -s 0/0                 -d 0/0     20 -p tcp     -j ACCEPT -y
    -A input   -s 0/0                 -d 0/0     21 -p tcp     -j ACCEPT -y
    -A input   -s 0/0                 -d 0/0     22 -p tcp     -j ACCEPT -y
    -A input   -s 0/0                 -d 0/0        -i lo      -j ACCEPT
    -A input   -s 0/0                 -d 0/0        -i eth1    -j ACCEPT
    -A input   -s 0/0                 -d 0/0        -p tcp     -j REJECT -y
    -A input   -s 0/0                 -d 0/0        -p udp     -j REJECT
    -A forward -s 0/0                 -d 0/0     80 -p tcp     -j DENY
    -A forward -s 192.168.0.0/24      -d 0/0                   -j MASQ
    

common daemons

  • httpd: /etc/rc.d/init.d/httpd start
  • httpd: /usr/local/apache/bin/apachectl start (rel. 1.3.33)
  • mysqld: /etc/rc.d/init.d/mysqld start
  • ipchains: /etc/rc.d/init.d/ipchains start
  • network configuration /etc/rc.d/init.d/network start
To have them automatically start at startup, if they don't, add the corresponding lines in this file: /etc/rc.d/rc3.d/S99local.

host name resolution

Linux uses the /etc/hosts file to resolve the IPs that have been defined there. Add as many IPs as you want. Each line starts with one IP, then the name follows, and finally one or more aliases. In the example below www is an alias for www.mydomain.it.

#/etc/hosts
127.0.0.1       localhost.localdomain   localhost
195.110.140.75  www.mydomain.it         www
231.144.0.23    orion
192.168.0.1     spacecalf               spacecalf.mydomain.it
192.168.0.233   neptune
192.168.0.234   jupiter
Linux also uses the /etc/resolv.conf file to resolve IPs. This file contains one or more DNS IPs, and the name resolution is performed by the listed DNS. Be sure to supply at least one valid DNS IP, differently many network services will fail (for example squid will refuse to start).

#/etc/resolv.conf
nameserver 195.110.128.1
nameserver 197.128.140.22
The file /etc/host.conf tells Linux to search /etc/hosts before using the DNS services listed into /etc/resolv.conf:

#/etc/host.conf
order hosts,bind          
multi on                
(bind is the name server daemon). multi on means "return more than one result if there are aliases" (a host can have several IP numbers, and an IP number can have several host names; this option should always be turned on; most applications use only the first value returned).

network

 
#/etc/sysconfig/network
NETWORKING=yes
HOSTNAME="www.mydomain.it"
GATEWAY="195.110.140.65"   // this is the default route
GATEWAYDEV="eth0"
FORWARD_IPV4="no"

NIC configuration file

/etc/sysconfig/network-scripts/ifcfg-eth0
 
DEVICE=eth0
BOOTPROTO=static
IPADDR=80.183.250.18
NETMASK=255.255.255.248
ONBOOT=yes
/etc/sysconfig/network-scripts/ifcfg-eth1
 
DEVICE=eth1
IPADDR=192.168.0.1
NETMASK=255.255.255.0
ONBOOT=yes

 

PPP

PPP configuration file:

#/etc/ppp/options
demand                      // will use DialOnDemand
idle 120                    // drop connection after 120s idle
ipcp-accept-remote          // the ISP gives a dynamic IP (overrides any dafault)
ipcp-accept-local
lock                        // prevents anything else accessing the modem or terminal adapter
noauth                      // no need for ISP to authenticate itself
defaultroute                // sets this connection as the default route to the Internet
user 
remotename ppp0
/dev/modem 115200           // max transfer rate through serial port
crtscts                     // hardware flow control
connect 'usr/sbin/chat -f /etc/sysconfig/network-scripts/chat-ppp0'
The last line points to a chat script that tells pppd howto to dial. The script might look like this:

'ABORT' 'BUSY'
'ABORT' 'ERROR'
'ABORT' 'NO CARRIER'
'ABORT' 'NO DIALTONE'
'ABORT' 'Invalid Login'
'ABORT' 'Login Incorrect'
'' 'ATZ'
'OK' 'ATDI
'CONNECT' ''
'TIMEOUT' '5'
'~__' ''

Standard dynamic HTML page

Skeleton:

#!/usr/bin/perl -w
 
# INIZIALIZATION
  use strict;
  use diagnostics;
  use DBI;
  my $single_quote = "\'";
  my $double_quote = "\"";
 
# RECEIVING VARIABLES (POST or GET)
  my $buffer = '';
  my %FORM;
  if ( $ENV{ 'REQUEST_METHOD' } eq 'GET' )
     {
       $buffer = $ENV{ 'QUERY_STRING' };
     }
  if ( $ENV{ 'REQUEST_METHOD' } eq 'POST' )
     {
       read ( STDIN, $buffer, $ENV{ 'CONTENT_LENGTH' } );
     }
  my @pairs = split ( /&/, $buffer );
  foreach my $pair ( @pairs )
     {
       my ( $name, $value ) = split ( /=/, $pair );
       $value =~ tr/+/ /;
       $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
       $FORM{ $name } = $value;
     }

# START HTML
  print qq |Expires: 0\n|;
  print qq |Content-type: text/html\n\n|;
  print qq |<html>|;
  print qq |< ---------- HEAD ---------- >|;
  print qq |<head>|;
  print qq |<title>PAGE TITLE<title>|;
  print qq |<script launguage=JavaScript>|;
  print qq |function my_js_function ( args ) {|;
  print qq |  ...|;
  print qq |}|;
  print qq |</script>|;
  print qq |</head>|;
  print qq |< -------- END HEAD -------- >|;
  print qq |< ---------- BODY ---------- >|;
  print qq |<body bgcolor=FFFFFF onload='my_js_function ( args );' |;
  print qq |topmargin='0' leftmargin='0' marginheight='0' marginwidth='0' |;
  print qq |link=0055bb alink=0066aa vlink=003355>|;

# PUT HERE BODY CONTENTS

# A TABLE
  print qq |<table width=780 border=2 cellpadding=2 cellspacing=2 bordercolor=FFFFFF>|;
  # first row
  print qq |  <tr colspan=2>|;
  print qq |    <td>|;
  print qq |      ...|;
  print qq |    </td>|;
  print qq |  </tr>|;
  # second row
  print qq |  <tr>|;
  print qq |    <td>|;
  print qq |      ...|;
  print qq |    </td>|;
  print qq |    <td>|;
  print qq |      ...|;
  print qq |    </td>|;
  print qq |  </tr>|;
  # third row
  print qq |  <tr>|;
  print qq |    <td>|;
  print qq |      ...|;
  print qq |    </td>|;
  print qq |    <td>|;
  print qq |      ...|;
  print qq |    </td>|;
  print qq |  </tr>|;
  print qq |</table>|;

# END HTML
  print qq |</body>|;
  print qq |< -------- END BODY -------- >|;
  print qq |</html> |;
  exit;

Perl & MySQL

Connecting to the database:

my ( $dbh, $sth, $rv, %RECORD );
$dbh = DBI -> connect ( 'dbi:mysql:DATABASENAME', 'username', 'password' )
              or die 'Could not open DATABASENAME';
Disonnecting from the database:

$dbh -> disconnect;
Query a table and fetch a couple of fields:

$query = "SELECT field_1, field_2 FROM table WHERE search_clause";
$sth = $dbh -> prepare ( $query ) or die "\r\n $dbh -> errstr";
$rv = $sth -> execute;
if ( $rv == 0 )
   {
     $alert = "Empty set.";
   }
else
   {
     while ( ( $field_1, $_field_2 ) = $sth -> fetchrow_array )
        {
          # substitutions required only when fetching text fields
          $field_1 =~ s/\\'/$single_quote/g;
          $field_1 =~ s/\\"/$double_quote/g;
          do something
        }
   }
Query a table and fetch all fields:

$query = "SELECT * FROM table WHERE search_clause";
$sth = $dbh -> prepare ( $query ) or die "\r\n $dbh -> errstr";
$rv = $sth -> execute;
if ( $rv == 0 )
   {
     $alert = "Empty set.";
   }
else
   {
     while ( $rv > 0 )
        {
          %RECORD = %{ $sth -> fetchrow_hashref };
          $rv--;
          $field_1 = $RECORD{ "field_1" };
          # substitutions required only when fetching text fields
          $field_1 =~ s/\\'/$single_quote/g;
          $field_1 =~ s/\\"/$double_quote/g;
          $field_2 = $RECORD{ "field_2" };
          $field_3 = $RECORD{ "field_3" };
          ...
          $field_n = $RECORD{ "field_n" };
          do something
        }
   }
Storing a record into a table:

# get fields in some way
  $field_1 = $FORM{ 'field_1' };
  ...
# process text fields
  $field_1 =~ s/$single_quote/\\'/g;
  $field_1 =~ s/$double_quote/\\'/g;
  ...
# insert
  $rv = $dbh -> do ( qq | INSERT INTO table SET
                          field_1 = '$field_1',
                          field_2 = '$field_2',
                          ...
                          field_n = '$field_n' | );
  if ( $rv == 1 )
     {
       print STDOUT qq |<b>OK</b><br>|;
     }
  else
     {
       print STDOUT qq |<font face=courier size=4>|;
       my $error_msg = $dbh -> errstr;
       print STDOUT qq |<br>ALERT !!! Something went wrong ($rv).|;
       print STDOUT qq |<br>Error message from MySQL: $error_msg<br>|;
     }
Altering records into a table:

# get fields in some way
  $field_1 = $FORM{ 'field_1' };
  ...
# process text fields
  $field_1 =~ s/$single_quote/\\'/g;
  $field_1 =~ s/$double_quote/\\'/g;
  ...
# update
  $rv = $dbh -> do ( qq | UPDATE table SET
                          field_1 = '$field_1',
                          field_2 = '$field_2',
                          ...
                          field_n = '$field_n' 
                          WHERE clause | );
  if ( $rv == "0E0" )
     {
       print STDOUT qq |<b>No records affected.</b><br>|;
     }
  else
     {
       print STDOUT qq |<font face=courier size=4>|;
       print STDOUT qq |<br>Number of affected records: $rv.|;
     }

Armoring Linux

  • install Linux with the box disconnected from the net to avoid intrusions at installation time
  • check last patches at www.redhat.com/support (and use another box to download them; use "rpm -Uvh" to install patches)
  • comment all unuseful services in /etc/inetd.conf to avoid /usr/sbin/inetd running them; check the remaining active services with grep -v "^#" /etc/inetd.conf; restart /usr/sbin/inetd with killall -HUP inetd
  • prevent unuseful scripts from being started by the init process in /etc/rc.d/rc3.d by replacing the capital S with a small s. Script you can start when needed: S60lpd (printing services daemon), S85httpd (HTTP service daemon).
  • use /etc/shadow password file by typing pwconv at the command prompt
  • remove all unused accounts from /etc/passwd

Protect the Linux box from script kiddies

  • periodically visit cert and ciac to inform yourself about current and common exploits
  • turn off any unused communication port; leave only httpd and ssh ports opened
  • don't use bind, wu-ftp etc.
  • periodically check logs to determine if your box is being probed
  • protect your log files by firewalling port 514 UDP

wu-ftpd

xinetd is in charge to load wu-ftpd whenever a FTP client attempts to connect to the server box. Although some tutorials exist, editing wu-ftpd configuration files can be extremely difficult. To configure user access to wu-ftpd do the following:
  • start KDE
  • select control panel
  • select wu-ftpd configurator
  • set any element in each tab of the window
  • in the last tab you can allow/deny access to normal users defined in passwd (I discourage you enabling FTP to users defined in passwd because their password will be sent unencrypted over the connection, with all the possible consequences)
  • select File, Save, and then exit (note: all the settings are saved into the /etc/ftpaccess configuration file. Other configuration files ftp* in the /etc/ directory appear not to be strictly required.)
  • restart xinetd issuing the following command: service xinetd restart
Be sure that the wu-ftpd service is on at the runlevel that the server box is usually run. Type chkconfig --list and see. Eventually type chkconfig wu-ftpd on: this command will turn on the wu-ftpd service at the runlevel that you are currently logged on.

Automated site backup

Suppose you have some sites under the directory /home/httpd in your web server, and you want to save them once a week. A good solution is to tar the directory and to transfer the tarball into another server. This solution can be run unattended using the services provided by crond, tar and wget. The solution provided below will also save all your MySQL data in your database.

In the /etc/cron.weekly directory of the web server create a script sitesave.sh with the following lines:

 
cd /ftp_user_dir
tar -czf sitebackup.tar.gz /home/httpd/*
mysqldump databasename > /ftp_user_dir/databasename.sql
(and don't forget to chmode it in order to be executed). In the /etc/cron.weekly directory of the backup server create a script get_tarball.sh with the following two lines:
 
cd /backupdir
/usr/local/bin/wget -m ftp://ftp_username:ftp_password@xxx.xxx.xxx.xxx/
(remember to make it executable). A good refinement would be to program the backup server weekly job to be executed one day after the web server weekly job.

Please note that wget operates in FTP mode, and you need an FTP-registered-user to accomplish the task. Its username and password are respectively ftp_username and ftp_password, and ftp_user_dir is the default directory where the FTP-registered-user is switched into at logon. xxx.xxx.xxx.xxx, finally, is the IP address of the web server. You can substitute it with its domain name www.foobar.com.

The backup tarball (togheter with the database dump) remains into the /backupdir of the backup server in the hope it will never be necessary to restore it.

.

sendmail

sendmail will not work if HOSTNAME in /etc/sysconfig/network is not a valid domain name registered in a valid Internet DNS server.

You can query the HOSTNAME of your server by typing hostname at the command prompt. You can also experiment by temporarily changing the hostame. To temporarily change it type hostname www.foobar.org at the command prompt. It will override the /etc/sysconfig/network HOSTNAME current setting. This latter will be restored at the next boot.

Also /usr/sbin/sendmail wants no firewalling rules to stop packets in transit to/from port number 25 (the smtp port).

Check rock solid firewalling rules using ipchains to see how to let port 25 usable from a smpt client.

sendmail daemon is not required to stay up when calling /usr/sbin/sendmail from within your Perl script.

Simple instructions to send a mail from a Perl script are the following:

 
open ( MAIL, "|/usr/sbin/sendmail -t" );
print MAIL <<EndMail;
To: somebody\@foobar.org
From: do-not-reply\@mydomain.org
Subject: odds & sodds

Hi. This is a mail message.

EndMail
close ( MAIL );

preventing Apache from directory listing

Edit /etc/httpd/conf/httpd.conf and search the following line:

Options Indexes FollowSymLinks
then delete the word Indexes, save the file, and restart httpd.

misc

Finding accounts with no password:
awk -F: '$2 == "" { print $1, "has no password" }' /etc/shadow

Finding Superuser Accounts:
awk -F: '$3 == 0 { print $1, "is a superuser!" }' /etc/passwd

Checking for Suspicious Account Use:

To print the entire login history:
last [username]

To print failed login attempts:
lastb [username]

Testing Your Search Path
perl -e 'print "PATH contains insecure relative directory \"$_\"\n" foreach grep ! m[^/], split /:/, $ENV{"PATH"}, -1;'

Finding setuid (or setgid) Programs
find / -xdev -type f -perm +ug=s -print

find / -xdev -type f -perm +ug=s -print0 | \
perl -0ne 'chomp;
open(FILE, $_);
read(FILE, $magic, 2);
print $_, "\n" if $magic eq "#!";
close(FILE)'

Securing Device Special Files
find / -xdev \( -type b -o -type c \) -ls
find /dev -type f ! -name MAKEDEV -print

Finding Writable Files
find / -xdev -perm +o=w ! \( -type d -perm +o=t \) ! -type l -print


logwatch --range All --detail High --output html-embed --save (nome del file di output)

Mount USB pendrive


mount -t vfat /dev/sdb1 /mnt/pendrive
umount /mnt/pendrive 
(get off /mnt/pendrive before issuing umount)

SPAM blacklists

MAPS RBL

MX toolbox

...