bookmark_borderHow to expand a disk from the Linux command line

I’ve been frustrated with the number of instructions that involve deleting a partition and then creating a new partition with the same starting block. Totally unnecessary! 

Life has gotten a lot easier thanks to the growpart command. The best part is that with the right filesystem you don’t even need to unmount.  I suggest taking a backup or snapshot first in case something goes wrong.

growpart /dev/device_name partition_number

You can test it first with –dry-run:

growpart --dry-run /dev/sda 3

Once that is done, just run the command for your given filesystem to expand into the rest of the partition.

For btrfs:

btrfs filesystem resize amount mount_point

The amount can be something like +50g or max. To resize the root partition to max simply type:

btrfs filesystem resize max /

For ext4 it is:

resize2fs /dev/device

For example:

resize2fs /dev/sda3

For XFS:

xfs_growfs /mount_point

for example:

xfs_growfs /

bookmark_borderNVME stalls in Linux

I’m putting this here since I haven’t seen it mentioned elsewhere and it took me forever to figure out:

I was getting timeouts on two different NVME drives, 2 different motherboards and two different CPUs, until I extended the timeout and after that I was just getting stalls. The fix was to disable ASPM:

echo performance > /sys/module/pcie_aspm/parameters/policy

Or you can add “pcie_aspm=off” to your kernel command line.

bookmark_borderApache config validater.

This is an Apache config sanitizer, it checks to make sure there are no orphaned files in the Debian style sites-available/sites-enabled type setup and checks to make sure each virtual host has a valid DNS.

#!/bin/bash
# Apache config sanitizer.. Checks to make sure all sites are correctly configured 
# for DNS and checks for orphaned config files.
#
# By Gerhard Mack <gmack@innerfire.net>

function getipaddress {
        if [[ "${1}" == 4 ]]
        then
                getent ahostsv4 "${2}" | grep STREAM | head -n 1 | cut -d ' ' -f 1
                return
        fi

        if [[ "${1}" == 6 ]]
        then
                getent ahostsv6 "${2}" | grep STREAM | head -n 1 | cut -d ' ' -f 1
                return
        fi
}

while read line
do
        name="$(basename $line)"

        #Ignore common standard files
        if [[ "${name}" == "000-default-le-ssl.conf" ]]
        then
                continue
        fi

        if [[ "${name}" == "default-ssl.conf" ]]
        then
                continue
        fi

        if [[ "${name}" == "000-default.conf" ]]
        then
                continue
        fi

        if [[ ! -e "/etc/apache2/sites-enabled/${name}" ]]
        then
                echo orphaned file: ${line}
        fi
done <<< "$(find /etc/apache2/sites-available/ -name '*.conf')"

while read line
do
        array=( $line )

        if [[ "${line:0:1}" == [0-9] ]]
        then
                VIP=$(echo ${array[0]} | cut -d: -f1 )
                IPV=4
                continue
        fi

        if [[ "${line:0:1}" == "[" ]]
        then
                 VIP=$(echo ${array[0]} | cut -d\] -f1 | cut -d \[ -f2)
                 IPV=6
                 continue
        fi

        if [[ "${line:0:1}" == "*" ]] 
        then
                 continue
        fi

        if [[ "${array[0]}" == "port" ]]
        then
                 VHOST="${array[3]}"

                 IP=$(getipaddress ${IPV} ${VHOST})

                 if [[ -z "${IP}" ]]
                 then
                         echo ${VHOST} does not resolve. \(should be \"${VIP}\"\)
                         continue
                 fi

                 if [[ "${IP}" == "::ffff:"* ]]
                 then
                          echo ${VHOST} does not have an IPv6 address. \(should be \"${VIP}\"\)
                          continue
                 fi

                 if [[ "$IP" != "$VIP" ]]
                 then
                          echo vhost ${VHOST} points to \"${IP}\" \(should be \"${VIP}\"\)
                 fi
                 
                 continue
         fi

         if [[ "$array[0]" == "alias[0]" ]]
         then
                 VALIAS="${array[1]}"
                 IP=$(getipaddress ${IPV} ${VALIAS})

         if [[ -z $IP ]] ; then
                 echo ${VHOST} alias ${VALIAS} does not resolve. \(should be \"${VIP}\"\)
                 continue
         fi

         if [[ ${IP} == "::ffff:"* ]]
         then
                 echo ${VHOST} alias ${VALIAS} does not have an IPv6 address. \(should be \"${VIP}\"\)
                 continue
         fi

         if [[ "$IP" != "$VIP" ]] ; then
                echo vhost ${VHOST} alias $VALIAS points to \"${IP}\" \(should be \"${VIP}\"\)
         fi

         continue
         fi
done <<< "$(apachectl -S)"

 

bookmark_borderconst vs static const in C with GCC

Something I’ve been wondering but have yet to see a good explanation for is if there is a difference between the way GCC handles const and static const.  Now in theory the compiler should handle them the same way but does it?  My web search didn’t really come up with much so I decided to test for myself.

A quick test using GCC 4.7.2:

const.c

#include <string.h>
#include <stdio.h>

void test()
{
        const char i[] = "not changed";
        char *j;
        printf("before %s\n", i);

        j = i;

        strcpy(j, "changed");
        printf("after i=%s\n", i);
}

int main()
{
        test();
        test();
}

staticconst.c

#include <string.h>
#include <stdio.h>

void test()
{
        static const char i[] = "not changed";
        char *j;
        printf("before %s\n", i);

        j = i;

        strcpy(j, "changed");
        printf("after i=%s\n", i);
}

int main()
{
        test();
        test();
}

How each turns out:

const.c

~$ gcc const.c -o const -g
const.c: In function ‘test’:
const.c:10:4: warning: assignment discards ‘const’ qualifier from pointer target type [enabled by default]
~$ ./const
before not changed
after i=changed
before not changed
after i=changed

Not only can I change the variable, but it resets it at each function call so this means it is reallocating the variable each time.

staticconst.c

~$ gcc staticconst.c -o staticconst -g
staticconst.c: In function ‘test’:
staticconst.c:10:4: warning: assignment discards ‘const’ qualifier from pointer target type [enabled by default]
./staticconst
before not changed
Segmentation fault (core dumped)

gdb shows the following:

Core was generated by `./staticconst’.
Program terminated with signal 11, Segmentation fault.
#0  0x0000000000400534 in test () at staticconst.c:12
12        strcpy(j, “changed”);

As you can see static const is stored somewhere actually read only and being static it is not being reallocated each time the function is called making this version more efficient.

 

bookmark_borderphp email validator

If you are like me you get tired of constant email bounces from your web apps so I sat down and wrote this simple validator to save the mail server the extra load of having to deal with obvious typos.

// email Validator
// returns 1 on success 
// return -1 if the email is not in the correct format 
// return -2 if the email doesn't resolve 
function check_email($email) {   
        if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
                return (-1) ;
        }

        list($username, $domain) = explode('@', $email);

        //as per the RFC: check the domain for an MX record or A record and allow for IPv6 addresses
        if (!checkdnsrr($domain, 'MX') && !checkdnsrr($domain, 'A') && !checkdnsrr($domain, 'AAAA')) {
                return (-2) ;
        } 

        return (1) ;
}
Here is a quick example of how to call it:
$ret = check_email($h_email) ;

if ($ret > 0) {
        echo "valid email<br>" ;
} else {
        echo "error: " ;
        if($ret == -1 ){
                echo "invalid format<br>" ;
        }
        if($ret == -2 ) {
                echo "does not resolve<br>" ;
        }
}

 

bookmark_borderPassword security

Weak passwords are still by far the most effective way to break into a system and even though many people think they have clever ways to obfuscate their passwords, they often fail badly either by inadvertently making something guessable or by coming up with something so hard you have to write it down somewhere or use a password manager just to use it.  How bad is it?  I have had 3 different techs assign me the same login “Gerhard” with password “G3rh4rd”  and at an additional time someone even tried to be even more clever “G3h4rd!”  This is bad.  I know from experience that I can expect a password guessing script to hit my personal server at least 4 times daily.  Originally the scripts all hit the ssh port until I took countermeasures but now they check every open port for possible password combinations from FTP to SASL to web logins and even with my countermeasures I can expect to have 1 or 2 accounts on my system cracked per year forcing me to disable someone’s website until they change their password again.

How can we come up with a password that is both hard to guess and easy to remember?  Thankfully it is easy.

Take a couple of lines from a song you like but not the first lines and not the chorus.  For example take this verse from a Election–The People’s Right [1] written in 1801:

We should support and pleasure take
In frequent Free Elections.

Now take the first letter of each word. “wssaptiffe”  and there you go. The password is not an actual word so not likely to be hit by a dictionary attack but if you know the song you know your password so it’s easy to remember.  One important note though: if ever the password was used on a website that got broken into you must assume the password is now added to several dictionaries for future attacks.

[1] I selected this song because it was the first one I could find that was both out of copyright and readable.

I feel this is important enough that I grant permission to republish this article provided a link to news.innerfire.net stays with the article.

bookmark_borderCheck for battery power with Linux

onbattery.tar.gz

I’ve been doing some work on my Debian Linux laptop lately and I have some nightly maintenance (disk check, btrfs tree balance) I want to do that will simply suck my battery dry if I’m not plugged into the wall.  I did a quick web search to see how to check from a script to see if the system is on battery power or not and what I found was:

  • Using outdated interfaces.
  • fragile
  • More complicated than it needed to be.

So I ended up writing something that took far less time than the original search did.  How did I do it you ask?

Enter the acpi comm and.  On old systems it uses proc and on new systems it uses sys.  It cares so we don’t have to. It is not designed to be used in the way I want but writing a wrapper around it is easier than browsing either the proc or the sys interfaces on their own so I made this simple wrapper around it.

#!/bin/sh
# Script to check if we are on battery power.
# By Gerhard Mack <gmack@innerfire.net>
# Licensed in the public domain.

#scan for any on-line adaptors
acpi -a | grep "on-line" > /dev/null 2>&1 

#Grep will return 0 if it finds a matching line.
if [ $? -eq 0 ]; then
	#we are on ac.  Return false and exit
	exit 0 ;
else
	#we are on battery.  Return true and exit ;
	exit 1 ;
fi

Example usage in bash:

onbattery

if [ $? -eq 1  ]; then
        # we are on battery so abort before sucking the battery dry
        exit
fi