check if a directory is a nfs mount

Use stat to display the file system status, following links, and output the format as the human readable file system type:

#stat -f -L -c %T /tmp
ext2/ext3
#
# stat -f -L -c %T /mnt/fileserver/volume
nfs
#

As suspected “/tmp” is a regular ext file system, but the path “/mnt/fileserver/volume” is an nfs mount. What happens if we unmount the nfs mount:

# umount /mnt/fileserver/volume
#
# stat -f -L -c %T /mnt/fileserver/volume
ext2/ext3
#

It reports properly that the directory is just an unmounted directory in a regular ext file system.

Alternatively you can use the mountpoint command:

# mountpoint /tmp
/tmp is not a mountpoint
#
# mountpoint /mnt/adfs40/vol1
/mnt/adfs40/vol1 is a mountpoint
#
# umount /mnt/fileserver/volume
# mountpoint /mnt/adfs40/vol1
/mnt/adfs40/vol1 is not a mountpoint
#

monitor host for connectivity

Sometimes, you want to be notified if a host goes up or down. Usually Nagios is perfect for this, but in this case I had an internet circuit, and all I cared about was knowing when the ISP deactivated it. Use ping in a loop, make 1 request every second, if ping doesn’t get a response, then send a text message (Verizon number) and stop the loop.

while true; do ping -nc 1 -W 1 5.6.7.8 | grep -q icmp; if [ "$?" == "1" ]; then echo "circuit is down" | mail <10-digit phone number no spaces>@vtext.com; break; fi; sleep 1s; done;

I also use the converse of this method when I want to know when a new circuit comes up.

test bandwidth throughput using iperf

Testing bandwidth between 2 hosts can be helpful to determine maximum transfer rates, and how much bandwidth can be pushed. The iperf utility is a great option for this. Set up one side as a listening server and the other side as a client. In this scenario I want to test an OpenVPN tunnel between a Raspberry Pi and a Vyatta server. The layout looks like this:

Laptop --(wireless)--> RPi --(wireless)--> Linksys router -> Enterasys router -> Cable Modem -> ISP -> INTERNET -> Vyatta -> remote host

Start iperf in server mode on the remote host listening for UDP datagrams:

# iperf -s -u
------------------------------------------------------------
Server listening on UDP port 5001
Receiving 1470 byte datagrams
UDP buffer size:   110 KByte (default)
------------------------------------------------------------

Start up the client. The -c flag tells it what remote host to connect to with iperf, the -u makes it use UDP, the -b tells it what bandwidth to try to achieve, and the -t sets how many seconds to run for:

# iperf -c 10.211.0.141 -u -b 1000K -t30

As the test runs, the server and client will output the rates. Here’s the server side output:

[  3] local 10.211.0.141 port 5001 connected with 10.211.0.6 port 40816
[ ID] Interval       Transfer     Bandwidth       Jitter   Lost/Total Datagrams
[  3]  0.0-30.0 sec  3.57 MBytes    998 Kbits/sec  14.738 ms    4/ 2552 (0.16%)

So we were able to push a full 1 Mbps and only lost 4 datagrams, that’s pretty good. I would say this can comfortably push 1Mbps. (Side note: top reported openvpn process on RPi was at 9% CPU utilization) Let’s try for 2Mbps:

# iperf -c 10.211.0.141 -u -b 2000K -t30

And the output:

[  4] local 10.211.0.141 port 5001 connected with 10.211.0.6 port 56707
[  4]  0.0-30.0 sec  6.21 MBytes  1.74 Mbits/sec  7.346 ms  670/ 5103 (13%)

We were able to achieve 1.74 Mbps, but we lost 13% of the traffic. That is unacceptable! I would run again at 1500K and narrow in where exactly the break point is for throughput. To find the bottleneck you can run iperf from every (Linux) host in the chain to pinpoint the limitation. I suspect it could be the upload speed of my home internet connection, or the poor wireless signal of the client side of the RPi.

change SSH listen address

If you have servers with internal and external interfaces, you may want to disable ssh on the external side. In this case we just get the internal IP address and tell sshd to only listen on that address:

sed -i "s/#ListenAddress 0.0.0.0/ListenAddress `grep address /etc/network/interfaces | grep 10.229 | awk '{print $2}'`/" /etc/ssh/sshd_config

Do it to many hosts:

for i in `seq 313 364`; do ssh ftp$i "sed -i \"s/#ListenAddress 0.0.0.0/ListenAddress \`grep address /etc/network/interfaces | grep 10.229 | awk '{print \$2}'\`/\" /etc/ssh/sshd_config"

And restart SSH:

for i in `seq 313 364`; do ssh ftp$i "service ssh restart"; done;

remove IPv6 address from interface

If you don’t want to have an IPv6 address on an interface, you can quickly remove it:

# ip addr show dev eth0 
2: eth0:  mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:c2:fc:59 brd ff:ff:ff:ff:ff:ff
    inet 10.210.0.141/16 brd 10.210.255.255 scope global eth0
    inet6 fe80::20c:29ff:fec2:fc59/64 scope link 
       valid_lft forever preferred_lft forever

Only get the address:

# ip addr show dev eth0 | grep inet6 | awk '{print $2}'
fe80::20c:29ff:fec2:fc59/64

Remove it:

# ip -6 addr del `ip addr show dev eth0 | grep inet6 | awk '{print $2}'` dev eth0

Or do it to many hosts:

for i in `seq 201 272`; do ssh www$i "ip -6 addr del \`ip addr show dev eth0 | grep inet6 | awk '{print \$2}'\` dev eth0"; done;

drop messages in mailqueue from single sender

Drop all messages from the sender ‘nagios’:

# for i in `mailq | tail -n +2 | awk  'BEGIN { RS = "" } { if ($7== "nagios") print $1}'`; do postsuper -d $i; done;
postsuper: B60BF9FB69: removed
postsuper: Deleted: 1 message
postsuper: C3B429FB6F: removed
postsuper: Deleted: 1 message
postsuper: 0306C9FB87: removed
postsuper: Deleted: 1 message
postsuper: E3BC79FB7E: removed
postsuper: Deleted: 1 message
postsuper: B32EA9FB65: removed
(many more lines)

Gets the mailqueue, starts the output on line 2, skipping the first header line, if the sender equals ‘nagios’ then print the first field, which is the message id. Then use postsuper to drop the message identified by it’s id.