Showing posts with label networking. Show all posts
Showing posts with label networking. Show all posts

2017-04-29

OpenBSD vmm Hypervisor Part 2: Installation and Networking

* Updated November 1, 2018, Thanks to some commenters below! 
This is going to be a (likely long-running, infrequently-appended) series of posts as I poke around in vmm.  A few months ago, I demonstrated some basic use of the vmm hypervisor as it existed in OpenBSD 6.0-CURRENT around late October, 2016. We'll call that video Part 1.

As good as the OpenBSD documentation is (and vmm/vmd/vmctl are no exception) I had to do a lot of fumbling around, and asking on the misc@ mailing list to really get to the point where I understand this stuff as well as I do. These are my notes so far.

Quite a bit of development was done on vmm before 6.1-RELEASE, and it's worth noting that some new features made their way in. Work continues, of course, and I can only imagine the hypervisor technology will mature plenty for the next release. As it stands, this is the first release of OpenBSD with a native hypervisor shipped in the base install, and that's exciting news in and of itself. In this article, we assume a few things:

  1. You are using OpenBSD 6.4-RELEASE or -STABLE  (or newer)
  2. You're running the amd64 architecture version of OpenBSD
  3. The system has an Intel CPU with a microarchitecture from the Nehalem family, or newer. (e.g. Westmere, Sandy Bridge, Ivy Bridge). Basically, if you've got an i5 or i7, you should be good to go.
  4. Your user-level account can perform actions as root via doas. See the man page for doas.conf(5) for details.
 Notes on formatting:
  1. Lines in blue are text inside configuration files.
  2. Lines in green are shell commands to be executed on the command line.

Basic network setup

To get our virtual machines onto the network, we have to spend some time setting up a virtual ethernet interface. We'll run a DHCP server on that, and it'll be the default route for our virtual machines. We'll keep all the VMs on a private network segment (via a bridge interface), and use NAT to allow them to get to the network. There is a way to directly bridge VMs to the network in some situations, but I won't be covering that today. (Hint: If you bridge to an interface with dhclient running in the host OS, no DHCP packets will reach the VMs, so it's best to static-assign your VM host's LAN port. or use a different interface entirely.)

Enable IP forwarding in sysctl. Add the following to /etc/sysctl.conf:

net.inet.ip.forwarding=1
net.inet6.ip6.forwarding=1

You can reboot to enable these, or run these commands manually:

doas sysctl net.inet.ip.forwarding=1
doas sysctl net.inet6.ip6.forwarding=1


We're going to be using "vether0" as the VM interface, and in my current configuration, "athn0" as the external interface. The below block of pf configuration was taken partially from /etc/example/pf.conf and some of the PF NAT example from the OpenBSD FAQ. Change your ext_if as needed, and save this as /etc/pf.conf:

ext_if="athn0"
vmd_if="vether0"

set skip on lo

block return
pass           
 

match out on $ext_if inet from $vmd_if:network to any nat-to ($ext_if)

Next, you'll need to specify an IP and subnet for vether0. I am going with 10.13.37.1 (and a 255.255.255.0 netmask for a /24 network) in my example. Place something like this in /etc/hostname.vether0:

inet 10.13.37.1 255.255.255.0

We need to create a bridge interface for the guest VMs to attach to, and bridge vether0 to it. Place the following in /etc/hostname.bridge0:

add vether0

Bring vether0 and bridge0 online by running the following commands:

doas sh /etc/netstart vether0
doas sh /etc/netstart bridge0

Reload the pf configuration (h/t to voutilad for the heads up in the comments about moving this step down a few spots):

doas pfctl -f /etc/pf.conf

Create a basic DHCP server configuration file that matches the vether0 configuration. I've specified 10.13.37.32-127 as the default DHCP pool range, and set 10.13.37.1 as the default route. Save this in /etc/dhcpd.conf:

option  domain-name "vmm.openbsd.local";
option  domain-name-servers 8.8.8.8, 8.8.4.4;

subnet 10.13.37.0 netmask 255.255.255.0 {
        option routers 10.13.37.1;

        range 10.13.37.32 10.13.37.127;

}

Configure a switch for vmm, so the VMs have connectivity. Put the following in /etc/vm.conf:

switch "local" {
        interface bridge0
}


Enable and start the DHCP server. We also need to set the flags on dhcpd so that it only listens on vether0. Otherwise, you'll end up with a rogue DHCP server on your primary network. Your network administrators and other users on your network will not appreciate this because it could potentially keep others from getting on the network properly.

doas rcctl enable dhcpd
doas rcctl set dhcpd flags vether0
doas rcctl start dhcpd

Enable vmd, then start it as well. For good measure, re-run fw_update to make sure you have the proper vmm-bios package.

doas rcctl enable vmd
doas rcctl start vmd
doas fw_update

You should notice a new interface, likely named "bridge0" in ifconfig now.

VM Creation and installation

Create an empty disk image for your new VM. I'd recommend 1.5GB to play with at first. You can do this without doas or root if you want your user account to be able to start the VM later. I made a "vmm" directory inside my home directory to store VM disk images in. You might have a different partition you wish to store these large files in. Adjust as needed.

mkdir ~/vmm
vmctl create ~/vmm/test.img -s 1500M

Boot up a brand new vm instance. You'll have to do this as root or with doas. You can download a -CURRENT install kernel/ramdisk (bsd.rd) from an OpenBSD mirror, or you can simply use the one that's on your existing system (/bsd.rd) like I'll do here.

The below command will start a VM named "test.vm", display the console at startup, use /bsd.rd (from our host environment) as the boot image, allocate 256MB of memory, attach the first network interface to the switch called "local" we defined earlier in /etc/vm.conf, and use the test image we just created as the first disk drive. 

doas vmctl start "test.vm" -c -b /bsd.rd -m 512M -n "local" -d ~/vmm/test.img

You should see the boot message log followed by the OpenBSD installer. Enter "I" at the prompt to install OpenBSD. I won't walk through how to install OpenBSD. If you've gotten this far, you've done this at least once before. I can say that the vm console works by emulating a serial port, so you should leave these values at their defaults (just press enter):
Change the default console to com0? [yes]
Available speeds are: 9600 19200 38400 57600 115200.
Which speed should com0 use? (or 'done') [9600]
You will also likely need to install packages without a prefetch area. Answer yes to this.
Cannot determine prefetch area. Continue without verification? [no] yes
After installation and before rebooting, I'd recommend taking note of the vio0 interface's generated MAC address (lladdr) so you can specify a static lease in dhcpd later. If you don't specify one, it seems to randomize the last few bytes of the address.
CONGRATULATIONS! Your OpenBSD install has been successfully completed!
To boot the new system, enter 'reboot' at the command prompt.
When you login to your new system the first time, please read your mail
using the 'mail' command.

# ifconfig vio0                                                               
vio0: flags=8b43 mtu 1500
        lladdr fe:e1:bb:d1:23:c4
        llprio 3
        groups: dhcp egress
        media: Ethernet autoselect
        status: active
        inet 10.13.37.39 netmask 0xffffff00 broadcast 10.13.37.255
Shut down the vm with "halt -p" and then press enter a few extra times. Enter the characters "~." (tilde period) to exit the VM console. Show the VM status, and stop the VM. I've been starting and stopping VMs all morning, so your VM ID will probably be 1 instead of 13.
# halt -p

(I hit ~. here...)
[EOT]
$ vmctl status
   ID   PID VCPUS  MAXMEM  CURMEM     TTY        OWNER NAME
   13 96542     1    256M   52.6M   ttyp3         root test.vm
$ doas vmctl stop 13
vmctl: terminated vm 13 successfully

VM Configuration

Now that the VM disk image file has a full installation of OpenBSD on it, build a VM configuration around it by adding the below block of configuration (with modifications as needed for owner, path and lladdr) to /etc/vm.conf.

# H-i-R.net Test VM
vm "test.vm" {
        disable
        owner axon
        memory 512M
        disk "/home/axon/vmm/test.img"
        interface {
                switch "local"
                lladdr fe:e1:bb:d1:23:c4
        }
}


I've noticed that VMs with much less than 256MB of RAM allocated tend to be a little unstable for me. You'll also note that in the "interface" clause, I hard-coded the lladdr that was generated for it earlier. By specifying "disable" in vm.conf, the VM will show up in a stopped state that the owner of the VM (that's you!) can manually start without root access.

Go ahead and reload the VM configuration with "doas vmctl reload", then look at the status again.
$ doas vmctl reload
$ vmctl status
   ID   PID VCPUS  MAXMEM  CURMEM     TTY        OWNER NAME

    -     -     1    512M       -       -         axon test.vm

DHCP Reservation (Optional)

I opted to set up a DHCP reservation for my VM so that I had a single IP address I knew I could SSH to from my VM host. This, to me, seems easier than using the VM console for everything.

Add this clause (again, modified to match the MAC address you noted earlier) to /etc/dhcpd.conf. You have to place this above the last curly-brace.

        host static-client {
                hardware ethernet fe:e1:bb:d1:23:c4;
                fixed-address 10.13.37.203;
        }

Restart dhcpd.

doas rcctl restart dhcpd

Go ahead and fire up the VM, and attach to the console.

vmctl start test.vm -c

You'll see the seabios messages, the boot> prompt, and eventually, all the kernel messages and the login console. Log in and have a look around. You're in a VM! Make sure the interface got the IP address you expected. Ping some stuff and make sure NAT works.
$ ifconfig vio0
vio0: flags=8b43 mtu 1500
        lladdr fe:e1:bb:d1:23:c4
        index 1 priority 0 llprio 3
        groups: egress
        media: Ethernet autoselect
        status: active
        inet 10.13.37.203 netmask 0xffffff00 broadcast 10.13.37.255
$ ping -c4 8.8.8.8
PING 8.8.8.8 (8.8.8.8): 56 data bytes
64 bytes from 8.8.8.8: icmp_seq=0 ttl=54 time=9.166 ms
64 bytes from 8.8.8.8: icmp_seq=1 ttl=54 time=7.295 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=54 time=9.178 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=54 time=25.935 ms

--- 8.8.8.8 ping statistics ---
4 packets transmitted, 4 packets received, 0.0% packet loss
round-trip min/avg/max/std-dev = 7.295/12.893/25.935/7.568 ms

Again, you can use <enter>~. to exit the VM console. You probably want to log off before you do that.  Go ahead and SSH in as well.

$ ssh axon@10.13.37.203
The authenticity of host '10.13.37.203 (10.13.37.203)' can't be established.
ECDSA key fingerprint is SHA256:f39GrAZouHQ3L+3/Qy3FHBma5K+eOe84B9QoFwqNpXo.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '10.13.37.203' (ECDSA) to the list of known hosts.
axon@10.13.37.203's password:
Last login: Sat Apr 29 14:21:54 2017
OpenBSD 6.1 (GENERIC) #19: Sat Apr  1 13:42:46 MDT 2017

Welcome to OpenBSD: The proactively secure Unix-like operating system.

Please use the sendbug(1) utility to report bugs in the system.
Before reporting a bug, please try to reproduce it with the latest
version of the code.  With bug reports, please try to ensure that
enough information to reproduce the problem is enclosed, and if a
known fix for it exists, include that as well.

$

Forward ports through the NAT (optional)

One last thing I did was to port-forward SSH and HTTP (on high ports) to my VM so that I could get to the VM from anywhere on my home network.

Add these lines to /etc/pf.conf directly under the vmd NAT rule we added earlier.

pass in on $ext_if proto tcp from any to any port 2200 rdr-to 10.13.37.203 port 22
pass in on $ext_if proto tcp from any to any port 8000 rdr-to 10.13.37.203 port 80

Reload the pf configuration

doas pfctl -f /etc/pf.conf

You should now be able to ssh to port 2200 on your host VM's IP. Obviously, browsing to port 8000 won't work until you've set up a web server on your VM, but this was how I started out when working on the PHP/MySQL guides.

2016-11-27

Introducing wiconn: A text-based 802.11 wireless network manager for OpenBSD

When I switched back to OpenBSD as my primary daily-use operating system back in 2011, my biggest complaint was the lack of an easy-to-use tool for managing wireless networks. I only used maybe two or three different wireless networks daily. I just used a few shell scripts that statically configured the network card for each of these environments. Any time I'd go somewhere else, though, it would be a pain to manually configure it.

Almost exactly five years ago, I did something about it, and I called it wiconn.sh. Since I already had one-off scripts for my home and office networks, Wiconn started as a script to display open networks. It would display only the open ones, and prompt me for an SSID, and it could remember the BSSID (MAC Addresses) of open networks I used to protect me from things like my own Evil WiFi setup and other "evil twin" style wireless attacks.
That first version looked something like this:


Wiconn evolved over time. By late 2012, I'd given it a bunch of features and made the interface look nicer. All SSIDs were being listed with color-coded backgrounds for the network you're connected to, and open networks. Visually, it hasn't changed much since 2012. This is how Wiconn looks today:
https://github.com/n0xa/wiconn

Over this long holiday weekend, I finally got it to a place where I feel like sharing it. Since it's already in the garage for maintenance, I figured I might as well put wiconn on GitHub.

Features:
  • Written primarily in Bourne shell (/bin/sh)
  • No dependencies: Relies only on the OpenBSD base distribution
  • Built-in protection from common wireless attacks
  • Easily connect to saved networks with one command (no scanning or prompt)
  • 2-Clause Simplified BSD license
There's still some more work to do.  I'd like to have it detect that one of your saved networks is in the list and ask if you'd like to join it. I'm also using NetBSD a bit more, and feel like there might be a way to make it work well on both OpenBSD and NetBSD from the same codebase, despite small differences in command syntax and output format between them.

Anyhow, for the growing number of folks who are giving OpenBSD a shot lately, I thought I'd share. Feedback is welcome, and more information is available through the documentation via GitHub.

n0xa/wiconn on GitHub

2016-10-29

OpenBSD vmm Hypervisor Part 1: Walk-through

Thursday night, I recorded a video while tinkering with vmm. I covered some basics of using it, networking, and installing OpenBSD inside a freshly-created VM. Sorry for the stammering and poor audio quality. Of course, the real fun was figuring out how to get it transcoded into webm and uploaded to youtube from within OpenBSD. I learned a lot about ffmpeg this week. Enjoy.

FYI, I used these same VMs to help me update and test the nginx and httpd PHP/MySQL articles. They're (finally) up-to-date for OpenBSD 6.0. Better late than never, right?

2015-12-12

PiTether: Mobile phone to ethernet bridge

Introduction

If you saw me at DefCon this year, you probably saw me using my HP Jornada. There was also a pretty good chance that you saw me getting it online in strange ways...
HACK THE PLANET! (Or just dial up a BBS...)
Since there aren't payphones everywhere, though, I built something interesting back in May, preparing for DefCon. It's a very simple Raspberry Pi ethernet bridge. I did this mostly to avoid using the open WiFi at DefCon, understanding that 3G/4G shenanigans are happening, but with a higher barrier to entry than the 802.11a/b/g/n/ac mess.

Yes, that's a Raspberry Pi Model B inside a case made of LEGO bricks.

Setting up Arch Linux

Being no stranger to building embedded systems, I decided to go with a bare-bones Arch Linux ARM install on a 2GB SD card. You could likely run with an even smaller card if you wanted to. The installation instructions are pretty straight-forward if you're familiar with the command line.

Once you have Arch Linux up and running on the Pi, I recommend changing the default passwords (alarm/alarm, root/root) and then doing a system update to get the latest packages from base. Simply connect the Pi to the Internet through its ethernet port, then run "pacman -Syyu" as root.

Configuring the network

The 3 interfaces we worry about are eth0, usb0 and br0. The first two basically work right out of the box:

/etc/systemd/network/eth0.network exists from the default installation, so the ethernet port is already set up for us.

When you activate USB Tethering from Android while plugged in to most modern Linux distros, it shows up as a network device (in this case, usb0) without any extra configuration.

br0 (the bridge interface) needs to be configured. First, we establish a netctl profile for it. Put the following text into a file called /etc/netctl/br0


Description="PiTether USB/Ethernet connection"
Interface=br0
Connection=bridge
BindsToInterfaces=(eth0 usb0)
IP=dhcp
SkipForwardingDelay=yes

Next, create a service file for systemd that calls netctl for the br0 interface. Put these contents in /etc/systemd/system/netctl@br0.service
.include /usr/lib/systemd/system/netctl@.service

[Unit]
Description=PiTether USB/Ethernet connection
BindsTo=sys-subsystem-net-devices-eth0.device
BindsTo=sys-subsystem-net-devices-usb0.device
After=sys-subsystem-net-devices-eth0.device
After=sys-subsystem-net-devices-usb0.device
Run the following command as root to enable the interface during start-up:

netctl enable br0

Reboot the Pi to make sure everything works as planned. To test:

  1. Plug in your phone and activate USB Tethering.
  2. Plug a device into the ethernet port of the Raspberry Pi
  3. Request a DHCP Lease (happens automatically on most devices)
  4. Try to browse the web or connect to something over the Internet (ping, ssh, etc)
As a finishing touch, I decided to make the entire filesystem read-only. This makes it so that the device can be safely powered off by simply unplugging it without any risk of corrupting the filesystem. I did this so that I never needed to SSH to it or hook up a console to safely shut it down. Since this is really a single-use project, this works pretty well. For more elaborate embedded-system work, I usually opt for a RAM disk configuration, but that's not needed here.

You can probably do this by sliding the write-protect tab on the SD card (for Pi A and B only) however, I opted to mark both filesystems "ro" in /etc/fstab. Apparently, root (/) is optional in fstab, but I added it by copying the /boot line and slightly altering the device and mountpoint fields. My /etc/fstab looks like this:
#
# /etc/fstab: static file system information
#
# file system   dir     type    options         dump    pass
/dev/mmcblk0p0  /       ext4    defaults,ro     0       0
/dev/mmcblk0p1  /boot   vfat    defaults,ro     0       0
You can give it one more reboot and test after that if you want. If you ever want to change anything in the filesystem, you can temporarily remount it read-write again by using the command "mount -o remount,rw /" while logged in as root. You can use that to remove ",ro" from the fstab options or to occasionally update packages.

2014-10-30

It's a loop recorder for your network!

I haven't written here much lately. I've been swamped with work and real life.

Recently, my wife wanted me to clone one of my VMs so she could play around with running a MUD for some friends. Yes, my wife's a nerd like me. As anyone who's ever run a game server can guess, it didn't take long for the griefers to show up. She asked me to log everything going to her VM. I could have probably compiled DaemonLogger or something similar, but I decided tcpdump was more than capable enough for us.

sudo tcpdump -i eth0 -wPacketLog -W10 -C100M

Throw that in the background (or in a tmux/screen session) and enjoy a 1GB looped recording of everything you can see on the network, broken into 100MB chunks (named PacketLog0 - PacketLog9), overwriting old files as it goes. You can also add typical tcpdump filters (e.g. "tcp port 80") to the end if you want. Adjust -W to increase/decrease the number of files it saves and -C to adjust the number of MB of data kept in each file. File prefixes, as you guessed, are controlled by the -w option.

If you want to monitor your whole network, this works best if you have a span/mirror port set up, or you can make a passive network tap.

To review the contents of the saved file, use tcpdump -nvXs0 -r PacketLogN (displays the contents in Hex/Ascii side-by-side format) on the file you want. You can also use tcpdump filters here to watch specific connections, protocols and/or hosts.

2009-12-22

Guest Post: Setting up a Pfsense firewall

This is a guest post by BIOSshadow. You can follow him on Twitter and at his blog, Geek Crack.

Pfsense is a free, as in speech and beer, firewall for home, business, and any other purpose you can think of. It's based on FreeBSD, so it's very stable and has a very good TCP/IP stack. It has a serious feature list.

I have to explain how little PfSense needs in the hardware department. My setup is an old desktop computer that a client gave me because it "went bad." The power supply unit blew out during a lightning storm in the middle of the night. Anyway, it's a single core Intel processor, I am not sure what speed, with 512 MB of RAM, and a 40 GB hard drive. Now the only reason I have 40 gig is because it was easier to keep in there than fight the case, and put in a 10 gig I had around. So any basic computer you have around will work. But as with any computer, the more memory the better. I will get into that later.

You will need a video card/monitor and keyboard and of course a Pfsense CD. USB keyboard will work, a PS/2 won't need to load extra drivers. After the install and a little configuring is done, you can remove the video card/monitor and the keyboard, you can do everything through the web panel or SSH connection, if you turn it on.

Now onto the setup. (Note: For the screenshots I am using VirtualBox. This for the screenshots only). When it boots up to the bootloader, you want to boot with default, either by waiting for the timer to run out or by hitting enter.



Now if you have two NICs, which I recommend, you do not need to setup VLANs, but you can. If you only have one NIC, you need to setup at least two VLANs.


Now this is one of the great things about Pfsense that I can't find anywhere else: You unplug the ethernet cables, and it askes you to plug in the LAN cable into the LAN NIC. Then it does the same for the WAN cable and NIC. Now if you want to setup a DMZ with third NIC this where it do it.



Pfsense will ask you if you want to proceed and then build the config files and startup all the daemons, like the Web Panel and others. Congrats! You have running Pfsense firewall, but everything is in memory and running from the CD. If you want run it like this then you are set, but if the power goes out you will have to set it up again using a backup config file or from scratch. If you want to install to a hard drive you will need to type "99" and hit enter to continue.


The hard drive installation is menu-driven and easy to use. If you are having issues, feel free to edit the setting and accept when done.


Select "Install PfSense" and select the hard drive you want to use. Format the disk and select "use this Geometry".








If you are lucky enough to have a muilti-processor system or are using a embedded system, select those options. Now remember this is "muilti processor" not "muilti-core processor".


Now Pfsense is installed and ready to go. Just restart it and remove the disc.


After the reboot, we will need to setup local IPs and their ranges. Unless, of course, you have a separate DHCP server, then set it up to connect to the server.


The IP settings are all up to you, I used a normal home setup for the sanity of my family (networked printers, NAS, and etc.) just remember the IP you give Pfsense, because you will need it to access the Web Panel.










Now you are all set up. You can unplug the monitor and keyboard, and other stuff were using for set up.


Now back on your computer, open up a browser and go to the IP of Pfsense. The default username is "admin" and the default password is "pfsense".


Of course, you want to change the password and if you want, you can change the username as well. To do so on the red navigation bar at the top, hover over system and click on General.


To enable SSH, which I recommend, you need to go the the Advanced section of the System Menu.


If your ISP is like mine, your MAC address is tied to the account and if you use it, you don't get access to the Internet. To edit it Go to Interfaces and then WAN.



Now you have working Pfsense firewall, have fun!


There are a few things Pfsense lacks, like a Squid proxy and A/V scanner. But it makes it up with its packages. It has quite a few packages, but remember: the more packages, processes and packets it handles, the more memory it uses and the lag increases. But they have packages for Snort, Squid, SquidGuard, and an A/V scanner.






Well there it is: a completely setup and configured Pfsense, with A/V scanning, proxy and traffic monitor.




2008-11-30

Reverse Tunnel with SSH

Inspired by a thread on the Hak5 Forums...

Sometimes, you might find yourself wishing you could poke arbitrary holes through a NAT or firewall. The potential uses (both good and evil) are nearly limitless. Perhaps you want to be able to log in to the computer in your dorm room while you're a thousand miles away on vacation with family.

You will need a few things before we start:

  1. Physical access to a computer on the "inside" of the network
  2. Access and permission to install software on that computer
  3. A system on the "outside" that can accept SSH connections from the Internet
It helps if the 2 computers involved are running Linux, Mac OS X, BSD or some UNIX variant, but you could probably use PuTTy on Windows for the "inside" computer in a pinch.

I'll be using NetBSD on my SparcStation 20 on the inside of the HiR Lab, and one of my web servers with a public IP address on the outside.

SSH Tunneling
is the process of encapsulating some other protocol within an SSH session. There are many advantages to this. Essentially, if you can get out of a network with SSH, you can get to almost any TCP service on the outside world, even if it's blocked.

Reverse SSH Tunneling is a similar process. If you can get out of the network with SSH, you can use that SSH tunnel to spawn a listening process on the outside of the network, from which you can get to anything internal.

Step One: Deploy SSH keys without a password
This has to be done from the "inside" computer. You can use your personal desktop system or a server where you have an account. It must be able to SSH out to the Internet.

I don't like to use public keys without passwords, but they do come in handy, particularly for tunneling. The un-protected public key should only be placed into the authorized keys list for UN-TRUSTED accounts that aren't in the wheel group or sudoers file.

I wrote about using passwordless SSH keys before. If you're using a UNIX variant, just follow the first few steps on generating and distributing the ssh keys. If you're using Windows, install PuTTy and follow the steps that Steve Friedl put together.

Step Two: Create and test your tunnel
I wrote a little about tunneling (forward and reverse) back in February. In this case, I'm going to tunnel SSH over a reverse SSH connection -- that is, I'm going to SSH from my inside box (NetBSD) to the web server (betaweb.h-i-r.net), and tell SSH to open a reverse tunnel port (2222) on the web server that connects to the SSH port on the NetBSD box (localhost:22). The -g option allows any remote host to use the tunnel. Otherwise, it will bind only to the localhost interface.
[axon@NetBSD]$ ssh axon@betaweb.h-i-r.net -g -R 2222:localhost:22
Last login: Sun Nov 30 14:13:08 2008 from netbsd.labs.h-i-r.net
[axon@betaweb.h-i-r.net]$
Now, from anywhere in the world that can access port 2222 on betaweb.h-i-r.net, I can SSH through my home NAT to get to the internal NetBSD box:
Chimera:~ axon$ ssh -oPort=2222 axon@betaweb.h-i-r.net
Password: [my password]
Last login: Tue Oct 14 19:01:57 2008 from localhost
NetBSD 4.0.1 (GENERIC) #0: Wed Oct 8 01:06:02 PDT 2008
Welcome to NetBSD!

[axon@NetBSD]$
You don't need to reverse tunnel to localhost, and you could just as easily use this trick to reverse-tunnel your e-mail (POP/IMAP), VNC to a Windows/Mac desktop or even to an internal web proxy server.

Step 3: Automate!

If you just leave the SSH tunnel up and running, it won't likely last too long because of session timeouts. You'll need some process to start the tunnel. Here's where you can get creative. Obviously, a process involving the use of cron or at would be one way of going about it. A script running in the background (with nohup) or in a screen session could also take care of things nicely. One idea I had was to set up fetchmail to check a dummy e-mail account every 5 minutes or so. If there's new mail, it initiates the tunnel. Send mail. Wait. Tunnel. Another way would be to upload a file to a web or ftp site to trigger it. You could even make it read information from that file to create the tunnel for different protocols. I opted to create a configuration file on the web server that would be downloaded and used.

On the "inside" box, I created this script and called it tunnel.sh:
#!/bin/sh
ssh betaweb.h-i-r.net rm .tunnel
args=`cat .tunnel`
rm .tunnel
ssh $args
Then, I added this to my crontab:
*/5 * * * * scp axon@betaweb.h-i-r.net:.tunnel ~/.tunnel && ~/scripts/tunnel.sh
Every five minutes, it will try to scp a file called ".tunnel" from the "outside" box. If it was successful, it runs the tunnel.sh script.

The tunnel.sh script removes the .tunnel file from the remote box (so that it doesn't try to spawn multiple tunnels every 5 minutes) and then uses the contents of .tunnel as the arguments for ssh.

I create a file on my laptop named ".tunnel" and add the following:
axon@betaweb.h-i-r.net -g -R 2222:localhost:22 sleep 600
Then, I upload it to the location and wait about 5 minutes. Then, I ssh to port 2222 of betaweb.h-i-r.net. The "sleep 600" is executed on the remote end, which means it will only stay connected for 10 minutes (600 seconds).

Tada!
chimaera:~ axon$ scp .tunnel axon@betaweb.h-i-r.net:
axon@betaweb.h-i-r.net's password:
stdin: is not a tty
.tunnel 100% 58 0.1KB/s 00:00

[ wait 5 minutes ... cue Jeopardy theme song ]

chimaera:~ axon$ ssh -oPort=2222 axon@betaweb.h-i-r.net
Password: [my password]
Last login: Tue Oct 14 23:24:10 2008 from localhost
NetBSD 4.0.1 (GENERIC) #0: Wed Oct 8 01:06:02 PDT 2008
Welcome to NetBSD!

[axon@NetBSD]$

Considerations and Risks:
I've already stated that using public keys without a password is risky business.

The other shady business is directly executing anything using arguments pulled from some file on a remote server. All it would take is "; [insert evil command here]" added to the .tunnel file and havoc can potentially be wreaked on that internal box.

If you can get away with it, BY ALL MEANS use separate accounts that are not used for anything other than this tunneling process. Lock them down as best you can and be mindful of local privilege escalation attacks.

See? This is why admins put firewalls up in the first place. And don't go pointing your finger at me if you get in trouble for unauthorized tunneling.

2008-11-06

Crimping Twisted-Pair Ethernet (and Crossover)

In the Geek 100, I said that every geek should be able to Terminate category 5 cable with RJ-45 plugs and make a crossover cable. While home networking isn't nearly as daunting as it used to be with ubiquitous WiFi routers, I stand by my assertion that no geek has a valid excuse for being unable to crimp some cables. It's a useful skill to have and it's quite easy to learn.

All you need (aside from some Twisted-Pair ethernet cable that has bad ends or no ends) are some crimp-on RJ-45 plugs, a knife and a crimping tool. The plugs are less than $1 each at Radio Shack and cents each in bulk, knives are commodity and crimping tools like the one shown (I've had it for probably 15 years) are available for $20 or less. If your crimping tool doesn't come with a wire cutter, a pair of diagonal pliers might be useful as well. There are some much nicer crimping tools available that get really expensive, but the entry-level ones are probably just fine for the geek who only needs to run wires occasionally.


Take your knife and cut the sheath off about 3/4" of the end of the cable. Inside, there are four pairs: Blue, Orange, Green and Brown. Due to carryover from ye-olde telecom days, the pairs are divided into "Tip" (color striped with white) and "Ring" (solid color). Many cable manufacturers put a nylon strand, string, or tuft inside the sheath as well. This makes stripping a long length of sheath easy, but you can safely cut away whatever of it is exposed without harm.

Arrange the wires in either of the two configurations shown below. We'll get to putting the RJ-45 plugs on in a moment. For the time being, focus on the order of the wires.


These days, 568-A is kind of "the standard" but when I was learning, the industry was hell-bent on using 568-B. Honestly, as long as you use the same 568 scheme on both ends of the cable and you crimp the RJ-45 plug properly, it really doesn't make a bit of difference at all. The wires are ordered this way to reduce crosstalk and interference, so I advise you stick with one of the two diagrams above.

I have the wires ordered 568-B below. The tips (white-striped wires) are hard to determine in the photo, and sometimes they'll be tricky to identify in real life. You may wish to do this under an eye loop or a workbench magnifying lens if your eyesight is sub-par.


Use a wire cutter or a diagonal plier to cut the wires to the same length. It's important to keep the wires held flat and in the right order as shown above.


Slide the RJ-45 plug onto the cable end. Make sure the wires are still even and in the right order, and make sure that the sheath goes deep into the plug while still allowing the wires to "bottom out" in the plug. The sheath should be positioned so that the plastic tab that's crimped to hold the wires in place also holds the sheath. The wires should not be exposed out the bottom of the plug. (Thanks for the reminder, Ryan)


I stole this crimping "action shot" from the Loopback tester tutorial. Crimping the plug should be pretty straightforward. Make sure to give it a few good squeezes to ensure a good connection.


Make sure you wire both ends the same, and make sure the plugs are both installed facing the proper direction (with the metal pins pointed toward you and up). Here's another diagram I found on Wikipedia:


To make a crossover cable that can be used to connect two hubs/switches or two computers together (Without a hub or switch), simply wire one end as 568A and the other as 568B.

2008-10-31

Oh noes! They be stealin' our garage doors! (Misc)

A few things:


First, Cowtown Computer Congress finally got blueprints of the building our hacker space will be located in. That's good news. The bad news? The awesome garage door we thought we'd have might be on the chopping block according to the blueprint -- as shown below the lolrus (which is actually a huge seal since it doesn't have tusks) Not cool. We're gonna try to have them leave the garage door.

Also, CCCKC will be thowing a "build it for them to throw it" party on Nov. 22, a few days before the Plaza Lighting Ceremony. This event for CCCKC members will get a bunch of geeks together to build LED Throwies.  The plan is to use the throwies for the fund-raiser on the 26th. What better time of year to lob magnetized LEDs at things than the official kick-off of Kansas City's Holiday Season? Become a member of CCCKC, come out and help us build some throwies, and then kick it with all of us at the next fund raiser.

Last but not least, I posted a fun project over at i-Hacked today.  Not many people knew that my RJ45 cuff links at DefCon were actually functional ethernet loopback testers. I walk you through the steps to build your own ethernet loopback tester that you can keep on your keychain or use as cuff links (if you make two). Photos below:


2008-10-29

The Geek 100 Pt. 2: Sysadmin and Network Skills

See the whole series: The Geek 100

This is a list of 100 basic things and skills every geek should have. I've broken this series up into five parts. Let's face it: a list of 100 things would be tedious to wade through. Over the rest of the week, look for twenty more skills to show up daily. The skills assume you have done it in the past and can remember how to do it right now (or, like a good Geek, you've jotted it down in one of your notebooks). Having it in your personal notebook is okay. Scrambling to the Internet means you don't have the skill. Yet...

This one is for all your Information Technology geeks, although it's a bit UNIX biased.

Systems Administration. All geeks should be able to:

  1. Compile a kernel
  2. Set up a file/print server that works across most operating systems
  3. Set up RAID on a server
  4. Set up an AMP server
  5. Set up an Internet mail server that won't get RBL'd
  6. Set up an RDBMS
  7. Use a Logical Volume Manager
  8. Use find with xargs
  9. Use sed and awk effectively
  10. Use sysctl

Networking. No, not Social Networking. All geeks should be able to:
  1. Explain the difference between PAT, NAT and a DMZ
  2. Flash new firmware to routers and switches
  3. Make an ethernet crossover cable
  4. Run cable through walls without tearing them up
  5. Set up port security on a network switch
  6. Terminate a fiber optic cable by hand
  7. Terminate a punch-down patch panel
  8. Terminate category 5 cable with RJ-45 plugs
  9. Trace cables
  10. Use a network sniffer or protocol analyzer

See the whole series: The Geek 100

2008-09-26

UNIX Tips: MAC Address Spoofing/Changing

I don't advocate using MAC Address spoofing for evil purposes such as:

  • Using a MAC-Address Filtered wireless Access Point
  • Deception
  • Cloning an ethernet card already in use to confuse a network
  • In order to mess with ethernet switches
  • ... Plenty of other malevolent uses ...
MAC Spoofing has several constructive troubleshooting uses:
  • Get a new IP Address from your DHCP server
  • Testing Ethernet switch port security rules
  • Troubleshooting issues with ARP
  • ... plenty of other great uses ...
The Technique to temporarily change your MAC address is pretty similar across the board.  I'll go over some. In any of these examples, replace IFace with the name of the ethernet/wireless interface name such as "eth0", "en1", "rausb0" etc.  Obviously, you can make the ethernet address whatever you want.  The addresses I provide are arbitrary. It just has to be six pairs of hexadecimal (0-9 or A-F) digits separated by colons.  Obviously, these commands must be run with sudo or otherwise with root privileges.  Also, it helps if the ethernet interface is "down" first:
ifconfig IFace down

Mac OS X: 
ifconfig IFace ether 00:12:34:56:78:90

OpenBSD:
ifconfig IFace lladdr 00:11:22:33:44:55

Linux:
ifconfig IFace hw ether 00:de:ad:c0:ed:ba:be

FreeBSD:
ifconfig IFace link 10:00:ca:b0:05:e5

2008-09-09

Passive Network Tap

At the 2600 meeting in May, Asmodian X brought a passive network tap to show off. It will capture bi-directional traffic on the line, while keeping the interfaces from being able to transmit anything. It does require two separate interfaces to collect all of the data on the line, but that's a small price to pay.

I found a great set of Passive Network Tap instructions on Instructables [via Make: Blog]. This is pretty much the same design that Asmodian X had set up, but this one is mounted in a three-jack wall-outlet faceplate. Head on over and take a look!

2008-03-06

Shutting off wireless auto-config in Mac OS X

As a matter of security and simply less annoyance, I prefer my computers to not connect willy-nilly to just any wireless network in range. OS X currently doesn't connect to random open networks, but it does always look for them, and by default it prompts you to connect to new ones. In OS X, all you have to do is un-check the "Ask to join new networks" on the AirPort adapter in Network preferences to stop this behavior.



Once you do that, go into the Advanced preferences and remove all those random access points that you've connected to in the past, leaving only the ones you know and trust on the list. If your access point has a default-ish name (like WLAN, Default, linksys, etc) you should probably change it so that your computer doesn't join up to the first "linksys" network it runs across.

On Linux and BSD, it's easy. You simply have to try -- and mean it -- to get on a wireless network. You don't just accidentally connect.

Also, it's a cold day in hell. Last week, I bought my wife a new computer that came loaded with Windows Vista Home Premium. I can only use it for a few minutes at a time before I have the urge to go take a shower with a steel wool pad to try to get Vista off of me, but I can't for the life of me figure out how to kill Vista's auto-join feature while letting it connect to preferred networks only. If you have any tips, drop us a line. It definitely isn't like XP. The only thing I saw told me to kill the Wireless Autoconfig service (maybe called something a little different) and all that did was completely disable wireless access on Vista.

2008-03-04

IP Subnetting - more fun with newLISP

I decided it would be fun to try to make an IP subnet calculator with newLISP.

Thanks to Elica and Lutz on the newLISP discussion boards. I needed some help with the logic. There's probably a way to compact this code down to about 3 lines somehow, but I'm still a newLISP n00b. I stuck with the logic examples that I have a firm understanding of, but the discussion yielded some interesting results.

Here's what I came up with


#!/usr/bin/newlisp
# newLISP IP Address calculator by ax0n
# ax0n (at) h-i-r.net
(define (iptostr ip4)
# Converts an integer to an IP in dotted decimal notation
(string
(mod (/ ip4 0x1000000) 0x100) "."
(mod (/ ip4 0x10000) 0x100) "."
(mod (/ ip4 0x100) 0x100) "."
(mod ip4 0x100))
)

(define (iptonum ip4str)
# Converts an IP string to an integer
(map set '(one two three four) (parse ip4str "."))
(+ (* 0x1000000 (float one)) (* 0x10000 (float two))
(* 0x100 (float three)) (float four))
)

(cond(
(< (length (main-args)) 3)
# Display usage if no args passed
(println "usage: ipcalc.lsp ip-address/maskbits")
(println "ex: ipcalc.lsp 192.168.1.20/24")
)
(true
(set 'ipstr (last(main-args)))
(map set '(ipaddr bits) (parse ipstr "/"))
(set 'binip (iptonum ipaddr))
(set 'netmask (& 0xffffffff ( << 0xffffffff (- 32 (int bits)))))
(set 'netaddr (& binip netmask))
(set 'bcast (& 0xffffffff (| binip (~ netmask))))
(println "host IP: " ipaddr )
(println "netmask: " (iptostr netmask) )
(println "network: " (iptostr netaddr) )
(println "broadcast: " (iptostr bcast))
(println "Host range: " (iptostr (+ netaddr 1))" - "(iptostr (- bcast 1)))
)
)
(exit)



Running it by itself gives you a syntax help page.

-bash-3.2$ ./ipcalc.lsp
usage: ipcalc.lsp ip-address/maskbits
ex: ipcalc.lsp 192.168.1.20/24

You have to provide an IP Address and mask in CIDR Notation. It does the rest!

-bash-3.2$ ./ipcalc.lsp 192.168.0.49/24
host IP: 192.168.0.49
netmask: 255.255.255.0
network: 192.168.0.0
broadcast: 192.168.0.255
Host range: 192.168.0.1 - 192.168.0.254


You can download the script here:
http://stuff.h-i-r.net/blogstuff/ipcalc.lsp

2008-03-03

IP subnetting

This really isn't that hard, but I had someone ask for help on one of the forums I participate in, and thought I'd share the answer here.

The person needed to determine the following given an IP/Mask of 146.141.219.47/18

  • Subnet Mask
  • Network Address
  • First usable host address
  • Last usable host address
The answer is to use binary math and boolean logic to solve the problems.

/18 means there is an 18 bit subnet mask on that IP address. This is neither a Class C (24 bit subnet mask) or Class B (16 bits). Although, "Classes" are kind of obsolete these days. It's just an 18 bit subnet mask. Straightforward.

In binary, it looks like this (decimal underneath):
11111111 11111111 11000000 00000000
255 255 192 0


To get the network address, you take the IP Address in binary, and do a boolean AND against the subnet mask. A boolean AND will only return a 1 where both numbers have a 1, and return a 0 everywhere else.


11111111 11111111 11000000 00000000 <-- subnet mask 255.255.192.0
10010010 10001101 11011011 00101111 <-- IP Address 146.141.219.47
======== ======== ======== ========
10010010 10001101 11000000 00000000 <-- Network Address 146.141.192.0


The first usable host IP address is always the first IP after the network address, in this case, 146.141.192.1.

To get the broadcast address, you simply change all of the non-masked bits from the network address (in this case, the last 14 bits) to 1.

10010010 10001101 11111111 11111111 <-- Broadcast        146.141.255.255


You need to know the broadcast address to come up with the last usable host IP address, which is always one IP below the broadcast address. The last usable IP in the network for this example is 146.141.255.254.