Wednesday, October 14, 2009

Zenoss monitor Windows Server 2008 via WMI

Zenoss supports Windows SNMP, it can get partition and interfaces infomation, but it couldn't get CPU/MEMORY info. WMI script can get almost any info in Windows. Zenoss supports Windows WMI by zenpack
The agent account in remote Windows Server doens't need to be admin user as long as following previleges granted.

Enable DCOM
The easy way is to add the user to group "Distributed COM users"

Alternatively, grant specific rights to the user
Start DCOM GUI by DCOMCNFG command-> Component Services -> Computers->Right-click My Computer, and then select Properties->COM Security tab
Give access permission and launch and activation permission.

Enabling Account Privileges in WMI
Computer Management -> Services and Applications-> WMI Control->right click select Properties->Security
Select CIMV2 under root

Select security button add new user with
Enable Account
Remote Enable

Allowing WMI through the Windows Firewall
Allow pre-defined rule: Windows Management Instrumentation (WMI)

Deny ssh interactive login but allow sftp

SSH interactive login need tty to be allocated but sftp/scp doesn't need tty. So you can disable SSH interactive login by no-pty option in OPENSSH. But no-pty option is valid only in public key authentication, so you have to disable password for the user with “passwd –l username” command.

I have attempted to use pam_listfile.so tty option to achieve this, I found it is impossible because pam_tty name ssh will be allocated in either ssh login or sftp.

All you need to is to put no-pty parameter in ~/.ssh/authorized_keys, it must be in the same line with the public key, multiple options are separated by comma e.g


no-pty,no-X11-forwarding ssh-dss AAAAB3Nz ... key-comment

Another useful feature of public key authentication is forced command, which means the command is invoked whenever the key is authenticated, it is great security feature for remote execution e.g backup job. you can also limit client source with "from= " option.


#Force to run command date only
$ cat /home/test/.ssh/authorized_keys
command="date" ssh-dss AAAAB3NzaC1kc3 ..

#date command was executed even given command is ls
$ ssh test@localhost ls
Wed Oct 14 10:29:39 EST 2009

#forced command can literally disable SSH interactive login.
$ ssh test@localhost
Wed Oct 14 10:29:44 EST 2009
Connection to localhost closed.

Tuesday, September 1, 2009

Command to get system hardware serial number.

SMBIOS/DMI standard includes system manufacturer, model name, serial number, BIOS version, asset tag as well as a lot of other details of varying level of interest and reliability depending on the manufacturer. This will often include usage status for the CPU sockets, expansion slots (e.g. AGP, PCI, ISA) and memory module slots, and the list of I/O ports (e.g. serial, parallel, USB).
Solaris X86:

$smbios
..
Manufacturer: HP
Product: ProLiant DL360 G3
Serial Number: B038XXXXX
..

Solaris Sparc:
smbios is not supported in SPARC yet, the traditional command prtdiag works for both X86 and SPARC ,but it reports less detailed hardware information.

Linux/BSD:
$dmidecode

Create restricted login account

Create a login in restricted shell and doesn’t allow user to change password.

rsh is a limiting version of the standard command inter-
preter sh, used to restrict logins to execution environments
whose capabilities are more controlled than those of sh (see
sh(1) for complete description and usage).

The actions of rsh are identical to those of sh, except that
the following are disallowed:

changing directory (see cd(1)),

setting the value of $PATH,

pecifying path or command names containing /,

redirecting output (> and >>).

Set restricted shell as login shell

Solaris:
usermod -s /usr/lib/rsh userid
Linux:
usermod -s /usr/bin/rbash userid

Set minimum number of days between password changes to large number, so user can’t change password until min days

Solaris:
passwd -n 9999 –x 9998 userid
(Solaris needs to set both Min Max days and Min is greater than Max)
Linux:
passwd –n 9999 userid

Thursday, August 20, 2009

Align partitions on the stripe Boundary for Linux and Windows to boost performance

Aligning partitions on the stripe Boundary can boost IO performance up to 20% depending on file system block size , stripe size and intensity of IO workload etc. Disk alignment issue exists for environment, in which all following factors are met

Disk: Hardware Raid(Including SAN)
Server: X86 32bit or 64bit PC server .
OS: Linux or Windows ( BSD, Solaris not investigated)

Terms:
- Sector Size: Normally 512 byte as industry standard to lower-format a single harddisk.
- Stripe Size: The smallest unit used by SAN, Hardware Raid and software Raid starting from 2 KB, in power of 2. but 32,64,128 is common stripe size
- Block Size: The smallest amount of disk space which can be allocated to hold a file for file system, ext3,NTFS is 4k by default

Issue:
Due to x86 architectures BIOS limitation, the first partition starts at 63 sector by default in Windows or Linux.
As a result, The partition doesn't align the Stripe Boundary, so there are chances that one FS block sits above 2 stripes, so one request involves 2 physical IOs. The chances can be calculated as (FS block size/ stripe size).so It is 100% for 4k FS block on 4K stripe size.

The offset should be multiple of stripe size, if you are not sure the stripe size, start at 1M should be safe.
Take 64K stripe size for example:
((Partition offset) * (Disk sector size)) / (Stripe unit size)

(63 * 512) / 65536=0.4921875
(128* 512) / 65536=1
So the partition should start 128 sector (65536 bytes) at least

Verify:
- Linux: fdisk -lu
$ fdisk -lu
Device Boot Start End Blocks Id System
/dev/sda1 63 37736684 18868311 83 Linux
- Windows:
Any version up to Windows 2003 are affected by default, Windows 2008 has fixed the issue

Fix:
- Linux:
Fdisk go to expert mode by type x then select b to adjust starting block
- Windows:
diskpart detailed in the Windows KB

Reference:
http://support.microsoft.com/kb/929491
http://www.vmware.com/pdf/esx3_partition_align.pdf
http://now.netapp.com/Knowledgebase/solutionarea.asp?id=kb8190

Friday, July 24, 2009

Generate random password with shell script.

Generate random passwords
Generate random passwords consist of letters, numbers and any special characters.
$ tr -cd \#_[:alnum:] < /dev/urandom |  fold -w 8 | head -5 
shu6_BEN
BIL2b#0w
xgHWgOJ2
E1NmtxX1
WqcTAsRN

or

$openssl passwd "$RANDOM" | cut -c1-8
cH75S94U



Pick the appropriate password
The above one liner is fine for general purpose, but with password policy, you have to choose one adheres to the password policy

The following script will pick the right password in form of at least 1 upper case, 1 lower case and 1 digit

#!/bin/bash
# Generate random password adhere to password policy
# caveat: if you need more strict policy e.g. 2 upper cases,2 lower cases, 2 digit, adjust the number retuned by head
LENGTH=8
MIN_U=1
MIN_L=1
MIN_D=1

for i in $(tr -dc [:alnum:] </dev/urandom |  fold -w $LENGTH |  head -20)
do
UPPERS=$(echo $i |  $AWK '{print gsub(/[A-Z]/,"")}')
LOWERS=$(echo $i |  $AWK '{print gsub(/[a-z]/,"")}')
DIGITS=$(echo $i |  $AWK '{print gsub(/[0-9]/,"")}')
if [ $UPPERS -ge $MIN_U -a $LOWERS -ge $MIN_L -a $DIGITS -ge $MIN_D ];then
FOUND=1; break
fi
done

if [  -z $FOUND ];then
echo "ERROR: could not generate appropriate password"
else
echo "Password Generated :" $i
fi


$ ./genpwd.sh
Password Generated : 8sZrR1az

Thursday, June 25, 2009

few scripting tips.



How to get the last digits of a string e.g print 201 for string ua07app201?


#sed back reference: print the first match pattern enclosed by ( )
echo ua07app201 | sed 's/.*[^0-9]\([0-9]*\)$/\1/'

#Sed delete: Delete the longest match of non-digits char
echo 'ua07app201' | sed 's/.*[^0-9]//'

#Expr matching operator : Similar to sed back reference, without (), it returns the the number of matched chars.
expr ua07app201 : '.*[^0-9]\([0-9]*\)$'

#Awk: set non-digit as seperator, print the last filed $NF
echo 'ua07app201' | nawk -F'[^0-9]' '{print $NF}'

#Perl in command line mode
echo ua07app201 | perl -nle ' $_ =~m /(\d+$)/; print $1'
or the simplizied version
echo ua07app201|perl -nle'print/(\d+)$/'

#Parameter Substitution, delete the longest match of non-digits chars from beginning.
a='ua07app201';echo "${a##*[!0-9]}"


How to get path only from full path of a file?


#Parameter Substitution, delete the shortest match from end
$ var=/var/tmp/test.txt;echo ${var%/*}
/var/tmp


How to sort a string?


#one-liner to sort a string
$echo "s03 s08 s01" | tr '[:space:]' '\n' | sort -n | paste -s
s01     s03     s08