Create a gist now

Instantly share code, notes, and snippets.

@meejah /NOTES
Created Jun 18, 2011

What would you like to do?
-*- mode:outline -*-
This is some of the stuff I've been playing with for VM building and
setup. Should be mostly self-explanatory.
#!/usr/bin/env python
##
## this is intended to automatically produce a debian-live based
## system hosted on a USB key with four partitions:
##
## 0. boot partition
## 1. FAT32 for windows auto-run and windows version of VirtualBox (qemu?)
## 2. HFS+ for MacOS auto-run (possible?) and MacOS version of VirtualBox (qemu?)
## 3. EXT3 for the debian-live system itself (encrypted)
##
## The intent here is that we have an encrypted debian-live system on
## most of the key, with software to boot and run that system from
## within a Windows or MacOS host. There's also a boot partition so
## that, where possible, we reboot the host hardware into our
## Debian-Live system.
##
import os
import sys
import subprocess
import re
## do not include the trailing /debian/ in the mirror -- presumes also
## /debian-security/ is available there.
MIRROR = None
MIRROR = 'http://mirror.cpsc.ucalgary.ca/mirror/debian.org'
BUILD_AREA = '.'
DEVICE = None
if os.getuid() != 0:
print "Please run me as root."
sys.exit(-1)
def run(s):
print s
retcode = os.system(s)
if retcode:
print "Error!",retcode
sys.exit(retcode)
def confirm(q):
yn = None
while not yn:
x = raw_input(q + ' ')
x = x.strip().lower()
if len(x) == 0:
continue
if x == 'y':
return True
elif x == 'n':
return False
base = os.path.realpath(BUILD_AREA)
print "Using",base,"to build image in."
if DEVICE is None:
print "No device specificed, trying to find one"
candidates = filter(lambda x: 'usb' in x.lower(), os.listdir('/dev/disk/by-id'))
candidates = map(lambda x: (x, os.path.realpath(os.path.join('/dev/disk/by-id',x))), candidates)
candidates = filter(lambda x: not re.match('.*/sd[a-z][0-9]$', x[1]), candidates)
if len(candidates) == 0:
print " Nothing found, please insert USB key or specify DEVICE variable in this script"
print " which is located at",os.path.realpath(sys.argv[0])
sys.exit(-1)
elif len(candidates) == 1:
DEVICE = candidates[0][1]
print " Found a single candidate",DEVICE,"called",candidates[0][0]
if not confirm("Shall I use it?"):
sys.exit(-2)
else:
while DEVICE is None:
print " Found several candidates, please choose one:"
for i in range(len(candidates)):
print " ",i,":",candidates[i][0],"called",candidates[i][1]
x = raw_input("%d -> %d?" % (0,len(candidates)-1))
try:
i = int(x.strip())
if i >= 0 and i < len(candidates):
DEVICE = candidates[i][1]
break
except:
print "Couldn't understand response."
print "Using device",DEVICE
if not confirm("Everything will be destroyed on this device, okay?"):
sys.exit(-1)
if os.path.exists(os.path.join(base,'.stage')):
print " There is a .stage; cleaning up first."
run('lb clean')
config_options = ''
## keep things simple, at first we'll just make the debian-live system
## a "stable" one
config_options += '--distribution wheezy '
## ...with "debian-forensics" packages specified.
#config_options += '--package-lists debian-forensics '
## USB/HDD suitable for a USB key (NOT cd/dvd)
config_options += '--binary-images usb-hdd '
## if we have a mirror, lets use it
if MIRROR:
config_options += '--mirror-bootstrap %s/debian/ --mirror-binary %s/debian/ --mirror-binary-security %s/debian-security/ ' % (MIRROR, MIRROR, MIRROR)
## configure our system
run('lb config ' + config_options)
## build the system (this will take a while)
run('lb build')
-*- mode:outline -*-
* customization notes
. there's a pre-configured "debian-forensics" one (for "lb config -p
debian-forensics")
. it seems that there's a problem building, e.g., stable on a wheezy
system -- maybe you can only go "forwards"? For now, just building
wheezy-on-wheezy.
* links
single-page HTML manual
http://live.debian.net/manual/en/html/live-manual.html
main debian-live site, with documentation tutorials etc
http://live.debian.net/
basic live-build usage
http://www.debianuserforums.org/viewtopic.php?f=9&t=185
how to make windows happy about which partition is what
http://lists.debian.org/debian-live/2009/04/msg00025.html
#!/usr/bin/env python
##
## this will set up a VDE switch which has a tap interface (tap_tor)
## which is also set up by this script. This tap interface has all its
## data pushed out through tor (or dropped, if it's UDP and not port
## 53) via some iptables rules. probably you need to run this as
## root. when the VM shuts down, the processes started here are killed
## as well.
##
## WARNING: all nat iptables rules are deleted by this script!
## (see near the bottom)
##
## your vm image is going to need config like this (presuming debian
## and an eth0 device):
##
## /etc/network/interfaces
## --------
## iface eth0 inet static
## address 10.0.0.5
## netmask 255.255.255.0
## gateway 10.0.0.210
## --------
import subprocess
import os
import time
import sys
## "config" such as it is
uplink_ip = "10.0.0.210"
tap_name = 'tap_tor'
tor_rc = '/tmp/torrc'
switch_name = '/tmp/vde_switch_tor'
vm_image = '/home/mike/src/vmbuilder/lemuria-debian-lenny-kvm/disk0.qcow2'
##
## VDE switch
##
vdeswitch = subprocess.Popen(['vde_switch', '-s', switch_name, '-tap', tap_name])
print "Started vde_switch at PID",vdeswitch.pid,"with control socket",switch_name
time.sleep(1)
##
## TAP interface
##
print "Bringing up",tap_name,"on",uplink_ip
if os.system("ifconfig %s %s up" % (tap_name,uplink_ip)):
vdeswitch.kill()
print "error, killed vde_switch"
sys.exit(-1)
##
## separate TOR instance for our traffic
##
open(tor_rc,'w').write("""
## tor seems to always want to start a SOCKS listener; 9050 is the default port
SocksPort 9050
SocksListenAddress 10.0.0.210
# possibly not needed for this example but this allows
# .onion and .exit routes to "just work"
AutomapHostsOnResolve 1
# this is where we'll send TCP traffic for proxying
TransPort 9040
TransListenAddress 10.0.0.210
# just DNS requests will be sent here
DNSPort 9053
DNSListenAddress 10.0.0.210
## flesh out a few more options for a full config
Log notice stderr
RunAsDaemon 0
DataDirectory /home/mike/src/virtual-machines/tor
""")
## may need to change the owner if you're not on debian
os.system('mkdir /home/mike/src/virtual-machines/tor')
os.system('chown debian-tor /home/mike/src/virtual-machines/tor')
tor = subprocess.Popen(['tor', '-f', tor_rc, '--quiet'])
print "Started tor at PID",tor.pid,"with",tor_rc,"for config"
##
## use iptables to forward all TAP traffic to Tor
##
for x in ['iptables -t nat -F',
'iptables -t nat -A PREROUTING -i %s -p udp --dport 53 -j REDIRECT --to-ports 9053' % tap_name,
'iptables -t nat -A PREROUTING -i %s -p tcp --syn -j REDIRECT --to-ports 9040' % tap_name]:
print x
os.system(x)
##
## now just start the VM
##
vm = subprocess.Popen(['kvm',
'-net', 'nic,macaddr=12:34:56:aa:bb:cc',
'-net', 'vde,sock=%s'%switch_name,
'-m', '128',
'-smp', '1',
'-drive', 'file=%s'%vm_image])
vm.wait()
print "VM exited..."
print "killing tor"
tor.kill()
print "killing vde switch"
vdeswitch.kill()
#!/usr/bin/env python
##
## this will set up a VDE switch which has a tap interface (tap_tor)
## which is also set up by this script. This tap interface has all its
## data pushed out through tor (or dropped, if it's UDP and not port
## 53) via some iptables rules. probably you need to run this as
## root. when the VM shuts down, the processes started here are killed
## as well.
##
## WARNING: all nat iptables rules are deleted by this script!
## (see near the bottom)
##
## your vm image is going to need something like this in
## /etc/network/interfaces (presuming it's debian and has an eth0
## network device):
##
## iface eth0 inet static
## address 10.0.0.5
## netmask 255.255.255.0
## gateway 10.0.0.210
##
import subprocess
import os
import time
import sys
## "config" such as it is
uplink_ip = "10.0.0.210"
tap_name = 'tap_tor'
tor_rc = '/tmp/torrc'
switch_name = '/tmp/vde_switch_tor'
vm_image = '/home/mike/src/vmbuilder/lemuria-debian-lenny-kvm/disk0.qcow2'
##
## VDE switch
##
vdeswitch = subprocess.Popen(['vde_switch', '-s', switch_name, '-tap', tap_name])
print "Started vde_switch at PID",vdeswitch.pid,"with control socket",switch_name
time.sleep(1)
##
## TAP interface
##
print "Bringing up",tap_name,"on",uplink_ip
if os.system("ifconfig %s %s up" % (tap_name,uplink_ip)):
vdeswitch.kill()
print "error, killed vde_switch"
sys.exit(-1)
##
## separate TOR instance for our traffic
##
open(tor_rc,'w').write("""
## tor seems to always want to start a SOCKS listener; 9050 is the default port
SocksPort 9055
SocksListenAddress 10.0.0.210
## don't need this, but good for getting info while it's running
## (default is 9051)
ControlPort 9056
HashedControlPassword 16:F224C256D983050B606E28C6C416BF879A3DE3E51CEC687C9DFDE6C94C
# possibly not needed for this example but this allows
# .onion and .exit routes to "just work"
AutomapHostsOnResolve 1
# this is where we'll send TCP traffic for proxying
TransPort 9040
TransListenAddress 10.0.0.210
# just DNS requests will be sent here
DNSPort 9053
DNSListenAddress 10.0.0.210
## flesh out a few more options for a full config
Log notice stderr
RunAsDaemon 0
DataDirectory /home/mike/src/virtual-machines/tor
""")
## may need to change the owner if you're not on debian
os.system('mkdir /home/mike/src/virtual-machines/tor')
os.system('chown debian-tor /home/mike/src/virtual-machines/tor')
tor = subprocess.Popen(['tor', '-f', tor_rc, '--quiet'])
print "Started tor at PID",tor.pid,"with",tor_rc,"for config"
##
## use iptables to forward all TAP traffic to Tor
##
for x in ['iptables -t nat -F',
'iptables -t nat -A PREROUTING -i %s -p udp --dport 53 -j REDIRECT --to-ports 9053' % tap_name,
'iptables -t nat -A PREROUTING -i %s -p tcp --syn -j REDIRECT --to-ports 9040' % tap_name]:
print x
os.system(x)
##
## now just start the VM
##
vm = subprocess.Popen(['kvm',
'-vga',
'std',
'-net', 'nic,macaddr=12:34:56:aa:bb:cc',
'-net', 'vde,sock=%s'%switch_name,
'-m', '128',
'-smp', '1',
'-drive', 'file=%s'%vm_image])
vm.wait()
print "VM exited..."
print "killing tor"
tor.kill()
print "killing vde switch"
vdeswitch.kill()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment