Articles

Adventures in Red Hat Enterprise Linux, CentOS, Fedora, OpenBSD and other open source solutions.

Change ssh configuration when the "Location" changes on Mac OS X

Have you ever used the "Location" facility in Mac OS X? It changes network settings for you when you work from different locations, like "work", "home", "mobile" or any other setting. As far as I can tell it's designed to change:

  • IP, netmask, gateway
  • Used interfaces (airport, ethernet, etc)
  • Proxy server

What's missing here is SSH settings. You configure your ssh-client in ~/.ssh/config manually. In my case I can login a machine from home directly, but when I am somewhere else, I need to use a step-stone.

That would mean I'd have to change ~/.ssh/config every time I am on a different location! Here is a solution to the problem, inspired by an article about Location based scripts.

  1. Create a new Location in Mac OS X Click on the Apple logo in the left corner, Location - Network Preferences - Edit Locations - The + symbol and so on.
  2. Copy/create ssh configurations, call them ~/.ssh.$PROFILE and replace $PROFILE by the name you came up with for you profile names. I use "~/.ssh/config.Automatic" and "~/.ssh/config.Mobile".
  3. Add a few lines to /~.locationchanger These lines actually link ~/.ssh/config to the right ssh configuration.
    location=$(scselect 2>&1|grep ' \* ' | awk '{print $NF}' | sed 's/(//g;s/)//g')
    if [ -f ~/.ssh/config.$location ] ; then
    rm ~/.ssh/config
    ln -s ~/.ssh/config.$location ~/.ssh/config
    fi
  4. Make the ~/.locationchanger executable Use chmod 750 ~/.locationchanger to do that.
  5. Create a file ~/Library/LaunchAgents/LocationChanger.plist The content should be like this:
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
            "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
            <key>Label</key>
            <string>tech.inhelsinki.nl.locationchanger</string>
            <key>ProgramArguments</key>
            <array>
                    <string>/Users/robertdb/.locationchanger</string>
            </array>
            <key>WatchPaths</key>
            <array>
                    <string>/Library/Preferences/SystemConfiguration</string>
            </array>
    </dict>
    </plist>
  6. Load that LocationChanger into launchd. Use launchctl load ~/Library/LaunchAgents/LocationChanger.plist to do this, or reboot.

From now on the script ~/.locationchanger will be started when changing Location.

Some items that might be changed when you switch locations are using a stepstone to ssh to machines or using corkscrew to puch through http proxies.

This tool uses scselect, an apple tool that confiures or prints locations.

SCSELECT(8)               BSD System Manager's Manual              SCSELECT(8)

NAME
     scselect -- Select system configuration "location"

SYNOPSIS
     scselect [-n] [new-location-name]

DESCRIPTION
     scselect provides access to the system configuration sets, commonly
     referred to as "locations".  When invoked with no arguments, scselect
     displays the names and associated identifiers for each defined "location"
     and indicates which is currently active.  scselect also allows the user
     to select or change the active "location" by specifying its name or iden-
     tifier.  Changing the "location" causes an immediate system re-configura-
     tion, unless the -n option is supplied.

     At present, the majority of preferences associated with a "location"
     relate to the system's network configuration.

     The command line options are as follows:

     -n  Delay changing the system's "location" until the next system boot (or
         the next time that the system configuration preferences are changed).

     new-location-name
         If not specified, a list of the available "location" names and asso-
         ciated identifiers will be reported on standard output.  If speci-
         fied, this argument is matched with the "location" names and identi-
         fiers and the matching set is activated.

SEE ALSO
     configd(8)

HISTORY
     The scselect command appeared in Mac OS X Public Beta.

Mac OS X                       November 4, 2003                       Mac OS X

Calculating a prime number with a shell script

For experimental purposes I tried to write a shell script that calculates a whole range of prime numbers. The script seems to be working, but is not very efficient. While writing this script I found a regular expression that does the same thing, only a couple of hundred times faster.

Here is that experimental shell script to calculate a prime number:

#!/bin/sh

throughnoother() {
# A function to calculate if the only argument given is not dividable through any other number.
# Set the status to no. No means, not a prime number. When every test is successful, change
# the status to yes.
status=no
# num starts at 1, and is increased by one each time.
num=1
# This for loop consists of numbers up to half the value of the given argument.
for divider in $(while [ $num -lt $(($1/2)) ] ; do num=$(($num+1)) ; echo $num ; done) ; do
  # This is not the test to divide through its own value, so skip that.
  if [ $1 != $divider ] ; then
   # This tests to see if the rounded calculation can be reversed and gives the same result.
   if [ $((($1/$divider)*$divider)) = $1 ] ; then
    status="yes"
   fi
  fi
done
# End by printing the status.
echo $status
}

# Start at 2.
number=2

while [ 1 ] ; do
# This first if test, test if the number is dividable through 1 and if it's dividable through itself.
  if [ $(($number/1)) = $number -a $(($number/$number)) = 1 ] ; then
   if [ $(throughnoother $number) != "yes" ] ; then
    # If all tests are succesful, then it must be a prime number, print it!
    echo "$number"
   fi
  fi
# Now increase the number to be tested by one.
number=$(($number+1))
done
done

How to burn an ISO file on a DVD in Mac OS X using Disk Utility

Because I alway forget how this exactly works, here is how to get and ISO image burned onto a DVD in Mac OS X. You will be using the application Disk Utility as it is installed by default on Mac OS X.

  1. Download the .ISO file to your computer. Use the desktop to find it back easily, but any other place will work just fine!
  2. Open Disk Utility. You can find this application in Utilities.
  3. Drag the .ISO file onto the left column (white) of Disk Utility. This tells the Disk Utility to do something with that ISO file.
  4. Highlight the image in the Disk Utility.
  5. Click Burn from the toolbar on top. Another screen will pop up, hit Burn to start burning.

Using SSH is not so secure as we expect it to be

It seems there are some negative reports related to the usage of SSH lately:

My faith in SSH as a protocol is huge, reconsidering the usage of SSH might be a good idea, although there are not many alternatives at the moment.

Using rsync from cron with ssh keys that have a passphrase

It took me some time to figure this one out, as everybody is using rsync and ssh-keys without passphrases, but I insist that an ssh-key should have a passphrase.

In my first attemts I got this error messages mailed to me by crontab:

Permission denied (gssapi-keyex,gssapi-with-mic,publickey,keyboard-interactive).

Here are the steps to automate a backup initiated from crontab using rsync, SSH and ssh-keys with a passphrase:

  1. Make a set of SSH keys.
  2. Setup SSH to use the agent automatically.
  3. Login once as the user who's cron will run the backup script. You will be asked for a passphrase. When the machine reboots, you will need to login once more, to enter the passphrase again.
  4. Make a backup script that includes some SSH variables.
    This script could be as simple as this:
    . /home/username/.ssh/variables
    rsync -avz --delete /data/ example.com:data

    N.B. This variables file only contains these lines:
    SSH_AUTH_SOCK=/tmp/ssh-DmFcb18036/agent.18036; export SSH_AUTH_SOCK;
    SSH_AGENT_PID=18037; export SSH_AGENT_PID;
    echo Agent pid 18037;
  5. Put that script in crontab.

That should do it for you, as it works like a charm for me!

Allowing a group to execute a specific command without using a password using sudo

So you have a user (or a group of users) on you Linux machine and want them to be able to execute something specific that normally can only be done by root or some other privileged user? Use sudo to solve your problem.

Open the sudoers file using visudo.
Append this line:

%groupname     ALL= NOPASSWD: /your/command -o with -o options -o and arguments like this

This will enable the group "groupname" to execute "/your/command", only with the specified options and arguments. The NOPASSWD makes sudo not ask for a password. Now the user can type:

$ sudo /your/command -o with -o options -o and arguments like this

Make OpenSSH logins 14 times faster!

Here is a trick to speedup your login to servers. This nice trick only works when you login to a box for the second time, now you might stop reading, but actually logging in again on a box occurs frequently on an average day with me.

First, lets measure time without any changes to SSH.

$ time ssh host ":"
real 0m0.573s
user 0m0.004s
sys 0m0.005s

Now let's modify ~/.ssh/config with these lines on top:

ControlMaster auto
ControlPath /tmp/ssh-%r@%h:%p

And measure again:

$ ssh host ":"
$ time ssh host ":"
real 0m0.039s
user 0m0.004s
sys 0m0.004s

Wow, that is an improvement of more than 14 times! Be aware this does not speed up SSH, it only speeds up the login process, but, always good to see speed improvements. Also be aware that your first SSH connection to a certain box will not be faster, only "recycled" connections (second or more times) are faster.

Files related to network configuration in OpenBSD

Setting up a network interface, it's routes, resolving and so on, can be complicated when you don't know your way around in OpenBSD. You will see it's not difficult at all to setup or change the network configuration of a box when you know about the existence of these files and man-pages.

  • /etc/hostname.if - This is where you set a IP address, netmask and broadcast address of the interface. Replace "if" with the name of the network interface, like sk0, sis1, etc. You are able to determine the available network interfaces using the command ifconfig(8). Checkout the man-page of hostname.if(5) for more details. One example of what you could find in a hostname.if file: inet 192.168.1.1 255.255.255.0 192.168.1.255 or just dhcp if you would want to use DHCP. When you are using DHPC, you don't need to read the rest, you are done!
  • /etc/mygate - The default route to the internet. One IP address (can be IPv4 or IPv6) will let the TCP/IP stack know where to send non-local traffic to.
  • /etc/myname - The hostname of the system, in the longest syntax, including domain and toplevel domain, like host1.example.com. Normally you will find this name and it's IP in /etc/hosts. (see below)
  • /etc/hosts - The manual resolver. Don't use this too much, better rely on DNS to resolve hostname to IP addressed and the other way around. But; it's common to at least put the hostname and localhost in /etc/hosts. One example line would be: 192.168.1.1 host1.example.com host1
  • /etc/resolv.conf - The system needs to know how can resolve names to IP addresses, this is the file you need! It contains a few items, like domain example.com. This tells the resolver that all hostnames you are searching for without a top level domain, are relative to example.com. If you would like to add more "local domains", you can use the search otherexample.com thirdexample.com variable. Do take care not to add too many domains; it will be confusing to what host you are connecting. The most important is to tell the resolver that there are nameservers in use. Each nameserver that it could use has it's own line, like this: nameserver 192.168.1.2.

Well, you should be able to configure the network cards on your OpenBSD machine now.

Sometimes you will find additional configuration in /etc/rc.local, like an extra route to you VPN network. OpenBSD does not facilitate for these extra parameters, so adding them to /etc/rc.local is a good, but not very generic option.

Tricks you can do using the command cd (Change Directory)

The command cd, which can change directory, seems as the most simple command there is. Guess what; there are a few tricks you can use to navigate faster over a filesystem.

command expanation
cd Go to the home directory.
cd - Go back to the previous directory.
cd -P /directory Go to the physical directory, so translate all symbolic links to what they point to.
cd -L /directory Go to that /directory and do follow symbolic links. This is default behaviour.

Here is a demonstration about that -P and -L behaviour:

$ cd /tmp ; mkdir test
$ ln -s test symlink
$ cd symlink ; pwd
/tmp/symlink
$ cd -P ../symlink ; pwd
/tmp/test

Syndicate content