Posts Tagged ‘bash

26
Aug
14

Finding the process of a listening socket

I had a irc user today asked me how they can find the process id of a listening port.  The obvious answer is to use netstat -lnap; however there are occasions when this will show a dash instead of the process ID.  This occurs when some kernel module spawned the PID that owns the socket.  RPC behaves in this manner and the simplest way to find the pid in that case is to use rpcinfo -p. our as pointed out in the initial irc chat you can use the nmap rpcinfo nse script as follows.

nmap -sU -p 111 --script rpcinfo localhost

however i suggested that is should be possible to find these PID’s by parsing the proc file system. using the netstat -e switch we get the inode of the listening socket and with a bit of hacking i came up with the following test code.

#!/bin/sh
INODE=304
for i in /proc/*/fd/*
do
   SOCKET_INODE=$(stat -c %N ${i} 2>/dev/null | awk -F\: '/socket:\[[0-9]+\]/ {gsub(/[\[\]]/, "", $NF);print $NF}')
   [ "${SOCKET_INODE%?}" == "${INODE}" ] && awk -F\/ '{print $3}'<<< ${i}
done

Unfortunately i don’t have a machine that shows these symptoms and the user disconnected from IRC before i could get them to check. However i think this could be reasonably expanded to the following.

netstat -lnptue | awk '{if ($NF == "-")print $0}' | while read CONNECTION
do
	CONN_TOKENS=($CONNECTION)
	LOCAL_ADDRESS=${CONN_TOKENS[3]}
	INODE=${CONN_TOKENS[7]}
	for i in /proc/*/fd/*
	do
		SOCKET_INODE=$(stat -c  %N ${i} 2>/dev/null | awk -F\: '/socket:\[[0-9]+\]/ {gsub(/[\[\]]/, "", $NF);print $NF}')
		if [ "${SOCKET_INODE%?}"  == "${INODE}"]
		then
			PID=$(awk -F\/ '{print $3}'<<< ${i})
			echo "${LOCAL_ADDRESS}: ${PID}"
		fi
	done
done

This is very inefficient as we scan the whole of proc for every entry we find but i will leave it as an exercise for the reader to optimise. Not sure if this is of any use other then my own curiosity so please feel free to leave feedback.

Advertisements
06
Nov
12

Swapping Raid Disks – Part 2 Fixing /boot

In the previous part post Swapping Raid Disks – Part 1 MDADM we showed how to completely swap all disks in a Linux Software Raid array.  One of the Raid partitions we swapped was the /boot partitions.  We now need to ensure that grub is installed to these new partitions so the system can still boot once we destroy the old disks.  You can use the device map file and grub-install to do this however i will be using the grub cli.

The first thing to do is run grub and use the find command to see how grub addresses the disks with the /boot partitions.  The (hdX,X) values will more then likley be different on your system. you will also need to do this as root

[root@server ~]#grub
Probing devices to guess BIOS drives. This may take a long time.
GNU GRUB  version 0.97  (640K lower / 3072K upper memory)
[ Minimal BASH-like line editing is supported.  For the first word, TAB
lists possible command completions.  Anywhere else TAB lists the possible
completions of a device/filename.]
grub> find /grub/stage1
find /grub/stage1
(hd0,1)
(hd1,1)
(hd8,1)
(hd9,1)

From this we can see that grub can see 4 /boot partitions ((hd0,1), (hd2,1), (hd8,1) & (hd9,1)). We now need to ensure that grub is installed on all of these partitions. If you know which disks are the new disks and which are the old disks you can get away with installing grub just on the new disks but it will do know harm to install on all disks.

Installing grub requires three steps. Telling grub which device we will be working on with a map; Telling grub which partitions is the boot/root partitions and installing grub

grub> device (hd0) /dev/sda
device (hd0) /dev/sda
grub> root (hd0,1)
root (hd0,1)
 Filesystem type is ext2fs, partition type 0xfd
grub> setup (hd0)
setup (hd0)
 Checking if "/boot/grub/stage1" exists... no
 Checking if "/grub/stage1" exists... yes
 Checking if "/grub/stage2" exists... yes
 Checking if "/grub/e2fs_stage1_5" exists... yes
 Running "embed /grub/e2fs_stage1_5 (hd0)"...  26 sectors are embedded.
succeeded
 Running "install /grub/stage1 (hd0) (hd0)1+26 p (hd0,1)/grub/stage2 /grub/grub.conf"... succeeded
Done.

Here is an example of hd9 (/dev/sdj) as well

grub> device (hd9) /dev/sdj
device (hd9) /dev/sdj
grub> root (hd9,1)
root (hd9,1)
 Filesystem type is ext2fs, partition type 0xfd
grub> setup (hd9)
setup (hd9)
 Checking if "/boot/grub/stage1" exists... no
 Checking if "/grub/stage1" exists... yes
 Checking if "/grub/stage2" exists... yes
 Checking if "/grub/e2fs_stage1_5" exists... yes
 Running "embed /grub/e2fs_stage1_5 (hd9)"...  26 sectors are embedded.
succeeded
 Running "install /grub/stage1 (hd9) (hd9)1+26 p (hd9,1)/grub/stage2 /grub/grub.conf"... succeeded
Done.

you will also need fix the grub.conf/menu.1st file to ensure it specifies the correct root drive to use. In my case i know my boot partitions are on hd8 & hd9 however as above you can create entries for all hdX partitions show in the find command. Below is a copy of my modified menu file

title CentOS
	root (hd8,1)
	kernel /vmlinuz-2.6.32-220.17.1.el6.x86_64 [Removed for simplicity]
	initrd /initramfs-2.6.32-220.17.1.el6.x86_64.img
title CentOS (if the first disk in the array dies you will need to use this)
	root (hd9,1)
	kernel /vmlinuz-2.6.32-220.17.1.el6.x86_64 [Removed for simplicity]
	initrd /initramfs-2.6.32-220.17.1.el6.x86_64.img
title CentOS (backp hd0 wont work after you format the old disks)
	root (hd0,1)
	kernel /vmlinuz-2.6.32-220.17.1.el6.x86_64 [Removed for simplicity]
	initrd /initramfs-2.6.32-220.17.1.el6.x86_64.img
title CentOS (backp hd1 wont work after you format the old disks)
	root (hd1,1)
	kernel /vmlinuz-2.6.32-220.17.1.el6.x86_64 [Removed for simplicity]
	initrd /initramfs-2.6.32-220.17.1.el6.x86_64.img

If you are using a system with grub v2 you can use the search command to set the root instead of having 4 seperate menu items. CentOS dose not support grub v2 yet and i have not needed to do this on another system. however Arch linux has a good article on grub v2 which should help
At this point you should reboot and check that at least the first two menu options work and allow you to boot. If they do not the last two options should work. Review the steps you have taken to see if you have made any errors. If they come up successfully you should be able to format the original partitions and reuse them.

In my situation i wanted to keep all the data and reclaime the space at the beginning of the disk so i decided to do something crazy with dd (part 3 coming soon)

06
Nov
12

Swapping Raid Disks – Part 1 MDADM

We have a 2 disks (/dev/sda & /dev/sdb) which contains 2 SW RAID partitions partitions and one data partition.  The SW raid partitions where used for /boot and /.  the data partition was used as an hadoop data partitions.  hadoop is designed to perform best by making sequential reads/writes from a disk.  By having OS partitions on the same disk as the data partition we noticed that we where causing some issues with hadoop performance and decided to move the OS partitions to dedicated disks (/dev/sdi & /dev/sdj).

This was relatively simple.  New disks where installed and we used sfdisk and mdadm to configure them.

The first thing to do was to dump the partitions table for the current disk(s)

sfdisk -l /dev/sda -O partition

This preduced the following partitions table

Disk /dev/sda: 243031 cylinders, 255 heads, 63 sectors/track

Units = cylinders of 8225280 bytes, blocks of 1024 bytes, counting from 0

Device Boot Start End #cyls #blocks Id System
/dev/sda1 0+ 45689- 45690- 367001600 fd Linux raid autodetect
/dev/sda2 * 45689+ 45702- 13- 102400 fd Linux raid autodetect
/dev/sda3 45702+ 243031- 197329- 1585042432 83 Linux
/dev/sda4 0 - 0 0 0 Empty

However we did not want the data partitions on the new disks so we had to modify the partition table a little first so it looked like this:

Disk /dev/sdi: 243031 cylinders, 255 heads, 63 sectors/track

Units = cylinders of 8225280 bytes, blocks of 1024 bytes, counting from 0

Device Boot Start End #cyls #blocks Id System
/dev/sdi1 0+ 45689- 45690- 367001600 fd Linux raid autodetect
/dev/sdi2 * 45689+ 45702- 13- 102400 fd Linux raid autodetect
/dev/sdi3 0 - 0 0 0 Empty
/dev/sdi4 0 - 0 0 0 Empty

We configure our new disk as follows:

sfdisk -I partition --force /dev/sdi

We then updated the raid configuration to add the new partitions

mdadm --manage /dev/md0 --add /dev/sdi2
mdadm --manage /dev/md1 --add /dev/sdi1
mdadm --manage /dev/md0 --fail /dev/sda2
mdadm --manage /dev/md1 --fail /dev/sda1
mdadm -D /dev/md0
mdadm -D /dev/md1

Wait until the sync has completed.  you can monitor progress with the below command

watch cat /proc/mdstat

Once all data has synced to both raid partitions repeat the above steps for sdb/sdj.  Once the raid partitions are configured in such a way that sdi and sdj or the two active partitions and have been completely synced you can remove sda and sdb from the raid configueration

mdadm --manage /dev/md0 --remove /dev/sda2
mdadm --manage /dev/md0 --remove /dev/sdb2
mdadm --zero-superblock /dev/sda2
mdadm --zero-superblock /dev/sdb2

mdadm --manage /dev/md1 --remove /dev/sda1
mdadm --manage /dev/md1 --remove /dev/sdb1
mdadm --zero-superblock /dev/sda1
mdadm --zero-superblock /dev/sdb1

continue to swapping raid disks – part 2 fixing /boot for info on how to fix grub and the /boot partitions

28
Jan
12

HideMyAss VPN Part 1

So you have a vpn account but its a pain in the arse to change servers when you want to change between iplayer and hulu. Below i describe the config i used to set up my system to have multiple vpns depending on the destination. in the below example i will use iplayer i.e. http://www.bbc.co.uk

Ok i’ll start by saying im using arch linux so instructions will be for that, if your stuck on a different distro, leave comments and ill try to help

First install nc, ipcalc, dnsutils, openvpn, curl and unzip (because for some reason hide my ass uses zip)

pacman -S openvpn curl unzip nc ipcalc dnsutils

Get a base uk file, selecting a location from the countries file

wget http://vpn.hidemyass.com/vpnconfig/countries.php -O - | sed -e 's/ /+/g' -e s'/+$//'
wget http://vpn.hidemyass.com/vpnconfig/client_config.php?win=1&loc=UK,+Greater+Manchester,+Manchester+(LOC1+S2) > /etc/openvpn/openvpn-uk.cfg

Add the option `route-nopull` to the config. This ignores the default route sent by the hidemyass servers.

Now to get a list of prefixes associated with http://www.bbc.co.uk.

First get a starting address:

dig +short www.bbc.co.uk | tail -1
212.58.244.67

Then the AS number:

echo origin 212.58.244.67 | nc asn.shadowserver.org 43
2818 | 212.58.224.0/19 | BBC | UK | BBC.CO.UK | BBC

Then the associated prefixes

echo "prefix 2818" |  nc asn.shadowserver.org 43

or

echo origin `dig +short www.bbc.co.uk | tail -1` | nc asn.shadowserver.org 43 | awk '{print "prefix",$1}' |  nc asn.shadowserver.org 43
132.185.128.0/20
132.185.144.0/20
132.185.240.0/24
132.185.0.0/16
212.58.224.0/19

now we need to convert
from:
132.185.240.0/24
to:
route 132.185.240.0 255.255.255.0

i used the following but im sure there is a better way:

echo -en "route " ; ipcalc --nocolor --nobinary 132.185.240.0/24 |  awk '/(Address|Netmask)/ {printf "%s ", $2}' ; echo

Adding it together:

echo "route-nopull"; echo origin `dig +short www.bbc.co.uk | tail -1` | nc asn.shadowserver.org 43 | awk '{print "prefix",$1}' |  nc asn.shadowserver.org 43 | while read line ; do  echo -en "route " ; ipcalc --nocolor --nobinary ${line}  |  awk '/(Address|Netmask)/ {printf "%s ", $2}' ; echo ; done >> /etc/openvpn/openvpn-uk.cfg

Finally fetch the hidemyass files:

wget https://vpn.hidemyass.com/linux.zip

unzip the linux.zip file and copy the keys directory to /etc/openvpn/keys. Update the ca, cert and keys parameters in  /etc/openvpn/openvpn-uk.cfg changing the directory to /etc/openvpn/openvpn-uk.cfg

unzip linux.zip
mv keys /etc/openvpn/
sed -i 's/\.\/keys\//\/etc\/openvpn\/keys\//g' /etc/openvpn/openvpn-uk.cfg

start openvpn and enter your username and password.

openvpn /etc/openvpn/openvpn-uk.cfg

Now traffic destined for the bbc will originate from a uk server. you can now create another config using to set up a tunnel for the us which is only valid for hulu. e.g.

wget http://vpn.hidemyass.com/vpnconfig/client_config.php?win=1&loc=USA,+New+York+(DC2+S1) > /etc/openvpn/openvpn-uk.cfg
echo "route-nopull"; echo origin `dig +short www.hulu.com | tail -1` | nc asn.shadowserver.org 43 | awk '{print "prefix",$1}' |  nc asn.shadowserver.org 43 | while read line ; do  echo -en "route " ; ipcalc --nocolor --nobinary ${line}  |  awk '/(Address|Netmask)/ {printf "%s ", $2}' ; echo ; done >> /etc/openvpn/openvpn-us.cfg
openvpn /etc/openvpn/openvpn-us.cfg

in the next part i show how to make these vpns into a daemon using daemon tools