iptables: blocking SAMBA traffic, but allowing from specific MAC addresses

Submitted by Jochus on Thu, 02/12/2010 - 10:10 | Posted in:


My god, it took me hours to configure the following setup. I want to block SAMBA traffic to all other clients, but allow them from specific hosts by MAC address:

1/ I keep the INPUT chain to policy ACCEPT
2/ I allow traffic on specific MAC address

$ iptables -A INPUT --protocol tcp --destination-port 135:139 -m mac --mac-source ##REPLACE_BY_YOUR_MAC_ADDRESS## -j ACCEPT
$ iptables -A INPUT --protocol tcp --source-port 135:139 -m mac --mac-source ##REPLACE_BY_YOUR_MAC_ADDRESS## -j ACCEPT
$ iptables -A INPUT --protocol udp --destination-port 135:139 -m mac --mac-source ##REPLACE_BY_YOUR_MAC_ADDRESS## -j ACCEPT
$ iptables -A INPUT --protocol udp --source-port 135:139 -m mac --mac-source ##REPLACE_BY_YOUR_MAC_ADDRESS## -j ACCEPT
$ iptables -A INPUT --protocol tcp --destination-port 445 -m mac --mac-source ##REPLACE_BY_YOUR_MAC_ADDRESS## -j ACCEPT
$ iptables -A INPUT --protocol tcp --source-port 445 -m mac --mac-source ##REPLACE_BY_YOUR_MAC_ADDRESS## -j ACCEPT
$ iptables -A INPUT --protocol udp --destination-port 445 -m mac --mac-source ##REPLACE_BY_YOUR_MAC_ADDRESS## -j ACCEPT
$ iptables -A INPUT --protocol udp --source-port 445 -m mac --mac-source ##REPLACE_BY_YOUR_MAC_ADDRESS## -j ACCEPT

3/ I deny all other traffic

$ iptables -A INPUT --protocol tcp --destination-port 135:139 -j DROP
$ iptables -A INPUT --protocol tcp --source-port 135:139 -j DROP
$ iptables -A INPUT --protocol udp --destination-port 135:139 -j DROP
$ iptables -A INPUT --protocol udp --source-port 135:139 -j DROP
$ iptables -A INPUT --protocol tcp --destination-port 445 -j DROP
$ iptables -A INPUT --protocol tcp --source-port 445 -j DROP
$ iptables -A INPUT --protocol udp --destination-port 445 -j DROP
$ iptables -A INPUT --protocol udp --source-port 445 -j DROP

Adding a file to a node programmatically

Submitted by Jochus on Fri, 29/10/2010 - 00:57 | Posted in: Drupal
Posted in

Ever wondered how you add a file to node in code? It's really easy :-) ... Please note that the file was already on the server (on a temporary location)

/**
 * @param node the node to which you want to add the file
 * @param file the path to the file: e.g.: /tmp/image.jpg
 * @return TRUE if success, FALSE if not
 */
function store_file($node, $file) {
    if (!isset($file) || !file_exists($file)) {
        drupal_set_message('File does not exists');
        return FALSE;
    }
 
    $details = stat($file);
    $filesize = $details['size'];
    $dest = file_directory_path();
    if(!file_copy($file,$dest)) {
        drupal_set_message("Failed to move file: $file");
        return FALSE;
    } else {
        $name = basename($file);
    }
 
    // build the file object
    $file_obj = array();
    $file_obj['filename'] = $name;
    $file_obj['filepath'] = $file;
    $file_obj['filemime'] =  file_get_mimetype($name);
    $file_obj['filesize'] = $filesize;
    $file_obj['status'] = FILE_STATUS_TEMPORARY;
    $file_obj['timestamp'] = time();
    $file_obj['list'] = 1;
    $file_obj['new'] = TRUE;
    $file_obj['data']['alt'] = 'foo';
    $file_obj['data']['title'] = 'bar';
    $file_obj['uid'] = '1'; // 1 = admin, but you can do here whatever you want ...
 
    // save file to files table, fid will be set
    drupal_write_record('files', $file_obj);
 
    // change file status to permanent
    file_set_status($file_obj, 1);
 
    // attach the file object to your node
    $node->field_main_picture[0] = $file_obj; // property can be different 
    return TRUE;
}

CPU monitoring in Ubuntu 10.04 Lucid

Submitted by Jochus on Thu, 21/10/2010 - 00:38 | Posted in: Linux
Posted in

Last week, I learned something important about CPU monitoring. At work, I have a AMD Athlon(tm) II X3 440 Processor. This is a CPU with 3 cores. Each core can go up to 3.0 GHz, but when idle, the cores drop down to 800 MHz.

So, to monitor this process, you first have to right click the toplevel panel of Ubuntu. Choose Add to Panel... and choose CPU Frequency Scaling Monitor. The effect should be something like this:

Ok, this means one of your cores is currently running at 800 MHz. Try clicking (left) on the monitor. You will see the following settings:

First of all, you can see you can manually set the clock speed, or you can use a planning. Default is set to On demand. When the PC needs a lot of CPU resources, the clock speed will go up. Or you can choose for performance. The cores will run at 3.0 GHz anytime.

To see a specific core, right click on the monitor and choose Preferences:

As you can see, it's possible to select a certain core. I've added 3 monitors, to be able to check all my cores in one time:

Converting (resizing) video's in Java with Xuggler

Submitted by Jochus on Wed, 13/10/2010 - 00:10 | Posted in: Java
Posted in


Last week, I had to investigate a case where we want to resize a video to a whole set of resized video's. So you have a source video with resolution: 1280x800 and I want a video for 640x400, 320x200, 160x100, ... etc, etc, ...

Of course, we need Java for this ;-) ! I came across this library http://www.xuggle.com/xuggler/. Xuggler is the easy way to uncompress, modify, and re-compress any media file (or stream) from Java.

Well, they say it is "easy", but for me it wasn't. This is my (finally!) working example.

Prerequisites

  • install Xuggler
  • set the following ENV vars
  • export XUGGLE_HOME="/usr/local/xuggler"
    export PATH=$PATH:$XUGGLE_HOME/bin
    export LD_LIBRARY_PATH="/usr/local/xuggler/lib"

Resizing a video

MediaConvertor

public class MediaConvertor {
	private static final Integer WIDTH = 640;
	private static final Integer HEIGHT = 360;
 
	private static final String INPUT_FILE = "/tmp/input.mp4";
	private static final String OUTPUT_FILE = "/tmp/output.mpg";
 
	public static void main(String[] args) {
		// create custom listeners
		MyVideoListener myVideoListener = new MyVideoListener(WIDTH, HEIGHT);
		Resizer resizer = new Resizer(WIDTH, HEIGHT);
 
		// reader
		IMediaReader reader = ToolFactory.makeReader(INPUT_FILE);
		reader.addListener(resizer);
 
		// writer
		IMediaWriter writer = ToolFactory.makeWriter(OUTPUT_FILE, reader);
		resizer.addListener(writer);
		writer.addListener(myVideoListener);
 
		// show video when encoding
		reader.addListener(ToolFactory.makeViewer(true));
 
		while (reader.readPacket() == null) { 
			// continue coding
		}
	}
}

Resizer

import com.xuggle.mediatool.MediaToolAdapter;
import com.xuggle.mediatool.event.IVideoPictureEvent;
import com.xuggle.mediatool.event.VideoPictureEvent;
import com.xuggle.xuggler.IVideoPicture;
import com.xuggle.xuggler.IVideoResampler;
 
public class Resizer extends MediaToolAdapter {
	private Integer width;
	private Integer height;
 
	private IVideoResampler videoResampler = null;
 
	public Resizer(Integer aWidth, Integer aHeight) {
		this.width = aWidth;
		this.height = aHeight;
	}
 
	@Override
	public void onVideoPicture(IVideoPictureEvent event) {
		IVideoPicture pic = event.getPicture();
		if (videoResampler == null) {
			videoResampler = IVideoResampler.make(width, height, pic.getPixelType(), pic.getWidth(), pic
					.getHeight(), pic.getPixelType());
		}
		IVideoPicture out = IVideoPicture.make(pic.getPixelType(), width, height);
		videoResampler.resample(out, pic);
 
		IVideoPictureEvent asc = new VideoPictureEvent(event.getSource(), out, event.getStreamIndex());
		super.onVideoPicture(asc);
		out.delete();
	}
}

MyVideoListener

import com.xuggle.mediatool.MediaToolAdapter;
import com.xuggle.mediatool.event.IAddStreamEvent;
import com.xuggle.xuggler.ICodec;
import com.xuggle.xuggler.IStreamCoder;
 
public class MyVideoListener extends MediaToolAdapter {
	private Integer width;
	private Integer height;
 
	public MyVideoListener(Integer aWidth, Integer aHeight) {
		this.width = aWidth;
		this.height = aHeight;
	}
 
	@Override
	public void onAddStream(IAddStreamEvent event) {
		int streamIndex = event.getStreamIndex();
		IStreamCoder streamCoder = event.getSource().getContainer().getStream(streamIndex).getStreamCoder();
		if (streamCoder.getCodecType() == ICodec.Type.CODEC_TYPE_AUDIO) {
		} else if (streamCoder.getCodecType() == ICodec.Type.CODEC_TYPE_VIDEO) {
			streamCoder.setWidth(width);
			streamCoder.setHeight(height);
		}
		super.onAddStream(event);
	}
 
}

Difference between constant DATE_W3C on different PHP versions

Submitted by Jochus on Tue, 12/10/2010 - 00:40 | Posted in:

I came across this "bug" in PHP when I was using the http://drupal.org/project/xmlsitemap module of Drupal on different servers (different PHP versions).

What is XMLSitemap?
The XML sitemap module creates a sitemap that conforms to the sitemaps.org specification. This helps search engines to more intelligently crawl a website and keep their results up to date. The sitemap created by the module can be automatically submitted to Ask, Google, Bing (formerly Windows Live Search), and Yahoo! search engines. The module also comes with several submodules that can add sitemap links for content, menu items, taxonomy terms, and user profiles.

So on the first server, Google was perfectly processing the sitemap.xml file. But on the second server, Google was telling me the format of the sitemap.xml was invalid (including linenumber, luckily :p ...). That was awkward, as I was using the same version of XMLSitemap (version 1.2).

After looking in the XML file, I noticed some differences:
First server:

<lastmod>2010-10-11T15:52:01+00:00</lastmod>

Second server:

<lastmod>2010-10-11T15:52:01+0000</lastmod>

As you can see, there's a colon missing in the second version.
The code which is producing these lines is in xmlsitemap.pages.inc

...
      $link->output .= "\t<lastmod>". gmdate(DATE_W3C, $link->changed) ."</lastmod>\n";
...

The problem is related to the DATE_W3C constant. In PHP 5.1.2, the constant is different to PHP 5.2.14. More information? http://bugs.php.net/36599

I fixed this bug by changing the line into:

...
      $link->output .= "\t<lastmod>". gmdate('Y-m-d\TH:i:s+00:00', $link->changed) ."</lastmod>\n";