Wednesday, October 11, 2006

HOW TO SETUP DIAL-IN SERVER on LINUX

A lot of my friends have been asking me how to setup a dial-in server on a linux box.. As far as im an concern i was able to make this kind of setup on a debian os.. i've tried it on ubuntu on breezy and dappeldrake and it both went well.. only it requires you to have a modem preferably external or internal will also do and a dedicated line to be used by the dial-in users.. below are the steps that i followed:


Part I . The short version:D on how to get remote access to your Ubuntu box via modem. Install mgetty
sudo apt-get install mgetty
Add a line at the end of file /etc/inittab
S0:2345:respawn:/sbin/mgetty ttyS0
If your modem is on COM1.
Initialize init by typing
sudo init q
Now from Win you can use HyperTerminal to connect to your Ubuntu box with your user name/pass.

For those who want more here is a real deal;)

Part II

The problem: Establish PPP connection to Ubuntu server from a remote location using a modem and to share internet connection.
Laptop modem<> Server modem <> Ethernet Router <> Cable/DSL modem <> Internet

Assumptions: drivers for your modems already installed and modem is at ttyS0. I have an external modem attached to COM1 - ttyS0, COM2 will be ttyS1. I didn't have X installed so I was using nano to edit conf files, you can use gedit if you have X installed or any other editor. Make sure your are familiar with the interface of the editor before you start modifying files. Make sure you create backups of the files before you modify them. You will need to use sudo or login as root for most of the tasks. If you don't know how to configure your dial up on your client look for a dial up howto or Ubuntu docs. I also assume that you already have your local nework including routers properly configured and have an access to the Internet from your Ubuntu server.

Part II.a - Dial in configuration

1. If not already installed use synaptic or apt-get to install ppp and mgetty packages. ppp should be already installed by default so
sudo apt-get install mgetty

2. Create a group ppp by adding a line in file /etc/group ppp:x:1001:

3. Create a new user "pppuser" or whatever you will use for your dial in connection and assign a password by using
sudo adduser pppuser
edit file /etc/passwd or use sudo vipw to change entry for pppuser to pppuser:x:1001:1001:,,,:/home/pppuser:/usr/sbin/ppplogin

4. Add a line to the file /etc/inittab S0:2345:respawn:/sbin/mgetty ttyS0 for modem on ttyS0. Or S1:2345:respawn:/sbin/mgetty ttyS1 for modem on ttyS1 That will let mgetty to accept incoming calls

5.Make a new file /usr/sbin/ppplogin and add the following in there
#!/bin/sh
#/etc/ppp/ppplogin
# PPP login script
mesg n
stty -echo
exec /usr/sbin/pppd -detach modem debug crtscts


6. Set access to the ppplogin file and etc/ppp directory
chmod 750 /usr/sbin/ppplogin
chown root:ppp /usr/sbin/ppplogin
chmod 775 /etc/ppp
chown root:root -R /etc/ppp

7. Restart init by typing init q
If you're use external modem it should be on before that.

8. Open file /etc/mgetty/login.config Comment out everything in there and add a line
/AutoPPP/ - a_ppp /usr/sbin/pppd file /etc/ppp/options

9. Open file /etc/ppp/options and make sure these lines are uncommented. If anything else is uncommented it probably should be commented.

-detach
asyncmap 0
modem
crtscts
proxyarp
lock
require-pap
refuse-chap
ms-dns 192.168.1.1 #put your dns server ip here
usepeerdns
In my case the ms-dns entry had an ip of my router, if you using Linksys router it's 192.168.1.1 by default unless you changed it.

10. Create a file /etc/ppp/options.ttyS0 for the modem on ttyS0 and add following in there
192.168.1.3:192.168.1.201
noauth
Where first address is the address of your server for ppp connection which I think, should be different from your eth ip. The second address is the address that will be assigned to the client when connection is established. It will probably make life easier, unless you know what you doing, if all those addresses on the same subnet as your other computers on the network. (ip starts with the same 192.168.1.x numbers)
You can substitute noauth for a debug line, this way it will log some info about you connection in a syslog.

11. Edit file /etc/ppp/pap-secrets
find a line after # Every regular user can use PPP and has to use passwords from /etc/passwd
It should look something like that
* hostname "" *
substitute hostnatname with * so it looks like that
* * "" *

If you don't do that pap will not authenticate you and you'll be immediately disconnected.

Now you're able to connect using dial-up connection from you laptop or a remote office into your Ubuntu server and use ssh or putty if you're using Win.

Part II.b - Accessing internet from a remote client

I'm sure there other or better solutions to that, but that was easy enough and it worked for me.

sudo apt-get install ipmasq

Done. ipmasq automatically senses all your interfaces and initializes IP Masquerade forwarding/firewalling and allows you to connect to the rest of your network and the Internet.

Tuesday, June 27, 2006

SETTING TWO IP ADDRESS in ONE LAN card or NIC

SETTING TWO IP ADDRESS in ONE LAN card or NIC.

Two options either you add it at /etc/netword/interfaces or you set using ifconfig


1. TO set using IFCONFIG (temporary)

ifconfig eth1:1 netmask 255.255.255.0


2. TO add permanently

for debian flavors:

edit
/etc/network/interfaces

iface eth1:1 inet static
address
netmask
broadcast
gateway

Wednesday, May 17, 2006

Adding Additional Hard drive on your Linux Machine


Normally one would ask? how do i add additional harddrive to my linux box.. well we could make use of utilities like fdisk, cfdisk or QtParted but it is fdisk that is im going to discuss below.

Why FDISK.. the answer is simple. since fdisk is the utility that i've been using eversince i've tried linux. :)

Here are the steps:

You must first be able to identify which partion is your new harddrive either though dmesg or using fdisk utility

 # fdisk -l

The output will display the current harddrive informations and which device it is assigned to.
for scsi drive its normally /dev/sda while for IDE drive its /dev/hda

# fdisk /dev/hdc

Command (m for help): _

For a short manual we need to enter the 'm' command:

        Command (m for help): m
Command action
a toggle a bootable flag
b edit bsd disklabel
c toggle the dos compatibility flag
d delete a partition
l list known partition types
m print this menu
n add a new partition
o create a new empty DOS partition table
p print the partition table
q quit without saving changes
s create a new empty Sun disklabel
t change a partition's system id
u change display/entry units
v verify the partition table
w write table to disk and exit
x extra functionality (experts only)

Command (m for help):

We need to know just few necessary commands: d,p,n,q,w. Don't be afraid to use them--all your changes will be done only in memory and will only be written to the hard after the 'w' command is entered. If we have an error, we just need to cancel all changes with the command 'q'.

First of all, let's make ourself sure that disk is empty:

        Command (m for help): p

Disk /dev/hdc: 64 heads, 63 sectors, 787 cylinders
Units = cylinders of 4032 * 512 bytes

Device Boot Start End Blocks Id System

Command (m for help):

Often sellers of PCs and hardware will pre-divide disks into partitions. In such cases we can use command 'd' (described below) to delete everything what we do not need.

So, let's create a new parititon (with command 'n'), answering all the questions as we go:

        Command (m for help): n
Command action
e extended
p primary partition (1-4)

Choosing the partition type-- primary or extended--we will enter P for primary.

In choosing number of the partition in this example, we will assign all of the all free space to one partition. Because this will be the first and only existing partition, we will assign the number 1:

        Partition number (1-4): 1

When setting the number of the first cylinder of the partition, we can just use the default value, which is recorded when we just press Enter:

        First cylinder (1-787, default 1):
Using default value 1

Setting the number of the last cylinder of the partition is easy in this example, since we are filling the entire drive with one partition. Again, just press Enter for the default (instead of the number of the cylinder, we can set size of partition in bytes, kbytes, or megabytes):

        Last cylinder or +size or +sizeM or +sizeK (1-787, default 787):
Using default value 787

Command (m for help):

Now, partition is created. We can take a look of new table of partitions with the help of the 'p' command:

        Command (m for help): p

Disk /dev/hdc: 64 heads, 63 sectors, 787 cylinders
Units = cylinders of 4032 * 512 bytes

Device Boot Start End Blocks Id System
/dev/hdc1 1 787 1586560+ 83 Linux

Command (m for help):

If we don't like (for some reason) the location or number of the partition, we can delete it using 'd' command:

        Command (m for help): d
Partition number (1-4): 1
Command (m for help):

If you want to divide the disk into a few partitions, you will need to repeat all these operations a few times. One thing that is important to remember is that if the amount of partitions is greater than four, you'll need to create not primary, but an extended partition across the whole available disk space. Inside this partition you can create as many logical parts as needed.

Remember, please, that logical partitions always should be numbered from 5 upwards; it doesn't matter how many primary partitions were created before (one, three, or none at all).

After a partition has been made. you may want to format it using mkfs command. you could use mkfs.ext3 depending on what type of partiition that you desired.

mkfs.ext3 /dev/hdc1

After formating you may want to mount it to your linux box so that you could use it already

mount /dev/hdc1 /u01

or simply add it on your fstab so that you dont need to remount it everytime your system is restarted.

Monday, May 01, 2006

3-legged 'Transparent Proxy' firewall using IPFilter 4.1.8, Squid on Fedora Core 1

3-legged 'Transparent Proxy' firewall using IPFilter 4.1.8, Squid on Fedora Core 1
Date: Oct 8, 2005
by Jett Tayer <>


Download and install apt for Fedora Core 1
# cd /usr/local/src
# wget http://apt.sw.be/fedora/1/en/i386/dag/RPMS/apt-0.5.15cnc6-4.1.fc1.rf.i386.rpm
# wget http://apt.sw.be/fedora/1/en/i386/dag/RPMS/apt-devel-0.5.15cnc6-4.1.fc1.rf.i386.rpm
# rpm -ivh apt-0.5.15cnc6-4.1.fc1.rf.i386.rpm
# rpm -ivh apt-devel-0.5.15cnc6-4.1.fc1.rf.i386.rpm
Update your apt database
# apt-get update
Upgrade your packages
# apt-get upgrade
Upgrade the kernel
# apt-get install kernel#2.4.22-1.2199.nptl kernel-source#2.4.22-1.2199.nptl
Install some needed apps
# apt-get install patch rpm-build
Restart your machine and boot the newly installed kernel.
Download and extract the Squid package.
# apt-get install squid
Configure Squid to do 'transparent proxying'
# vi /etc/squid/squid.conf
You will need to make at least the following changes in /etc/squid/squid.conf
http_port 3128
http_access deny to_localhost
acl our_networks src 192.168.1.0/24 192.168.2.0/24
http_access allow our_networks
visible_hostname your.server.name.dom
httpd_accel_host virtual
httpd_accel_port 80
httpd_accel_with_proxy on
httpd_accel_uses_host_header on
Fire up Squid!
# service squid start
Install Bind 9: Provide caching DNS service to LAN only
# apt-get install bind bind-chroot
# service named start
Install IPFilter
Download and extract ipfilter software package
# wget http://coombs.anu.edu.au/~avalon/ip_fil4.1.8.tar.gz
# gzip -cd ip_fil4.1.8.tar.gz tar xvf -
# cd ip_fil4.1.8
Edit Makefile
# vi Makefile
look for the line,
LINUXKERNEL=/usr/src/linux
and change it to,
LINUXKERNEL=/usr/src/linux-2.4
Uncomment the following 3 lines
STATETOP_CFLAGS=-DSTATETOP
STATETOP_INC=
STATETOP_INC=-I/usr/local/include
and change the last line
STATETOP_INC=-I/usr/local/include
to
STATETOP_INC=-I/usr/include
Uncomment the following 2 lines
STATETOP_LIB=-lncurses
STATETOP_LIB=-L/usr/local/lib -lncurses
and change the last line
STATETOP_LIB=-L/usr/local/lib -lncurses
to
STATETOP_LIB=-L/usr/lib -lncurses
Next look for the line
POLICY=-DIPF_DEFAULT_PASS=FR_PASS
and change it to
POLICY=-DIPF_DEFAULT_PASS=FR_BLOCK
Save the file
# wq!
Compile IPFilter
# make linux
# make install-linux
Note:
There will be errors about ipfilter.o not being found.
Just copy ipfilter.o created in 'make-linux' command above in
/usr/src/redhat/BUILD/ipfilter/lib/modules/2.4.22-1.2199.nptl/kernel/net/ipv4/
then do a "make install-linux" again.
Still there will be errors, but don't worry because ipfilter RPM file will
be written in /usr/src/redhat/RPMS/i386. In that case just go directly
to the location of IPFilter RPM file and install it manually.
# cd /usr/src/redhat/RPMS/i386/
# rpm -ivh ipfilter-4.1.8-1.i386.rpm
IPFilter is now installed.
Config file (/etc/ipf.conf)
Here is my working ipf.conf for a 3-legged firewall
############################
### ipf.conf starts here ###
#
# $Linux ipf.conf 2005/07/17 16:15:55 tayer Exp $
#
# See /usr/share/ipfilter/examples for syntax and examples.
# eth0 is connected to the Internet with ip address 10.10.10.1 which is part of
# 10.10.10.0/24 network (not my real ip block of course!)
# eth1 is connected to the private subnet 192.168.1.0/24, 192.168.1.1 is the IP of eth1
# eth2 is connected to the private subnet 192.168.2.0/24, 192.168.2.1 is the IP of eth2
# Filtering:
block in all
block out all
block in quick on eth0 from 127.0.0.0/8 to any
block in quick on eth0 from 192.168.0.0/16 to any
block in quick on eth0 from 172.16.0.0/12 to any
block in quick on eth0 from 10.0.0.0/8 to any
block in quick on eth0 from 169.254.0.0/16 to any
block in quick on eth0 from 223.0.0.0/8 to any
block in quick on eth0 from 198.18.0.0/15 to any
block in quick on eth0 from 197.0.0.0/8 to any
block in quick on eth0 from 224.0.0.0/3 to any
block out quick on eth0 from any to 127.0.0.0/8
block out quick on eth0 from any to 192.168.0.0/16
block out quick on eth0 from any to 172.16.0.0/12
block out quick on eth0 from any to 10.0.0.0/8
block out quick on eth0 from any to 169.254.0.0/16
block out quick on eth0 from any to 223.0.0.0/8
block out quick on eth0 from any to 198.18.0.0/15
block out quick on eth0 from any to 197.0.0.0/8
block out quick on eth0 from any to 224.0.0.0/3
# What's these?? :)
block in log quick on eth0 from any to 10.10.10.0
block in log quick on eth0 from any to 10.10.10.255
block in log quick on eth0 from any to 255.255.255.255
##### Block a bunch of different nasty things. ############
# That I don"t want to see in the log
#
# Block frags
block in log quick on eth0 all with frags
# Block short tcp packets
block in log quick from any to any with ipopts
block in log quick all with short
# Block anything with special options
block in log quick all with ipopts
#
# Log packets with BOTH ssrr and lsrr set
log in all with opt lsrr,ssrr
# block source routed packets
block in log quick all with opt lsrr
block in log quick all with opt ssrr
# Block nmap OS fingerprint attempts
# Log first occurrence of these so I can get their IP address
block in log first quick on eth0 proto tcp from any to any flags FUP
# Block public pings
#block in log quick on eth0 proto icmp all
# Allow loopback packets freely
pass in quick on lo
pass out quick on lo
# Allow LAN packets freely
# allow freely packets from 192.168.1.0/24 LAN
pass in quick on eth1
pass out quick on eth1
# allow freely packets from 192.168.2.0/24 LAN
pass in quick on eth2
pass out quick on eth2
# Allow incoming data channel for outgoing connections, reject
# and log all incoming control connections
pass out quick on eth0 proto tcp from any to any port = 21 flags S keep state
# Allow SSH
pass in on eth0 proto tcp from any to eth0/32 port = 22 flags S/SA keep state
# Allow SMTP traffic
#pass in on eth0 proto tcp from any to eth0/32 port = 25 flags S/SA keep state
# Allow DNS traffic (tcp & axfr)
#pass in on eth0 proto tcp from any to eth0/32 port = 53 flags S/SA keep state
# Allow DNS traffic (udp)
#pass in on eth0 proto udp from any to eth0/32 port = 53 keep state
# Allow outside world to ping me (bad idea)
#pass in on eth0 proto icmp from any to any icmp-type 8 code 0 keep state keep frags
# Allow me to ping the outside world
pass out quick proto icmp from any to any icmp-type 8 code 0 keep state keep frags
# Allow all outgoing tcp traffic
pass out on eth0 proto tcp all flags S/SA keep state
# Allow all outgoing udp traffic
pass out on eth0 proto udp all keep state
#
### ipf.conf ends here ###
##########################
Config file (/etc/ipnat.conf)
Here is my working ipnat.conf for my 3-legged firewall
### ipnat.conf starts here ###
#
map eth0 192.168.1.0/24 -> 10.10.10.1/32 proxy port ftp ftp/tcp
map eth0 192.168.1.0/24 -> 10.10.10.1/32 portmap tcp/udp 40000:60000
map eth0 192.168.1.0/24 -> 10.10.10.1/32
map eth0 192.168.2.0/24 -> 10.10.10.1/32 proxy port ftp ftp/tcp
map eth0 192.168.2.0/24 -> 10.10.10.1/32 portmap tcp/udp 40000:60000
map eth0 192.168.2.0/24 -> 10.10.10.1/32
#
# Redirection is triggered for input packets.
# For example, to redirect FTP connections through this box, to the local ftp
# port, forcing them to connect through a proxy, you would use:
#
rdr eth0 0.0.0.0/0 port ftp -> 127.0.0.1 port ftp
#
# squid transparent proxy
rdr eth1 192.168.1.1/32 port 80 -> 192.168.1.1 port 80
rdr eth1 0.0.0.0/0 port 80 -> 192.168.1.1 port 3128
rdr eth1 192.168.2.1/32 port 80 -> 192.168.2.1 port 80
rdr eth1 0.0.0.0/0 port 80 -> 192.168.2.1 port 3128
#
### ipnat.conf ends here ###
Enable IP Forwarding:
Add this line in /etc/sysctl.conf if not already there
# echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
Re-read /etc/sysctl.conf
# sysctl -p
Fire up IPFilter
# service ipfilter start
IPFilter admin commands
Display a table of data detailing firewall performance,
including how many packets have been passed or blocked.
# ipfstat -hio
To flush and load ipfilter rules
# ipf -Fa -f /etc/ipf.conf
To flush and load ipnat rules
# ipnat -CF -f /etc/ipnat.conf

Thursday, April 27, 2006

Basic Linux Commands

BASIC LINUX COMMANDS

alias    Create an alias
awk Find and Replace text, database sort/validate/index
break Exit from a loop
builtin Run a shell builtin

cal Display a calendar
case Conditionally perform a command
cat Display the contents of a file
cd Change Directory
cfdisk Partition table manipulator for Linux
chgrp Change group ownership
chmod Change access permissions
chown Change file owner and group
chroot Run a command with a different root directory
cksum Print CRC checksum and byte counts
clear Clear terminal screen
cmp Compare two files
comm Compare two sorted files line by line
command Run a command - ignoring shell functions
continue Resume the next iteration of a loop
cp Copy one or more files to another location
cron Daemon to execute scheduled commands
crontab Schedule a command to run at a later time
csplit Split a file into context-determined pieces
cut Divide a file into several parts

date Display or change the date & time
dc Desk Calculator
dd Data Dump - Convert and copy a file
declare Declare variables and give them attributes
df Display free disk space
diff Display the differences between two files
diff3 Show differences among three files
dir Briefly list directory contents
dircolors Colour setup for `ls'
dirname Convert a full pathname to just a path
dirs Display list of remembered directories
du Estimate file space usage

echo Display message on screen
ed A line-oriented text editor (edlin)
egrep Search file(s) for lines that match an extended expression
eject Eject CD-ROM
enable Enable and disable builtin shell commands
env Display, set, or remove environment variables
eval Evaluate several commands/arguments
exec Execute a command
exit Exit the shell
expand Convert tabs to spaces
export Set an environment variable
expr Evaluate expressions

factor Print prime factors
false Do nothing, unsuccessfully
fdformat Low-level format a floppy disk
fdisk Partition table manipulator for Linux
fgrep Search file(s) for lines that match a fixed string
find Search for files that meet a desired criteria
fmt Reformat paragraph text
fold Wrap text to fit a specified width.
for Expand words, and execute commands
format Format disks or tapes
free Display memory usage
fsck Filesystem consistency check and repair.
function Define Function Macros

gawk Find and Replace text within file(s)
getopts Parse positional parameters
grep Search file(s) for lines that match a given pattern
groups Print group names a user is in
gzip Compress or decompress named file(s)

hash Remember the full pathname of a name argument
head Output the first part of file(s)
history Command History
hostname Print or set system name

id Print user and group id's
if Conditionally perform a command
import Capture an X server screen and save the image to file
info Help info
install Copy files and set attributes

join Join lines on a common field

kill Stop a process from running

less Display output one screen at a time
let Perform arithmetic on shell variables
ln Make links between files
local Create variables
locate Find files
logname Print current login name
logout Exit a login shell
lpc Line printer control program
lpr Off line print
lprint Print a file
lprintd Abort a print job
lprintq List the print queue
lprm Remove jobs from the print queue
ls List information about file(s)

m4 Macro processor
man Help manual
mkdir Create new folder(s)
mkfifo Make FIFOs (named pipes)
mknod Make block or character special files
more Display output one screen at a time
mount Mount a file system
mtools Manipulate MS-DOS files
mv Move or rename files or directories

nice Set the priority of a command or job
nl Number lines and write files
nohup Run a command immune to hangups

passwd Modify a user password
paste Merge lines of files
pathchk Check file name portability
popd Restore the previous value of the current directory
pr Convert text files for printing
printcap Printer capability database
printenv Print environment variables
printf Format and print data
ps Process status
pushd Save and then change the current directory
pwd Print Working Directory

quota Display disk usage and limits
quotacheck Scan a file system for disk usage
quotactl Set disk quotas

ram ram disk device
rcp Copy files between two machines.
read read a line from standard input
readonly Mark variables/functions as readonly
remsync Synchronize remote files via email
return Exit a shell function
rm Remove files
rmdir Remove folder(s)
rpm Remote Package Manager
rsync Remote file copy (Synchronize file trees)

screen Terminal window manager
sdiff Merge two files interactively
sed Stream Editor
select Accept keyboard input
seq Print numeric sequences
set Manipulate shell variables and functions
shift Shift positional parameters
shopt Shell Options
shutdown Shutdown or restart linux
sleep Delay for a specified time
sort Sort text files
source Run commands from a file `.'
split Split a file into fixed-size pieces
su Substitute user identity
sum Print a checksum for a file
symlink Make a new name for a file
sync Synchronize data on disk with memory

tac Concatenate and write files in reverse
tail Output the last part of files
tar Tape ARchiver
tee Redirect output to multiple files
test Evaluate a conditional expression
time Measure Program Resource Use
times User and system times
touch Change file timestamps
top List processes running on the system
traceroute Trace Route to Host
trap Run a command when a signal is set(bourne)
tr Translate, squeeze, and/or delete characters
true Do nothing, successfully
tsort Topological sort
tty Print filename of terminal on stdin
type Describe a command

ulimit Limit user resources
umask Users file creation mask
umount Unmount a device
unalias Remove an alias
uname Print system information
unexpand Convert spaces to tabs
uniq Uniquify files
units Convert units from one scale to another
unset Remove variable or function names
unshar Unpack shell archive scripts
until Execute commands (until error)
useradd Create new user account
usermod Modify user account
users List users currently logged in
uuencode Encode a binary file
uudecode Decode a file created by uuencode

v Verbosely list directory contents (`ls -l -b')
vdir Verbosely list directory contents (`ls -l -b')

watch Execute/display a program periodically
wc Print byte, word, and line counts
whereis Report all known instances of a command
which Locate a program file in the user's path.
while Execute commands
who Print all usernames currently logged in
whoami Print the current user id and name (`id -un')

xargs Execute utility, passing constructed argument list(s)
yes Print a string until interrupted

Monday, April 24, 2006

Mirror Your Web Site With rsync

Mirror Your Web Site With rsync

Version 1.0
Author: Falko Timme
Last edited 04/20/2006

This tutorial shows how you can mirror your web site from your main web server to a backup server that can take over if the main server fails. We use the tool rsync for this, and we make it run through a cron job that checks every x minutes if there is something to update on the mirror. Thus your backup server should usually be up to date if it has to take over.

rsync updates only files that have changed, so you do not need to transfer 5 GB of data whenever you run rsync. It only mirrors new/changed files, and it can also delete files from the mirror that have been deleted on the main server. In addition to that it can preserve permissions and ownerships of mirrored files and directories; to preserve the ownerships, we need to run rsync as root which is what we do here. If permissions and/or ownerships change on the main server, rsync will also change them on the backup server.

In this tutorial we will tunnel rsync through SSH which is more secure; it also means you do not have to open another port in your firewall for rsync - it is enough if port 22 (SSH) is open. The problem is that SSH requires a password for logging in which is not good if you want to run rsync as a cron job. The need for a password requires human interaction which is not what we want.

But fortunately there is a solution: the use of public keys. We create a pair of keys (on our backup server mirror.example.com), one of which is saved in a file on the remote system (server1.example.com). Afterwards we will not be prompted for a password anymore when we run rsync. This also includes cron jobs which is exactly what we want.

As you might have guessed already from what I have written so far, the concept is that we initiate the mirroring of server1.example.com directly from mirror.example.com; server1.example.com does not have to do anything to get mirrored.

I will use the following setup here:

  • Main server: server1.example.com (server1) - IP address: 192.168.0.100
  • Mirror/backup server: mirror.example.com (mirror) - IP address: 192.168.0.175
  • The web site that is to be mirrored is in /var/www on server1.example.com.

rsync is for mirroring files and directories only; if you want to mirror your MySQL database, please take a look at these tutorials:

I want to say first that this is not the only way of setting up such a system. There are many ways of achieving this goal but this is the way I take. I do not issue any guarantee that this will work for you!

1 Install rsync

First we have to install rsync on both server1.example.com and mirror.example.com. For Debian systems, this looks like this:

server1/mirror:

(We do this as root!)

apt-get install rsync

On other Linux distributions you would use yum (Fedora/CentOS) or yast (SuSE) to install rsync.

2 Create An Unprivileged User On server1.example.com

Now we create an unprivileged user called someuser on server1.example.com that will be used by rsync on mirror.example.com to mirror the directory /var/www (of course, someuser must have read permissions on /var/www on server1.example.com).

server1:

(We do this as root!)

useradd -d /home/someuser -m -s /bin/bash someuser

This will create the user someuser with the home directory /home/someuser and the login shell /bin/bash (it is important that someuser has a valid login shell - something like /bin/false does not work!). Now give someuser a password:

passwd someuser

3 Test rsync

Next we test rsync on mirror.example.com. As root we do this:

mirror:

rsync -avz -e ssh someuser@server1.example.com:/var/www/ /var/www/

You should see something like this. Answer with yes:

The authenticity of host 'server1.example.com (192.168.0.100)' can't be established.
RSA key fingerprint is 32:e5:79:8e:5f:5a:25:a9:f1:0d:ef:be:5b:a6:a6:23.
Are you sure you want to continue connecting (yes/no)?

<-- yes

Then enter someuser's password, and you should see that server1.example.com's /var/www directory is mirrored to /var/www on mirror.example.com.

You can check that like this on both servers:

server1/mirror:

ls -la /var/www

You should see that all files and directories have been mirrored to mirror.example.com, and the files and directories should have the same permissions/ownerships as on server1.example.com.

4 Create The Keys On mirror.example.com

Now we create the private/public key pair on mirror.example.com:

mirror:

(We do this as root!)

mkdir /root/rsync
ssh-keygen -t dsa -b 2048 -f /root/rsync/mirror-rsync-key

You will see something like this:

Generating public/private dsa key pair.
Enter passphrase (empty for no passphrase): [press enter here]
Enter same passphrase again: [press enter here]
Your identification has been saved in /root/cron/mirror-rsync-key.
Your public key has been saved in /root/cron/mirror-rsync-key.pub.
The key fingerprint is:
68:95:35:44:91:f1:45:a4:af:3f:69:2a:ea:c5:4e:d7 root@mirror

It is important that you do not enter a passphrase otherwise the mirroring will not work without human interaction so simply hit enter!

Next, we copy our public key to server1.example.com:

mirror:

(Still, we do this as root.)

scp /root/rsync/mirror-rsync-key.pub someuser@server1.example.com:/home/someuser/

The public key mirror-rsync-key.pub should now be available in /home/someuser on server1.example.com.

Mirror Your Web Site With rsync

Mirror Your Web Site With rsync

Version 1.0
Author: Falko Timme
Last edited 04/20/2006

This tutorial shows how you can mirror your web site from your main web server to a backup server that can take over if the main server fails. We use the tool rsync for this, and we make it run through a cron job that checks every x minutes if there is something to update on the mirror. Thus your backup server should usually be up to date if it has to take over.

rsync updates only files that have changed, so you do not need to transfer 5 GB of data whenever you run rsync. It only mirrors new/changed files, and it can also delete files from the mirror that have been deleted on the main server. In addition to that it can preserve permissions and ownerships of mirrored files and directories; to preserve the ownerships, we need to run rsync as root which is what we do here. If permissions and/or ownerships change on the main server, rsync will also change them on the backup server.

In this tutorial we will tunnel rsync through SSH which is more secure; it also means you do not have to open another port in your firewall for rsync - it is enough if port 22 (SSH) is open. The problem is that SSH requires a password for logging in which is not good if you want to run rsync as a cron job. The need for a password requires human interaction which is not what we want.

But fortunately there is a solution: the use of public keys. We create a pair of keys (on our backup server mirror.example.com), one of which is saved in a file on the remote system (server1.example.com). Afterwards we will not be prompted for a password anymore when we run rsync. This also includes cron jobs which is exactly what we want.

As you might have guessed already from what I have written so far, the concept is that we initiate the mirroring of server1.example.com directly from mirror.example.com; server1.example.com does not have to do anything to get mirrored.

I will use the following setup here:

  • Main server: server1.example.com (server1) - IP address: 192.168.0.100
  • Mirror/backup server: mirror.example.com (mirror) - IP address: 192.168.0.175
  • The web site that is to be mirrored is in /var/www on server1.example.com.

rsync is for mirroring files and directories only; if you want to mirror your MySQL database, please take a look at these tutorials:

I want to say first that this is not the only way of setting up such a system. There are many ways of achieving this goal but this is the way I take. I do not issue any guarantee that this will work for you!

1 Install rsync

First we have to install rsync on both server1.example.com and mirror.example.com. For Debian systems, this looks like this:

server1/mirror:

(We do this as root!)

apt-get install rsync

On other Linux distributions you would use yum (Fedora/CentOS) or yast (SuSE) to install rsync.

2 Create An Unprivileged User On server1.example.com

Now we create an unprivileged user called someuser on server1.example.com that will be used by rsync on mirror.example.com to mirror the directory /var/www (of course, someuser must have read permissions on /var/www on server1.example.com).

server1:

(We do this as root!)

useradd -d /home/someuser -m -s /bin/bash someuser

This will create the user someuser with the home directory /home/someuser and the login shell /bin/bash (it is important that someuser has a valid login shell - something like /bin/false does not work!). Now give someuser a password:

passwd someuser

3 Test rsync

Next we test rsync on mirror.example.com. As root we do this:

mirror:

rsync -avz -e ssh someuser@server1.example.com:/var/www/ /var/www/

You should see something like this. Answer with yes:

The authenticity of host 'server1.example.com (192.168.0.100)' can't be established.
RSA key fingerprint is 32:e5:79:8e:5f:5a:25:a9:f1:0d:ef:be:5b:a6:a6:23.
Are you sure you want to continue connecting (yes/no)?

<-- yes

Then enter someuser's password, and you should see that server1.example.com's /var/www directory is mirrored to /var/www on mirror.example.com.

You can check that like this on both servers:

server1/mirror:

ls -la /var/www

You should see that all files and directories have been mirrored to mirror.example.com, and the files and directories should have the same permissions/ownerships as on server1.example.com.

4 Create The Keys On mirror.example.com

Now we create the private/public key pair on mirror.example.com:

mirror:

(We do this as root!)

mkdir /root/rsync
ssh-keygen -t dsa -b 2048 -f /root/rsync/mirror-rsync-key

You will see something like this:

Generating public/private dsa key pair.
Enter passphrase (empty for no passphrase): [press enter here]
Enter same passphrase again: [press enter here]
Your identification has been saved in /root/cron/mirror-rsync-key.
Your public key has been saved in /root/cron/mirror-rsync-key.pub.
The key fingerprint is:
68:95:35:44:91:f1:45:a4:af:3f:69:2a:ea:c5:4e:d7 root@mirror

It is important that you do not enter a passphrase otherwise the mirroring will not work without human interaction so simply hit enter!

Next, we copy our public key to server1.example.com:

mirror:

(Still, we do this as root.)

scp /root/rsync/mirror-rsync-key.pub someuser@server1.example.com:/home/someuser/

The public key mirror-rsync-key.pub should now be available in /home/someuser on server1.example.com.

Sunday, April 23, 2006

How To Set Up Database Replication In MySQL

How To Set Up Database Replication In MySQL

Version 1.1
Author: Falko Timme
Last edited: 01/14/2006

This tutorial describes how to set up database replication in MySQL. MySQL replication allows you to have an exact copy of a database from a master server on another server (slave), and all updates to the database on the master server are immediately replicated to the database on the slave server so that both databases are in sync. This is not a backup policy because an accidentally issued DELETE command will also be carried out on the slave; but replication can help protect against hardware failures though.

In this tutorial I will show how to replicate the database exampledb from the master with the IP address 192.168.0.100 to a slave. Both systems (master and slave) are running Debian Sarge; however, the configuration should apply to almost all distributions with little or no modification.

Both systems have MySQL installed, and the database exampledb with tables and data is already existing on the master, but not on the slave.

I want to say first that this is not the only way of setting up such a system. There are many ways of achieving this goal but this is the way I take. I do not issue any guarantee that this will work for you!

1 Configure The Master

First we have to edit /etc/mysql/my.cnf. We have to enable networking for MySQL, and MySQL should listen on all IP addresses, therefore we comment out these lines (if existant):

#skip-networking
#bind-address = 127.0.0.1

Furthermore we have to tell MySQL for which database it should write logs (these logs are used by the slave to see what has changed on the master), which log file it should use, and we have to specify that this MySQL server is the master. We want to replicate the database exampledb, so we put the following lines into /etc/mysql/my.cnf:

log-bin = /var/log/mysql/mysql-bin.log
binlog-do-db=exampledb
server-id=1

Then we restart MySQL:

/etc/init.d/mysql restart

Then we log into the MySQL database as root and create a user with replication privileges:

mysql -u root -p
Enter password:

Now we are on the MySQL shell.

For mysql version 3.23 and below

GRANT LINE ON *.* TO 'slave_user'@'Host IP' IDENTIFIED BY ''; (Replace with a real password! and Host IP with ip adress or host.domainname will do)

For Mysql version 4 and up

GRANT REPLICATION SLAVE ON *.* TO 'slave_user'@'%' IDENTIFIED BY ''; (Replace with a real password!)
FLUSH PRIVILEGES;

* you could also use grant all privileges although not recommended

Next (still on the MySQL shell) do this:

USE exampledb;
FLUSH TABLES WITH READ LOCK;
SHOW MASTER STATUS;

The last command will show something like this:

+---------------+----------+--------------+------------------+
| File | Position | Binlog_do_db | Binlog_ignore_db |
+---------------+----------+--------------+------------------+
| mysql-bin.006 | 183 | exampledb | |
+---------------+----------+--------------+------------------+
1 row in set (0.00 sec)

Write down this information, we will need it later on the slave!

Then leave the MySQL shell:

quit;


There are two possibilities to get the existing tables and data from exampledb from the master to the slave. The first one is to make a database dump, the second one is to use the LOAD DATA FROM MASTER; command on the slave. The latter has the disadvantage the the database on the master will be locked during this operation, so if you have a large database on a high-traffic production system, this is not what you want, and I recommend to follow the first method in this case. However, the latter method is very fast, so I will describe both here.

If you want to follow the first method, then do this:

mysqldump -u root -p --opt exampledb > exampledb.sql (Replace with the real password for the MySQL user root! Important: There is no space between -p and !)

This will create an SQL dump of exampledb in the file exampledb.sql. Transfer this file to your slave server!

If you want to go the LOAD DATA FROM MASTER; way then there is nothing you must do right now.


Finally we have to unlock the tables in exampledb:

mysql -u root -p
Enter password:
UNLOCK TABLES;
quit;

Now the configuration on the master is finished. On to the slave...

2 Configure The Slave

On the slave we first have to create the database exampledb:

mysql -u root -p
Enter password:
CREATE DATABASE exampledb;
quit;


If you have made an SQL dump of exampledb on the master and have transferred it to the slave, then it is time now to import the SQL dump into our newly created exampledb on the slave:

mysql -u root -p exampledb < /path/to/exampledb.sql (Replace with the real password for the MySQL user root! Important: There is no space between -p and !)

If you want to go the LOAD DATA FROM MASTER; way then there is nothing you must do right now.


Now we have to tell MySQL on the slave that it is the slave, that the master is 192.168.0.100, and that the master database to watch is exampledb. Therefore we add the following lines to /etc/mysql/my.cnf:

server-id=2
master-host=192.168.0.100
master-user=slave_user
master-password=secret
master-connect-retry=60
replicate-do-db=exampledb

Then we restart MySQL:

/etc/init.d/mysql restart


If you have not imported the master exampledb with the help of an SQL dump, but want to go the LOAD DATA FROM MASTER; way, then it is time for you now to get the data from the master exampledb:

mysql -u root -p
Enter password:
LOAD DATA FROM MASTER;
quit;

If you have phpMyAdmin installed on the slave you can now check if all tables/data from the master exampledb is also available on the slave exampledb.


Finally, we must do this:

mysql -u root -p
Enter password:
SLAVE STOP;

In the next command (still on the MySQL shell) you have to replace the values appropriately:

CHANGE MASTER TO MASTER_HOST='192.168.0.100', MASTER_USER='slave_user', MASTER_PASSWORD='', MASTER_LOG_FILE='mysql-bin.006', MASTER_LOG_POS=183;

  • MASTER_HOST is the IP address or hostname of the master (in this example it is 192.168.0.100).
  • MASTER_USER is the user we granted replication privileges on the master.
  • MASTER_PASSWORD is the password of MASTER_USER on the master.
  • MASTER_LOG_FILE is the file MySQL gave back when you ran SHOW MASTER STATUS; on the master.
  • MASTER_LOG_POS is the position MySQL gave back when you ran SHOW MASTER STATUS; on the master.

Now all that is left to do is start the slave. Still on the MySQL shell we run

START SLAVE;
quit;

That's it! Now whenever exampledb is updated on the master, all changes will be replicated to exampledb on the slave. Test it!

How do I scan my Linux system for rootkits, worms, trojans, etc.?

Either with ckrootkit or with rkhunter.

chkrootkit:

Either install the package that comes with your distribution (on Debian you would run

apt-get install chkrootkit

), or download the sources from www.chkrootkit.org and install manually:

wget --passive-ftp ftp://ftp.pangeia.com.br/pub/seg/pac/chkrootkit.tar.gz

tar xvfz chkrootkit.tar.gz

cd chkrootkit-/

make sense

Afterwards, you can move the chkrootkit directory somewhere else, e.g. /usr/local/chkrootkit:

cd ..

mv chkrootkit-/ /usr/local/chkrootkit

Now you can run chkrootkit manually:

cd /usr/local/chkrootkit

./chkrootkit

(if you installed a chkrootkit package coming with your distribution, your chkrootkit might be somewhere else).

You can even run chkrootkit by a cron job and get the results emailed to you:

Run

crontab -e

to create a cron job like this:

0 3 * * * (cd /usr/local/chkrootkit-; ./chkrootkit 2>&1 | mail -s "chkrootkit output my server" you@yourdomain.com)

That would run chkrootkit every night a 3.00h.

rkhunter:

Download the latest rkhunter sources from www.rootkit.nl:

wget http://downloads.rootkit.nl/rkhunter-1.2.7.tar.gz

tar xvfz rkhunter-1.2.7.tar.gz

cd rkhunter/

./installer.sh

This will install rkhunter to the directory /usr/local/rkhunter. Now run

rkhunter --update

to download the latest chkrootkit/trojan/worm signatures (you should do this regularly).

Now you can scan your system for malware by running

rkhunter -c

Tuesday, April 18, 2006

TRACKING OF LOGINS AND LOGOUTS on LINUX / UNIX Distros

TRACKING OF LOGINS AND LOGOUTS


In the .login file add the commands:
------------------------------
------

echo login time `date` >> .daylogs/masterlog

grep -i "sun" .daylogs/masterlog > .daylogs/sunday.log
grep -i "mon" .daylogs/masterlog > .daylogs/monday.log
grep -i "tue" .daylogs/masterlog > .daylogs/tuesday.log
grep -i "wen" .daylogs/masterlog > .daylogs/wensday.log
grep -i "thu" .daylogs/masterlog > .daylogs/thursday.log
grep -i "fri" .daylogs/masterlog > .daylogs/friday.log
grep -i "sat" .daylogs/masterlog > .daylogs/saturday.log


In the .logout file add this line
-----------------------------------

echo logout time `date`>> .daylogs/masterlog

This script assumes you have a hidden
directory called .daylogs this helps keep it
out of sight and away from prying eyes and
if you keep root ownership of the directory
change the mode to:

chmod 744 .daylogs

This will not allow anyone to get in to the
directory to look around.

Saturday, April 15, 2006

CREATING TRASH

CREATING TRASH

Sometimes unwittingly we may delete
some important files and realise it
later. To avoid such a situation,
you can use this following idea.

Create a small bash script containing
the line

mv $1 ~/trash/

Save this file in your home say
".srm" (safe rm) and in your
".bashrc" enter this line:

alias rm='~/.srm'

Now whenever you delete any files
it will go to "trash" directory
instead of deletion. You will
have to create a "trash" directory
in your home directory.

Thursday, April 13, 2006

BASH SHELL OPTION

BASH SHELL OPTION

If you are using bash shell. There is
a way to cd a particular directory
even if you spelled incorrectly on the
command line. Set the shell option to:

shopt -s cdspell

eg:-
Suppose you want to cd to "cd /tmp"
and you have miss typed to "cd /pmp"
still it will cd to "cd /tmp".

This setting will be very usefull if
you have a long named directory.

Wednesday, April 12, 2006

NFS BETWEEN SOLARIS & LINUX

NFS BETWEEN SOLARIS & LINUX


If you receive error messages such
as "unknown version" when attempting to
mount a Linux based NFS server from
Solaris, you probably have an
incompatibility between the NFS versions
running on both of them. Linux uses
version 2, while Solaris uses version 3.
In order to get the machines to
communicate, you have to use the vers
option on the Solaris machine as follows:

mount -o vers=2 nfsserver:/remotedir /localdir

Tuesday, April 11, 2006

MAINTAINING LOG AND TMP FILE

MAINTAINING LOG AND TMP FILE

If you need to maintain an
application that generate
a lot of logfiles or tmp
files with running numbers
as part of the filename and
uses a common extension.
These two command together
will help to maintain it
for a window of time.

It compress those files that
are more than 24hrs and
have it remove after 120hrs.
You need to put it in
daily cron.

find $LOGDIR -name '*.ext' -mtime +0 -exec compress {} \;
find $LOGDIR -name '*.Z' -mtime +5 -exec rm -f {} \;

You can change the time to
suit your needs and use
wherever compressing utility
you have to save space.
If you need to maintain
directories created by
application here are help;

find $LOGDIR -type d -mtime +0 -exec compress -r {} \;
find $LOGDIR -type d -mtime +5 -exec rm -f {}
The compression is to save
space while waiting to be
deleted. Application
developers may need to read
these files/directories so
keep those files/directories
for a certain amount of time
before deleting.

EXTRACT CORRUPTED TAR FILE

EXTRACT CORRUPTED TAR FILE

In many case if there is a corrupted tar file,
the following command can be used in an attempt
to extract the file:

% cat [tar-filename] | tar -xvf -

NOTE: Where "-" is the STDOUT

Sunday, April 02, 2006

EFFICIENT COMMANDS

EFFICIENT COMMANDS

I cringe anytime I see someone code
inefficiently. Here are three of the
most common mistakes, followed by a
better way to do the same thing.

Bad: cat somefile | grep something
Better: grep something somefile
Why: You're running one program (grep) instead of two (cat and grep).

Bad: ps -ef | grep something | grep -v grep
Better: ps -ef | grep [s]omething
Why: You're running two commands (grep) instead of three (ps
and two greps).

Bad: cat /dev/null > somefile
Better: > somefile
Why: You're running a command (cat) with I/O redirection,
instead of just redirection.

Although the bad way will have the
same result, the good way is far
faster. This may seem trivial, but
the benefits will really show when
dealing with large files or loops.

Saturday, April 01, 2006

Removing Blank Line using SED

I SED BLANK

Using sed, you can remove blank lines, and
lines that contain only whitespace, from a
file using the following:

sed -e '/^[ ]*$/d' InputFile >OutputFile

Within the single quotes ('), the forward
slashes (/) delimit the regular expression
that will be interpreted by sed. The "d"
before the closing single quote, tells sed
to delete any lines that match the regular
expression.

Within the regular expression, the caret
(^) matches the beginning of a line.
The []* matches zero to many occurrences of
the character list between the open bracket
([) and the close bracket (]) (in the above
regular expression, you must insert a space
and a tab between the brackets). The dollar
sign ($) matches the end of a line.

These three constructs together match any
blank line or any line that contains only
spaces and tabs (in any combination).

Since the standard operation of sed is to
echo lines to stdout, all lines except blank
lines (or lines that only contain whitespace)
will be sent to OutputFile.

Thursday, March 30, 2006

VI COPY FILE TO FILE

VI COPY FILE TO FILE

Here is how to copy the required number
of lines from one file to another in
VI editor. First use the following
key combinations in the source file.

Press ESCAPE
Press Shift "(Shift double quotes)
Press a
Press the number of lines you want to copy
press y followed by another y

Now press " : " (COLON) to get the vi prompt.
Hit e "Destination file name"
Once you enter the Destination file
go to the line where you want the lines
copied to be inserted.

Press ESCAPE.
Press SHIFT "(Double quotes).
Press a.
Press p.

The lines get copied.

FIND THOSE HIDDEN FILES

FIND THOSE HIDDEN FILES

Finding only hidden files
(starting with .) in a directory.

ls -a | grep "^\." OR
ls -a | awk '$0~/^\./ {print $0}'

Sunday, March 19, 2006

Most commonly exploited UNIX vulnerabilities?

Most commonly exploited UNIX vulnerabilities?


Poor system administration practices

Reusable/poor passwords

Flawed SUID programs (e.g., rdist, binmail)

HTTP servers and CGI application vulnerabilities

Default "+" entries in the /etc/hosts.equiv file

NFS/NIS vulverabilities sendmail program bugs

Buffer overruns (e.g., gets(), syslog())

SUID shell scripts

Saturday, March 11, 2006

ANOTHER SORT BY FILE SIZE

ANOTHER SORT BY FILE SIZE

To sort certain files in the directory and to show
the biggest file first, do

$ du -a | sort -n -r | more

GREP TEXT NOT BINARY

GREP TEXT NOT BINARY

In some directories such as /etc you have a mix of file types.
You may want to grep out a string from one of the files but
don't want to worry about the binaries, data, etc. To accomplish
this, searching only text files do this:

grep `file * | egrep 'script|text' | awk -F: '{print $1}'`

Monday, March 06, 2006

ZERO THOSE LOG FILES

ZERO THOSE LOG FILES


Some programs write to multiple
log files in a directory and
need to be zeroed out sometimes
to save diskspace. The following
ksh shell script will zero out
all files with the ".log"
extension in a directory.

--- cut here ---
for object in *.log
do
> $object
print "$object has been zeroed!"
done
--- cut here ---

Just a little time saver when
you have 100 other things to
be doing.

REMOVING BLANK LINES

REMOVING BLANK LINES

To remove blank lines from a file using sed, use the following:

sed -e '/^$/d' filetoread >filetowrite

The ^ matches the beginning of a line and the $ matches the end.
The two of them together matches a line that begins and ends with
nothing in between (blank line).
The d just says delete the lines for which we have a match.
Since the standard operation of sed is to print every line,
all lines exept blank lines will be sent to filetowrite.

BASH SHELL OPTION

BASH SHELL OPTION

If you are using bash shell. There is
a way to cd a particular directory
even if you spelled incorrectly on the
command line. Set the shell option to:

shopt -s cdspell

eg:-
Suppose you want to cd to "cd /tmp"
and you have miss typed to "cd /pmp"
still it will cd to "cd /tmp".

This setting will be very usefull if
you have a long named directory.

BASH HOTKEYS

BASH HOTKEYS

Bash provides many hot keys to ease use. Like
ctrl-l -- clear screen
ctrl-r -- does a search in the previously given commands so that you don't
have to repeat long command.
ctrl-u -- clears the typing before the hotkey.
ctrl-a -- takes you to the begining of the command you are currently typing.
ctrl-e -- takes you to the end of the command you are currently typing in.
esc-b -- takes you back by one word while typing a command.
ctrl-c -- kills the current command or process.
ctrl-d -- kills the shell.
ctrl-h -- deletes one letter at a time from the command you are typing in.
ctrl-z -- puts the currently running process in background, the process
can be brought back to run state by using fg command.
esc-p -- like ctrl-r lets you search through the previously given commands.
esc-. -- gives the last command you typed.