Skip to content

Instantly share code, notes, and snippets.

@meejah meejah/NOTES
Created Jun 18, 2011

Embed
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
You can’t perform that action at this time.