Création de machine virtuelle dans ipfire

Cette page explique la procédure pour créer une machine virtuelle dans ipfire. Ne pas oublier d'installer le paquet qemu avec pakfire.

Mise à jour le 23 aout 2016.

Je déplace mes fichiers de configuration sur github.com.

Mise à jour le 29 octobre 2016.

Avec l'aide d'un plugin faisant le liens entre SynthaxHighLighter et pastacode, je réaffiche les scripts.

Ajout du drivers virtio pour le disque dur virtuel.

 

1/ Création de la carte réseau virtuelle tuntap en orange0

Copier le script dans le repertoire /etc/init.d, il sert à créer la carte réseau pour notre machine virtuelle

Le script est téléchargeable ici.

#!/bin/sh
########################################################################
# Begin $rc_base/init.d/tap
#######################################################################

. /etc/sysconfig/rc
. ${rc_functions}

INTERFACE=orange0
MAC=72:A3:C3:F7:6E:01
KVM=qemu
case "${1}" in
   start)
		boot_mesg "Create virtual interface for dmz..."
		modprobe tun && 
		sleep 2 &&
		ip tuntap add mode tap dev $INTERFACE group $KVM &&

		# assign MAC address to $INTERFACE
		ip link set $INTERFACE address $MAC &&


		# Change settings on tap1 to improve performance for virtio
		ethtool --offload $INTERFACE gso off tso off &&

		modprobe vhost_net
		evaluate_retval
      ;;

   stop)
		boot_mesg "Remove virtual interface for dmz..."

		tunctl -d $INTERFACE &&

		sleep 2 &&
        rmmod vhost_net &&

		sleep 2 &&
	  	rmmod tun
		evaluate_retval

      ;;
   *)
      echo "Usage: ${0} {start|stop}"
      exit 1
      ;;
esac

# End $rc_base/init.d/tap

Donner les droits d’exécution, établir les liens symboliques pour le boot, lancer le script et setup pour attribuer la carte virtuelle à la zone orange.

chmod +x /etc/init.d/tap
ln -s /etc/init.d/tap /etc/rc.d/rc3.d/S17tap
ln -s /etc/init.d/tap /etc/rc.d/rc0.d/K84tap
ln -s /etc/init.d/tap /etc/rc.d/rc6.d/K84tap
/etc/init.d/tap start
setup

2/ Création de(s) bridge(s) en vue du raccordement d'une machine virtuelle

Copier le script dans le répertoire /etc/init.d, il sert à créer un pont réseau. Le script lit les lignes d'un fichier et créée le pont si la variable portant le nom de la carte est à yes.

Le script est téléchargeable ici.

#!/bin/sh

. /etc/sysconfig/rc
. ${rc_functions}
. /var/ipfire/ethernet/settings
a_file=/etc/default/bridge

#
case "${1}" in
   start)
		while read line; 
		do 
			card=$(echo $line | cut -f1 -d=)
			bool=$(echo $line | cut -f2 -d=)

			if [ $bool = "yes" ];then
				adress=${card^^}_ADDRESS
				mask=${card^^}_NETMASK

				boot_mesg "Create bridge for ${card}..."
				ifconfig ${card,,}0 0.0.0.0

				ip link set ${card,,}0 down

				ip link set ${card,,}0 name ${card,,}1

				brctl addbr ${card,,}0

				ifconfig ${card,,}0 ${!adress} netmask ${!mask}

				brctl addif ${card,,}0 ${card,,}1

				ip link set ${card,,}1 up 

				evaluate_retval

				fi
		done < ${a_file}
	   ;;

   stop)
		while read line; 
		do 
			card=$(echo $line | cut -f1 -d=)
			bool=$(echo $line | cut -f2 -d=)
			if [ ${bool,,} = "yes" ];then
				adress=${card^^}_ADDRESS
				mask=${card^^}_NETMASK
				boot_mesg "Remove bridge for ${card,,}..."

				brctl delif ${card,,}0 ${card,,}1 

				ifconfig ${card,,}0 0.0.0.0	

				ip link set ${card,,}1 down 
				ip link set ${card,,}0 down 

				brctl delbr ${card,,}0

				ip link set ${card,,}1 name ${card,,}0

				ip link set ${card,,}0 up 

				ifconfig ${card,,}0 ${!adress} netmask ${!mask}

				evaluate_retval
			fi

		done < ${a_file}

      ;;
   *)
      echo "Usage: ${0} {start|stop}"
      exit 1
      ;;
esac

# End $rc_base/init.d/bridge

Créer le fichier de configuration des bridges, donner le droits d’exécution du script, établir les liens symboliques pour le boot et lancer le script pour créer le bridge.

cat << EOF > /etc/default/bridge
orange=yes
EOF
chmod +x /etc/init.d/bridge
ln -s /etc/init.d/bridge /etc/rc.d/rc3.d/S21bridge
ln -s /etc/init.d/bridge /etc/rc.d/rc0.d/K83bridge
ln -s /etc/init.d/bridge /etc/rc.d/rc6.d/K83bridge
/etc/init.d/bridge start

3/ Création d'une machine virtuelle

Copier le script dans le répertoire /etc/init.d, il sert à créer si besoin le disque dur virtuel et boot dans la foulé sur une iso (à spécifier dans le script), si l'image disque existe déjà, la machine y boot.

Le script est téléchargeable ici.

#!/bin/sh
########################################################################
# Name Script : vhost
#
#
#
#
# Description : script use to create a virtual host
#
########################################################################
# cat /etc/vhost/XXX.vhost
# INDEX=1
# RAM=
# DISK=/home/qemu/example.img
# BRIDGE=orange
# MAC_TAP="72:A3:C3:F7:6F:01"
# MAC_NET="72:A3:C3:F7:6F:03"
# ISO=/home/qemu/example.iso
# BOOT=d to force iso start at boot

# cat /etc/default/vhost
# SIZE=8G
# KEYBOARD=fr
# BOOT=c
# RAM=512M

. /etc/sysconfig/rc
. ${rc_functions}

stop_host(){
	. ${1}
	HOST=${1##*/}
	PID_FILE=/var/run/${HOST}.pid
	FILE_MONITOR=/var/run/${HOST}

	if [ -S ${FILE_MONITOR} ]; then		
		boot_mesg "Send shutdown to virtual host ${HOST}..."
		/usr/local/sbin/shutdown.pm ${HOST}
		evaluate_retval
		sleep 15
	fi

	boot_mesg "Removing tap${INDEX} from ${BRIDGE} bridge..." 

	ip link set tap${INDEX} down 

	brctl delif ${BRIDGE} tap${INDEX}
	evaluate_retval

	boot_mesg "Destroying tap${INDEX} ..." 
	COUNTER=10
	tunctl -d tap${INDEX}
	while [[ $? != 0   &&  ${COUNTER} > 0 ]];
	do
		sleep 5
		COUNTER=$((${COUNTER}-1))
		tunctl -d tap${INDEX}
	done
	if [[ $? != 0 ]]; then
		kill -9 ${PID_FILE}
		sleep 1
		tunctl -d tap${INDEX}
	fi

	rm ${PID_FILE}
	rm ${FILE_MONITOR}

	evaluate_retval
	
}
start_host(){
	. /etc/default/vhost
	. ${1}
	HOST=${1##*/}
	PID_FILE=/var/run/${HOST}.pid
	FILE_MONITOR=/var/run/${HOST}
	GREEN=`ifconfig green0 | grep 'inet addr:' | cut -d: -f2 | awk '{ print $1}'`
	_KEYBOARD="-k ${KEYBOARD}"
	_RAM="-m ${RAM}"

	# VNC access, usable with TightVNC
	_VNC="-vnc ${GREEN}:${INDEX}"

	_NET="-netdev type=tap,id=net0,ifname=tap${INDEX},script=no,downscript=no,vhost=on -device virtio-net,netdev=net0,mac=${MAC_NET}"
	
	if test "${ISO}" == ""; then
		_DISK="-drive file=${DISK},if=virtio"
	else
		_DISK="-drive file=${DISK},if=virtio -cdrom ${ISO}"
	fi

	if ! test -f ${DISK}; then
		qemu-img create -f qcow2 ${DISK} ${SIZE}
		_BOOT="-boot d"
	else
		if ! test "${BOOT}" == ""; then
			_BOOT="-boot ${BOOT}"
		else
			_BOOT="-boot c"
		fi
	fi

	boot_mesg "Creating tap${INDEX} for virtual host ${HOST}..."
	ip tuntap add mode tap dev tap${INDEX}
	
	# assign MAC address to tapX
	ip link set tap${INDEX} address ${MAC_TAP}
	
	# Change settings on tapX to improve performance for virtio
	ethtool --offload tap${INDEX} gso off tso off
	evaluate_retval 
	
	sleep 1
	boot_mesg "Adding tap${INDEX} to ${BRIDGE} bridge..."

	# Add real green nic
	brctl addif ${BRIDGE} tap${INDEX}

	# Bring nic's up
	ip link set tap${INDEX} up
	evaluate_retval 

	boot_mesg "Starting virtual host ${HOST}..." 
	qemu-system-x86_64 -enable-kvm -daemonize -cpu host \
		${_KEYBOARD} \
		${_BOOT} \
		${_DISK} \
		${_VNC} \
		${_RAM} \
		${_NET} \
		-monitor unix:${FILE_MONITOR},server,nowait,nodelay \
		-pidfile ${PID_FILE}
		evaluate_retval
}
stop(){
	for f in $(find /etc/vhost/ -iname "*.vhost"); do
		stop_host $f
	done
}
start(){
	for f in $(find /etc/vhost/ -iname "*.vhost"); do
		start_host $f
	done
}
status(){
	C_RED='\033[0;31m'
	C_GREEN='\033[0;32m'
	NC='\033[0m' # No Color
	for f in $(find /etc/vhost/ -iname "${1}*.vhost"); do
		a_File=$(readlink -f $f)
		HOST=${a_File##*/}
		PID_FILE=/var/run/${HOST}.pid
		if [ -f ${PID_FILE} ]; then
			echo  -e "${NC}${HOST}${C_GREEN}\t" `cat ${PID_FILE}` "${NC}"
		else
			echo -e "${NC}${HOST}${C_RED}\t not start${NC}"
		fi	
	done
}
case "${1}" in
	start)
		if ! test "${2}" == "" ; then
			if test -f "/etc/vhost/${2}.vhost" ; then
				start_host /etc/vhost/${2}.vhost
			fi
		else
			start
		fi
		
	;;
	stop)
		if ! test "${2}" == "" ; then
			if test -f "/etc/vhost/${2}.vhost" ; then
				stop_host /etc/vhost/${2}.vhost
			fi
		else
			stop
		fi
	;;
	status)
		status
	;;
	*)
		echo "Usage: ${0} {start|stop|status}"
		exit 1
	;;
esac

Créer le fichier d’attribution des bridges, donner le droits d’exécution du script, établir les liens symboliques pour le boot et lancer le script pour créer le bridge.

chmod +x /etc/init.d/vhost
ln -s /etc/init.d/vhost /etc/rc.d/rc3.d/S99vhost
ln -s /etc/init.d/vhost /etc/rc.d/rc0.d/K01vhost
ln -s /etc/init.d/vhost /etc/rc.d/rc6.d/K01vhost

Il est nécessaire de créer un fichier .vhost par machine virtuelle dans le répertoire /etc/vhost/ pour que le script lance une nouvelle virtualisation.

mkdir /etc/vhost
cat << EOF > /etc/vhost/une_machine.vhost
INDEX=1
RAM=512M
DISK=/PATH/TO/IMG/XXX.img
SIZE=10G
MAC_TAP="01:AA:01:AA:01:AB"
MAC_NET="01:AA:01:AA:01:AA"
ISO=/PATH/TO/ISO
EOF

/etc/init.d/vhost start une_machine

Pour que la machine virtuelle puisse communiquer, il ne reste plus qu'à lui attribuer une adresses IP de même réseau.

Pour que la machine virtuelle s’éteigne correctement, il manque un script perl  (grand merci à hadfl du forum d'Ipfire).
Le script est téléchargeable ici.

#!/usr/bin/perl -w

use strict;
use warnings;
use IO::Socket::UNIX qw(SOCK_STREAM);

my $RUN_PATH="/var/run";

my $sendMonitor = sub {
    my $name = shift;
    my $msg  = shift;
    print "$RUN_PATH/$name $msg";

    my $sock = IO::Socket::UNIX->new(
        Type => SOCK_STREAM,
        Peer => "$RUN_PATH/$name",
    ) || do {
        print "Cannot open socket $!\n";
        exit 1;
    };
    print $sock $msg;
# print $sock "$msg\n";
    $sock->close();
};

my $acpiShutdown = sub {
    $sendMonitor->(shift, "system_powerdown\n");
};

$acpiShutdown->($ARGV[0]);

1;

4/ Redirection des ports de red0 vers orange0

Surtout, ne pas ajouter d'autres règles comme ACCEPT en entrée sur red, seul une redirection NAT est nécessaire pour accéder à la machine virtuelle dans la DMZ orange. Remplir le formulaire comme ci-dessous.

 

Comments

This post currently has 2 responses

  • Bonjour,

    Je trouve que ton site est tres instructif et bien monter

    Dans la vm j'ai installer ubuntu server 32bit et un plex server (qui fontionne bien). Pour ajouter des fichiers facilement, dans IPfire j'ai installer le addons SMB pour partager un disque dur sur le GREEN.
    Dans le script vhost de la vm j'ai ajouter la commande -smb pour avoir acces au meme disque, par contre je n'arrive pas a le mounter. Avez-vous des suggestion?
    Merci

    J'ai trouver quelques petites erreurs probablement causer par des copie/coller

    Dans le script bridge a la ligne 38 et 69 et dans le script dessous (creation de /root/ipfire/bridge), il y a des < et > qui devrai etre

    Dans le script vhost:
    a la ligne 47, il faut enlever les && a la fin de la ligne
    a la ligne 90, dans le site web il manque la fin de la commande, mais quand on la copie elle est sur une autre ligne ce qui fait bugger le script

    Quand on creer le fichier une_machine.vhost, le mac pour la carte reseau dans la vm ne peut pas etre configurer. Suggerer d'aller sur http://www.miniwebtool.com/mac-address-generator/ pour avoir un autre mac adresse

    • Bonjour

      Merci (en retard), pour votre commentaire, je viens de mettre à jour les script.

      Pour partager un répertoire, comme la racine /, entre deux linux, le mieux reste nfs.

      Les adresses MAC sont à fixer avant et s'assurer que les ponts réseaux sont bien mis en place avant la création de la machine virtuelle.


      # [root@ipfire ~] cat /root/ipfire/bridge
      green=yes
      # [root@ipfire ~] cat /root/ipfire/vhost/jessie.vhost
      # VNC access, use with TightVNC
      INDEX=3
      DISK=64G
      PATH_IMAGE=/home/qemu/jessie.vhost.img
      BRIDGE=green
      RAM=512M
      TAP=tap${INDEX}
      MAC_TAP="72:A3:C3:F7:67:04"
      MAC_NET="72:A3:C3:F7:67:06"

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.

Sidebar