Showing posts with label Linux. Show all posts
Showing posts with label Linux. Show all posts

Friday, March 2, 2012

CentOS 5.7 - Build and Install BIND-9.9.0 DNS RPMS

Building the latest, as of March 2012, BIND DNS server RPMS on CentOS 5.7:
yum -y install make gcc rpm-build libtool autoconf openssl-devel libcap-devel libidn-devel libxml2-devel openldap-devel postgresql-devel sqlite-devel mysql-devel krb5-devel xmlto openscap-devel

cd /usr/src/redhat/SRPMS
wget http://centos.alt.ru/pub/repository/centos/5/SRPMS/bind-9.9.0-1.el5.src.rpm
rpm -ivh --nomd5 bind-9.9.0-1.el5.src.rpm

cd /usr/src/redhat/SPECS
rpmbuild -ba ./bind9_9.spec

cd /usr/src/redhat/RPMS/x86_64/
rpm -Uvh bind-9.9.0-1.x86_64.rpm bind-chroot-9.9.0-1.x86_64.rpm bind-utils-9.9.0-1.x86_64.rpm bind-libs-9.9.0-1.x86_64.rpm bind-devel-9.9.0-1.x86_64.rpm

Tuesday, February 21, 2012

Apache LDAP Authentication

This is how to authenticate Microsoft Windows Active Directory users with Apache:

vi /etc/httpd/conf/httpd.conf

Make sure the following 3 lines are NOT hashed out:

LoadModule authnz_ldap_module modules/mod_authnz_ldap.so
LoadModule ldap_module modules/mod_ldap.so
LoadModule auth_basic_module modules/mod_auth_basic.so

Wherever your web directory is, still in /etc/httpd/conf/httpd.conf:
<Directory "/var/www/html">

Options Indexes FollowSymLinks
Order deny,allow
Deny from All
AuthName "AD Username Password please"
AuthType Basic
AuthBasicProvider ldap
AuthzLDAPAuthoritative off
AuthLDAPUrl "ldap://your_dc_fqdn:389/OU=SOME_OU,DC=yourdomain,DC=com?sAMAccountName?sub?(objectClass=*)" NONE
AuthLDAPBindDN "CN=your_AD_user,CN=Users,DC=yourdomain,DC=com"
AuthLDAPBindPassword your_AD_user_password
Require valid-user
Satisfy any

</Directory>
vi /etc/openldap/ldap.conf

Hash everything out and add the following line:

REFERRALS off

Restart Apache
/etc/init.d/httpd restart

Now if you go to your web server's root with your browser, you will be prompted for a username and password. If you do have a valid Active Directory user account, you will be authenticated against AD.

Monday, February 20, 2012

Bulk User Account Migration - RedHat/CentOS

Here are two scripts to transfer user accounts from one RedHat/CentOS server to another. All home directory files, mail, group settings, passwords stays in tact. The first script needs to be executed on the source server and the second script needs to be executed on the destination server:
#!/bin/bash
#Run on Source Server

DESTSERVER=<destination_server_ip>
export UGIDLIMIT=500
mkdir /root/usersmigrate

awk -v LIMIT=$UGIDLIMIT -F: '($3>=LIMIT) && ($3!=65534)' /etc/passwd > /root/usersmigrate/passwd.mig
awk -v LIMIT=$UGIDLIMIT -F: '($3>=LIMIT) && ($3!=65534)' /etc/group > /root/usersmigrate/group.mig
awk -v LIMIT=$UGIDLIMIT -F: '($3>=LIMIT) && ($3!=65534) {print $1}' /etc/passwd | tee - |egrep -f - /etc/shadow > /root/usersmigrate/shadow.mig
cp /etc/gshadow /root/usersmigrate/gshadow.mig

scp -rp /root/usersmigrate root@$DESTSERVER:/root/

tar zcvf - /home/ | ssh root@$DESTSERVER 'cd /; tar zxvf - '
tar zcvf - /var/spool/mail/ | ssh root@$DESTSERVER 'cd /; tar zxvf - '

#!/bin/bash
#Run on Destination Server

export UGIDLIMIT=500

awk -v LIMIT=$UGIDLIMIT -F: '($3<=LIMIT) && ($3!=500)' /etc/passwd > /etc/passwdnew
awk -v LIMIT=$UGIDLIMIT -F: '($3<=LIMIT) && ($3!=500)' /etc/group > /etc/groupnew
awk -v LIMIT=$UGIDLIMIT -F: '($3<=LIMIT) && ($3!=500) {print $1}' /etc/passwd | tee - |egrep -f - /etc/shadow > /etc/shadownew

cat /root/usersmigrate/passwd.mig >> /etc/passwdnew
mv -f /etc/passwdnew /etc/passwd
cat /root/usersmigrate/group.mig >> /etc/groupnew
mv -f /etc/groupnew /etc/group
cat /root/usersmigrate/shadow.mig >> /etc/shadownew
mv -f /etc/shadownew /etc/shadow
cp /root/usersmigrate/gshadow.mig /etc/gshadow

Sunday, February 19, 2012

Asterisk - Registered Useragent Audit

Here is a quick script I put together to get a list of all phones currently registered to our Asterisk box:
#!/bin/bash

for i in `asterisk -rx "sip show peers" | grep -av Unspecified | grep -a "/" | grep -a "^[0-9]" | cut -f 1 -d '/'`
do
user=`asterisk -rx "sip show peer $i" | grep -a "Useragent"`
echo $i = $user |awk '{ print $1","$5 }'
done

Saturday, February 18, 2012

"On-the-Fly" Read-Write Compressed Filesystem

I recently had a problem where "SARG" (SQUID Proxy reporting tool) completely chew up all root filesystem space as reports was generated daily and stored under /var/www/html/sarg. Quick solution... I thought this can also come in handy for future reference... "On-the-Fly read-write compressed filesystem"

I did this on CentOS 5.5:

rpm -Uhv http://apt.sw.be/redhat/el5/en/x86_64/rpmforge/RPMS//rpmforge-release-0.3.6-1.el5.rf.x86_64.rpm

yum -y install squashfs-tools fuse-unionfs

mv /var/www/html/sarg /root/sarg-old
mkdir /var/www/html/sarg

mksquashfs /root/sarg-old /.sarg-compressed.sqfs -check_data

mkdir -p /var/squashed/{ro,rw}

Add the following to /etc/fstab:
/.sarg-compressed.sqfs  /var/squashed/ro  squashfs  loop,ro  0 0
unionfs#/var/squashed/rw=rw:/var/squashed/ro=ro /var/www/html/sarg fuse default_permissions,allow_other,use_ino,nonempty,suid,cow 0 0

mount -all

touch /var/www/html/sarg/test
rm -rf /var/www/html/sarg-old

Check that your new fuse filesystem is mounted:

df -h

By doing this, all files writen to /var/www/html/sarg is actually being written "inside" /.sarg-compressed.sqfs (The compressed filesystem) Files like text or html in this instance are compressed at a massive ratio.

Saturday, April 24, 2010

The Gentoo KIOSK System - part1

In part1 of this guide I will setup the base CLI system. In part2 I will install X, some extras and lock the system down.


To most people reading this article, the following will seem irrelivant. If this is the case, skip to the part on how to build the KIOSK system.

To those that does not understand or choose to ignore the difference between the two words, "cannot" and "refuse", if you would tell the same lie enough to yourself, you will start believing it! I would like to give the following examples:

Quote from the Cambridge Online dictionary:

cannot (modal verb)
can not; the negative form of the verb 'can'

can (modal verb) ( ABILITY )
to be able to
Can you drive?
She can speak four languages.
Can you read that sign from this distance?
The doctors are doing all that they can, but she's still not breathing properly.
Do the best you can - I realize the circumstances are not ideal.
If the party is awful, we can always leave (= that would be one possible solution to our problem).
"She's really furious about it." "Can you blame her (= I'm not surprised)?"

refuse (verb)
to say that you will not do or accept something

If you would say: I'll make him an offer he cannot refuse and "cannot" and "refuse" had the same meaning, You would have said: I'll make him an offer he refuse to refuse. Clearly this explains that the word "cannot" and the word "refuse" have two different meanings. In the Afrikaans language the synonym of this would be: Ek maak vir hom 'n aanbod wat hy nie kan weier nie. Cannot="nie kan" or "kan nie" and refuse="weier" If these two words had the same meaning I would have said in Afrikaans: Ek maak vir hom n' aanbod wat hy weier om te weier. This doesn't make sence and change the syntax completely...

Another example: To say "I cannot go to your wedding" and to say "I refuse to go to your wedding" means two different things. In the first example the person is not able to go to the wedding. In the second example the person can go but grossly choose not to go. In the Afrikaans language: "Ek kan nie na jou troue toe gaan nie" and "Ek weier om na jou troue toe te gaan" once again has two different meanings.

In other words, moral of the story... "Cannot" and "Refuse" does indeed have two different meanings.

That being said, here is the guide to setup and configure a completely locked down KIOSK system that can be used in KIOSKs or as in my case as a Super Duper client system for Call Centers with a Web driven backend. Nice thing is that to have your agents work on different systems (Web Backends), you can update all workstations in batch to point to the "URL" (backend system) that they need to work on. Agents can't fiddle with the system and break things... Yeaay...No Microsoft licensing costs... No viruses... Cheap hardware... The list goes on.

Download and burn the minimum installation CD:
http://www.gentoo.org/main/en/where.xml

Boot with minimal live cd
If it hangs at "Scanning... wd7000" reboot and boot with gentoo noload=pata_qdi
passwd root
give it a password and repeat
/etc/init.d/sshd start ifconfig
See what your IP address is.
Back to your main PC...
ssh root@gentoo_ip_address
Now you're in and can start the install process.

Configuring disk partitions and filesystems:
fdisk /dev/hda
o
n
p
1
default cylinders
+128M
n
p
2
default cylinders
+2048M
n
p
3
default cylinders
default size
press p to print partition layout to see if all looks good.
press w to write the partition table.

Now to apply the filesystems and activate the swop partition:
mke2fs /dev/hda1
mke2fs -j /dev/hda3
mkswap /dev/hda2
swapon /dev/hda2
Mounting the new partitions:
mount /dev/hda3 /mnt/gentoo
mkdir /mnt/gentoo/boot
mount /dev/hda1 /mnt/gentoo/boot
Getting stage3 and portage: (Substitute where stage filename differs)
cd /mnt/gentoo
wget ftp://ftp.is.co.za/linux/distributions/gentoo/releases/x86/current-stage3/stage3-i486-20100126.tar.bz2
tar xvjpf stage3-*.tar.bz2
wget ftp://ftp.is.co.za/linux/distributions/gentoo/releases/snapshots/current/portage-latest.tar.bz2
tar xvjf /mnt/gentoo/portage-latest.tar.bz2 -C /mnt/gentoo/usr
Configuring compile options:
nano -w /mnt/gentoo/etc/make.conf
Add the following two lines and save.
FEATURES="ccache distlocks fixpackages parallel-fetch preserve-libs protect-owned sandbox sfperms strict unmerge-orphans userfetch"
INPUT_DEVICES="evdev"
mkdir -p /mnt/gentoo/usr/lib/ccache/bin
Set Gentoo mirrors and sync:
mirrorselect -i -o >> /mnt/gentoo/etc/make.conf
mirrorselect -i -r -o >> /mnt/gentoo/etc/make.conf
For local South African mirrors:
nano -w /mnt/gentoo/etc/make.conf
add http://ftp.leg.uct.ac.za/pub/linux/gentoo to GENTOO_MIRRORS
replace SYNC="rsync://ftp.leg.uct.ac.za/gentoo-portage"

DNS configuration:
cp -L /etc/resolv.conf /mnt/gentoo/etc/
Mounting /proc and /dev filesystems:
mount -t proc none /mnt/gentoo/proc
mount -o bind /dev /mnt/gentoo/dev
CHROOT into the newly created environment:
chroot /mnt/gentoo /bin/bash
env-update
source /etc/profile
export PS1="(chroot) $PS1"
Syncing portage:
emerge --sync
Check if make.profile link looks good:
ls -FGg /etc/make.profile
Adding custom USE FLAGS to make.conf:
nano -w /etc/make.conf
And make the USE flags line look like this:
USE="server zlib nsplugin motif nptl -debug -pic -xcb -gnome -kde -qt3 -qt4 dbus hal nptl X xorg -dmx -ipv6 -kdrive -minimal -sdl -tslib ssl alsa oss midi jpeg png xulrunner nspr nss ntp caps unicode"  or what else you want or don't want between quotes
Updating portage:
emerge portage
Set the timezone:
cp /usr/share/zoneinfo/Africa/Johannesburg /etc/localtime
Emerging the Gentoo kernel sources:
emerge gentoo-sources
Doing some manual kernel configuration: (NOTE: for kernel 2.6.31-r6)
cd /usr/src/linux
(If you're going to recompile your kernel, remember to make "make clean" first)
make menuconfig

Processor type and features
 [*] Support for old Pentium 5 / WinChip machine checks

File systems
 <*> Second extended fs support                                                                          
        [*]   Ext2 extended attributes                                                                             
 [*]   Ext2 POSIX Access Control Lists                  
 [*]   Ext2 Security Labels
 [*]   Ext2 execute in place support
File systems
 CD-ROM/DVD Filesystems  --->
  <*> UDF file system support
File systems
 DOS/FAT/NT Filesystems  ---> 
  <*> NTFS file system support
  [*] NTFS write support
File systems
 Network File Systems  --->
  <*> CIFS support (advanced network filesystem, SMBFS successor) 
  [*] CIFS statistics                                                                           
            [*] Extended statistics                                                        
             [*] Support legacy servers which use weaker LANMAN security                                      
            [*] Kerberos/SPNEGO advanced session setup                                                
           [*] CIFS extended attributes                                                          
            [*] CIFS POSIX Extensions
                                                
Device Drivers  ---> 
 <M> Sound card support  --->
  <M> Advanced Linux Sound Architecture  --->
                        <M> Sequencer support
                        <M> Sequencer dummy client                                                                            
                        <M> OSS Mixer API                                                                               
                        <M> OSS PCM (digital audio) API                                                                        
                        [*] OSS PCM (digital audio) API - Include plugin system                                             
                        [*] OSS Sequencer API                                                                                    
                        <M> HR-timer backend support                                                                             
                        [*] Use HR-timer as default sequencer timer
                        [ ] Support old ALSA API   
  PCI sound devices  --->
   <M> Intel/SiS/nVidia/AMD/ALi AC97 Controller
   <M> VIA 82C686A/B, 8233/8235 AC97 Controller
 Graphics support --->
            <*> /dev/agpgart (AGP Support) --->
   <*> ALI chipset support
   <*> ATI chipset support
   <*> NVIDIA nForce/nForce2 chipset support
   <*> VIA chipset support
  <*> Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)  --->
   <*> ATI Radeon
   <*> Intel I810 
  -*- Support for frame buffer devices  --->
                        [*] Enable firmware EDID
   [ ] Enable Tile Blitting Support
   [*] VESA VGA graphics support
                        <*> nVidia Framebuffer Support
                         [*] Enable DDC Support
                        <*> Intel 810/815 support (EXPERIMENTAL)
   <*> Matrox acceleration
                        <*> ATI Radeon display support
                [ ] Bootup logo  --->
 Network device support  --->
  [*] Ethernet (10 or 100Mbit)  --->
   <*> 3c590/3c900 series (592/595/597) "Vortex/Boomerang" support
   <*> 3cr990 series "Typhoon" support
   <*> Broadcom 440x/47xx ethernet support
   [*] Support for older RTL-8129/8130 boards
   [*] Ethernet (1000 Mbit)  --->
   <*> Intel(R) 82575/82576 PCI-Express Gigabit Ethernet support
   <*> JMicron(R) PCI-Express Gigabit Ethernet support
   <*> Broadcom CNIC support

Bus options (PCI etc.)  ---> 
 [*] Enable deprecated pci_find_* API

Kernel hacking --->
 [*] Enable unused/obsolete exported symbols
Compiling and installing the new kernel:
make && make modules_install
cp arch/i386/boot/bzImage /boot/kernel-2.6.31-gentoo-r6
If you have kernel modules that you want to load automatically, follow
http://www.gentoo.org/doc/en/handbook/handbook-x86.xml?part=1&chap=7#kernel_modules

Creating new fstab and configuring mount points at boot:
Note that mount points must be defined as sda although your harddrive is hda.
The new kernels does not recognize hda anymore.
nano -w /etc/fstab

/dev/sda1               /boot           ext2            noauto,noatime          1 2
/dev/sda2               none            swap            sw                      0 0
/dev/sda3               /               ext3            noatime                 0 1
/dev/cdrom              /mnt/cdrom      auto            noauto,user             0 0
#/dev/fd0               /mnt/floppy     auto            noauto                  0 0
proc                    /proc           proc            defaults                0 0
shm                     /dev/shm        tmpfs           nodev,nosuid,noexec     0 0
Configuring the network settings:
nano -w /etc/conf.d/hostname
HOSTNAME="your_preferred_hostname"

nano -w /etc/conf.d/net
dns_domain_lo="your_preferred_domain_name"
#config_eth0=( "192.168.0.2 netmask 255.255.255.0 brd 192.168.0.255" )
#routes_eth0=( "default via 192.168.0.1" )
config_eth0=( "dhcp" )

rc-update add net.eth0 default
Configure the hosts file:
nano -w /etc/hosts
Set the root password:
passwd root
Configure the clock:
nano -w /etc/conf.d/clock
CLOCK="local"
TIMEZONE="Johannesburg"
Installing basic system tools:
emerge syslog-ng
rc-update add syslog-ng default
emerge logrotate
emerge vixie-cron
rc-update add vixie-cron default
emerge jfsutils
emerge dhcpcd
emerge net-misc/ntp

nano -w /etc/ntp.conf
server ntp.time.za.net

rc-update add ntpd default
rm /etc/adjtime
NOTE: date 012514262010 (for 14:26PM 2010-01-25) Format is: MMDDhhmm[[CC]YY][.ss]
hwclock --local --systohc
cd /
touch currtime
find . -cnewer /currtime -exec touch {} \; (Don't worry about errors)
rm -rf /currtime
rc-update add sshd default
rc-update del netmount
emerge mingetty
emerge sudo
Configure the bootloader:
emerge grub
nano -w /boot/grub/grub.conf

default 0
timeout 1
#splashimage=(hd0,0)/boot/grub/splash.xpm.gz
title Gentoo Linux 2.6.31-r6
root (hd0,0)
kernel /boot/kernel-2.6.31-gentoo-r6 root=/dev/sda3

grep -v rootfs /proc/mounts > /etc/mtab
grub-install --no-floppy /dev/hda
If you want smaller fonts in the CLI:
nano -w /etc/rc.conf
CONSOLEFONT="default8x9"
Exit CHROOT, umounting mount points and rebooting into the new system:
exit
cd
umount /mnt/gentoo/boot /mnt/gentoo/dev /mnt/gentoo/proc /mnt/gentoo
reboot

The Gentoo KIOSK System - part2

Part2 of the Gentoo Linux KIOSK system. Here I will configure the X system, extras and lock the system down.

emerge xorg-server (if you get "A file is not listed in the Manifest"... do, nano /etc/make.conf and FEATURES=-strict)
env-update
source /etc/profile
/etc/init.d/hald start
rc-update add hald default
Xorg -configure
cp /root/xorg.conf.new /etc/X11/xorg.conf
rm -rf /root/xorg.conf.new

nano -w /etc/X11/xorg.conf
In the Section "Screen" add the following under Monitor...
DefaultDepth 24

Then in SubSection "Display", Depth 24 add the following under Depth 24
Modes "1024x768" "800x600"

Under Section "InputDevice", replace:
Driver "kbd"
with
Driver "evdev"

and

Driver "mouse"
with
Driver "evdev"

Adding the client user:
useradd -m -G users,audio,wheel clientsales
Automatic login the client user:
nano -w /etc/inittab
replace c1:12345:respawn:/sbin/agetty 38400 tty1 linux
with
c1:12345:respawn:/sbin/mingetty --autologin clientsales --noclear tty1

#Disable ctrl+alt+delete key combination
# What to do at the "Three Finger Salute".
#ca:12345:ctrlaltdel:/sbin/shutdown -r now

nano /etc/sudoers
Under the "# User privilege specification" section add the following:
clientsales ALL=(ALL) NOPASSWD: ALL

Installaing VNC server:
emerge net-misc/tigervnc
vncpasswd
su clientsales
vncpasswd
exit

nano /etc/X11/xorg.conf
Add the following to Section "Module"
        Load  "vnc"
Add the following to Section "Screen"
        Option     "PasswordFile"    "/home/clientsales/.vnc/passwd"

Installing sound:
emerge alsa-utils
alsamixer to configure sound levels
alsaconf
rc-update add alsasound boot

## Please note: Firefox 3.6 and newer does NOT work this way with Java plugin
Installing firefox with all dependencies:
emerge mozilla-firefox
emerge -C mozilla-firefox
cd /opt
wget http://mirror.atratoip.net/mozilla/firefox/releases/3.5.7/linux-i686/is/firefox-3.5.7.tar.bz2
bzip2 firefox-3.5.7.tar.bz2

Installing Adobe Flash plugin:
Download tar.gz version from Adobe
copy gz file to /opt/
tar -zxvf install_flash_player_10_linux.tar
move the .so file to /opt/firefox/plugins/

Installaing Sun Java Runtime Environment:
emerge -C dev-java/icedtea6-bin
Download Sun JRE bin file and install in /opt/
chmod +x jre-6u20-linux-i586.bin
./jre-6u20-linux-i586.bin
ln -s /opt/jre1.6.0_18/plugin/i386/ns7/libjavaplugin_oji.so /opt/firefox/plugins/libjavaplugin_oji.so

Adding environment variables for JAVA, lockdown and make X automatically start at boot for the clientsales user profile.
su clientsales
nano /home/clientsales/.bashrc (Add the following:)
export J2RE_HOME=/opt/jre1.6.0_18
export PATH=$J2RE_HOME/bin:$PATH
sudo /bin/stty intr undef
sudo /bin/stty kill undef
sudo /bin/stty quit undef
sudo /bin/stty susp undef
sudo startx &>/dev/null

exit

nano startx
Paste the following code and save:
userclientrc=$HOME/.xinitrc
sysclientrc=/etc/X11/xinit/xinitrc

userserverrc=$HOME/.xserverrc
sysserverrc=/etc/X11/xinit/xserverrc
defaultclientargs=""
defaultserverargs="-nolisten tcp -br"
clientargs=""
serverargs=""

if [ -f $userclientrc ]; then
    defaultclientargs=$userclientrc
elif [ -f $sysclientrc ]; then
    defaultclientargs=$sysclientrc

fi
if [ -f $userserverrc ]; then
    defaultserverargs=$userserverrc
elif [ -f $sysserverrc ]; then
    defaultserverargs=$sysserverrc
fi

whoseargs="client"
while [ x"$1" != x ]; do
    case "$1" in
      /''*|\.*) if [ "$whoseargs" = "client" ]; then
                  if [ "x$clientargs" = x ]; then
                      clientargs="$1"
                  else
                      clientargs="$clientargs $1"
                  fi
              else
                  if [ "x$serverargs" = x ]; then
                      serverargs="$1"
                  else
                      serverargs="$serverargs $1"
                  fi
              fi ;;
      --) whoseargs="server" ;;
      *) if [ "$whoseargs" = "client" ]; then
                  if [ "x$clientargs" = x ]; then
                      clientargs="$defaultclientargs $1"
                  else
                      clientargs="$clientargs $1"
                  fi
              else
                  case "$1" in
                      :[0-9]*) display="$1"; serverargs="$serverargs $1";;
                      *) serverargs="$serverargs $1" ;;
                  esac
              fi ;;
    esac
    shift
done

if [ x"$clientargs" = x ]; then
 clientargs="$defaultclientargs"
fi
if [ x"$serverargs" = x ]; then
 serverargs="$defaultserverargs"
fi

if [ x"$XAUTHORITY" = x ]; then
    XAUTHORITY=$HOME/.Xauthority
    export XAUTHORITY
fi

removelist=

# set up default Xauth info for this machine
case `uname` in
Linux*)
 if [ -z "`hostname --version 2>&1 | grep GNU`" ]; then
  hostname=`hostname -f`
 else
  hostname=`hostname`
 fi
 ;;
*)
 hostname=`hostname`
 ;;
esac

authdisplay=${display:-:0}
mcookie=`/usr/bin/mcookie`
dummy=0

# create a file with auth information for the server. ':0' is a dummy.
xserverauthfile=$HOME/.serverauth.$$
xauth -q -f $xserverauthfile << EOF
add :$dummy . $mcookie
EOF
serverargs=${serverargs}" -auth "${xserverauthfile}

# now add the same credentials to the client authority file
# if '$displayname' already exists don't overwrite it as another
# server man need it. Add them to the '$xserverauthfile' instead.
for displayname in $authdisplay $hostname$authdisplay; do
     authcookie=`xauth list "$displayname" \
       | sed -n "s/.*$displayname[[:space:]*].*[[:space:]*]//p"` 2>/dev/null;
    if [ "z${authcookie}" = "z" ] ; then
        xauth -q << EOF
add $displayname . $mcookie
EOF
 removelist="$displayname $removelist"
    else
        dummy=$(($dummy+1));
        xauth -q -f $xserverauthfile << EOF
add :$dummy . $authcookie
EOF
    fi
done

cleanup() {
    [ -n "$PID" ] && kill $PID > /dev/null 2>&1

if [ x"$removelist" != x ]; then
    xauth remove $removelist
fi
if [ x"$xserverauthfile" != x ]; then
    rm -f $xserverauthfile
fi

if command -v deallocvt > /dev/null 2>&1; then
    deallocvt
fi
}

trap cleanup 0

xinit $clientargs -- $serverargs -deferglyphs 16 &

PID=$!

wait $PID

unset PID

chmod +x startx
cp startx /usr/bin/startx

nano xinitrc
Paste the following code and save:
userresources=$HOME/.Xresources
usermodmap=$HOME/.Xmodmap
xinitdir=/etc/X11
sysresources=$xinitdir/Xresources
sysmodmap=$xinitdir/Xmodmap

# merge in defaults and keymaps

if [ -f $sysresources ]; then
    xrdb -merge $sysresources
fi

if [ -f $sysmodmap ]; then
    xmodmap $sysmodmap
fi

if [ -f $userresources ]; then
    xrdb -merge $userresources
fi

if [ -f $usermodmap ]; then
    xmodmap $usermodmap
fi

# First try ~/.xinitrc
if [ -f "$HOME/.xinitrc" ]; then
 XINITRC="$HOME/.xinitrc"
 if [ -x $XINITRC ]; then
  # if the x bit is set on .xinitrc
  # it means the xinitrc is not a
  # shell script but something else
  exec $XINITRC
 else
  exec /bin/sh "$HOME/.xinitrc"
 fi
# If not present, try the system default
elif [ -n "`/etc/X11/chooser.sh`" ]; then
 exec "`/etc/X11/chooser.sh`"
# Failsafe
else
 # start some nice programs
        #twm &
        #xclock -geometry 50x50-1+1 &
        #xterm -geometry 80x50+494+51 &
        #xterm -geometry 80x20+494-0 &
        #exec xterm -geometry 80x66+0+0 -name login
        exec /opt/firefox/firefox
fi

chmod +x xinitrc
cp xinitrc /etc/X11/xinit/xinitrc

Adding some cron entries if needed:
crontab -e

init 6
When the system returns from boot, first set all Firefox preferences. Not saving passwords, not using cookies, exc. Set the following URL as default homepage: file:///home/clientsales/index.html
nano /home/clientsales/.mozilla/firefox/THIS_WILL_BE_DIFFERENT.default/localstore.rdf
sizemode="maximized"
width="1024"
height="768"

nano /home/clientsales/.mozilla/firefox/THIS_WILL_BE_DIFFERENT.default/prefs.js
Add the following 3 lines and save:
user_pref("accessibility.browsewithcaret", false);
user_pref("accessibility.warn_on_browsewithcaret", false);
user_pref("browser.startup.homepage", "file:///home/clientsales/index.html");

mkdir /home/clientsales/.startpage
mkdir /home/clientsales/.startpage/images
nano /home/clientsales/.startpage/defaulthtml
Paste the following code and save:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
  <title>Unconfigured System!</title>
  </head>
  <body bgcolor="#000000" text="#FFFFFF" link="#FFFFFF" vlink="#FFFFFF">
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <center><img src="./.startpage/images/stop.png" /></center>
    <br>
    <br>
    <center><font size="3"><b>This system needs to be configured.
    <br>
    <br>
    <font size="8">
    Network problem detected!
    </font>
    <br>
    <br>
    Please contact the HELPDESK for support!</b></b></font></center>
  </body>
</html>
Save the 2 attached images from part1 and part2 of this article to /home/clientsales/.startpage/images/ with names exclam.png and stop.png
chown -R clientsales:clientsales /home/clientsales/
nano /etc/prep_default_page.sh
And paste the following code:
#!/bin/bash

##URL in prefs.js must be pointing to: file:////home/clientsales/index.html

ipaddr=`ifconfig |grep Bcast |sed 's/Bcast.*//' |sed 's/          inet addr://'`
if [ "$ipaddr" == "" ]
   then
      cat /home/clientsales/.startpage/defaulthtml > /home/clientsales/index.html
   else
      cat /home/clientsales/.startpage/defaulthtml |sed "s/Network problem detected!/IP Address: $ipaddr/" |sed 's/stop.png/exclam.png/' > /home/clientsales/index.html
fi

chmod +x /etc/prep_default_page.sh
chown root:root /etc/prep_default_page.sh

nano /etc/conf.d/local.start
Add the following line:
/etc/prep_default_page.sh

nano /etc/conf.d/rc
Make the following two changes:
RC_PARALLEL_STARTUP="yes"
RC_INTERACTIVE="no"

Cleaning up the system and make it smaller:

Purge Unused Locales:
nano /etc/locale.gen
Unhash the following entries:
en_US ISO-8859-1
en_US.UTF-8 UTF-8
locale-gen
The following will remove features not needed and win space:
NOTE: After these commands ran, Kernel source, portage, man pages, exc will be removed. You will not be able to add more software to this system via emerge anymore.
rm -rf /home/clientsales/.serverauth.*
rm -rf /usr/portage/*
rm -rf /var/tmp/portage/*
rm -rf /usr/share/man/*
rm -rf /usr/src/linux-*
rm -rf /usr/share/portage/*
rm -rf /usr/share/man/*
rm -rf /var/tmp/*
rm -rf /usr/share/doc
rm -rf /var/log/*
rm -rf /var/db/pkg/*
rm -rf /root/.mozilla
rm -rf /usr/share/locale/a*
rm -rf /usr/share/locale/b*
rm -rf /usr/share/locale/c*
rm -rf /usr/share/locale/d*
rm -rf /usr/share/locale/f*
rm -rf /usr/share/locale/g*
rm -rf /usr/share/locale/h*
rm -rf /usr/share/locale/i*
rm -rf /usr/share/locale/j*
rm -rf /usr/share/locale/k*
rm -rf /usr/share/locale/m*
rm -rf /usr/share/locale/n*
rm -rf /usr/share/locale/o*
rm -rf /usr/share/locale/p*
rm -rf /usr/share/locale/q*
rm -rf /usr/share/locale/r*
rm -rf /usr/share/locale/s*
rm -rf /usr/share/locale/t*
rm -rf /usr/share/locale/v*
rm -rf /usr/share/locale/w*
rm -rf /usr/share/locale/x*
rm -rf /usr/share/locale/y*
rm -rf /usr/share/locale/z*
rm -rf /usr/share/locale/el*
rm -rf /usr/share/locale/eo*
rm -rf /usr/share/locale/es*
rm -rf /usr/share/locale/et*
rm -rf /usr/share/locale/lg*
rm -rf /usr/share/locale/li*
rm -rf /usr/share/locale/lt*
rm -rf /usr/share/locale/lv*
rm -rf /usr/share/locale/ug*
rm -rf /usr/share/locale/ur*
rm -rf /usr/share/locale/uz*
find / \( -iname ".serverauth.*" \) -delete
Give this build a new version number:
echo "1.000-2.6.31r6-i686" > /etc/build
Install Firefox Kiosk mode Plugin:

Install the Firefox r-kiosk plugin https://addons.mozilla.org/en-US/firefox/addon/1659

Reboot your system!

This can now be packeged into a nice self-installer CD for rapid deployment to similar hardware.

HINT: The default homepage URL can be changed in batch with scripting. The URL and all other Firefox specific settings can be altered in /home/clientsales/.mozilla/firefox/-somenumber-/prefs.js

Tuesday, April 13, 2010

MySQL, getting data in and out with Perl/CGI

Creating the database and tables:
mysql -u root -p
mysql> CREATE DATABASE tv;
mysql> USE tv;
mysql> CREATE TABLE episodeguide (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, tvshow VARCHAR(50), shownumber VARCHAR(20), showtitle VARCHAR(50), aired VARCHAR(20), overview VARCHAR(500));
NOTE: The database is set up to auto increment the row id, with every new row that's inserted.

Creating Indexes:
mysql> CREATE INDEX tvshow ON episodeguide (tvshow);
mysql> CREATE INDEX showtitle ON episodeguide (showtitle);
mysql> CREATE INDEX overview ON episodeguide (overview);
mysql> exit

Inserting data into the MySQL database with Perl/CGI/HTML:

The HTML file; Call it insert.html and put it in the root of the website.
<form action="https://192.168.1.1/cgi-bin/insertdata.pl"     
method="post"> 
<html>    
<head>     
<title>TV Episode Data Capture Form</title>     
</head>     
<body> 
<H1>TV Episode Data Capture Form</H1>    
<P>     
<HR> 
<H2>Episode submission form: </H2>    
TV Show Name:     
<select name="tvshow">     
<option selected>SHOW     
<option>TV Show 1     
<option>TV Show 2     
<option>TV Show 3     
<option>TV Show 4     
<option>TV Show 5     
</select>     
<P> 
Episode Number:    
<select name="shownumber">     
<option selected>NUMBER     
<option>01     
<option>02     
<option>03     
<option>04     
<option>05     
<option>06     
<option>07     
<option>08     
<option>09     
<option>10     
<option>11     
<option>12     
<option>13     
<option>14     
<option>15     
<option>16     
<option>17     
<option>18     
<option>19     
<option>20     
<option>21     
<option>22     
<option>23     
<option>24     
<option>25     
<option>26     
<option>27     
<option>28     
<option>29     
<option>30     
<option>31     
</select> 
<P>    
Episode Title: <input name="showtitle"><P>     
Original Aired: <input name="aired"><P> 
<P>    
Episode Description:     
<P>     
<textarea name="overview" rows=5 cols=60></textarea>     
<P> 
<input type="submit" value="Click to submit entry"> 
</form>
The Perl/CGI file; This must be called insertdata.pl and be placed in the cgi-bin directory of your website.
#!/usr/bin/perl    
use CGI qw(:standard);     
use DBI; 
print <<END;    
Content-type: text/html 
<html>    
<head>     
<title>TV Episode capture Form</title>     
</head> 
<body bgcolor="white"> 
END 
# database connection info    
$db="tv";     
$host="localhost";     
$userid="mysql_username";     
$passwd="mysql_password";     
$connectionInfo="dbi:mysql:$db;$host"; 
$tvshow = param('tvshow');    
$shownumber = param('shownumber');     
$showtitle = param('showtitle');     
$aired = param('aired');     
$overview = param('overview');     
$year = param('minutesstart');     
$month = param('yearstop');     
$day = param('monthstop'); 
# connect to database    
$dbh = DBI->connect($connectionInfo,$userid,$passwd); 
# prepare and execute query    
$query = "INSERT INTO episodeguide (tvshow,shownumber,showtitle,aired,overview) VALUES(\"$tvshow\",\"Episode $shownumber\",\"$showtitle\",\"$aired\",\"$overview\");";     
$sth = $dbh->prepare($query) || die "Could not prepare SQL statement ... maybe invalid?";     
$sth->execute() || die "Could not execute SQL statement ... maybe invalid?"; 
# assign fields to variables    
$sth->bind_columns(\$ID, \$tvshow, \$shownumber, \$showtitle, \$aired, \$overview); 
# output thanks message to browser    
print "<b>Your entry was sucessfully captured in the database!</b><p>\n";     
print "</table>\n";     
print "</body>\n";     
print "</html>\n"; 
$sth->finish(); 
# disconnect from database    
$dbh->disconnect; 
sub fail {    
print "<title>Error</title>",     
"<p>ERROR: An error ocured, please try again!</p>";     
exit; }
Give the Perl script the correct permissions:
chmod 755 /var/www/cgi-bin/insertdata.pl

And test: http://192.168.1.1/insert.html

Display the inserted data with Perl/CGI:
nano /var/www/cgi-bin/displaydata.pl
#!/usr/bin/perl -w 
use DBI; 
print <<END;    
Content-type: text/html 
<html>    
<head>     
<title>Display my data!</title>     
</head> 
<body bgcolor="white"> 
END 
# database connection info    
$db="tv";     
$host="localhost";     
$userid="mysql_username";     
$passwd="mysql_password";     
$connectionInfo="dbi:mysql:$db;$host"; 
# connect to database    
$dbh = DBI->connect($connectionInfo,$userid,$passwd); 
# prepare and execute query    
$query = "SELECT * FROM episodeguide WHERE tvshow = 'Test TV Show'";     
$sth = $dbh->prepare($query);     
$sth->execute(); 
# assign fields to variables    
$sth->bind_columns(\$ID, \$tvshow, \$shownumber, \$showtitle, \$aired, \$overview); 
# output result to browser    
print "<b>Matches for this hardcoded query:</b><p>\n";     
print "<table width=\"100\%\" border=\"1\" cellpadding=\"2\" cellspacing=\"0\"> <th>ID</th> <th>Show Name</th> <th>Episode Number</th> <th>Episode Title</th> <th>Date Aired</th> <th>Episode Overview</th>\n";     
while($sth->fetch()) {     
print "<tr><td>$ID</td> <td>$tvshow</td> <td>$shownumber</td> <td>$showtitle</td> <td>$aired</td> <td>$overview</td> </tr>\n";     
}     
print "</table>\n";     
print "</body>\n";     
print "</html>\n"; 
$sth->finish(); 
# disconnect from database    
$dbh->disconnect;
Give the correct permissions to the Perl script.
chmod 755 /var/www/cgi-bin/displaydata.pl

And test: http://192.168.1.1/cgi-bin/displaydata.pl

Saturday, April 10, 2010

Public/Private key authentication with SSH, passwordless

On the local server, logged in as, eg. myuser:
Change to myuser's home directory.
mkdir /home/myuser/.ssh
cd /home/myuser/.ssh
ssh-keygen -t rsa
NOTE: When asked for file in wich to save the key, make sure the path reads /home/myuser/.ssh/. We want to save the new generated key-pair in /home/myuser/.ssh/. Also make sure not to specify a passphrase, otherwise, you will still have to input a password at logon. You can also choose to generate a type DSA pair in place of the RSA key pair.
scp /home/myuser/.ssh/id_rsa.pub myuser@remote-server:/home/myuser/id_rsa.local-server.pub

On the remote server, you wish to log into:
mkdir /home/myuser/.ssh
chmod 700 /home/myuser/.ssh
cat /home/myuser/id_rsa.local-server.pub >> /home/myuser/.ssh/authorized_keys
chmod 644 /home/myuser/.ssh/authorized_keys

Monday, April 5, 2010

Ubuntu, LAMP, SSL, CGI and password protection

I'll setup a minimal install of Ubuntu 9.10, Apache webserver, MySQL database and make it PHP compatible. I'll be using a self signed SSL certificate, create a Virtual Host and password protect the space. I'll also make the Virual Host ready to run CGI scripts.

1. Install LAMP environment:

Login as "root"
apt-get update

apt-get install mysql-server mysql-client apache2 ssl-cert php5 libapache2-mod-php5 php5-mysql php5-mcrypt php5-memcache php5-snmp php5-xmlrpc php5-xsl php5-suhosin apache2-suexec libapache2-mod-ruby libapache2-mod-perl2 libapache2-mod-python python-mysqldb
Insert your MySQL "root" user password
echo "ServerName localhost" | sudo tee /etc/apache2/conf.d/fqdn
echo "<?php phpinfo(); ?>" > /var/www/info.php

nano /etc/php5/apache2/php.ini
change upload_max_filesize = 16M to upload_max_filesize = 32M
change memory_limit = 16M to memory_limit = 32M
/etc/init.d/apache2 restart
From another PC type http://yourserverip in your browser and make sure you get the "It works!" message.
From another PC type http://yourserverip/info.php in your browser and you should see some nice info about your PHP installation. After we've seen this page, we know PHP works and "info.php" can be removed:
rm -rf /var/www/info.php
I am not going to use the default port 80 site, so I'll disable it:
nano /etc/apache2/ports.conf
and comment out the following two lines:
#NameVirtualHost *:80
#Listen 80

2. Configure a SSL and CGI ready Virtual Host:
a2enmod ssl

/etc/init.d/apache2 restart

mkdir -p /var/www/www.mydomain.com/public_html
mkdir /var/www/www.mydomain.com/cgi-bin
mkdir /var/www/www.mydomain.com/logs
cp /etc/apache2/sites-available/default-ssl /etc/apache2/sites-available/www.mydomain.com
nano /etc/apache2/sites-available/www.mydomain.com
Change <VirtualHost _default_:443> to <VirtualHost youripaddress:443>
Change ServerAdmin webmaster@localhost to ServerAdmin youremail@address
Add ServerName www.mydomain.com:443 under ServerAdmin line
Change DocumentRoot /var/www to DocumentRoot /var/www/www.mydomain.com/public_html
Change AllowOverride None to AllowOverride AuthConfig
Change <Directory /var/www/> to <Directory /var/www/www.mydomain.com/>
Change AllowOverride None to AllowOverride AuthConfig
Change ScriptAlias to ScriptAlias /cgi-bin/ /var/www/www.mydomain.com/cgi-bin/
Change <Directory "/usr/lib/cgi-bin"> to <Directory "/var/www/www.mydomain.com/cgi-bin">
Change ErrorLog /var/www/www.mydomain.com/logs/error.log
Change CustomLog to CustomLog /var/www/www.mydomain.com/logs/ssl_access.log combined
Change, under </FilesMatch>, <Directory /usr/lib/cgi-bin> to <Directory /var/www/www.mydomain.com/cgi-bin>
a2dissite default-ssl
a2ensite www.mydomain.com
/etc/init.d/apache2 restart

3. Create my own self-signed certificate:

The following will create a self-signed certificate and private key file in one file:
make-ssl-cert /usr/share/ssl-cert/ssleay.cnf /etc/ssl/private/www.mydomain.com.crt

cat /etc/ssl/private/www.mydomain.com.crt
The .crt file needs to be split in two, .key and .pem:
nano /etc/ssl/private/www.mydomain.com.key
Copy the part beginning with -----BEGIN RSA PRIVATE KEY-----  and ending with -----END RSA PRIVATE KEY----- and paste it into your .key file and save.
nano /etc/ssl/certs/www.mydomain.com.pem
Copy the part beginning with -----BEGIN CERTIFICATE-----  and ending with -----END CERTIFICATE----- and paste it into your .pem file and save.
rm -f /etc/ssl/private/www.mydomain.com.crt

nano /etc/apache2/sites-available/www.mydomain.com
Change these two lines to match your server name:
SSLCertificateFile    /etc/ssl/certs/ssl-cert-snakeoil.pem
to
SSLCertificateFile    /etc/ssl/certs/www.mydomain.com.pem
and
SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
to
SSLCertificateKeyFile /etc/ssl/private/www.mydomain.com.key
/etc/init.d/apache2 restart

> /var/www/index.html
Now your secured Virtual Host can be accessed at https://yourservername.

4. Password protect the Virtual host:
cd /var/www/www.mydomain.com
NOTE: This directory is not a web accessible directory.
htpasswd -c -s .htpasswd yourusername
Enter new password
NOTE: To add more usernames and passwords to the same file you must:
htpasswd -s .htpasswd anotherusername

The .htaccess file must exist in the directory that you want to protect:
nano /var/www/www.mydomain.com/public_html/.htaccess
and paste the following:
AuthUserFile /var/www/www.mydomain.com/.htpasswd
AuthType Basic
AuthName "Enter Login Details"
Require valid-user
/etc/init.d/apache2 restart
If you go to https://yourservername now, you will be asked to enter your password, created earlier, to enter the site.

Sunday, April 4, 2010

Ubuntu, Trusted SSL Certificate install in Apache

Generating the Private Key file:
su root
apt-get update
apt-get install ssl-cert
make-ssl-cert /usr/share/ssl-cert/ssleay.cnf /etc/ssl/private/www.mydomainname.com.crt
When asked for username, insert www.mydomainname.com
cat /etc/ssl/private/www.mydomainname.com.crt
As you can see, the file consists of two parts. The RSA Private Key part and the Certificate part. We are interested in the Private Key part. Copy the part beginning with -----BEGIN RSA PRIVATE KEY----- and ending with -----END RSA PRIVATE KEY-----
nano /etc/ssl/private/www.mydomainname.com.key
Paste the copied data and save your key file.
rm -f /etc/ssl/private/www.mydomainname.com.crt
mkdir /etc/ssl/csr
openssl req -new -key /etc/ssl/private/www.mydomainname.com.key -out /etc/ssl/csr/www.mydomainname.com.csr
You will get some questions to answer. Type your answers but IMPORTANT, the "Common Name" must be the domain or hostname of your Virtual Host, e.g. www.mydomainname.com
Your new CSR file will be located here:
cat /etc/ssl/csr/www.mydomainname.com.csr
Now this new CSR file needs to be submitted to a Certificate Authority (CA) like Thawte/Verisign. After you then receive your new certificate from the CA, you must install it:

Open your new certificate you just received and copy the part beginning with -----BEGIN CERTIFICATE-----  and ending with -----END CERTIFICATE-----
nano /etc/ssl/certs/www.mydomainname.com.pem
Paste the copied data and save your pem file.
/etc/init.d/apache2 restart
Your new Trusted Certificate is now installed and should be working. Should your CA request that a certificate chain file or intermediate certificate be installed, you can do the following:

Copy the chain file, given by your CA, to for example your /etc/ssl/certs/ directory on your server. Let's assume the chain filename is CAchainFile.pem
nano /etc/apache2/sites-available/www.mydomainname.com-ssl
In the SSLCertificate section change or add the following:

SSLCertificateChainFile /etc/ssl/certs/CAchainFile.pem

Apache needs to be restarted after this change:
/etc/init.d/apache2 restart
Free Trusted Certificate Authorities:
http://cert.startcom.org
http://www.cacert.org

Friday, April 2, 2010

Ubuntu "Live / Install CD" from existing system

A. Prepare the environment:

1. Set the variables:
export WORK=~/work
export CD=~/cd
export FORMAT=squashfs
export FS_DIR=casper
2. Create the CD and the WORK directory structure:
sudo mkdir -p ${CD}/{${FS_DIR},boot/grub} ${WORK}/rootfs
3. Install packages on the source system:
sudo apt-get update
sudo apt-get install mkisofs grub squashfs-tools linux-headers-$(uname -r)

B. Copy existing installation into the new filesystem:
sudo rsync -av --one-file-system --exclude=/proc/* --exclude=/dev/*\ --exclude=/sys/* --exclude=/tmp/* --exclude=/home/*\ --exclude=/lost+found / ${WORK}/rootfs
If you have a separate boot partition you will have to copy it using the following command:
sudo cp -av /boot/* ${WORK}/rootfs/boot
Copy custom settings:
cp -r /home/yourusername/.config /home/yourusername/.xscreensaver /root/work/rootfs/etc/skel/

C. Chroot into the new system and modify it:

1. Chroot into the copied system after mounting proc and dev:
sudo mount -o bind /dev/ ${WORK}/rootfs/dev 
sudo mount -t proc proc ${WORK}/rootfs/proc
sudo chroot ${WORK}/rootfs /bin/bash
2. Now you are within the chroot environment, type the following commands:
LANG= 
apt-get update 
apt-get install casper discover1 xresprobe
"casper" contain the live scripts. "discover1" & "xresprobe" are used for autodetecting hardware at startup.

3. (Optional) If you want your live cd to have an installer, install the Ubuntu installer:
apt-get install ubiquity
4. (Optional) Install any packages you want to be in the CD with "apt-get".

5. Update the modules.dep and initramfs:
depmod -a $(uname -r)
update-initramfs -u -k $(uname -r)
The initramfs is reponsible for much of the preparation required at the boot time of the CD/DVD. The updated initramfs now contain the live scripts installed with casper.

6. Remove non system users: (script)
for i in `cat /etc/passwd | awk -F":" '{print $1}'`
do
        uid=`cat /etc/passwd | grep "^${i}:" | awk -F":" '{print $3}'`
        [ "$uid" -gt "999" -a  "$uid" -ne "65534"  ] && userdel --force ${i} 2>/dev/null
done
Non-system users are users created by you that have user id more than 999.

7. Delete these files: (script)
for i in "/etc/hosts /etc/hostname /etc/resolv.conf /etc/timezone /etc/fstab /etc/mtab /etc/shadow /etc/shadow- /etc/gshadow  /etc/gshadow- /etc/gdm/gdm-cdd.conf /etc/X11/xorg.conf /boot/grub/menu.lst /boot/grub/device.map"
do
        rm $i
done 2>/dev/null
These files are not needed in the CD/DVD. some of them are could interfer with the CD/DVD boot process. (e.g. shadow and gdm.conf-custom can interfere with autologin).

8. Cleanup the chroot environment: 
apt-get clean 
find /var/run /var/log /var/mail /var/spool /var/lock /var/backups /var/tmp -type f -exec rm {} \;
rm -r /boot/*.bak /tmp/* /home/* /root/* 2>/dev/null
9. If you are using GDM recreate it's config file:
[ -f "/etc/gdm/factory-gdm.conf" ] && cp -f /etc/gdm/factory-gdm.conf /etc/gdm/gdm.conf 2>/dev/null
A customized /etc/gdm/gdm.conf can interfere with the live CD/DVD autologin.

10. Create needed log files in /var/log: (script)
for i in dpkg.log lastlog mail.log syslog auth.log daemon.log faillog lpr.log mail.warn user.log boot debug mail.err messages wtmp bootstrap.log dmesg kern.log mail.info
do
        touch /var/log/${i}
done
Most of these files are log files that have been cleaned in step 7. We created an empty files in their place to prevent the system from complaining at boot.
rm /usr/lib/ubiquity/apt-setup/generators/50cdrom
(Optional) If you want the Installer Icon removed from the final system's Desktop:
rm /usr/share/applications/ubiquity-gtkui.desktop
11. Exit chroot
exit

D. Prepare The CD directory tree:

1. Copy the kernel, the updated initrd and memtest prepared in the chroot:
sudo cp -vp ${WORK}/rootfs/boot/vmlinuz-$(uname -r) ${CD}/boot/vmlinuz 
sudo cp -vp ${WORK}/rootfs/boot/initrd.img-$(uname -r) ${CD}/boot/initrd.gz
sudo cp -vp ${WORK}/rootfs/boot/memtest86+.bin ${CD}/boot
2. Generate manifest:

Note: This step is only needed if you installed the Ubuntu installer ubiquity. This step generates two files (filesystem.manifest & filesystem.manifest-desktop).
sudo chroot ${WORK}/rootfs dpkg-query -W --showformat='${Package} ${Version}\n' | sudo tee ${CD}/${FS_DIR}/filesystem.manifest
sudo cp -v ${CD}/${FS_DIR}/filesystem.manifest{,-desktop}
REMOVE='ubiquity casper user-setup discover1 xresprobe os-prober libdebian-installer4'
(script)
for i in $REMOVE
do
        sudo sed -i "/${i}/d" ${CD}/${FS_DIR}/filesystem.manifest-desktop
done
These two files are used by the ubiquity installer when installing to harddisk. These two files are just lists of packages. Ubiquity compares these two files and removes packages unique to filesystem.manifest. This way when installing to harddisk, packages like casper which is only useful in a live CD/DVD are removed. These packages that will be removed at install are defined in the variable $REMOVE

3. Unmount bind mounted dirs:
sudo umount ${WORK}/rootfs/dev ${WORK}/rootfs/proc
4. Convert the directory tree into a squashfs:
sudo mksquashfs ${WORK}/rootfs ${CD}/${FS_DIR}/filesystem.${FORMAT}
Note: Make sure the resulting file size can fit into your live media.

5. Make Grub the bootloader for the CD

Copy grub file:
sudo find /boot /usr/lib/grub/ -iname 'stage2_eltorito' -exec cp -v {} ${CD}/boot/grub \;
Make the menu.lst
sudo nano ${CD}/boot/grub/menu.lst
Adjust and copy the following text into it and save it:
# By default, boot the first entry.
default 0

# Boot automatically after 30 secs.
timeout 30

title                System (Graphical Mode)
kernel                /boot/vmlinuz BOOT=casper boot=casper nopersistent rw quiet splash
initrd                /boot/initrd.gz

title                System (Safe Graphical Mode)
kernel                /boot/vmlinuz BOOT=casper boot=casper xforcevesa rw quiet splash
initrd                /boot/initrd.gz

title                Linux (Text Mode CLI)
kernel                /boot/vmlinuz BOOT=casper boot=casper nopersistent textonly rw quiet
initrd                /boot/initrd.gz

title                Memory Test
kernel                /boot/memtest86+.bin

title                Boot the First Hard Disk
root                (hd0)
chainloader +1
6. Calculate MD5:
cd $CD && find . -type f -print0 | xargs -0 sudo md5sum | sudo tee ${CD}/md5sum.txt

E. Build the CD/DVD

1. Make the ISO file:
sudo mkisofs -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -boot-info-table -V "MY_LIVE_CD" -cache-inodes -r -J -l -o ~/my-live-install-cd.iso $CD
2. Burn your new created ISO! 

Wednesday, March 24, 2010

Microsoft Exchange as relay for Elastix 1.6 eMail

You will need to have a valid domain user with an Exchange mailbox to send mail as.

SSH to your Elastix box and run the following commands:
postconf -e 'relayhost = exchange-ip-address'
postconf -e 'smtp_sasl_auth_enable = no'
postconf -e 'smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd'
postconf -e 'smtp_sasl_security_options ='
postconf -e 'mydomain = your-domain-name.com'
postconf -e 'myhostname = elastix-hostname.your-domain-name.com'

echo "exchange-ip-address   domain-username:domain-password" > /etc/postfix/sasl_passwd

chown root:root /etc/postfix/sasl_passwd
chmod 600 /etc/postfix/sasl_passwd

postmap /etc/postfix/sasl_passwd

/etc/init.d/postfix restart
To test mail function:
mail -s test valid-email@whatever.com < /etc/hosts
You should then get an email from your Elastix box with subject "test".

Elastix 1.6 and A2Billing 1.4.2.1 upgrade

rpm -e elastix-a2billing

mkdir /usr/local/src/a2billing
cd /usr/local/src/a2billing
wget http://www.asterisk2billing.org/downloads/A2Billing_1.4.2.1.tar.gz
tar zxvf A2Billing_1.4.2.1.tar.gz

init 6

cd /usr/local/src/a2billing
mysql -u root -p < DataBase/mysql-5.x/a2billing-createdb-user.sql
(The default Elastix MySQL root password is: eLaStIx.2oo7)
The script will create a database, username and password with the following default values
Database name is: mya2billing
Database user is: a2billinguser
User password is: a2billing
mysql -u root -p
drop database mya2billing;
quit
mysql -u root -p < DataBase/mysql-5.x/a2billing-createdb-user.sql
mysql -u root -p mya2billing < DataBase/mysql-5.x/a2billing-schema-v1.4.0.sql
mysql -u root -p mya2billing < DataBase/mysql-5.x/UPDATE-a2billing-v1.4.0-to-v1.4.1.sql
mysql -u root -p mya2billing < DataBase/mysql-5.x/UPDATE-a2billing-v1.4.1-to-v1.4.2.sql

cp /usr/local/src/a2billing/a2billing.conf /etc/
nano /etc/a2billing.conf (Change as follows:)
[database]
hostname = localhost
port = 3306
user = a2billinguser
password = a2billing
dbname = mya2billing
dbtype = mysql
touch /etc/asterisk/additional_a2billing_iax.conf
touch /etc/asterisk/additional_a2billing_sip.conf
echo #include additional_a2billing_sip.conf >> /etc/asterisk/sip.conf
echo #include additional_a2billing_iax.conf >> /etc/asterisk/iax.conf
chown -Rf asterisk:asterisk /etc/asterisk/additional_a2billing_iax.conf
chown -Rf asterisk:asterisk /etc/asterisk/additional_a2billing_sip.conf

cd /usr/local/src/a2billing/addons/sounds/
./install_a2b_sounds.sh
cd /usr/local/src/a2billing
nano /etc/asterisk/manager.conf (Add following lines:)
[myasterisk]
secret=mycode
read=system,call,log,verbose,command,agent,user
write=system,call,log,verbose,command,agent,user

[cacti]
secret = cacti
deny=0.0.0.0/0.0.0.0
permit=192.168.1.1/255.255.255.0 #Your Cacti Server IP and Mask
read = command
write = command
cd /usr/local/src/a2billing/AGI
cp a2billing.php /var/lib/asterisk/agi-bin/
cp -Rf /usr/local/src/a2billing/common/lib /var/lib/asterisk/agi-bin/

chown asterisk:asterisk /var/lib/asterisk/agi-bin/a2billing.php
chown -Rf asterisk:asterisk /var/lib/asterisk/agi-bin/lib
chmod +x /var/lib/asterisk/agi-bin/a2billing.php
cd /usr/local/src/a2billing

mkdir /var/www/html/a2billing
chown asterisk:asterisk /var/www/html/a2billing

cp -rf /usr/local/src/a2billing/admin /var/www/html/a2billing/
cp -rf /usr/local/src/a2billing/agent /var/www/html/a2billing/
cp -rf /usr/local/src/a2billing/customer /var/www/html/a2billing/
cp -rf /usr/local/src/a2billing/common /var/www/html/a2billing/

chmod 755 /var/www/html/a2billing/admin/templates_c
chmod 755 /var/www/html/a2billing/customer/templates_c
chmod 755 /var/www/html/a2billing/agent/templates_c
chown -Rf asterisk:asterisk /var/www/html/a2billing/admin/templates_c
chown -Rf asterisk:asterisk /var/www/html/a2billing/customer/templates_c
chown -Rf asterisk:asterisk /var/www/html/a2billing/agent/templates_c
nano /etc/httpd/conf.d/a2billing.conf (Add the following line:)
Alias /a2billing /var/www/html/a2billing/admin
service httpd restart
Now, to enter to new a2billing you must access it throught the follow URL:
http://elastix-ip-address/a2billing
the default user and password are:
user: root
pass: changepassword

nano /etc/asterisk/extensions_a2billing.conf (Add the following lines:)
[a2billing]
; CallingCard application
exten => _X.,1,Answer
exten => _X.,2,Wait,2
exten => _X.,3,DeadAGI,a2billing.php
exten => _X.,4,Wait,2
exten => _X.,5,Hangup

[did]
; CallingCard application
exten => _X.,1,DeadAGI(a2billing.php|1|did)

nano /etc/asterisk/extensions.conf (Add the following line to the TOP of the file:)
#include extensions_a2billing.conf

nano /var/spool/cron/a2billing (Add the following lines:)
# update the currency table
0 6 * * * php /usr/local/src/a2billing/Cronjobs/currencies_update_yahoo.php

# manage the monthly services subscription
0 6 1 * * php /usr/local/src/a2billing/Cronjobs/a2billing_subscription_fee.php

# To check account of each Users and send an email if the balance is less than the user have choice.
0 * * * * php /usr/local/src/a2billing/Cronjobs/a2billing_notify_account.php

# To check all the accounts and send an notification email if the balance is less than the first argument.
0 */6 * * php /usr/local/src/a2billing/Cronjobs/a2billing_check_account.php

# this script will browse all the DID that are reserve and check if the customer need to pay for it
# bill them or warn them per email to know if they want to pay in order to keep their DIDs
0 2 * * * php /usr/local/src/a2billing/Cronjobs/a2billing_bill_diduse.php

# This script will take care of the recurring service.
0 12 * * * php /usr/local/src/a2billing/Cronjobs/a2billing_batch_process.php

# To generate invoices and for each user.
0 6 * * * php /usr/local/src/a2billing/Cronjobs/a2billing_invoice_cront.php

# to proceed the autodialer
*/5 * * * * php /usr/local/src/a2billing/Cronjobs/a2billing_batch_autodialer.php

# manage alarms
0 * * * * php /usr/local/src/a2billing/Cronjobs/a2billing_alarm.php
mkdir /var/log/a2billing
touch /var/log/a2billing/a2billing_agi.log
touch /var/log/a2billing/a2billing_api_callback_request.log
touch /var/log/a2billing/a2billing_api_card.log
touch /var/log/a2billing/a2billing_api_ecommerce_request.log
touch /var/log/a2billing/a2billing_epayment.log
touch /var/log/a2billing/a2billing_paypal.log
touch /var/log/a2billing/cront_a2b_alarm.log
touch /var/log/a2billing/cront_a2b_archive_data.log
touch /var/log/a2billing/cront_a2b_autorefill.log
touch /var/log/a2billing/cront_a2b_batch_process.log
touch /var/log/a2billing/cront_a2b_bill_diduse.log
touch /var/log/a2billing/cront_a2b_check_account.log
touch /var/log/a2billing/cront_a2b_currency_update.log
touch /var/log/a2billing/cront_a2b_invoice.log
touch /var/log/a2billing/cront_a2b_subscription_fee.log

yum install python-setuptools MySQL-python python-psycopg2 python-sqlalchemy
cd /usr/local/src/a2billing/CallBack

easy_install --upgrade SQLAlchemy
LOAD_LOC=/usr/local/src/a2billing
cd $LOAD_LOC/CallBack/callback-daemon-py
cp callback_daemon/a2b-callback-daemon.rc /etc/init.d/a2b-callback-daemon
chmod +x /etc/init.d/a2b-callback-daemon
cp dist/callback_daemon-1.0.prod-r1528.tar.gz /tmp
cd /tmp
tar xvfz callback_daemon-1.0.prod-r1528.tar.gz
cd callback_daemon-1.0.prod-r1528
python setup.py build
python setup.py bdist_egg
easy_install dist/callback_daemon-1.0.prod_r1528-py2.4.egg

chkconfig --add a2b-callback-daemon
service a2b-callback-daemon start
chkconfig a2b-callback-daemon on
mv /etc/rc.d/rc0.d/K60a2b-callback-daemon /etc/rc.d/rc0.d/K02a2b-callback-daemon
mv /etc/rc.d/rc1.d/K60a2b-callback-daemon /etc/rc.d/rc1.d/S022za2b-callback-daemon
mv /etc/rc.d/rc3.d/S40a2b-callback-daemon /etc/rc.d/rc3.d/S98za2b-callback-daemon
mv /etc/rc.d/rc4.d/S40a2b-callback-daemon /etc/rc.d/rc4.d/S98za2b-callback-daemon
mv /etc/rc.d/rc5.d/S40a2b-callback-daemon /etc/rc.d/rc5.d/S98za2b-callback-daemon
mv /etc/rc.d/rc6.d/K60a2b-callback-daemon /etc/rc.d/rc6.d/K02a2b-callback-daemon

Tuesday, March 23, 2010

PFSense 1.2.3 BSD and traffic splitting between 2 ISPs

I was once working on a this project in the attempt to migrate from IPCOP... but instead I went for DD-WRT on Linksys, and this project died a quite dead... This was done to split traffic between "Local" and "International" in South Africa, due to that "Local" internet traffic that's much cheaper. Anyways, here is the code:

Install stock PFSense 1.2.3
pkg_add -v -r mpd5 wget
The "get local route" script:
#!/bin/sh

WORKDIR="/tmp"
DATE=`date`

cd $WORKDIR

#Retrieve the local routes file
/usr/local/bin/wget "http://developers.locality.co.za/routes.txt" -O $WORKDIR/routes.raw
cat $WORKDIR/routes.raw | grep "/" | /usr/bin/awk '{print "route add -net "$1" -interface ng0"}' > $WORKDIR/routes.dat

# Make sure downloaded routes file exists
# If file does not exist Restore the backup
if [ ! -s $WORKDIR/routes.dat ]; then
   /usr/bin/logger -t ROUTESET "Local routes download failed. Using backup if routes.dat.bak exists..."
   cp -f $WORKDIR/routes.dat.bak $WORKDIR/routes.dat
else
  /usr/bin/logger -t ROUTESET "Local routes - routes.dat successfully created."

  #Backup new downloaded routes.dat file
  cp $WORKDIR/routes.dat $WORKDIR/routes.dat.bak

  #Add the new local routes
  chmod 777 $WORKDIR/routes.dat
  route flush
  $WORKDIR/routes.dat
  /usr/bin/logger -t ROUTESET "Local routes sucessfully added."

  #Clean up
  rm -f $WORKDIR/routes.raw $WORKDIR/routes.txt $WORKDIR/routes.dat
fi
Then to make PFSense dial 2 PPP connections, I had to do the following:

vi /usr/local/etc/mpd5/mpd.conf
startup:

default:
        load local
        load international

local:
        create bundle static Local
        set iface route default
        set iface up-script /usr/local/sbin/ppp-linkup
        set ipcp ranges 0.0.0.0/0 0.0.0.0/0
        create link static Local pppoe
        set link action bundle Local
        set auth authname your_local_account_username
        set auth password your_local_account_password
        set link max-redial 0
        set link mtu 1462
        set link mru 1462
        set link keep-alive 10 60
        set pppoe iface fxp0
        set pppoe service "Local"
        open

international:
        create bundle static International
        set iface route default
        set iface up-script /usr/local/sbin/ppp-linkup
        set ipcp ranges 0.0.0.0/0 0.0.0.0/0
        create link static International pppoe
        set link action bundle International
        set auth authname your_international_account_username
        set auth password your_international_account_password
        set link max-redial 0
        set link mtu 1462
        set link mru 1462
        set link keep-alive 10 60
        set pppoe iface fxp0
        set pppoe service "International"
        open
Then you can connect by doing /usr/local/sbin/mpd5. This will create two PPP interfaces called ng0 for local and ng1 for international.

The problem still exists that I do not know how to do the routing between these two PPP interfaces to make this work. I do get only local access this way. PFSense uses the Packet Filter Firewall... and here is where I've lost track and went for DD-WRT that uses iptables...

Windows domain admins and sudoers group Linux

I have struggled to make our domain admins have sudo rights on one of our Linux boxes. The change was actually simple at the end. Add the following line to your sudoers file on the Linux box. Replace DOMAIN with your domain name.
%DOMAIN\\domain^admins

Mounting LVM volumes from live CD

These instructions are for when you need to get data from a hard disk, but the disk is configured with LVM volumes. I've used a Gentoo minimal install/Live disk:

Mounting the LVM Volume:
vgchange -a y
lvscan
mount -t ext3 /dev/VolGroup00/LogVol00 /mnt/

Unmounting the LVM Volume:
umount /mnt/
vgchange -a y

Monday, March 22, 2010

Minimal Centos 5 Server install

You only need CD #1 to do the basic install.

Minimal Install Steps
1. Boot to CD #1
2. At the Boot: prompt, type in "linux text" to get the text installation setup
3. Proceed normally with the installation until it asks which packages to install
4. Deselect all of the packages and then click on the "customize package selection" check box
5. Hold down the "-" (dash) key, which scrolls through all of the package options and deselects them all
6. Finish the installation
7. Do a "yum update" to get latest versions of everything
8. Do a "yum install " for what ever other packages you need

Free Resources on a Server:
chkconfig anacron off
chkconfig apmd off
chkconfig atd off
chkconfig autofs off
chkconfig cpuspeed off
chkconfig cups off
chkconfig cups-config-daemon off
chkconfig gpm off
chkconfig isdn off
chkconfig netfs off
chkconfig nfslock off
chkconfig openibd off
chkconfig pcmcia off
chkconfig portmap off
chkconfig rawdevices off
chkconfig readahead_early off
chkconfig rpcgssd off
chkconfig rpcidmapd off
chkconfig smartd off
chkconfig xfs off
chkconfig ip6tables off
chkconfig avahi-daemon off
chkconfig firstboot off
chkconfig yum-updatesd off
chkconfig sendmail off
chkconfig mcstrans off
chkconfig pcscd off
chkconfig bluetooth off
chkconfig hidd off

NOTES:
The next group of services is more useful to servers.
--- xinetd
- may be needed for some servers
--- acpid
- needed for power button to shut down server gently
--- microcode_ctl
- not needed on AMD machines
--- irqbalance
- not needed unless running SMP
- multiple cores, multiple processors, hyperthreading
--- haldaemon and messagebus
- support for plug and play devices
--- mdmonitor
- not needed unless running software RAID

Evaluate their worth even more closely before disabling them.
chkconfig xinetd off
chkconfig acpid off
chkconfig microcode_ctl off
chkconfig irqbalance off
chkconfig haldaemon off
chkconfig messagebus off
chkconfig mdmonitor off

Run the following to see what else is enabled:
chkconfig --list |grep "3:on" |awk '{print $1}' |sort

If you want to compare the list before and after, you can:
chkconfig --list |grep "3:on" |awk '{print $1}' |sort > before
and
chkconfig --list |grep "3:on" |awk '{print $1}' |sort > after

Virtual Terminals
You may also minimize the virtual terminals. The default is six virtual terminals. You
can probably do with two.
To disable them, edit the /etc/inittab file and comment out the ones that you don't
want running like this:
# Run gettys in standard runlevels
1:2345:respawn:/sbin/mingetty tty1
2:2345:respawn:/sbin/mingetty tty2
#3:2345:respawn:/sbin/mingetty tty3
#4:2345:respawn:/sbin/mingetty tty4
#5:2345:respawn:/sbin/mingetty tty5
#6:2345:respawn:/sbin/mingetty tty6

Updating system and Rebooting
yum update
init 6

References:
http://www.sonoracomm.com/support/18-support/202-centos-min
http://www.sonoracomm.com/support/18-support/114-minimal-svcs
http://www.hscripts.com/tutorials/linux-services/

Saturday, March 20, 2010

Netatalk 2.0.5-3, Ubuntu 9.10 minimal install and Snow Leopard Time Machine

wget http://ftp.us.debian.org/debian/pool/main/d/db/libdb4.8_4.8.26-1_i386.deb
dpkg -i libdb4.8_4.8.26-1_i386.deb
wget http://ftp.us.debian.org/debian/pool/main/libg/libgcrypt11/libgcrypt11_1.4.5-2_i386.deb
dpkg -i libgcrypt11_1.4.5-2_i386.deb

apt-get install libcrack2

wget http://ftp.us.debian.org/debian/pool/main/n/netatalk/netatalk_2.0.5-3_i386.deb
dpkg -i netatalk_2.0.5-3_i386.deb

mkdir /storage/TimeMachine
chmod a+rw /storage/TimeMachine
nano /etc/netatalk/AppleVolumes.default
change the last part to look like this:
# By default all users have access to their home directories.
#~/                     "Home Directory"
/storage/TimeMachine "TimeMachine" options:tm
/etc/init.d/netatalk restart

apt-get install avahi-daemon
apt-get install libnss-mdns
nano /etc/nsswitch.conf
add "mdns to end of line to look like this:
hosts:          files mdns4_minimal [NOTFOUND=return] dns mdns4 mdns
nano /etc/avahi/services/afpd.service
Paste the following code and save:
<!--*-nxml-*-->
<service-group>
<name replace-wildcards="yes">%h</name>
<service>
<type>_afpovertcp._tcp</type>
<port>548</port>
</service>
<service>
<type>_device-info._tcp</type>
<port>0</port>
<txt-record>model=Xserve</txt-record>
</service>
</service-group>
init 6
NOTES:
After the machine returns from reboot, you can check to see if everything is running:
ps -ef | grep afpd
ps -ef | grep avahi

Should you need to manually connect to server via finder, you can:
Go --> Connect to Server and type afp://your-server-ip

If you were not able to log in, you can check in /var/log/daemon.log on your linux server
for any debug messages.