Archive for April, 2006

Pattern-based file renaming

Monday, April 3rd, 2006

Ever wanted to do bulk operations on files, similar to xargs, but much more flexible? For example:

* rename all files .jpeg to .jpg
* remove a prefix from many file names?
* add a suffix/extension?
* remove a prefix/suffx/extension?

Here’s a script I wrote:


#!/bin/bash
#
# Pattern-based file rename
# #(c)2006 by Tadeusz Pietraszek
#
# Usage:
# ./mv-pattern -i a *.txt <- delete all 'a's in file names
# ./mv-pattern -i jpeg -o jpg *.jpeg <- rename all jpegs to jpg
# ./mv-pattern -o .txt <- add an extension
# ./mv-pattern -i .txt <- remove an extension
#

if [ $# -eq 0 ]
then
  echo "Usage: `basename $0` [-i
]  [-o
]  [-c ] files"
  exit -1;
fi

INPATTERN="";
OUTPATTERN="";
COMMAND="echo";

while getopts "i:o:c:" Option
do
  case $Option in
    i ) INPATTERN=$OPTARG;;
    o ) OUTPATTERN=$OPTARG;;
    c ) COMMAND=$OPTARG;;
    * ) echo "Unimplemented option chosen. Has to be one of -i -o -c"; exit -1;;
  esac
done

if [ -z "$INPATTERN" ]; then
  echo "No input pattern. Are you sure it's what you want?";
#  exit -1;
fi

if [ -z "$INPATTERN" ]; then
  echo "No input pattern. Are you sure it's what you want?";
#  exit -1;
fi

shift $(($OPTIND - 1))
# Decrements the argument pointer so it points to next argument.

#echo "in: $INPATTERN, out: $OUTPATTERN";

#rename
for FILE in  "$@" ; do
    if [ -f $FILE ]; then
        NEWFILE=`echo $FILE | sed -re "s/(.*)$INPATTERN(.*)/\1$OUTPATTERN\2/"`;
        if [ "$FILE" != "$NEWFILE" ]; then
            $COMMAND $FILE $NEWFILE;
        fi;
    fi;
done

exit 0

  • [Linux Home Server HOWTO - Network File System](http://www.brennan.id.au/19-Network_File_System.html) – an cool page on setting up an NFS sever on Linux, discussing NFS4 support. – Gentoo’s wiki on NFS4 (0)

On the perils of masquerading with Linux

Sunday, April 2nd, 2006

I recently discovered a potential security problem with the __configuration__ of Linux-based masquerading firewalls, which (I must admit I fell prey of).

Suppose I a server with one outgoing IP address, which has two network cards (`eth0` – outgoing link and `eth1` – internal link). I want to set up masquerading of the internal network 192.168.0.0/24.

The way I would proceed is:

1. Enable packet routing:

net.ipv4.ip_forward = 1

2. Configure a masquearing rule:

iptables -t nat -A POSTROUTING -j MASQUERADE

3. Set up a firewall rules:

iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -i eth1 -j ACCEPT
iptables -A INPUT -m conntrack –ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp -m multiport –dports -j ACCEPT
iptables -P INPUT DROP

Does it work and is it secure? Yes… well… not really. Suppose the atacker is on the same network as I am and sets my host as his router. He will then be able to:

1. Connect to my internal hosts (which will be helpfully masqueraded).
2. Use my server to masquerade his connections (only on the allowed ports, but still).
3. If the server has another interface (e.g. running an IPsec tunnel to a restricted network, it’s getting __really scary__.

What can I do:

1. Control the FORWARD chain:

iptables -A FORWARD -m conntrack –ctstate RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i eth1 -j ACCEPT
iptables -P FORWARD DENY

2. Block the incoming connections in `iptables -A INPUT -p tcp -m multiport –dports -j ACCEPT` by specifying the destination IP address. However, this may be tricky, if the server uses a DHCP address (otherwise you wouldn’t be using MASQUERADE in the first place).

3. Change masquerade so that it has an interface specified: `iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE`. This only partially solves the problem, as the packets will still be forwarded to internal networks.