Find DrewDahl on Facebook! Find DrewDahl on Twitter! View Andrew Dahl's Profile Drew's Blog

Linux

Using NetworkManager to run scripts after connecting

by Drew Dahl on May.03, 2011, under HowTo, Linux

For years now, I’ve had to run vpnc after connecting my school’s wireless. Truly, it never bothered me; however, at my new job, I need to run route after I connect to their wireless. For whatever reason, that got to me. I didn’t really want to run route when I wasn’t on their network (it likely wouldn’t have screwed anything up, but still…). So, I went about putting a quick bit in /etc/sysconfig/network-scripts/ifup-wireless, and it didn’t work… =\ So, after some digging, I’ve found another way using NetworkManager. Here’s what I did:

Because I hate hacking up scripts that services use, I wrote a quick script and put it in /usr/local/bin/wireless.sh:

#!/bin/bash

if iwconfig|grep -c MY-WORK-ESSID
then
        route add -net 111.111.111.111/22 gw 222.222.222.222
fi

if iwconfig|grep -c msum-wireless
then
        vpnc
fi

Once that was done, I ran:

chmod +x /usr/local/bin/wireless.sh

and added the line:

/usr/local/bin/wireless.sh

to the file /etc/NetworkManager/dispatcher.d/00-netreport right before the exit.

And that’s it! It would be neat if NetworkManager added in similar functionality through the GUI, but until that day, this should work fine. Also, to note, those scripts are run as root, so be careful!

Update!

Upon upgrading from Fedora 14 to 15, the file 00-netreport was overwritten. I’ve done updates to NetworkManager, so that had nothing to do with it. In any case, if you end up upgrading your distro, there’s a chance that’ll get overwritten. In the event it does, you’ll just have to paste the line to the script again. (Another good reason to use a script!)

There may be a better way than what I’m doing above, but it works for me, so I’m not going to bother looking for another way. Hope this helps!

Leave a Comment :, , , more...

Using Ruby to run commands on a lab of Linux machines

by Drew Dahl on Feb.24, 2011, under Linux, Programming

Lately, I’ve been getting acquainted with Rails development at work. It’s been a pretty steep learning curve (for that matter, I guess it still is), but I’ve enjoyed it thus far. So, with my new found Ruby skills (or, I guess more-so my new found need to learn Ruby), I wrote a script that uses SSH to iteratively connect to every computer in a lab and update them. This could be used for just about anything, but for my instance it was updating a lab. There was a bit more to my script as I needed to recompile some device drivers when there was a new kernel, but for simplicities sake, I’ve ripped them out. Hope this helps someone else!

First, you’ll need to install the ruby-ssh library.

sudo gem install net-ssh
sudo gem install highline

And, the script is:

#!/usr/bin/ruby

require 'rubygems'
require 'net/ssh'
require 'highline/import'

hosts=[ "host1",
            "host2" ]

cmds = ["yum -y update",
             "init 6"]

username = "root"

# Assuming that all hosts have the same password
password = ask("Enter Password: ") { |q| q.echo = false }

hosts.each do |host|
    Net::SSH.start( host , username, :password => password) do |ssh|
        puts "Connected to #{host}"
        cmds.each do |cmd|
            puts "Performing #{cmd} on #{host}"
            output = ssh.exec! cmd do |ch, stream, data|
                if stream == :stderr
                    puts "Error: #{data}"
                else
                    puts data
                end
            end
        end
    end
end

And, that’s all there is to it! There’s a real lack of comments, but I feel it’s pretty self-explanatory. Enjoy!

2 Comments :, , , , , more...

Simple Shell in C

by Drew Dahl on Dec.02, 2010, under Linux, Programming

Well, life has been a 24/7 hell for the last few months. As an example of how much free time I’ve had, I haven’t seen a couple of my really good friends since July or August. Hopefully they haven’t forgotten about me ;-)

In any case, I wrote a pretty good simple shell in C for my Operating Systems class. I finished it back in October, but haven’t posted it until now as several students just recently finished theirs.  Wouldn’t want them to cheat. ;-)

Less rambling.  The reason I’m posting this is that I think it is a really good example of using some basic system calls, such as malloc(), printf(), fgets(), strtok(), strcmp(), strcpy(), sprintf(), free(), chdir(), fork(), execpe(), opendir(), and wait(). Hopefully someone finds this useful :-)

#include <stdio .h>
#include <stdlib .h>
#include <unistd .h>
#include <string .h>
#include <sys /types.h>
#include <dirent .h>

const int SIZE=100;
const int ARGSIZE=10;

void cd(char *dir)
{
    int ret = 0;

    //Check to see if directory argument is blank
    if(dir == '\0')
        dir = getenv("HOME");
    //Check to see if directory argument starts with ~ and replace it with $HOME
    else if(dir[0] == '~')
    {
        char* temp = malloc(SIZE);
        strcpy(temp,dir+1);
        sprintf(dir,"%s%s",getenv("HOME"),temp);
        free(temp);
    }

    //Change Directory
    ret = chdir(dir);
           
    if(ret != 0)
        fprintf(stderr,"Failed to enter directory: %s\n",dir);
    else
        printf("%s\n",dir);
}

void ls(char *dir)
{
    DIR* open_dir;
    struct dirent* drent;

    if(dir == '\0') //See if dir is valid, if not set it to current directory
        dir = (char*)".";

    if((open_dir = opendir(dir)) != NULL) //open dir
    {
        while((drent = readdir(open_dir)) != NULL) //get contents of directory
        {
            printf("%s\n",drent->d_name); //print contents
        }
   
        closedir(open_dir); //close dir
    }
}

void execute(char *args[])
{
    int status;
    pid_t pid;

    //fork and execute the command   
    if((pid = fork()) == 0)
    {
        execvp(args[0],args);
        //execvp should only return if there was an error

        fprintf(stderr,"Unknown command\n");
        exit(0);
    }
    else if(pid < 0)
    {
        fprintf(stderr,"Failed to fork(): %s\n", args[0]);
        status = -1;
    }
    //Wait for child so stdin and stdout aren't fighting for use   
    else
        while(wait(&status) != pid)
           continue;
}

int main(int argc, char *argv[], char *envp[])
{
    char *temp;
    char *line;
    char *args[ARGSIZE];
    char argIndex = 0;

    for(;;)
    {
        line = malloc(SIZE); //Allocate memory for line
        argIndex = 0; //Initialize argIndex

        printf("\n[SHELL ] ");

        fgets(line, SIZE, stdin); //Get Input

        temp = strtok(line, " \n"); //Get input into an array to use w/ execve

        while(temp != NULL)
        {
            args[argIndex] = temp;
            argIndex++;
            temp = strtok(NULL, " \n");
        }

        args[argIndex] = (char*) 0; //Set the end of the arguments list

        if(strcmp(args[0], "quit") == 0 || strcmp(args[0], "exit") == 0)
            break; //break out for for(;;) loop

        if(line== "\n")
            printf("[SHELL ] ");
        else if ((strcmp(args[0], "ls") ==0))
            ls(args[1]); //run ls
        else if ((strcmp(args[0], "cd") == 0))
            cd(args[1]); //run cd
        else
            execute(args); //Fork and Execute command

        free(line); //Free memory from line
    }

    printf("\n");
    return 0;
}

And, in case you want a Makefile (I know I do!):

CC = gcc
OBJECTS =
PROC = shell

CFLAGS =
LFLAGS =

$(PROC):
$(CC) $(CFLAGS) simpleshell.c -o $(PROC) $(LFLAGS)
all:
$(CC) $(CFLAGS) simpleshell.c -o $(PROC) $(LFLAGS)
clean:
rm -rf *.o *.c~ $(PROC)

Enjoy!

(P.S… Todoist-for-Android updates will follow! I promise! The holidays are coming after all! :-] )

2 Comments more...

HowTo Setup Authenticated Postfix

by Drew Dahl on May.15, 2010, under HowTo, Linux, Mail

I recently had the experience of setting up Postfix. It works really well, in my opinion; however, setting it up wasn’t the simplest for what I wanted. But, at least it was simpler than sendmail :-)

Reading through several articles on the Internet, everyone was giving steps on how to setup postfix to handle e-mail for any FQDN (Fully-Qualified Domain Name). Well, we don’t want to be handling someone else’s e-mail, so we decided to set it up with authentication. All of the guides on setting up Postfix with SASL authentication are great and all; however, they don’t address the issue of, what if you want to receive mail as well. That’s a simple fix, but moreover, what if you have a service like mailman running? Mailman isn’t easily configured to authenticate against the SMTP server to send mail. So, the following are the configurations that I’ve come up with to solve all of these problems:

For the file /etc/postfix/main.cf

<strong>queue_directory = /var/spool/postfix
command_directory = /usr/sbin
daemon_directory = /usr/libexec/postfix
data_directory = /var/lib/postfix
mail_owner = postfix
myhostname = hostname.domain.tld
mydomain = domain.tld
myorigin = $mydomain
inet_interfaces = all
inet_protocols = all
mydestination = $myhostname, localhost.$mydomain, localhost, localhost.localdomain, $mydomain
unknown_local_recipient_reject_code = 550
mynetworks = 192.168.0.0/24, 127.0.0.1/32
relay_domains = $mydestination
smtpd_sasl_auth_enable = yes
smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination
broken_sasl_auth_clients = yes
alias_maps = hash:/etc/aliases, hash:/etc/mailman/aliases
alias_database = hash:/etc/aliases
recipient_delimiter = +
debug_peer_level = 2
debugger_command =
         PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin
         ddd $daemon_directory/$process_name $process_id & sleep 5
sendmail_path = /usr/sbin/sendmail.postfix
newaliases_path = /usr/bin/newaliases.postfix
mailq_path = /usr/bin/mailq.postfix
setgid_group = postdrop
html_directory = no
manpage_directory = /usr/share/man
sample_directory = /usr/share/doc/postfix-2.6.5/samples
readme_directory = /usr/share/doc/postfix-2.6.5/README_FILES</strong>

Now keep in mind, your values for some of the above WILL be different. This configuration is on a machine that’s running mailman as well (thus the /etc/mailman/aliases file).

And lastly, for SASL auth, edit the file: /usr/lib64/sasl2/smtpd.conf

<strong>pwcheck_method: saslauthd
mech_list: plain login</strong>

Your lib64 directory may just be lib, depending on the architecture of your box. All of these edits were made a 64-bit Fedora 12 machine, but they should work for every machine.

And last note. After all of the edits have been made, make sure to restart postfix and restart saslauthd with the following:

/etc/init.d/postfix restart
/etc/init.d/saslauthd restart

For questions on what some of the postfix settings mean, you can check out one of the following:

postconf man-page by running “man postconf” or visit http://www.postfix.org/postconf.5.html

Postfix Documentation at: http://www.postfix.org/documentation.html

Postfix HowTo’s at: http://www.postfix.org/docs.html

Postfix is definition the easiest MTA I’ve ever had the pleasure of working with, as far as configuration goes. I hope this helps :-)

Leave a Comment :, , , more...

Setup sendmail to use Gmail’s SMTP server

by Drew Dahl on Feb.18, 2010, under HowTo, Linux, Mail

Well, I did this on Fedora 12, so I’ll be basing everything off of Fedora packages and yum; however, this should work on any distro.

Things you’ll need: sendmail, sendmail-cf, cyrus-sasl

Might need something more, but if so, I’ve overlooked it…

The first thing we’re going to do is setup our authinfo. Do the following:

mkdir /etc/mail/auth/
cd /etc/mail/auth/
vim client-info

In the client-info file you’ve open in your text editor, insert the following line:

AuthInfo:smtp.gmail.com “U:root” “I:username@gmail.com” “P:password” “M:PLAIN”
AuthInfo:smtp.gmail.com:587 “U:root” “I:username@gmail.com” “P:password” “M:PLAIN”

Now, save it, quit your editor, and run the following in the same directory.

makemap -r hash client-info.db < client-info
chmod 600 *
cd ../
chmod 700 auth

Now, let’s move on to making our certs. Do the following:

mkdir /etc/mail/certs/
cd /etc/mail/certs/
openssl req -new -x509 -keyout cakey.pem -out cacert.pem -days 3650
openssl req -nodes -new -x509 -keyout sendmail.pem -out sendmail.pem -days 3650
cp  /etc/pki/tls/certs/ca-bundle.crt /etc/mail/certs

And finally, let's edit our sendmail.mc. Do the following:

cd /etc/mail/
vim sendmail.mc

And, add the following to sendmail.mc:

FEATURE(`authinfo’,`hash /etc/mail/auth/client-info.db’)dnl
define(`SMART_HOST’,`smtp.gmail.com’)dnl
define(`RELAY_MAILER_ARGS’, `TCP $h 587′)
define(`ESMTP_MAILER_ARGS’, `TCP $h 587′)
define(`CERT_DIR’, `/etc/mail/certs’)
define(`confCACERT_PATH’, `CERT_DIR’)
define(`confCACERT’, `CERT_DIR/ca-bundle.crt’)
define(`confCRL’, `CERT_DIR/ca-bundle.crt’)
define(`confSERVER_CERT’, `CERT_DIR/sendmail.pem’)
define(`confSERVER_KEY’, `CERT_DIR/sendmail.pem’)
define(`confCLIENT_CERT’, `CERT_DIR/sendmail.pem’)
define(`confCLIENT_KEY’, `CERT_DIR/sendmail.pem’)
define(`confAUTH_MECHANISMS’, `EXTERNAL GSSAPI DIGEST-MD5 CRAM-MD5 LOGIN PLAIN’)
TRUST_AUTH_MECH(`EXTERNAL DIGEST-MD5 CRAM-MD5 LOGIN PLAIN’)

Now run:

m4 sendmail.mc > sendmail.cf
/etc/init.d/sendmail restart

I think it's all self explanatory for the most part. Happy mailing :-)

-=EDIT=-06/02/2010

In the above configuration files, a user reported having issues while copying the above information into their config files. The issue was regarding the quotes around various options. So, if you experience any trouble, please try replacing the quotes. (e.g. delete the ones that are there and add them back within your text editor)

10 Comments :, , more...

Quick Overview of SELinux and Apache

by Drew Dahl on Jan.17, 2010, under HowTo, Linux

I found this link on-line and found it to be quite useful.

http://www.beginlinux.com/server_training/web-server/976-apache-and-selinux

I refer to it often as I forget some of the commands once in a while when I add new files for Apache to serve.

Leave a Comment :, more...

DBDesigner 4 on Fedora 12

by Drew Dahl on Jan.17, 2010, under HowTo, Linux

I found this very useful article on running DBDesigner 4 on Fedora 8, here. I followed the directions and found it to work on Fedora 11 and Fedora 12. I’m sure it’ll work for just about any distro, so I’m just reposting the directions here as I find it to be a very useful program.

Do not use the original DBDesigner4 download available on the fabForce.net website. Instead download the dbdesigner-fork package from here:

http://sourceforge.net/projects/dbdesigner-fork/

Once you have unpacked it. Edit the bin/startdbd_using_kernel2.6 script and remove the assume kernel 2.4.1 text:

Original file contents: LD_ASSUME_KERNEL=2.4.1 LANG=en_US.ISO8859-1 LD_LIBRARY_PATH=./Linuxlib/ ./DBDesignerFork

Edited contents: LANG=en_US.ISO8859-1 LD_LIBRARY_PATH=./Linuxlib/ ./DBDesignerFork

Save it and run it. It should all work as expected on Linux Fedora 8 or indeed any other modern distribution like Ubuntu, etc.

Leave a Comment :, , , more...

.htaccess – No Auth for local access/Auth for outside access

by Drew Dahl on Dec.28, 2009, under HowTo, Linux

For this, we’ll throw an .htaccess file into the directory you don’t want anyone to access that’s served via apache. For this, we’ll also have to have the following set for the directory in the httpd.conf file:

AllowOverides AuthConfig

Here’s what the .htaccess file should look like (with a few modifications for location and network if you need):

AuthType Basic
AuthName "Remote Auth"
AuthUserFile /var/www/html/.htpasswd
Require valid-user

Order deny,allow
deny from all
allow from 192.168.0

Satisfy any

And then in the same directory, create the .htpasswd file by:

htpasswd -c .htpasswd username

Then when promptd, enter the password for that username. Make sure both files are owned by apache (or www-data if your webserver runs as such). Viola! It works.

(Note: To add more users that the htpasswd file, do the same command as above, without the -c)

Leave a Comment :, more...

Fixing The Error: DB_RUNRECOVERY: Fatal error, run database recovery

by Drew Dahl on Dec.27, 2009, under HowTo, Linux

If you get a message similar to this:

[username@localhost ~]$ sudo yum update
rpmdb: Thread/process 2402/139688794072832 failed: Thread died in Berkeley DB library
error: db4 error(-30974) from dbenv-&gt;failchk: DB_RUNRECOVERY: Fatal error, run database recovery
error: cannot open Packages index using db3 -  (-30974)
error: cannot open Packages database in /var/lib/rpm
CRITICAL:yum.main:

Error: rpmdb open failed

You can fix it by running the following 3 commands:

[username@localhost ~]$ sudo rm -f /var/lib/rpm/__db*
[username@localhost ~]$ sudo db_verify /var/lib/rpm/Packages
[username@localhost ~]$ sudo rpm --rebuilddb
Leave a Comment :, more...

HowTo: Clone a VirtualBox HDD (.vdi)

by Drew Dahl on Dec.06, 2009, under HowTo, Linux, VirtualBox, Windows

Okay, this will be short and sweet. Here’s how you clone a VirtualBox HDD in Windows:

“C:\Program Files\Sun\VirtualBox\VBoxManage.exe” clonevdi “C:\Users\Andrew\.VirtualBox\HardDisks\Windows XP.vdi” “C:\Users\Andrew\.VirtualBox\HardDisks\Windows XP Clone.vdi”

and in Linux:

VBoxManage clonevdi /home/andrew/.VirtualBox/HardDisks/WindowsXP.vdi /home/andrew/.VirtualBox/HardDisks/WindowsXPClone.vdi

The basic form is “VBoxManage clonevdi sourcevdi destinationvdi”. Now you may ask, why clone a virtual machine’s hard drive? Well, if you want to back them up, this works for that. Or, if you want to duplicate that same virtual machine without having to do a second installation/activation.

Also to note, doing it this way will change the HDD’s UID, so you don’t get the error: “A hard disk with UUID {92c7da90-00f3-4bda-b338-57d24dad7f4b} or with the same properties (’/home/andrew/.VirtualBox/HardDisks/WindowsXP.vdi’) is already registered.”

Also, last thing to note… Instead of the directory “HardDrives”, yours may be “VDI”. I believe in older versions of VirtualBox it was VDI; however, these days it’s HardDrives.

1 Comment :, , more...

Looking for something?

Use the form below to search the site:

Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!