Wednesday, 28 April 2010

mplayer PIE on amd64 :)

For ages it was not possible to compile mplayer as Position Independent Executable (at least not on amd64) - until today! To my greatest surprise it compiled fine using the default gentoo hardened gcc spec, including PIE support.

So simply sync your portage tree, emerge mplayer-1.0_rc4_p20100427 and enjoy! Watching your favourite movie has never felt so safe before! ;]


./checksec.sh --file /usr/bin/mplayer
RELRO STACK CANARY NX PIE FILE
Full RELRO Canary found NX enabled PIE enabled /usr/bin/mplayer

...or alternatively:

readelf -h /usr/bin/mplayer
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: DYN (Shared object file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0xcae48
Start of program headers: 64 (bytes into file)
Start of section headers: 9064016 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 56 (bytes)
Number of program headers: 10
Size of section headers: 64 (bytes)
Number of section headers: 27
Section header string table index: 26

Enjoy the PIE! ;]

Thursday, 15 April 2010

KVM setup with bridged networking

The other day I hat to run my virtual machines on the same network as the host system itself and as I found information on the net to be a bit confusing I thought I could share how I came to terms with it :)

As usual I've used the following information resources - both of which have different view on the networking setup... ;) They do, however, mention all the prerequisites which have to met in order for the networking to work. So I assume that you have emerged bridge-utils and that kernel support for TUN/TAP device driver, "802.1d Ethernet Bridging" and "802.1Q VLAN Support" is enabled.

If you've been using NATed networking before, you need to remove vde from your start-up script:

rc-update vde del default

In my case my host and my VMs were getting addresses via DHCP. You could use static addresses as well - just specify the addresses for each interface manually and remember to add line for default route (see the links above for some examples on this). So below is my /etc/conf.d/net file.

bridge_br0="eth0 tap0 tap1" config_eth0=( "null" )
config_br0=( "dhcp" )
brctl_br0=( "setfd 0" "sethello 0" "stp off" )
rc_need_br0=( "net.tap0" "net.tap1" "net.eth0" )

config_tap0=( "null ")
tuntap_tap0="tap"
tunctl_tap0="-u radegand"
mac_tap0="00:a0:b0:c0:d0:f0"
config_tap1=( "null ")
tuntap_tap1="tap"
tunctl_tap1="-u radegand"
mac_tap1="00:a1:b1:c1:d1:f1"

Ok, section by section...
The first section defines the bridge to be comprised of three interfaces: one physical (eth0) and two virtual (tap0 and tap1). It then specifies that no ip address is required for eth0, instead it specifies that interface br0 will obtain it ip settings via DHCP. It also specifies some bridge options and sets dependencies for the br0 so when the init.d script is executed it can handle these properly.

The next two sections define tap0 and tap1 interfaces. It specifies that no IP address is needed for each of them (VM will get the IP instead - more on it later), the device type, the user who will have access to that device - this should be the same user who would run the VM itself. Finally - a specific mac address (you can be creative here! ;)) needs to be assigned to each tap device. You need such a section for each VM that will use the bridged network and each of such virtual interface can be used by one VM only.

Ok, time two start the new shiny interfaces! ;) Make sure that you have all the required links to start them:

ln -s /etc/init.d/net.lo /etc/init.d/net.tap0
ln -s /etc/init.d/net.lo /etc/init.d/net.tap1
ln -s /etc/init.d/net.lo /etc/init.d/net.br0

...and start them of course!:

/etc/init.d/net.tap0 start
/etc/init.d/net.tap1 start
/etc/init.d/net.br0 start

Remember to add them to a relevant boot level using rc-update when everything is tested and working fine...

Rite, now the interfaces should be up and ready to test! Let's see...

# ifconfig
br0 Link encap:Ethernet HWaddr 00:aa:bb:cc:dd:ee
inet addr:192.168.0.10 Bcast:192.168.0.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:201 errors:0 dropped:0 overruns:0 frame:0
TX packets:150 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:16269 (15.8 KiB) TX bytes:38080 (37.1 KiB)

eth0 Link encap:Ethernet HWaddr 00:aa:bb:cc:dd:ee
UP BROADCAST RUNNING PROMISC MULTICAST MTU:1500 Metric:1
RX packets:202 errors:0 dropped:0 overruns:0 frame:0
TX packets:157 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:20135 (19.6 KiB) TX bytes:39152 (38.2 KiB)
Interrupt:17

tap0 Link encap:Ethernet HWaddr 00:a0:b0:c0:d0:f0
UP BROADCAST RUNNING PROMISC MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:21 overruns:0 carrier:0
collisions:0 txqueuelen:500
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)

tap1 Link encap:Ethernet HWaddr 00:a1:b1:c1:d1:f1
UP BROADCAST RUNNING PROMISC MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:21 overruns:0 carrier:0
collisions:0 txqueuelen:500
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)

Note that the mac address of the br0 is the same as eth0 (yes, I did amended them a bit here, they're not my real mac addresses but they DO match nevertheless...)

Time to start VMs! So the magic command that needs to be added to the qemu/kvm command line which will get you bridged network is...:

-net tap,ifname=tap0,script=no,downscript=no -net nic,macaddr=00:a0:b0:c0:d0:f1

Now, the important bits are highlighted - for each of your VMs you need to use separate tap interface. Moreover, you need to specify mac address for the VM and it has to be different that the one specified for given tap interface in /etc/conf.d/net file. Of course it can be entirely different, not only by last byte - I just keep it this way to keep track of my VMs...But don't take my world for that - try using the same mac address for your VM as you set for the tap interface...and then when your VM is up and running grep the /var/log/kern.log file on your host system for:

tap0: received packet with own address as source address

So for each VM you run use different tap interface and remember to set different mac address than the tap device itself...

Ok, now you should have KVM setup up with bridged networking...no additional setup is need - no need for specific iptables rules and you don't even need to have the ip forwarding (/proc/sys/net/ipv4/ip_forward) enabled for it to work! Now - how cool is that? ;)

PS. No - it won't work with wireless, only with ethernet...if you need a wireless bridge - have a look here.